Lines Matching refs:tree
93 * - The tree is queued in the list of trees of its user.
94 * - References will be given out if the tree is looked up.
95 * - Files under that tree can be accessed.
100 * - The tree is queued in the list of trees of its user.
101 * - References will not be given out if the tree is looked up.
102 * - The files and directories open under the tree are being closed.
103 * - The resources associated with the tree remain.
108 * - The tree is queued in the list of trees of its user.
109 * - References will not be given out if the tree is looked up.
110 * - The tree has no more files and directories opened.
111 * - The resources associated with the tree remain.
115 * This transition occurs in smb_tree_connect(). A new tree is created and
125 * with the tree are freed as well as the tree structure. For the transition
126 * to occur, the tree must be in the SMB_TREE_STATE_DISCONNECTED state and
132 * The state machine of the tree structures is controlled by 3 elements:
137 * There's a mutex embedded in the tree structure used to protect its fields
140 * To insert the tree into the list of trees of the user and to remove
141 * the tree from it, the lock must be entered in RW_WRITER mode.
143 * Rules of access to a tree structure:
148 * 2) All actions applied to a tree require a reference count.
150 * 3) There are 2 ways of getting a reference count: when a tree is
151 * connected and when a tree is looked up.
153 * It should be noted that the reference count of a tree registers the
154 * number of references to the tree in other structures (such as an smb
157 * 1) The tree is connected. An tree is anchored by his state. If there's
158 * no activity involving a tree currently connected, the reference
159 * count of that tree is zero.
161 * 2) The tree is queued in the list of trees of the user. The fact of
193 static void smb_tree_netinfo_init(smb_tree_t *tree, smb_netconnectinfo_t *);
276 * Disconnect a tree.
279 smb_tree_disconnect(smb_tree_t *tree, boolean_t do_exec)
283 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
285 mutex_enter(&tree->t_mutex);
286 ASSERT(tree->t_refcnt);
288 if (smb_tree_is_connected_locked(tree)) {
292 tree->t_state = SMB_TREE_STATE_DISCONNECTING;
293 mutex_exit(&tree->t_mutex);
297 * The files opened under this tree are closed.
299 smb_ofile_close_all(tree);
301 * The directories opened under this tree are closed.
303 smb_tree_close_odirs(tree, 0);
306 mutex_enter(&tree->t_mutex);
307 tree->t_state = SMB_TREE_STATE_DISCONNECTED;
308 smb_server_dec_trees(tree->t_server);
311 mutex_exit(&tree->t_mutex);
313 if (do_exec && (tree->t_state == SMB_TREE_STATE_DISCONNECTED) &&
314 (tree->t_execflags & SMB_EXEC_UNMAP)) {
316 smb_tree_set_execinfo(tree, &execinfo, SMB_EXEC_UNMAP);
317 (void) smb_kshare_exec(tree->t_server, &execinfo);
322 * Take a reference on a tree.
326 smb_tree_t *tree)
328 SMB_TREE_VALID(tree);
330 mutex_enter(&tree->t_mutex);
332 if (smb_tree_is_connected_locked(tree)) {
333 tree->t_refcnt++;
334 mutex_exit(&tree->t_mutex);
338 mutex_exit(&tree->t_mutex);
343 * Bump the hold count regardless of the tree state. This is used in
345 * valid tree connection, and don't want to deal with the possiblity
346 * that the tree state might have changed to disconnecting after our
348 * request even when new requests cannot lookup that tree anymore.
352 smb_tree_t *tree)
354 SMB_TREE_VALID(tree);
356 mutex_enter(&tree->t_mutex);
357 tree->t_refcnt++;
358 mutex_exit(&tree->t_mutex);
362 * Release a reference on a tree. If the tree is disconnected and the
369 smb_tree_t *tree)
371 SMB_TREE_VALID(tree);
373 mutex_enter(&tree->t_mutex);
374 ASSERT(tree->t_refcnt);
375 tree->t_refcnt--;
378 smb_llist_flush(&tree->t_ofile_list);
379 smb_llist_flush(&tree->t_odir_list);
381 if (smb_tree_is_disconnected(tree) && (tree->t_refcnt == 0))
382 smb_session_post_tree(tree->t_session, tree);
384 mutex_exit(&tree->t_mutex);
388 smb_tree_post_ofile(smb_tree_t *tree, smb_ofile_t *of)
390 SMB_TREE_VALID(tree);
394 ASSERT(of->f_tree == tree);
396 smb_llist_post(&tree->t_ofile_list, of, smb_ofile_delete);
400 smb_tree_post_odir(smb_tree_t *tree, smb_odir_t *od)
402 SMB_TREE_VALID(tree);
406 ASSERT(od->d_tree == tree);
408 smb_llist_post(&tree->t_odir_list, od, smb_odir_delete);
416 smb_tree_t *tree,
419 ASSERT(tree);
420 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
422 smb_ofile_close_all_by_pid(tree, pid);
423 smb_tree_close_odirs(tree, pid);
427 * Check whether or not a tree supports the features identified by flags.
430 smb_tree_has_feature(smb_tree_t *tree, uint32_t flags)
432 ASSERT(tree);
433 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
435 return ((tree->t_flags & flags) == flags);
439 * If the enumeration request is for tree data, handle the request
442 * This function should be called with a hold on the tree.
445 smb_tree_enum(smb_tree_t *tree, smb_svcenum_t *svcenum)
451 ASSERT(tree);
452 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
455 return (smb_tree_enum_private(tree, svcenum));
457 of = smb_tree_get_ofile(tree, NULL);
459 ASSERT(of->f_tree == tree);
467 next = smb_tree_get_ofile(tree, of);
479 smb_tree_fclose(smb_tree_t *tree, uint32_t uniqid)
483 ASSERT(tree);
484 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
486 if ((of = smb_ofile_lookup_by_uniqid(tree, uniqid)) == NULL)
655 smb_tree_t *tree;
731 tree = smb_tree_alloc(sr, si, snode, access, sr->sr_cfg->skc_execflags);
735 if (tree == NULL)
738 if (tree->t_execflags & SMB_EXEC_MAP) {
739 smb_tree_set_execinfo(tree, &execinfo, SMB_EXEC_MAP);
741 rc = smb_kshare_exec(tree->t_server, &execinfo);
743 if ((rc != 0) && (tree->t_execflags & SMB_EXEC_TERM)) {
744 smb_tree_disconnect(tree, B_FALSE);
745 smb_tree_release(tree);
750 sr->tid_tree = tree;
751 sr->smb_tid = tree->t_tid;
773 smb_tree_t *tree;
820 tree = smb_tree_alloc(sr, si, snode, access, sr->sr_cfg->skc_execflags);
824 if (tree == NULL)
827 sr->tid_tree = tree;
828 sr->smb_tid = tree->t_tid;
842 smb_tree_t *tree;
863 tree = smb_tree_alloc(sr, si, NULL, ACE_ALL_PERMS, 0);
864 if (tree == NULL)
867 sr->tid_tree = tree;
868 sr->smb_tid = tree->t_tid;
874 * Allocate a tree.
881 smb_tree_t *tree;
888 tree = kmem_cache_alloc(smb_cache_tree, KM_SLEEP);
889 bzero(tree, sizeof (smb_tree_t));
891 tree->t_session = session;
892 tree->t_server = session->s_server;
894 /* grab a ref for tree->t_owner */
896 tree->t_owner = sr->uid_user;
899 if (smb_tree_getattr(si, snode, tree) != 0) {
901 kmem_cache_free(smb_cache_tree, tree);
906 if (smb_idpool_constructor(&tree->t_fid_pool)) {
908 kmem_cache_free(smb_cache_tree, tree);
912 if (smb_idpool_constructor(&tree->t_odid_pool)) {
913 smb_idpool_destructor(&tree->t_fid_pool);
915 kmem_cache_free(smb_cache_tree, tree);
919 smb_llist_constructor(&tree->t_ofile_list, sizeof (smb_ofile_t),
922 smb_llist_constructor(&tree->t_odir_list, sizeof (smb_odir_t),
925 (void) strlcpy(tree->t_sharename, si->shr_name,
926 sizeof (tree->t_sharename));
927 (void) strlcpy(tree->t_resource, si->shr_path,
928 sizeof (tree->t_resource));
930 mutex_init(&tree->t_mutex, NULL, MUTEX_DEFAULT, NULL);
932 tree->t_refcnt = 1;
933 tree->t_tid = tid;
934 tree->t_res_type = stype;
935 tree->t_state = SMB_TREE_STATE_CONNECTED;
936 tree->t_magic = SMB_TREE_MAGIC;
937 tree->t_access = access;
938 tree->t_connect_time = gethrestime_sec();
939 tree->t_execflags = execflags;
942 if (tree->t_flags & SMB_TREE_READONLY)
943 tree->t_access &= ~ACE_ALL_WRITE_PERMS;
947 tree->t_snode = snode;
948 tree->t_acltype = smb_fsop_acltype(snode);
952 smb_llist_insert_head(&session->s_tree_list, tree);
956 return (tree);
960 * Deallocate a tree. The open file and open directory lists should be
963 * Remove the tree from the user's tree list before freeing resources
964 * associated with the tree.
970 smb_tree_t *tree = (smb_tree_t *)arg;
972 SMB_TREE_VALID(tree);
973 ASSERT(tree->t_state == SMB_TREE_STATE_DISCONNECTED);
974 ASSERT(tree->t_refcnt == 0);
976 session = tree->t_session;
978 smb_llist_remove(&session->s_tree_list, tree);
979 smb_idpool_free(&session->s_tid_pool, tree->t_tid);
983 mutex_enter(&tree->t_mutex);
984 mutex_exit(&tree->t_mutex);
986 tree->t_magic = (uint32_t)~SMB_TREE_MAGIC;
988 if (tree->t_snode)
989 smb_node_release(tree->t_snode);
991 mutex_destroy(&tree->t_mutex);
992 smb_llist_destructor(&tree->t_ofile_list);
993 smb_llist_destructor(&tree->t_odir_list);
994 smb_idpool_destructor(&tree->t_fid_pool);
995 smb_idpool_destructor(&tree->t_odid_pool);
997 SMB_USER_VALID(tree->t_owner);
998 smb_user_release(tree->t_owner);
1000 kmem_cache_free(smb_cache_tree, tree);
1004 * Determine whether or not a tree is connected.
1005 * This function must be called with the tree mutex held.
1008 smb_tree_is_connected_locked(smb_tree_t *tree)
1010 switch (tree->t_state) {
1017 * The tree exists but being diconnected or destroyed.
1028 * Determine whether or not a tree is disconnected.
1029 * This function must be called with the tree mutex held.
1032 smb_tree_is_disconnected(smb_tree_t *tree)
1034 switch (tree->t_state) {
1082 * Obtain the tree attributes: volume name, typename and flags.
1085 smb_tree_getattr(const smb_kshare_t *si, smb_node_t *node, smb_tree_t *tree)
1094 smb_tree_get_volname(vfsp, tree);
1095 smb_tree_get_flags(si, vfsp, tree);
1105 smb_tree_get_volname(vfs_t *vfsp, smb_tree_t *tree)
1109 (void) strlcpy(tree->t_volume, "fake", SMB_VOLNAMELEN);
1119 (void) strlcpy(tree->t_volume, s, SMB_VOLNAMELEN);
1123 name = tree->t_volume;
1137 smb_tree_get_flags(const smb_kshare_t *si, vfs_t *vfsp, smb_tree_t *tree)
1139 smb_session_t *ssn = tree->t_session;
1203 (void) strlcpy(tree->t_typename, name, SMB_TYPENAMELEN);
1204 (void) smb_strupr((char *)tree->t_typename);
1227 tree->t_flags = flags;
1268 * Find the specified odir in the tree's list of odirs, and
1278 smb_tree_t *tree = sr->tid_tree;
1280 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
1282 od_list = &tree->t_odir_list;
1311 smb_tree_is_connected(smb_tree_t *tree)
1315 mutex_enter(&tree->t_mutex);
1316 rb = smb_tree_is_connected_locked(tree);
1317 mutex_exit(&tree->t_mutex);
1331 smb_tree_get_ofile(smb_tree_t *tree, smb_ofile_t *of)
1335 ASSERT(tree);
1336 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
1338 ofile_list = &tree->t_ofile_list;
1362 * Find the next odir in the tree's list of odirs, and obtain a
1365 * of the tree's odir list, otherwise the search starts after the
1369 smb_tree_get_odir(smb_tree_t *tree, smb_odir_t *od)
1373 ASSERT(tree);
1374 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
1376 od_list = &tree->t_odir_list;
1401 * Close all open odirs in the tree's list which were opened by
1403 * If pid is zero, close all open odirs in the tree's list.
1406 smb_tree_close_odirs(smb_tree_t *tree, uint16_t pid)
1410 ASSERT(tree);
1411 ASSERT(tree->t_magic == SMB_TREE_MAGIC);
1413 od = smb_tree_get_odir(tree, NULL);
1416 ASSERT(od->d_tree == tree);
1418 next_od = smb_tree_get_odir(tree, od);
1428 smb_tree_set_execinfo(smb_tree_t *tree, smb_shr_execinfo_t *exec,
1431 exec->e_sharename = tree->t_sharename;
1432 exec->e_winname = tree->t_owner->u_name;
1433 exec->e_userdom = tree->t_owner->u_domain;
1434 exec->e_srv_ipaddr = tree->t_session->local_ipaddr;
1435 exec->e_cli_ipaddr = tree->t_session->ipaddr;
1436 exec->e_cli_netbiosname = tree->t_session->workstation;
1437 exec->e_uid = crgetuid(tree->t_owner->u_cred);
1445 smb_tree_enum_private(smb_tree_t *tree, smb_svcenum_t *svcenum)
1462 rc = smb_tree_netinfo_encode(tree, pb, svcenum->se_bavail, &nbytes);
1477 smb_tree_netinfo_encode(smb_tree_t *tree, uint8_t *buf, size_t buflen,
1483 smb_tree_netinfo_init(tree, &info);
1491 smb_tree_netinfo_username(smb_tree_t *tree, char **namestr, uint32_t *namelen)
1493 smb_user_t *user = tree->t_owner;
1512 * the share rather than the number of references on the tree but
1516 smb_tree_netinfo_init(smb_tree_t *tree, smb_netconnectinfo_t *info)
1518 ASSERT(tree);
1520 info->ci_id = tree->t_tid;
1521 info->ci_type = tree->t_res_type;
1522 info->ci_numopens = tree->t_open_files;
1523 info->ci_numusers = tree->t_refcnt;
1524 info->ci_time = gethrestime_sec() - tree->t_connect_time;
1526 info->ci_sharelen = strlen(tree->t_sharename) + 1;
1527 info->ci_share = smb_mem_strdup(tree->t_sharename);
1529 smb_tree_netinfo_username(tree, &info->ci_username, &info->ci_namelen);