da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * fields enclosed by brackets "[]" replaced with your own identifying
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * SMB Node State Machine
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * ----------------------
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright *
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * +----------- Creation/Allocation
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * |
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * | T0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * v
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * +----------------------------+
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * | SMB_NODE_STATE_AVAILABLE |
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * +----------------------------+
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * |
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * | T1
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * |
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * v
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * +-----------------------------+
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * | SMB_NODE_STATE_DESTROYING |
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * +-----------------------------+
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * |
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * |
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * | T2
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * |
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright * +----------> Deletion/Free
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Transition T0
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_node_lookup(). If the node looked for is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * not found in the has table a new node is created. The reference count is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * initialized to 1 and the state initialized to SMB_NODE_STATE_AVAILABLE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Transition T1
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_node_release(). If the reference count
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * drops to zero the state is moved to SMB_NODE_STATE_DESTROYING and no more
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * reference count will be given out for that node.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Transition T2
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This transition occurs in smb_node_release(). The structure is deleted.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Comments
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * --------
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * The reason the smb node has 2 states is the following synchronization
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * rule:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * There's a mutex embedded in the node used to protect its fields and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * there's a lock embedded in the bucket of the hash table the node belongs
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to. To increment or to decrement the reference count the mutex must be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * entered. To insert the node into the bucket and to remove it from the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * bucket the lock must be entered in RW_WRITER mode. When both (mutex and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * lock) have to be entered, the lock has always to be entered first then
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the mutex. This prevents a deadlock between smb_node_lookup() and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node_release() from occurring. However, in smb_node_release() when the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * reference count drops to zero and triggers the deletion of the node, the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * mutex has to be released before entering the lock of the bucket (to
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * remove the node). This creates a window during which the node that is
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * about to be freed could be given out by smb_node_lookup(). To close that
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * window the node is moved to the state SMB_NODE_STATE_DESTROYING before
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * releasing the mutex. That way, even if smb_node_lookup() finds it, the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * state will indicate that the node should be treated as non existent (of
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * course the state of the node should be tested/updated under the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * protection of the mutex).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
bbf6f00c25b6a2bed23c35eac6d62998ecdb338cJordan Brown#include <smbsrv/smb_kproto.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <smbsrv/smb_fsops.h>
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego#include <smbsrv/smb_kstat.h>
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk#include <sys/ddi.h>
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk#include <sys/extdirent.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/pathname.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#include <sys/sdt.h>
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as#include <sys/nbmlock.h>
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States#include <fs/fs_reparse.h>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregouint32_t smb_is_executable(char *);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void smb_node_delete_on_close(smb_node_t *);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void smb_node_create_audit_buf(smb_node_t *, int);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void smb_node_destroy_audit_buf(smb_node_t *);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void smb_node_audit(smb_node_t *);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshstatic smb_node_t *smb_node_alloc(char *, vnode_t *, smb_llist_t *, uint32_t);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void smb_node_free(smb_node_t *);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic int smb_node_constructor(void *, void *, int);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void smb_node_destructor(void *, void *);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic smb_llist_t *smb_node_get_hash(fsid_t *, smb_attr_t *, uint32_t *);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void smb_node_init_reparse(smb_node_t *, smb_attr_t *);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void smb_node_init_system(smb_node_t *);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw#define VALIDATE_DIR_NODE(_dir_, _node_) \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT((_dir_)->n_magic == SMB_NODE_MAGIC); \
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(((_dir_)->vp->v_xattrdir) || ((_dir_)->vp->v_type == VDIR)); \
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ASSERT((_dir_)->n_dnode != (_node_));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai/* round sz to DEV_BSIZE block */
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai#define SMB_ALLOCSZ(sz) (((sz) + DEV_BSIZE-1) & ~(DEV_BSIZE-1))
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic kmem_cache_t *smb_node_cache = NULL;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbstatic smb_llist_t smb_node_hash_table[SMBND_HASH_MASK+1];
8622ec4569457733001d4982ef7f5b44427069beGordon Rossstatic smb_node_t *smb_root_node;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb/*
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * smb_node_init
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb *
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * Initialization of the SMB node layer.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb *
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * This function is not multi-thread safe. The caller must make sure only one
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * thread makes the call.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb */
8622ec4569457733001d4982ef7f5b44427069beGordon Rossvoid
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_node_init(void)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_attr_t attr;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_llist_t *node_hdr;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_node_t *node;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross uint32_t hashkey;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross int i;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross
8622ec4569457733001d4982ef7f5b44427069beGordon Ross if (smb_node_cache != NULL)
8622ec4569457733001d4982ef7f5b44427069beGordon Ross return;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_cache = kmem_cache_create(SMBSRV_KSTAT_NODE_CACHE,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego sizeof (smb_node_t), 8, smb_node_constructor, smb_node_destructor,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego NULL, NULL, NULL, 0);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb for (i = 0; i <= SMBND_HASH_MASK; i++) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_llist_constructor(&smb_node_hash_table[i],
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sizeof (smb_node_t), offsetof(smb_node_t, n_lnd));
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
8622ec4569457733001d4982ef7f5b44427069beGordon Ross
8622ec4569457733001d4982ef7f5b44427069beGordon Ross /*
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * The node cache is shared by all zones, so the smb_root_node
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * must represent the real (global zone) rootdir.
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * Note intentional use of kcred here.
8622ec4569457733001d4982ef7f5b44427069beGordon Ross */
8622ec4569457733001d4982ef7f5b44427069beGordon Ross attr.sa_mask = SMB_AT_ALL;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross VERIFY0(smb_vop_getattr(rootdir, NULL, &attr, 0, kcred));
8622ec4569457733001d4982ef7f5b44427069beGordon Ross node_hdr = smb_node_get_hash(&rootdir->v_vfsp->vfs_fsid, &attr,
8622ec4569457733001d4982ef7f5b44427069beGordon Ross &hashkey);
8622ec4569457733001d4982ef7f5b44427069beGordon Ross node = smb_node_alloc("/", rootdir, node_hdr, hashkey);
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_llist_enter(node_hdr, RW_WRITER);
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_llist_insert_head(node_hdr, node);
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_llist_exit(node_hdr);
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_root_node = node; /* smb_node_release in smb_node_fini */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb/*
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * smb_node_fini
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb *
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * This function is not multi-thread safe. The caller must make sure only one
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * thread makes the call.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbvoid
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsmb_node_fini(void)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb{
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int i;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
8622ec4569457733001d4982ef7f5b44427069beGordon Ross if (smb_root_node != NULL) {
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_node_release(smb_root_node);
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_root_node = NULL;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross }
8622ec4569457733001d4982ef7f5b44427069beGordon Ross
8622ec4569457733001d4982ef7f5b44427069beGordon Ross if (smb_node_cache == NULL)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb return;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb#ifdef DEBUG
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb for (i = 0; i <= SMBND_HASH_MASK; i++) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_node_t *node;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb /*
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * The following sequence is just intended for sanity check.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * This will have to be modified when the code goes into
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * production.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb *
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * The SMB node hash table should be emtpy at this point. If the
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * hash table is not empty a panic will be triggered.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb *
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * The reason why SMB nodes are still remaining in the hash
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * table is problably due to a mismatch between calls to
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * smb_node_lookup() and smb_node_release(). You must track that
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb * down.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb */
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb node = smb_llist_head(&smb_node_hash_table[i]);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ASSERT(node == NULL);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb#endif
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb for (i = 0; i <= SMBND_HASH_MASK; i++) {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb smb_llist_destructor(&smb_node_hash_table[i]);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego kmem_cache_destroy(smb_node_cache);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_cache = NULL;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb}
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node_lookup()
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * NOTE: This routine should only be called by the file system interface layer,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * and not by SMB.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node_lookup() is called upon successful lookup, mkdir, and create
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * (for both non-streams and streams). In each of these cases, a held vnode is
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * passed into this routine. If a new smb_node is created it will take its
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * own hold on the vnode. The caller's hold therefore still belongs to, and
7f667e74610492ddbce8ce60f52ece95d2401949jose borrego * should be released by, the caller.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * A reference is taken on the smb_node whether found in the hash table
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * or newly created.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If an smb_node needs to be created, a reference is also taken on the
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * dnode (if passed in).
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * See smb_node_release() for details on the release of these references.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*ARGSUSED*/
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_node_t *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_node_lookup(
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct smb_request *sr,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw struct open_param *op,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw cred_t *cred,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw vnode_t *vp,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *od_name,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_node_t *dnode,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_node_t *unode)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_t *node_hdr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *node;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_attr_t attr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw uint32_t hashkey = 0;
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego fsid_t fsid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int error;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw krw_t lock_mode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw vnode_t *unnamed_vp = NULL;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_vop_getattr() is called here instead of smb_fsop_getattr(),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * because the node may not yet exist. We also do not want to call
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * it with the list lock held.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (unode)
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown unnamed_vp = unode->vp;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This getattr is performed on behalf of the server
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * that's why kcred is used not the user's cred
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh attr.sa_mask = SMB_AT_ALL;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross error = smb_vop_getattr(vp, unnamed_vp, &attr, 0, zone_kcred());
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (error)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego if (sr && sr->tid_tree) {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * The fsid for a file is that of the tree, even
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * if the file resides in a different mountpoint
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * under the share.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego fsid = SMB_TREE_FSID(sr->tid_tree);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego /*
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * This should be getting executed only for the
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego * tree root smb_node.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego */
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego fsid = vp->v_vfsp->vfs_fsid;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh node_hdr = smb_node_get_hash(&fsid, &attr, &hashkey);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lock_mode = RW_READER;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(node_hdr, lock_mode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (;;) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node = list_head(&node_hdr->ll_list);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw while (node) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(node->n_magic == SMB_NODE_MAGIC);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(node->n_hash_bucket == node_hdr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((node->n_hashkey == hashkey) && (node->vp == vp)) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_enter(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DTRACE_PROBE1(smb_node_lookup_hit,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (node->n_state) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_NODE_STATE_AVAILABLE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /* The node was found. */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->n_refcnt++;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if ((node->n_dnode == NULL) &&
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (dnode != NULL) &&
96a62ada8aa6cb19b04270da282e7e21ba74b808joyce mcintosh (node != dnode) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (strcmp(od_name, "..") != 0) &&
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (strcmp(od_name, ".") != 0)) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown VALIDATE_DIR_NODE(dnode, node);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown node->n_dnode = dnode;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_node_ref(dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_audit(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(node_hdr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_NODE_STATE_DESTROYING:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Although the node exists it is about
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * to be destroyed. We act as it hasn't
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * been found.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Although the node exists it is in an
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * unknown state. We act as it hasn't
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * been found.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(0);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node = smb_llist_next(node_hdr, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if ((lock_mode == RW_READER) && smb_llist_upgrade(node_hdr)) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw lock_mode = RW_WRITER;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw continue;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw break;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh node = smb_node_alloc(od_name, vp, node_hdr, hashkey);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_init_reparse(node, &attr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (op)
eb1d736b1c19f6abeee90c921a9320b67fedd016afshin salek ardakani - Sun Microsystems - Irvine United States node->flags |= smb_is_executable(op->fqi.fq_last_comp);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (dnode) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_node_ref(dnode);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown node->n_dnode = dnode;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ASSERT(dnode->n_dnode != node);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ASSERT((dnode->vp->v_xattrdir) ||
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown (dnode->vp->v_type == VDIR));
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (unode) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_node_ref(unode);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown node->n_unode = unode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_init_system(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DTRACE_PROBE1(smb_node_lookup_miss, smb_node_t *, node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_audit(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_insert_head(node_hdr, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(node_hdr);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_stream_node_lookup()
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Note: stream_name (the name that will be stored in the "od_name" field
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * of a stream's smb_node) is the same as the on-disk name for the stream
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * except that it does not have SMB_STREAM_PREFIX prepended.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_node_t *
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_stream_node_lookup(smb_request_t *sr, cred_t *cr, smb_node_t *fnode,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh vnode_t *xattrdirvp, vnode_t *vp, char *stream_name)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *xattrdir_node;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *snode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw xattrdir_node = smb_node_lookup(sr, NULL, cr, xattrdirvp, XATTR_DIR,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh fnode, NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (xattrdir_node == NULL)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (NULL);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw snode = smb_node_lookup(sr, NULL, cr, vp, stream_name, xattrdir_node,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh fnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw (void) smb_node_release(xattrdir_node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return (snode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * This function should be called whenever a reference is needed on an
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node pointer. The copy of an smb_node pointer from one non-local
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * data structure to another requires a reference to be taken on the smb_node
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * (unless the usage is localized). Each data structure deallocation routine
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * will call smb_node_release() on its smb_node pointers.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * In general, an smb_node pointer residing in a structure should never be
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * stale. A node pointer may be NULL, however, and care should be taken
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * prior to calling smb_node_ref(), which ASSERTs that the pointer is valid.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Care also needs to be taken with respect to racing deallocations of a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * structure.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_node_ref(smb_node_t *node)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_enter(&node->n_mutex);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego switch (node->n_state) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego case SMB_NODE_STATE_AVAILABLE:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_refcnt++;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego ASSERT(node->n_refcnt);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego DTRACE_PROBE1(smb_node_ref_exit, smb_node_t *, node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_audit(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego break;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego default:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_PANIC();
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node_lookup() takes a hold on an smb_node, whether found in the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * hash table or newly created. This hold is expected to be released
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * in the following manner.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node_lookup() takes an address of an smb_node pointer. This should
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * be getting passed down via a lookup (whether path name or component), mkdir,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * create. If the original smb_node pointer resides in a data structure, then
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * the deallocation routine for the data structure is responsible for calling
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node_release() on the smb_node pointer. Alternatively,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node_release() can be called as soon as the smb_node pointer is no longer
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * needed. In this case, callers are responsible for setting an embedded
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * pointer to NULL if it is known that the last reference is being released.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * If the passed-in address of the smb_node pointer belongs to a local variable,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * then the caller with the local variable should call smb_node_release()
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * directly.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * smb_node_release() itself will call smb_node_release() on a node's n_dnode,
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown * as smb_node_lookup() takes a hold on dnode.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_node_release(smb_node_t *node)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_enter(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(node->n_refcnt);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DTRACE_PROBE1(smb_node_release, smb_node_t *, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (--node->n_refcnt == 0) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw switch (node->n_state) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw case SMB_NODE_STATE_AVAILABLE:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->n_state = SMB_NODE_STATE_DESTROYING;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_enter(node->n_hash_bucket, RW_WRITER);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_remove(node->n_hash_bucket, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_llist_exit(node->n_hash_bucket);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw /*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * Check if the file was deleted
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_delete_on_close(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (node->n_dnode) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ASSERT(node->n_dnode->n_magic ==
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NODE_MAGIC);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_node_release(node->n_dnode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown if (node->n_unode) {
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ASSERT(node->n_unode->n_magic ==
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw SMB_NODE_MAGIC);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown smb_node_release(node->n_unode);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_free(node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw return;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw default:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_PANIC();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_audit(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwstatic void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_node_delete_on_close(smb_node_t *node)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw smb_node_t *d_snode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw int rc = 0;
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States uint32_t flags = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown d_snode = node->n_dnode;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE;
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States flags = node->n_delete_on_close_flags;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ASSERT(node->od_name != NULL);
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_dir(node))
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_rmdir(0, node->delete_on_close_cred,
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States d_snode, node->od_name, flags);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw else
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw rc = smb_fsop_remove(0, node->delete_on_close_cred,
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States d_snode, node->od_name, flags);
148c5f43199ca0b43fc8e3b643aab11cd66ea327Alan Wright crfree(node->delete_on_close_cred);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (rc != 0)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw cmn_err(CE_WARN, "File %s could not be removed, rc=%d\n",
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->od_name, rc);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw DTRACE_PROBE2(smb_node_delete_on_close, int, rc, smb_node_t *, node);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw/*
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw * smb_node_rename()
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw *
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregovoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_node_rename(
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_t *from_dnode,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_t *ret_node,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_t *to_dnode,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw char *to_name)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(from_dnode);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(to_dnode);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(ret_node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_ref(to_dnode);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_enter(&ret_node->n_mutex);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego switch (ret_node->n_state) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego case SMB_NODE_STATE_AVAILABLE:
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ret_node->n_dnode = to_dnode;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&ret_node->n_mutex);
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown ASSERT(to_dnode->n_dnode != ret_node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego ASSERT((to_dnode->vp->v_xattrdir) ||
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (to_dnode->vp->v_type == VDIR));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_release(from_dnode);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (void) strcpy(ret_node->od_name, to_name);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego /*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * XXX Need to update attributes?
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego break;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego default:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_PANIC();
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8622ec4569457733001d4982ef7f5b44427069beGordon Ross/*
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * Find/create an SMB node for the root of this zone and store it
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * in *svrootp. Also create nodes leading to this directory.
8622ec4569457733001d4982ef7f5b44427069beGordon Ross */
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwint
8622ec4569457733001d4982ef7f5b44427069beGordon Rosssmb_node_root_init(smb_server_t *sv, smb_node_t **svrootp)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
8622ec4569457733001d4982ef7f5b44427069beGordon Ross zone_t *zone = curzone;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb int error;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8622ec4569457733001d4982ef7f5b44427069beGordon Ross ASSERT(zone->zone_id == sv->sv_zid);
8622ec4569457733001d4982ef7f5b44427069beGordon Ross if (smb_root_node == NULL)
8622ec4569457733001d4982ef7f5b44427069beGordon Ross return (ENOENT);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
8622ec4569457733001d4982ef7f5b44427069beGordon Ross /*
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * We're getting smb nodes below the zone root here,
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * so need to use kcred, not zone_kcred().
8622ec4569457733001d4982ef7f5b44427069beGordon Ross */
8622ec4569457733001d4982ef7f5b44427069beGordon Ross error = smb_pathname(NULL, zone->zone_rootpath, 0,
8622ec4569457733001d4982ef7f5b44427069beGordon Ross smb_root_node, smb_root_node, NULL, svrootp, kcred);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
8622ec4569457733001d4982ef7f5b44427069beGordon Ross return (error);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk/*
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk * Helper function for smb_node_set_delete_on_close(). Assumes node is a dir.
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk * Return 0 if this is an empty dir. Otherwise return a NT_STATUS code.
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk * We distinguish between readdir failure and non-empty dir by returning
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk * different values.
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk */
5496c1178a1a48006226450b13c2df195831794cAlek Pinchukstatic uint32_t
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuksmb_rmdir_possible(smb_node_t *n, uint32_t flags)
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk{
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk ASSERT(n->vp->v_type == VDIR);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk char buf[512]; /* Only large enough to see if the dir is empty. */
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk int eof, bsize = sizeof (buf), reclen = 0;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk char *name;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk boolean_t edp = vfs_has_feature(n->vp->v_vfsp, VFSFT_DIRENTFLAGS);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk union {
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk char *u_bufptr;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk struct edirent *u_edp;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk struct dirent64 *u_dp;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk } u;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk#define bufptr u.u_bufptr
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk#define extdp u.u_edp
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk#define dp u.u_dp
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk if (smb_vop_readdir(n->vp, 0, buf, &bsize, &eof, flags, zone_kcred()))
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (NT_STATUS_CANNOT_DELETE);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk if (bsize == 0)
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (NT_STATUS_CANNOT_DELETE);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk bufptr = buf;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk while ((bufptr += reclen) < buf + bsize) {
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk if (edp) {
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk reclen = extdp->ed_reclen;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk name = extdp->ed_name;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk } else {
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk reclen = dp->d_reclen;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk name = dp->d_name;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk }
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk if (strcmp(name, ".") != 0 && strcmp(name, "..") != 0)
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (NT_STATUS_DIRECTORY_NOT_EMPTY);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk }
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (0);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States/*
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * When DeleteOnClose is set on an smb_node, the common open code will
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * reject subsequent open requests for the file. Observation of Windows
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * 2000 indicates that subsequent opens should be allowed (assuming
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * there would be no sharing violation) until the file is closed using
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * the fid on which the DeleteOnClose was requested.
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States *
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * If there are multiple opens with delete-on-close create options,
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * whichever the first file handle is closed will trigger the node to be
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * marked as delete-on-close. The credentials of that ofile will be used
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States * as the delete-on-close credentials of the node.
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States */
5496c1178a1a48006226450b13c2df195831794cAlek Pinchukuint32_t
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_set_delete_on_close(smb_node_t *node, cred_t *cr, uint32_t flags)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright int rc = 0;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk uint32_t status;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_attr_t attr;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (node->n_pending_dosattr & FILE_ATTRIBUTE_READONLY)
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (NT_STATUS_CANNOT_DELETE);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh bzero(&attr, sizeof (smb_attr_t));
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh attr.sa_mask = SMB_AT_DOSATTR;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = smb_fsop_getattr(NULL, zone_kcred(), node, &attr);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if ((rc != 0) || (attr.sa_dosattr & FILE_ATTRIBUTE_READONLY)) {
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (NT_STATUS_CANNOT_DELETE);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk }
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk /*
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk * If the directory is not empty we should fail setting del-on-close
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk * with STATUS_DIRECTORY_NOT_EMPTY. see MS's
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk * "File System Behavior Overview" doc section 4.3.2
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk */
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk if (smb_node_is_dir(node)) {
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk status = smb_rmdir_possible(node, flags);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk if (status != 0) {
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (status);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright mutex_enter(&node->n_mutex);
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk mutex_exit(&node->n_mutex);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (NT_STATUS_CANNOT_DELETE);
a0aa776e20803c84edd153d9cb584fd67163aef3Alan Wright }
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk crhold(cr);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk node->delete_on_close_cred = cr;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk node->n_delete_on_close_flags = flags;
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk node->flags |= NODE_FLAGS_DELETE_ON_CLOSE;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross /*
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * Tell any change notify calls to close their handles
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * and get out of the way. FILE_ACTION_DELETE_PENDING
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross * is a special, internal-only action for this purpose.
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross */
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_notify_event(node, FILE_ACTION_DELETE_PENDING, NULL);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross
5496c1178a1a48006226450b13c2df195831794cAlek Pinchuk return (NT_STATUS_SUCCESS);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwvoid
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsmb_node_reset_delete_on_close(smb_node_t *node)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_enter(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw crfree(node->delete_on_close_cred);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw node->delete_on_close_cred = NULL;
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States node->n_delete_on_close_flags = 0;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_exit(&node->n_mutex);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw}
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as/*
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb * smb_node_open_check
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as *
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * check file sharing rules for current open request
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * against all existing opens for a file.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as *
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Returns NT_STATUS_SHARING_VIOLATION if there is any
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * sharing conflict, otherwise returns NT_STATUS_SUCCESS.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asuint32_t
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_open_check(smb_node_t *node, uint32_t desired_access,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States uint32_t share_access)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as{
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_ofile_t *of;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as uint32_t status;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_llist_enter(&node->n_ofile_list, RW_READER);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as of = smb_llist_head(&node->n_ofile_list);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as while (of) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States status = smb_ofile_open_check(of, desired_access, share_access);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb switch (status) {
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb case NT_STATUS_INVALID_HANDLE:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb case NT_STATUS_SUCCESS:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb of = smb_llist_next(&node->n_ofile_list, of);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb break;
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb default:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb ASSERT(status == NT_STATUS_SHARING_VIOLATION);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_llist_exit(&node->n_ofile_list);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as return (status);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb smb_llist_exit(&node->n_ofile_list);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as return (NT_STATUS_SUCCESS);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as}
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asuint32_t
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_rename_check(smb_node_t *node)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_ofile_t *of;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint32_t status;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as /*
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Intra-CIFS check
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_llist_enter(&node->n_ofile_list, RW_READER);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb of = smb_llist_head(&node->n_ofile_list);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb while (of) {
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb status = smb_ofile_rename_check(of);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb switch (status) {
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb case NT_STATUS_INVALID_HANDLE:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb case NT_STATUS_SUCCESS:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb of = smb_llist_next(&node->n_ofile_list, of);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb break;
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb default:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb ASSERT(status == NT_STATUS_SHARING_VIOLATION);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb smb_llist_exit(&node->n_ofile_list);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb return (status);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_llist_exit(&node->n_ofile_list);
bc7c423f80bd757204d3b17cfd74585ae5b30ed8Gordon Ross return (NT_STATUS_SUCCESS);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as}
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
3ad684d66b78e06edd37e2c4fd3b3949f095194bjbuint32_t
dc20a3024900c47dd2ee44b9707e6df38f7d62a5assmb_node_delete_check(smb_node_t *node)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_ofile_t *of;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint32_t status;
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_dir(node))
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as return (NT_STATUS_SUCCESS);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (smb_node_is_reparse(node))
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (NT_STATUS_ACCESS_DENIED);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as /*
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * intra-CIFS check
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_llist_enter(&node->n_ofile_list, RW_READER);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb of = smb_llist_head(&node->n_ofile_list);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb while (of) {
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb status = smb_ofile_delete_check(of);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb switch (status) {
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb case NT_STATUS_INVALID_HANDLE:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb case NT_STATUS_SUCCESS:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb of = smb_llist_next(&node->n_ofile_list, of);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb break;
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb default:
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb ASSERT(status == NT_STATUS_SHARING_VIOLATION);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_llist_exit(&node->n_ofile_list);
3ad684d66b78e06edd37e2c4fd3b3949f095194bjb return (status);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as }
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as smb_llist_exit(&node->n_ofile_list);
bc7c423f80bd757204d3b17cfd74585ae5b30ed8Gordon Ross return (NT_STATUS_SUCCESS);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as}
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * smb_node_share_check
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh *
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * Returns: TRUE - ofiles have non-zero share access
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * B_FALSE - ofile with share access NONE.
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh */
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshboolean_t
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshsmb_node_share_check(smb_node_t *node)
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh{
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_ofile_t *of;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh boolean_t status = B_TRUE;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh SMB_NODE_VALID(node);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_llist_enter(&node->n_ofile_list, RW_READER);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh of = smb_llist_head(&node->n_ofile_list);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh if (of)
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh status = smb_ofile_share_check(of);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh smb_llist_exit(&node->n_ofile_list);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh return (status);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh}
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross/*
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross * SMB Change Notification
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross */
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Rossvoid
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Rosssmb_node_fcn_subscribe(smb_node_t *node, smb_request_t *sr)
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross{
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_node_fcn_t *fcn = &node->n_fcn;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross mutex_enter(&fcn->fcn_mutex);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross if (fcn->fcn_count == 0)
8622ec4569457733001d4982ef7f5b44427069beGordon Ross (void) smb_fem_fcn_install(node);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross fcn->fcn_count++;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross list_insert_tail(&fcn->fcn_watchers, sr);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross mutex_exit(&fcn->fcn_mutex);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross}
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Rossvoid
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Rosssmb_node_fcn_unsubscribe(smb_node_t *node, smb_request_t *sr)
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross{
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_node_fcn_t *fcn = &node->n_fcn;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross mutex_enter(&fcn->fcn_mutex);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross list_remove(&fcn->fcn_watchers, sr);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross fcn->fcn_count--;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross if (fcn->fcn_count == 0)
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_fem_fcn_uninstall(node);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross mutex_exit(&fcn->fcn_mutex);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross}
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross
b1352070d318187b41b088da3533692976f3f225Alan Wrightvoid
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Rosssmb_node_notify_change(smb_node_t *node, uint_t action, const char *name)
b1352070d318187b41b088da3533692976f3f225Alan Wright{
b1352070d318187b41b088da3533692976f3f225Alan Wright SMB_NODE_VALID(node);
b1352070d318187b41b088da3533692976f3f225Alan Wright
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_notify_event(node, action, name);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross /*
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross * These two events come as a pair:
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross * FILE_ACTION_RENAMED_OLD_NAME
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross * FILE_ACTION_RENAMED_NEW_NAME
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross * Only do the parent notify for "new".
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross */
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross if (action == FILE_ACTION_RENAMED_OLD_NAME)
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross return;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_notify_parents(node);
b1352070d318187b41b088da3533692976f3f225Alan Wright}
b1352070d318187b41b088da3533692976f3f225Alan Wright
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States/*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * smb_node_notify_parents
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States *
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Iterate up the directory tree notifying any parent
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * directories that are being watched for changes in
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * their sub directories.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Stop at the root node, which has a NULL parent node.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesvoid
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_notify_parents(smb_node_t *dnode)
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier{
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross smb_node_t *pnode; /* parent */
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_NODE_VALID(dnode);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross pnode = dnode->n_dnode;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross while (pnode != NULL) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_NODE_VALID(pnode);
a90cf9f29973990687fa61de9f1f6ea22e924e40Gordon Ross smb_notify_event(pnode, FILE_ACTION_SUBDIR_CHANGED, NULL);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross /* cd .. */
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross dnode = pnode;
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross pnode = dnode->n_dnode;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier}
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as/*
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * smb_node_start_crit()
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as *
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Enter critical region for share reservations.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * See comments above smb_fsop_shrlock().
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asvoid
dc20a3024900c47dd2ee44b9707e6df38f7d62a5assmb_node_start_crit(smb_node_t *node, krw_t mode)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rw_enter(&node->n_lock, mode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as nbl_start_crit(node->vp, mode);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as}
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as/*
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * smb_node_end_crit()
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as *
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as * Exit critical region for share reservations.
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as */
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asvoid
dc20a3024900c47dd2ee44b9707e6df38f7d62a5assmb_node_end_crit(smb_node_t *node)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as{
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as nbl_end_crit(node->vp);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rw_exit(&node->n_lock);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as}
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as
dc20a3024900c47dd2ee44b9707e6df38f7d62a5asint
dc20a3024900c47dd2ee44b9707e6df38f7d62a5assmb_node_in_crit(smb_node_t *node)
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (nbl_in_crit(node->vp) && RW_LOCK_HELD(&node->n_lock));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregovoid
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_rdlock(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rw_enter(&node->n_lock, RW_READER);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregovoid
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_wrlock(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rw_enter(&node->n_lock, RW_WRITER);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregovoid
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_unlock(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rw_exit(&node->n_lock);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregovoid
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_add_ofile(smb_node_t *node, smb_ofile_t *of)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_enter(&node->n_ofile_list, RW_WRITER);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_insert_tail(&node->n_ofile_list, of);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_exit(&node->n_ofile_list);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregovoid
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_rem_ofile(smb_node_t *node, smb_ofile_t *of)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_enter(&node->n_ofile_list, RW_WRITER);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_remove(&node->n_ofile_list, of);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_exit(&node->n_ofile_list);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh/*
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * smb_node_inc_open_ofiles
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregovoid
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_inc_open_ofiles(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross atomic_inc_32(&node->n_open_count);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh/*
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * smb_node_dec_open_ofiles
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * returns new value
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Rossuint32_t
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_dec_open_ofiles(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross return (atomic_dec_32_nv(&node->n_open_count));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * smb_node_inc_opening_count
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh */
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshvoid
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshsmb_node_inc_opening_count(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross atomic_inc_32(&node->n_opening_count);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh/*
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh * smb_node_dec_opening_count
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh */
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshvoid
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintoshsmb_node_dec_opening_count(smb_node_t *node)
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh{
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh SMB_NODE_VALID(node);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross atomic_dec_32(&node->n_opening_count);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States/*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * smb_node_getmntpath
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesint
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_getmntpath(smb_node_t *node, char *buf, uint32_t buflen)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States vnode_t *vp, *root_vp;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States vfs_t *vfsp;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States int err;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(node->vp);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States ASSERT(node->vp->v_vfsp);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States vp = node->vp;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States vfsp = vp->v_vfsp;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (VFS_ROOT(vfsp, &root_vp))
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (ENOENT);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States VN_HOLD(vp);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States /* NULL is passed in as we want to start at "/" */
8622ec4569457733001d4982ef7f5b44427069beGordon Ross err = vnodetopath(NULL, root_vp, buf, buflen, zone_kcred());
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States VN_RELE(vp);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States VN_RELE(root_vp);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (err);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States/*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * smb_node_getshrpath
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States *
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Determine the absolute pathname of 'node' within the share (tree).
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * For example if the node represents file "test1.txt" in directory
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * "dir1" the pathname would be: \dir1\test1.txt
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesint
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_getshrpath(smb_node_t *node, smb_tree_t *tree,
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States char *buf, uint32_t buflen)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States int rc;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai ASSERT(node);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai ASSERT(tree);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai ASSERT(tree->t_snode);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai rc = smb_node_getpath(node, tree->t_snode->vp, buf, buflen);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai (void) strsubst(buf, '/', '\\');
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai return (rc);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai/*
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * smb_node_getpath
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai *
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * Determine the absolute pathname of 'node' from 'rootvp'.
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai *
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * Using vnodetopath is only reliable for directory nodes (due to
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * its reliance on the DNLC for non-directory nodes). Thus, if node
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * represents a file, construct the pathname for the parent dnode
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * and append filename.
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * If node represents a named stream, construct the pathname for the
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * associated unnamed stream and append the stream name.
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai *
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai * The pathname returned in buf will be '/' separated.
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai */
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desaiint
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desaismb_node_getpath(smb_node_t *node, vnode_t *rootvp, char *buf, uint32_t buflen)
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai{
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai int rc;
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai vnode_t *vp;
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai smb_node_t *unode, *dnode;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross cred_t *kcr = zone_kcred();
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai unode = (SMB_IS_STREAM(node)) ? node->n_unode : node;
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai dnode = (smb_node_is_dir(unode)) ? unode : unode->n_dnode;
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai /* find path to directory node */
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai vp = dnode->vp;
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai VN_HOLD(vp);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai if (rootvp) {
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai VN_HOLD(rootvp);
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = vnodetopath(rootvp, vp, buf, buflen, kcr);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai VN_RELE(rootvp);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai } else {
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = vnodetopath(NULL, vp, buf, buflen, kcr);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai }
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai VN_RELE(vp);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai if (rc != 0)
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai return (rc);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai /* append filename if necessary */
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai if (!smb_node_is_dir(unode)) {
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai if (buf[strlen(buf) - 1] != '/')
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai (void) strlcat(buf, "/", buflen);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai (void) strlcat(buf, unode->od_name, buflen);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai /* append named stream name if necessary */
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai if (SMB_IS_STREAM(node))
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai (void) strlcat(buf, node->od_name, buflen);
c586600796766c83eb9485c446886fd9ed2359a9Keyur Desai
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (rc);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * smb_node_alloc
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic smb_node_t *
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_alloc(
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego char *od_name,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego vnode_t *vp,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_t *bucket,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint32_t hashkey)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_t *node;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States vnode_t *root_vp;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node = kmem_cache_alloc(smb_node_cache, KM_SLEEP);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (node->n_audit_buf != NULL)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_audit_buf->anb_index = 0;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh node->flags = 0;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego VN_HOLD(vp);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->vp = vp;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_refcnt = 1;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_hash_bucket = bucket;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_hashkey = hashkey;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross node->n_pending_dosattr = 0;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_open_count = 0;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross node->n_allocsz = 0;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown node->n_dnode = NULL;
1fcced4c370617db71610fecffd5451a5894ca5eJordan Brown node->n_unode = NULL;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->delete_on_close_cred = NULL;
8b2cc8ac894f2d58f38cf2fb7c3ac778f4c57c09afshin salek ardakani - Sun Microsystems - Irvine United States node->n_delete_on_close_flags = 0;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh node->n_oplock.ol_fem = B_FALSE;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh node->n_oplock.ol_xthread = NULL;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh node->n_oplock.ol_count = 0;
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh node->n_oplock.ol_break = SMB_OPLOCK_NO_BREAK;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego (void) strlcpy(node->od_name, od_name, sizeof (node->od_name));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (strcmp(od_name, XATTR_DIR) == 0)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->flags |= NODE_XATTR_DIR;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (VFS_ROOT(vp->v_vfsp, &root_vp) == 0) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (vp == root_vp)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States node->flags |= NODE_FLAGS_VFSROOT;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States VN_RELE(root_vp);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_state = SMB_NODE_STATE_AVAILABLE;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_magic = SMB_NODE_MAGIC;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * smb_node_free
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_free(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_NODE_VALID(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_magic = 0;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego VERIFY(!list_link_active(&node->n_lnd));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego VERIFY(node->n_lock_list.ll_count == 0);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego VERIFY(node->n_ofile_list.ll_count == 0);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh VERIFY(node->n_oplock.ol_count == 0);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego VERIFY(node->n_oplock.ol_xthread == NULL);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh VERIFY(node->n_oplock.ol_fem == B_FALSE);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross VERIFY(MUTEX_NOT_HELD(&node->n_mutex));
fc724630b14603e4c1147df68b7bf45f7de7431fAlan Wright VERIFY(!RW_LOCK_HELD(&node->n_lock));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego VN_RELE(node->vp);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego kmem_cache_free(smb_node_cache, node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * smb_node_constructor
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic int
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_constructor(void *buf, void *un, int kmflags)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego _NOTE(ARGUNUSED(kmflags, un))
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_t *node = (smb_node_t *)buf;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego bzero(node, sizeof (smb_node_t));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_constructor(&node->n_ofile_list, sizeof (smb_ofile_t),
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego offsetof(smb_ofile_t, f_nnd));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_constructor(&node->n_lock_list, sizeof (smb_lock_t),
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego offsetof(smb_lock_t, l_lnd));
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross mutex_init(&node->n_fcn.fcn_mutex, NULL, MUTEX_DEFAULT, NULL);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross list_create(&node->n_fcn.fcn_watchers, sizeof (smb_request_t),
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross offsetof(smb_request_t, sr_ncr.nc_lnd));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego cv_init(&node->n_oplock.ol_cv, NULL, CV_DEFAULT, NULL);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh mutex_init(&node->n_oplock.ol_mutex, NULL, MUTEX_DEFAULT, NULL);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh list_create(&node->n_oplock.ol_grants, sizeof (smb_oplock_grant_t),
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh offsetof(smb_oplock_grant_t, og_lnd));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rw_init(&node->n_lock, NULL, RW_DEFAULT, NULL);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_init(&node->n_mutex, NULL, MUTEX_DEFAULT, NULL);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_create_audit_buf(node, kmflags);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (0);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * smb_node_destructor
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_destructor(void *buf, void *un)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego _NOTE(ARGUNUSED(un))
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_t *node = (smb_node_t *)buf;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_node_destroy_audit_buf(node);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego mutex_destroy(&node->n_mutex);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego rw_destroy(&node->n_lock);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego cv_destroy(&node->n_oplock.ol_cv);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh mutex_destroy(&node->n_oplock.ol_mutex);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross list_destroy(&node->n_fcn.fcn_watchers);
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross mutex_destroy(&node->n_fcn.fcn_mutex);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_destructor(&node->n_lock_list);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_llist_destructor(&node->n_ofile_list);
cb174861876aea6950a7ab4ce944aff84b1914cdjoyce mcintosh list_destroy(&node->n_oplock.ol_grants);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * smb_node_create_audit_buf
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_create_audit_buf(smb_node_t *node, int kmflags)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_audit_buf_node_t *abn;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (smb_audit_flags & SMB_AUDIT_NODE) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego abn = kmem_zalloc(sizeof (smb_audit_buf_node_t), kmflags);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego abn->anb_max_index = SMB_AUDIT_BUF_MAX_REC - 1;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_audit_buf = abn;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * smb_node_destroy_audit_buf
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_destroy_audit_buf(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (node->n_audit_buf != NULL) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego kmem_free(node->n_audit_buf, sizeof (smb_audit_buf_node_t));
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego node->n_audit_buf = NULL;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego/*
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * smb_node_audit
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego *
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * This function saves the calling stack in the audit buffer of the node passed
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego * in.
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic void
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_audit(smb_node_t *node)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#ifdef _KERNEL
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_audit_buf_node_t *abn;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego smb_audit_record_node_t *anr;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego if (node->n_audit_buf) {
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego abn = node->n_audit_buf;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego anr = abn->anb_records;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego anr += abn->anb_index;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego abn->anb_index++;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego abn->anb_index &= abn->anb_max_index;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego anr->anr_refcnt = node->n_refcnt;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego anr->anr_depth = getpcstack(anr->anr_stack,
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego SMB_AUDIT_STACK_DEPTH);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego }
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#else /* _KERNEL */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross _NOTE(ARGUNUSED(node))
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#endif /* _KERNEL */
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego}
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregostatic smb_llist_t *
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregosmb_node_get_hash(fsid_t *fsid, smb_attr_t *attr, uint32_t *phashkey)
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego{
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego uint32_t hashkey;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego hashkey = fsid->val[0] + attr->sa_vattr.va_nodeid;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego hashkey += (hashkey >> 24) + (hashkey >> 16) + (hashkey >> 8);
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego *phashkey = hashkey;
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego return (&smb_node_hash_table[(hashkey & SMBND_HASH_MASK)]);
dc20a3024900c47dd2ee44b9707e6df38f7d62a5as}
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesboolean_t
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_is_file(smb_node_t *node)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_NODE_VALID(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return (node->vp->v_type == VREG);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshboolean_t
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshsmb_node_is_dir(smb_node_t *node)
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh{
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh SMB_NODE_VALID(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return ((node->vp->v_type == VDIR) ||
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (node->flags & NODE_FLAGS_DFSLINK));
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh}
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshboolean_t
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_is_symlink(smb_node_t *node)
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh{
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh SMB_NODE_VALID(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return ((node->vp->v_type == VLNK) &&
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States ((node->flags & NODE_FLAGS_REPARSE) == 0));
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesboolean_t
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_is_dfslink(smb_node_t *node)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_NODE_VALID(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return ((node->vp->v_type == VLNK) &&
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (node->flags & NODE_FLAGS_DFSLINK));
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesboolean_t
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_is_reparse(smb_node_t *node)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_NODE_VALID(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return ((node->vp->v_type == VLNK) &&
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (node->flags & NODE_FLAGS_REPARSE));
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesboolean_t
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_is_vfsroot(smb_node_t *node)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_NODE_VALID(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return ((node->flags & NODE_FLAGS_VFSROOT) == NODE_FLAGS_VFSROOT);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesboolean_t
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_is_system(smb_node_t *node)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States SMB_NODE_VALID(node);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return ((node->flags & NODE_FLAGS_SYSTEM) == NODE_FLAGS_SYSTEM);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh}
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh/*
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * smb_node_file_is_readonly
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Checks if the file (which node represents) is marked readonly
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * in the filesystem. No account is taken of any pending readonly
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * in the node, which must be handled by the callers.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * (See SMB_OFILE_IS_READONLY and SMB_PATHFILE_IS_READONLY)
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshboolean_t
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshsmb_node_file_is_readonly(smb_node_t *node)
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh{
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh smb_attr_t attr;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (node == NULL)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross return (B_FALSE); /* pipes */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (node->n_pending_dosattr & FILE_ATTRIBUTE_READONLY)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross return (B_TRUE);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh bzero(&attr, sizeof (smb_attr_t));
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh attr.sa_mask = SMB_AT_DOSATTR;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross (void) smb_fsop_getattr(NULL, zone_kcred(), node, &attr);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh return ((attr.sa_dosattr & FILE_ATTRIBUTE_READONLY) != 0);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh}
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh/*
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * smb_node_setattr
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * The sr may be NULL, for example when closing an ofile.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * The ofile may be NULL, for example when a client request
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * specifies the file by pathname.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Returns: errno
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross *
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * Timestamps
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Windows and Unix have different models for timestamp updates.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * [MS-FSA 2.1.5.14 Server Requests Setting of File Information]
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * An open "handle" in Windows can control whether and when
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * any timestamp updates happen for that handle. For example,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * timestamps set via some handle are no longer updated by I/O
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * operations on that handle. In Unix we don't really have any
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * way to avoid the timestamp updates that the file system does.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Therefore, we need to make some compromises, and simulate the
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * more important parts of the Windows file system semantics.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * For example, when an SMB client sets file times, set those
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * times in the file system (so the change will be visible to
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * other clients, at least until they change again) but we also
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * make those times "sticky" in our open handle, and reapply
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * those times when the handle is closed. That reapply on close
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * simulates the Windows behavior where the timestamp updates
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * would be discontinued after they were set. These "sticky"
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * attributes are returned in any query on the handle where
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * they are stored.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Other than the above, the file system layer takes care of the
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * normal time stamp updates, such as updating the mtime after a
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * write, and ctime after an attribute change.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Dos Attributes are stored persistently, but with a twist:
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * In Windows, when you set the "read-only" bit on some file,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * existing writable handles to that file continue to have
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * write access. (because access check happens at open)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * If we were to set the read-only bit directly, we would
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * cause errors in subsequent writes on any of our open
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * (and writable) file handles. So here too, we have to
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * simulate the Windows behavior. We keep the read-only
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * bit "pending" in the smb_node (so it will be visible in
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * any new opens of the file) and apply it on close.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * File allocation size is also simulated, and not persistent.
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * When the file allocation size is set it is first rounded up
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * to block size. If the file size is smaller than the allocation
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai * size the file is truncated by setting the filesize to allocsz.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshint
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshsmb_node_setattr(smb_request_t *sr, smb_node_t *node,
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh cred_t *cr, smb_ofile_t *of, smb_attr_t *attr)
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh{
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh int rc;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross uint_t times_mask;
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai smb_attr_t tmp_attr;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh SMB_NODE_VALID(node);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai /* set attributes specified in attr */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (attr->sa_mask == 0)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross return (0); /* nothing to do (caller bug?) */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Allocation size and EOF position interact.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * We don't persistently store the allocation size
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * but make it look like we do while there are opens.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Note: We update the caller's attr in the cases
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * where they're setting only one of allocsz|size.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross switch (attr->sa_mask & (SMB_AT_ALLOCSZ | SMB_AT_SIZE)) {
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross case SMB_AT_ALLOCSZ:
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Setting the allocation size but not EOF position.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Get the current EOF in tmp_attr and (if necessary)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * truncate to the (rounded up) allocation size.
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * Using kcred here because if we don't have access,
8622ec4569457733001d4982ef7f5b44427069beGordon Ross * we want to fail at setattr below and not here.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross bzero(&tmp_attr, sizeof (smb_attr_t));
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross tmp_attr.sa_mask = SMB_AT_SIZE;
8622ec4569457733001d4982ef7f5b44427069beGordon Ross rc = smb_fsop_getattr(NULL, zone_kcred(), node, &tmp_attr);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai if (rc != 0)
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai return (rc);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_allocsz = SMB_ALLOCSZ(attr->sa_allocsz);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (tmp_attr.sa_vattr.va_size > attr->sa_allocsz) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /* truncate the file to allocsz */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_size = attr->sa_allocsz;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_mask |= SMB_AT_SIZE;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross }
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross break;
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross case SMB_AT_SIZE:
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Setting the EOF position but not allocation size.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * If the new EOF position would be greater than
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * the allocation size, increase the latter.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (node->n_allocsz < attr->sa_vattr.va_size) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_mask |= SMB_AT_ALLOCSZ;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_allocsz =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross SMB_ALLOCSZ(attr->sa_vattr.va_size);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross break;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross case SMB_AT_ALLOCSZ | SMB_AT_SIZE:
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Setting both. Increase alloc size if needed.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (attr->sa_allocsz < attr->sa_vattr.va_size)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_allocsz =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross SMB_ALLOCSZ(attr->sa_vattr.va_size);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross break;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross default:
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross break;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * If we have an open file, and we set the size,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * then set the "written" flag so that at close,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * we can force an mtime update.
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (of != NULL && (attr->sa_mask & SMB_AT_SIZE) != 0)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross of->f_written = B_TRUE;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * When operating on an open file, some settable attributes
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * become "sticky" in the open file object until close.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * (see above re. timestamps)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross times_mask = attr->sa_mask & SMB_AT_TIMES;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (of != NULL && times_mask != 0) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross smb_attr_t *pa;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross SMB_OFILE_VALID(of);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross mutex_enter(&of->f_mutex);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa = &of->f_pending_attr;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_mask |= times_mask;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (times_mask & SMB_AT_ATIME)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_vattr.va_atime =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_atime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (times_mask & SMB_AT_MTIME)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_vattr.va_mtime =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_mtime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (times_mask & SMB_AT_CTIME)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_vattr.va_ctime =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_ctime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (times_mask & SMB_AT_CRTIME)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_crtime =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_crtime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross mutex_exit(&of->f_mutex);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * The f_pending_attr times are reapplied in
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * smb_ofile_close().
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * After this point, tmp_attr is what we will actually
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * store in the file system _now_, which may differ
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * from the callers attr and f_pending_attr w.r.t.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * the DOS readonly flag etc.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross bcopy(attr, &tmp_attr, sizeof (tmp_attr));
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (attr->sa_mask & (SMB_AT_DOSATTR | SMB_AT_ALLOCSZ)) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross mutex_enter(&node->n_mutex);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if ((attr->sa_mask & SMB_AT_DOSATTR) != 0) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross tmp_attr.sa_dosattr &= smb_vop_dosattr_settable;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (((tmp_attr.sa_dosattr &
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross FILE_ATTRIBUTE_READONLY) != 0) &&
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross (node->n_open_count != 0)) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /* Delay setting readonly */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross node->n_pending_dosattr =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross tmp_attr.sa_dosattr;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross tmp_attr.sa_dosattr &=
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross ~FILE_ATTRIBUTE_READONLY;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross } else {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross node->n_pending_dosattr = 0;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross }
ccc71be50bb49efb4e31004c77fb3e065e9c0596Gordon Ross }
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Simulate n_allocsz persistence only while
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * there are opens. See smb_node_getattr
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if ((attr->sa_mask & SMB_AT_ALLOCSZ) != 0 &&
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross node->n_open_count != 0)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross node->n_allocsz = attr->sa_allocsz;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross mutex_exit(&node->n_mutex);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross }
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross rc = smb_fsop_setattr(sr, cr, node, &tmp_attr);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (rc != 0)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross return (rc);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (node->n_dnode != NULL) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross smb_node_notify_change(node->n_dnode,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross FILE_ACTION_MODIFIED, node->od_name);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
fe1c642d06e14b412cd83ae2179303186ab08972Bill Krier
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh return (0);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh}
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh/*
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * smb_node_getattr
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Get attributes from the file system and apply any smb-specific
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * overrides for size, dos attributes and timestamps
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * When node->n_pending_readonly is set on a node, pretend that
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * we've already set this node readonly at the filesystem level.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * We can't actually do that until all writable handles are closed
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * or those writable handles would suddenly loose their access.
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh *
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh * Returns: errno
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh */
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintoshint
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Rosssmb_node_getattr(smb_request_t *sr, smb_node_t *node, cred_t *cr,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross smb_ofile_t *of, smb_attr_t *attr)
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh{
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh int rc;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross uint_t want_mask, pend_mask;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross boolean_t isdir;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh SMB_NODE_VALID(node);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /* Deal with some interdependencies */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (attr->sa_mask & SMB_AT_ALLOCSZ)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_mask |= SMB_AT_SIZE;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (attr->sa_mask & SMB_AT_DOSATTR)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_mask |= SMB_AT_TYPE;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross rc = smb_fsop_getattr(sr, cr, node, attr);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh if (rc != 0)
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh return (rc);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross isdir = smb_node_is_dir(node);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai mutex_enter(&node->n_mutex);
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * When there are open handles, and one of them has
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * set the DOS readonly flag (in n_pending_dosattr),
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * it will not have been stored in the file system.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * In this case use n_pending_dosattr. Note that
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * n_pending_dosattr has only the settable bits,
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * (setattr masks it with smb_vop_dosattr_settable)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * so we need to keep any non-settable bits we got
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * from the file-system above.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (attr->sa_mask & SMB_AT_DOSATTR) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (node->n_pending_dosattr) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_dosattr &= ~smb_vop_dosattr_settable;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_dosattr |= node->n_pending_dosattr;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross }
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (attr->sa_dosattr == 0) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_dosattr = (isdir) ?
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross FILE_ATTRIBUTE_DIRECTORY:
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross FILE_ATTRIBUTE_NORMAL;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross }
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai }
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * Also fix-up sa_allocsz, which is not persistent.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * When there are no open files, allocsz is faked.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * While there are open files, we pretend we have a
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * persistent allocation size in n_allocsz, and
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * keep that up-to-date here, increasing it when
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * we see the file size grow past it.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
e3f2c991a8548408db0a2787bd8b43d5124821d3Keyur Desai if (attr->sa_mask & SMB_AT_ALLOCSZ) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (isdir) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_allocsz = 0;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross } else if (node->n_open_count == 0) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_allocsz =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross SMB_ALLOCSZ(attr->sa_vattr.va_size);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross } else {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (node->n_allocsz < attr->sa_vattr.va_size)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross node->n_allocsz =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross SMB_ALLOCSZ(attr->sa_vattr.va_size);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_allocsz = node->n_allocsz;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh mutex_exit(&node->n_mutex);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (isdir) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_size = 0;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_nlink = 1;
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross /*
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * getattr with an ofile gets any "pending" times that
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * might have been previously set via this ofile.
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross * This is what makes these times "sticky".
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross */
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross want_mask = attr->sa_mask & SMB_AT_TIMES;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (of != NULL && want_mask != 0) {
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross smb_attr_t *pa;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross SMB_OFILE_VALID(of);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross mutex_enter(&of->f_mutex);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa = &of->f_pending_attr;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pend_mask = pa->sa_mask;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (want_mask & pend_mask & SMB_AT_ATIME)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_atime =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_vattr.va_atime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (want_mask & pend_mask & SMB_AT_MTIME)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_mtime =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_vattr.va_mtime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (want_mask & pend_mask & SMB_AT_CTIME)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_vattr.va_ctime =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_vattr.va_ctime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross if (want_mask & pend_mask & SMB_AT_CRTIME)
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross attr->sa_crtime =
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross pa->sa_crtime;
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross mutex_exit(&of->f_mutex);
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross }
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross return (0);
037cac007b685e7ea79f6ef7e8e62bfd342a4d56joyce mcintosh}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
5fd03bc0f2e00e7ba02316c2e08f45d52aab15dbGordon Ross
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#ifndef _KERNEL
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Rossextern int reparse_vnode_parse(vnode_t *vp, nvlist_t *nvl);
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross#endif /* _KERNEL */
b819cea2f73f98c5662230cc9affc8cc84f77fcfGordon Ross
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States/*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * Check to see if the node represents a reparse point.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * If yes, whether the reparse point contains a DFS link.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_init_reparse(smb_node_t *node, smb_attr_t *attr)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States nvlist_t *nvl;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States nvpair_t *rec;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States char *rec_type;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if ((attr->sa_dosattr & FILE_ATTRIBUTE_REPARSE_POINT) == 0)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if ((nvl = reparse_init()) == NULL)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if (reparse_vnode_parse(node->vp, nvl) != 0) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States reparse_free(nvl);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States node->flags |= NODE_FLAGS_REPARSE;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States rec = nvlist_next_nvpair(nvl, NULL);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States while (rec != NULL) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States rec_type = nvpair_name(rec);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if ((rec_type != NULL) &&
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (strcasecmp(rec_type, DFS_REPARSE_SVCTYPE) == 0)) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States node->flags |= NODE_FLAGS_DFSLINK;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States break;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States rec = nvlist_next_nvpair(nvl, rec);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States reparse_free(nvl);
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States/*
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * smb_node_init_system
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States *
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * If the node represents a special system file set NODE_FLAG_SYSTEM.
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * System files:
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * - any node whose parent dnode has NODE_FLAG_SYSTEM set
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * - any node whose associated unnamed stream node (unode) has
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * NODE_FLAG_SYSTEM set
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States * - .$EXTEND at root of share (quota management)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States */
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statesstatic void
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United Statessmb_node_init_system(smb_node_t *node)
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States{
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_t *dnode = node->n_dnode;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States smb_node_t *unode = node->n_unode;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if ((dnode) && (dnode->flags & NODE_FLAGS_SYSTEM)) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States node->flags |= NODE_FLAGS_SYSTEM;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if ((unode) && (unode->flags & NODE_FLAGS_SYSTEM)) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States node->flags |= NODE_FLAGS_SYSTEM;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States return;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States if ((dnode) && (smb_node_is_vfsroot(node->n_dnode) &&
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States (strcasecmp(node->od_name, ".$EXTEND") == 0))) {
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States node->flags |= NODE_FLAGS_SYSTEM;
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States }
9fb67ea305c66b6a297583b9b0db6796b0dfe497afshin salek ardakani - Sun Microsystems - Irvine United States}