Lines Matching defs:node

53  *    This transition occurs in smb_node_lookup(). If the node looked for is
54 * not found in the has table a new node is created. The reference count is
61 * reference count will be given out for that node.
70 * The reason the smb node has 2 states is the following synchronization
73 * There's a mutex embedded in the node used to protect its fields and
74 * there's a lock embedded in the bucket of the hash table the node belongs
76 * entered. To insert the node into the bucket and to remove it from the
81 * reference count drops to zero and triggers the deletion of the node, the
83 * remove the node). This creates a window during which the node that is
85 * window the node is moved to the state SMB_NODE_STATE_DESTROYING before
87 * state will indicate that the node should be treated as non existent (of
88 * course the state of the node should be tested/updated under the
130 * Initialization of the SMB node layer.
140 smb_node_t *node;
157 * The node cache is shared by all zones, so the smb_root_node
165 node = smb_node_alloc("/", rootdir, node_hdr, hashkey);
167 smb_llist_insert_head(node_hdr, node);
169 smb_root_node = node; /* smb_node_release in smb_node_fini */
193 smb_node_t *node;
200 * The SMB node hash table should be emtpy at this point. If the
208 node = smb_llist_head(&smb_node_hash_table[i]);
209 ASSERT(node == NULL);
253 smb_node_t *node;
263 * because the node may not yet exist. We also do not want to call
299 node = list_head(&node_hdr->ll_list);
300 while (node) {
301 ASSERT(node->n_magic == SMB_NODE_MAGIC);
302 ASSERT(node->n_hash_bucket == node_hdr);
303 if ((node->n_hashkey == hashkey) && (node->vp == vp)) {
304 mutex_enter(&node->n_mutex);
306 smb_node_t *, node);
307 switch (node->n_state) {
309 /* The node was found. */
310 node->n_refcnt++;
311 if ((node->n_dnode == NULL) &&
313 (node != dnode) &&
316 VALIDATE_DIR_NODE(dnode, node);
317 node->n_dnode = dnode;
321 smb_node_audit(node);
322 mutex_exit(&node->n_mutex);
324 return (node);
328 * Although the node exists it is about
332 mutex_exit(&node->n_mutex);
336 * Although the node exists it is in an
341 mutex_exit(&node->n_mutex);
345 node = smb_llist_next(node_hdr, node);
353 node = smb_node_alloc(od_name, vp, node_hdr, hashkey);
354 smb_node_init_reparse(node, &attr);
357 node->flags |= smb_is_executable(op->fqi.fq_last_comp);
361 node->n_dnode = dnode;
362 ASSERT(dnode->n_dnode != node);
369 node->n_unode = unode;
372 smb_node_init_system(node);
374 DTRACE_PROBE1(smb_node_lookup_miss, smb_node_t *, node);
375 smb_node_audit(node);
376 smb_llist_insert_head(node_hdr, node);
378 return (node);
418 * stale. A node pointer may be NULL, however, and care should be taken
424 smb_node_ref(smb_node_t *node)
426 SMB_NODE_VALID(node);
428 mutex_enter(&node->n_mutex);
429 switch (node->n_state) {
431 node->n_refcnt++;
432 ASSERT(node->n_refcnt);
433 DTRACE_PROBE1(smb_node_ref_exit, smb_node_t *, node);
434 smb_node_audit(node);
439 mutex_exit(&node->n_mutex);
460 * smb_node_release() itself will call smb_node_release() on a node's n_dnode,
464 smb_node_release(smb_node_t *node)
466 SMB_NODE_VALID(node);
468 mutex_enter(&node->n_mutex);
469 ASSERT(node->n_refcnt);
470 DTRACE_PROBE1(smb_node_release, smb_node_t *, node);
471 if (--node->n_refcnt == 0) {
472 switch (node->n_state) {
475 node->n_state = SMB_NODE_STATE_DESTROYING;
476 mutex_exit(&node->n_mutex);
478 smb_llist_enter(node->n_hash_bucket, RW_WRITER);
479 smb_llist_remove(node->n_hash_bucket, node);
480 smb_llist_exit(node->n_hash_bucket);
485 smb_node_delete_on_close(node);
487 if (node->n_dnode) {
488 ASSERT(node->n_dnode->n_magic ==
490 smb_node_release(node->n_dnode);
493 if (node->n_unode) {
494 ASSERT(node->n_unode->n_magic ==
496 smb_node_release(node->n_unode);
499 smb_node_free(node);
506 smb_node_audit(node);
507 mutex_exit(&node->n_mutex);
511 smb_node_delete_on_close(smb_node_t *node)
517 d_snode = node->n_dnode;
518 if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
519 node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE;
520 flags = node->n_delete_on_close_flags;
521 ASSERT(node->od_name != NULL);
523 if (smb_node_is_dir(node))
524 rc = smb_fsop_rmdir(0, node->delete_on_close_cred,
525 d_snode, node->od_name, flags);
527 rc = smb_fsop_remove(0, node->delete_on_close_cred,
528 d_snode, node->od_name, flags);
529 crfree(node->delete_on_close_cred);
533 node->od_name, rc);
534 DTRACE_PROBE2(smb_node_delete_on_close, int, rc, smb_node_t *, node);
573 * Find/create an SMB node for the root of this zone and store it
597 * Helper function for smb_node_set_delete_on_close(). Assumes node is a dir.
647 * whichever the first file handle is closed will trigger the node to be
649 * as the delete-on-close credentials of the node.
652 smb_node_set_delete_on_close(smb_node_t *node, cred_t *cr, uint32_t flags)
658 if (node->n_pending_dosattr & FILE_ATTRIBUTE_READONLY)
663 rc = smb_fsop_getattr(NULL, zone_kcred(), node, &attr);
673 if (smb_node_is_dir(node)) {
674 status = smb_rmdir_possible(node, flags);
680 mutex_enter(&node->n_mutex);
681 if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
682 mutex_exit(&node->n_mutex);
687 node->delete_on_close_cred = cr;
688 node->n_delete_on_close_flags = flags;
689 node->flags |= NODE_FLAGS_DELETE_ON_CLOSE;
690 mutex_exit(&node->n_mutex);
697 smb_notify_event(node, FILE_ACTION_DELETE_PENDING, NULL);
703 smb_node_reset_delete_on_close(smb_node_t *node)
705 mutex_enter(&node->n_mutex);
706 if (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) {
707 node->flags &= ~NODE_FLAGS_DELETE_ON_CLOSE;
708 crfree(node->delete_on_close_cred);
709 node->delete_on_close_cred = NULL;
710 node->n_delete_on_close_flags = 0;
712 mutex_exit(&node->n_mutex);
725 smb_node_open_check(smb_node_t *node, uint32_t desired_access,
731 SMB_NODE_VALID(node);
733 smb_llist_enter(&node->n_ofile_list, RW_READER);
734 of = smb_llist_head(&node->n_ofile_list);
741 of = smb_llist_next(&node->n_ofile_list, of);
745 smb_llist_exit(&node->n_ofile_list);
750 smb_llist_exit(&node->n_ofile_list);
755 smb_node_rename_check(smb_node_t *node)
760 SMB_NODE_VALID(node);
765 smb_llist_enter(&node->n_ofile_list, RW_READER);
766 of = smb_llist_head(&node->n_ofile_list);
773 of = smb_llist_next(&node->n_ofile_list, of);
777 smb_llist_exit(&node->n_ofile_list);
781 smb_llist_exit(&node->n_ofile_list);
786 smb_node_delete_check(smb_node_t *node)
791 SMB_NODE_VALID(node);
793 if (smb_node_is_dir(node))
796 if (smb_node_is_reparse(node))
802 smb_llist_enter(&node->n_ofile_list, RW_READER);
803 of = smb_llist_head(&node->n_ofile_list);
810 of = smb_llist_next(&node->n_ofile_list, of);
814 smb_llist_exit(&node->n_ofile_list);
818 smb_llist_exit(&node->n_ofile_list);
829 smb_node_share_check(smb_node_t *node)
834 SMB_NODE_VALID(node);
836 smb_llist_enter(&node->n_ofile_list, RW_READER);
837 of = smb_llist_head(&node->n_ofile_list);
840 smb_llist_exit(&node->n_ofile_list);
850 smb_node_fcn_subscribe(smb_node_t *node, smb_request_t *sr)
852 smb_node_fcn_t *fcn = &node->n_fcn;
856 (void) smb_fem_fcn_install(node);
863 smb_node_fcn_unsubscribe(smb_node_t *node, smb_request_t *sr)
865 smb_node_fcn_t *fcn = &node->n_fcn;
871 smb_fem_fcn_uninstall(node);
876 smb_node_notify_change(smb_node_t *node, uint_t action, const char *name)
878 SMB_NODE_VALID(node);
880 smb_notify_event(node, action, name);
891 smb_node_notify_parents(node);
900 * Stop at the root node, which has a NULL parent node.
926 smb_node_start_crit(smb_node_t *node, krw_t mode)
928 rw_enter(&node->n_lock, mode);
929 nbl_start_crit(node->vp, mode);
938 smb_node_end_crit(smb_node_t *node)
940 nbl_end_crit(node->vp);
941 rw_exit(&node->n_lock);
945 smb_node_in_crit(smb_node_t *node)
947 return (nbl_in_crit(node->vp) && RW_LOCK_HELD(&node->n_lock));
951 smb_node_rdlock(smb_node_t *node)
953 rw_enter(&node->n_lock, RW_READER);
957 smb_node_wrlock(smb_node_t *node)
959 rw_enter(&node->n_lock, RW_WRITER);
963 smb_node_unlock(smb_node_t *node)
965 rw_exit(&node->n_lock);
969 smb_node_add_ofile(smb_node_t *node, smb_ofile_t *of)
971 SMB_NODE_VALID(node);
973 smb_llist_enter(&node->n_ofile_list, RW_WRITER);
974 smb_llist_insert_tail(&node->n_ofile_list, of);
975 smb_llist_exit(&node->n_ofile_list);
979 smb_node_rem_ofile(smb_node_t *node, smb_ofile_t *of)
981 SMB_NODE_VALID(node);
983 smb_llist_enter(&node->n_ofile_list, RW_WRITER);
984 smb_llist_remove(&node->n_ofile_list, of);
985 smb_llist_exit(&node->n_ofile_list);
992 smb_node_inc_open_ofiles(smb_node_t *node)
994 SMB_NODE_VALID(node);
995 atomic_inc_32(&node->n_open_count);
1003 smb_node_dec_open_ofiles(smb_node_t *node)
1005 SMB_NODE_VALID(node);
1006 return (atomic_dec_32_nv(&node->n_open_count));
1013 smb_node_inc_opening_count(smb_node_t *node)
1015 SMB_NODE_VALID(node);
1016 atomic_inc_32(&node->n_opening_count);
1023 smb_node_dec_opening_count(smb_node_t *node)
1025 SMB_NODE_VALID(node);
1026 atomic_dec_32(&node->n_opening_count);
1033 smb_node_getmntpath(smb_node_t *node, char *buf, uint32_t buflen)
1039 ASSERT(node);
1040 ASSERT(node->vp);
1041 ASSERT(node->vp->v_vfsp);
1043 vp = node->vp;
1062 * Determine the absolute pathname of 'node' within the share (tree).
1063 * For example if the node represents file "test1.txt" in directory
1067 smb_node_getshrpath(smb_node_t *node, smb_tree_t *tree,
1072 ASSERT(node);
1076 rc = smb_node_getpath(node, tree->t_snode->vp, buf, buflen);
1084 * Determine the absolute pathname of 'node' from 'rootvp'.
1087 * its reliance on the DNLC for non-directory nodes). Thus, if node
1090 * If node represents a named stream, construct the pathname for the
1096 smb_node_getpath(smb_node_t *node, vnode_t *rootvp, char *buf, uint32_t buflen)
1103 unode = (SMB_IS_STREAM(node)) ? node->n_unode : node;
1106 /* find path to directory node */
1129 if (SMB_IS_STREAM(node))
1130 (void) strlcat(buf, node->od_name, buflen);
1145 smb_node_t *node;
1148 node = kmem_cache_alloc(smb_node_cache, KM_SLEEP);
1150 if (node->n_audit_buf != NULL)
1151 node->n_audit_buf->anb_index = 0;
1153 node->flags = 0;
1155 node->vp = vp;
1156 node->n_refcnt = 1;
1157 node->n_hash_bucket = bucket;
1158 node->n_hashkey = hashkey;
1159 node->n_pending_dosattr = 0;
1160 node->n_open_count = 0;
1161 node->n_allocsz = 0;
1162 node->n_dnode = NULL;
1163 node->n_unode = NULL;
1164 node->delete_on_close_cred = NULL;
1165 node->n_delete_on_close_flags = 0;
1166 node->n_oplock.ol_fem = B_FALSE;
1167 node->n_oplock.ol_xthread = NULL;
1168 node->n_oplock.ol_count = 0;
1169 node->n_oplock.ol_break = SMB_OPLOCK_NO_BREAK;
1171 (void) strlcpy(node->od_name, od_name, sizeof (node->od_name));
1173 node->flags |= NODE_XATTR_DIR;
1177 node->flags |= NODE_FLAGS_VFSROOT;
1181 node->n_state = SMB_NODE_STATE_AVAILABLE;
1182 node->n_magic = SMB_NODE_MAGIC;
1184 return (node);
1191 smb_node_free(smb_node_t *node)
1193 SMB_NODE_VALID(node);
1195 node->n_magic = 0;
1196 VERIFY(!list_link_active(&node->n_lnd));
1197 VERIFY(node->n_lock_list.ll_count == 0);
1198 VERIFY(node->n_ofile_list.ll_count == 0);
1199 VERIFY(node->n_oplock.ol_count == 0);
1200 VERIFY(node->n_oplock.ol_xthread == NULL);
1201 VERIFY(node->n_oplock.ol_fem == B_FALSE);
1202 VERIFY(MUTEX_NOT_HELD(&node->n_mutex));
1203 VERIFY(!RW_LOCK_HELD(&node->n_lock));
1204 VN_RELE(node->vp);
1205 kmem_cache_free(smb_node_cache, node);
1216 smb_node_t *node = (smb_node_t *)buf;
1218 bzero(node, sizeof (smb_node_t));
1220 smb_llist_constructor(&node->n_ofile_list, sizeof (smb_ofile_t),
1222 smb_llist_constructor(&node->n_lock_list, sizeof (smb_lock_t),
1224 mutex_init(&node->n_fcn.fcn_mutex, NULL, MUTEX_DEFAULT, NULL);
1225 list_create(&node->n_fcn.fcn_watchers, sizeof (smb_request_t),
1227 cv_init(&node->n_oplock.ol_cv, NULL, CV_DEFAULT, NULL);
1228 mutex_init(&node->n_oplock.ol_mutex, NULL, MUTEX_DEFAULT, NULL);
1229 list_create(&node->n_oplock.ol_grants, sizeof (smb_oplock_grant_t),
1231 rw_init(&node->n_lock, NULL, RW_DEFAULT, NULL);
1232 mutex_init(&node->n_mutex, NULL, MUTEX_DEFAULT, NULL);
1233 smb_node_create_audit_buf(node, kmflags);
1245 smb_node_t *node = (smb_node_t *)buf;
1247 smb_node_destroy_audit_buf(node);
1248 mutex_destroy(&node->n_mutex);
1249 rw_destroy(&node->n_lock);
1250 cv_destroy(&node->n_oplock.ol_cv);
1251 mutex_destroy(&node->n_oplock.ol_mutex);
1252 list_destroy(&node->n_fcn.fcn_watchers);
1253 mutex_destroy(&node->n_fcn.fcn_mutex);
1254 smb_llist_destructor(&node->n_lock_list);
1255 smb_llist_destructor(&node->n_ofile_list);
1256 list_destroy(&node->n_oplock.ol_grants);
1263 smb_node_create_audit_buf(smb_node_t *node, int kmflags)
1270 node->n_audit_buf = abn;
1278 smb_node_destroy_audit_buf(smb_node_t *node)
1280 if (node->n_audit_buf != NULL) {
1281 kmem_free(node->n_audit_buf, sizeof (smb_audit_buf_node_t));
1282 node->n_audit_buf = NULL;
1289 * This function saves the calling stack in the audit buffer of the node passed
1293 smb_node_audit(smb_node_t *node)
1299 if (node->n_audit_buf) {
1300 abn = node->n_audit_buf;
1305 anr->anr_refcnt = node->n_refcnt;
1310 _NOTE(ARGUNUSED(node))
1326 smb_node_is_file(smb_node_t *node)
1328 SMB_NODE_VALID(node);
1329 return (node->vp->v_type == VREG);
1333 smb_node_is_dir(smb_node_t *node)
1335 SMB_NODE_VALID(node);
1336 return ((node->vp->v_type == VDIR) ||
1337 (node->flags & NODE_FLAGS_DFSLINK));
1341 smb_node_is_symlink(smb_node_t *node)
1343 SMB_NODE_VALID(node);
1344 return ((node->vp->v_type == VLNK) &&
1345 ((node->flags & NODE_FLAGS_REPARSE) == 0));
1349 smb_node_is_dfslink(smb_node_t *node)
1351 SMB_NODE_VALID(node);
1352 return ((node->vp->v_type == VLNK) &&
1353 (node->flags & NODE_FLAGS_DFSLINK));
1357 smb_node_is_reparse(smb_node_t *node)
1359 SMB_NODE_VALID(node);
1360 return ((node->vp->v_type == VLNK) &&
1361 (node->flags & NODE_FLAGS_REPARSE));
1365 smb_node_is_vfsroot(smb_node_t *node)
1367 SMB_NODE_VALID(node);
1368 return ((node->flags & NODE_FLAGS_VFSROOT) == NODE_FLAGS_VFSROOT);
1372 smb_node_is_system(smb_node_t *node)
1374 SMB_NODE_VALID(node);
1375 return ((node->flags & NODE_FLAGS_SYSTEM) == NODE_FLAGS_SYSTEM);
1381 * Checks if the file (which node represents) is marked readonly
1383 * in the node, which must be handled by the callers.
1387 smb_node_file_is_readonly(smb_node_t *node)
1391 if (node == NULL)
1394 if (node->n_pending_dosattr & FILE_ATTRIBUTE_READONLY)
1399 (void) smb_fsop_getattr(NULL, zone_kcred(), node, &attr);
1456 smb_node_setattr(smb_request_t *sr, smb_node_t *node,
1463 SMB_NODE_VALID(node);
1488 rc = smb_fsop_getattr(NULL, zone_kcred(), node, &tmp_attr);
1505 if (node->n_allocsz < attr->sa_vattr.va_size) {
1576 mutex_enter(&node->n_mutex);
1581 (node->n_open_count != 0)) {
1583 node->n_pending_dosattr =
1588 node->n_pending_dosattr = 0;
1596 node->n_open_count != 0)
1597 node->n_allocsz = attr->sa_allocsz;
1598 mutex_exit(&node->n_mutex);
1601 rc = smb_fsop_setattr(sr, cr, node, &tmp_attr);
1605 if (node->n_dnode != NULL) {
1606 smb_node_notify_change(node->n_dnode,
1607 FILE_ACTION_MODIFIED, node->od_name);
1619 * When node->n_pending_readonly is set on a node, pretend that
1620 * we've already set this node readonly at the filesystem level.
1627 smb_node_getattr(smb_request_t *sr, smb_node_t *node, cred_t *cr,
1634 SMB_NODE_VALID(node);
1642 rc = smb_fsop_getattr(sr, cr, node, attr);
1646 isdir = smb_node_is_dir(node);
1648 mutex_enter(&node->n_mutex);
1661 if (node->n_pending_dosattr) {
1663 attr->sa_dosattr |= node->n_pending_dosattr;
1683 } else if (node->n_open_count == 0) {
1687 if (node->n_allocsz < attr->sa_vattr.va_size)
1688 node->n_allocsz =
1690 attr->sa_allocsz = node->n_allocsz;
1694 mutex_exit(&node->n_mutex);
1742 * Check to see if the node represents a reparse point.
1746 smb_node_init_reparse(smb_node_t *node, smb_attr_t *attr)
1758 if (reparse_vnode_parse(node->vp, nvl) != 0) {
1763 node->flags |= NODE_FLAGS_REPARSE;
1770 node->flags |= NODE_FLAGS_DFSLINK;
1782 * If the node represents a special system file set NODE_FLAG_SYSTEM.
1784 * - any node whose parent dnode has NODE_FLAG_SYSTEM set
1785 * - any node whose associated unnamed stream node (unode) has
1790 smb_node_init_system(smb_node_t *node)
1792 smb_node_t *dnode = node->n_dnode;
1793 smb_node_t *unode = node->n_unode;
1796 node->flags |= NODE_FLAGS_SYSTEM;
1801 node->flags |= NODE_FLAGS_SYSTEM;
1805 if ((dnode) && (smb_node_is_vfsroot(node->n_dnode) &&
1806 (strcasecmp(node->od_name, ".$EXTEND") == 0))) {
1807 node->flags |= NODE_FLAGS_SYSTEM;