Lines Matching refs:vnode

54 #define HAS_FS_CALL(vnode, op)			(vnode->ops->op != NULL)
57 #define FS_CALL(vnode, op, params...) \
58 vnode->ops->op(vnode->mount->volume, vnode, params)
59 #define FS_CALL_NO_PARAMS(vnode, op) \
60 vnode->ops->op(vnode->mount->volume, vnode)
74 struct vnode : fssh_fs_vnode {
75 struct vnode *next;
82 struct vnode *covered_by;
95 fssh_vnode_id vnode;
103 (e.g. by holding a reference to a vnode of that mount) (read) access
106 making the access path vnode->mount->covers_vnode->mount->... safe if a
107 reference to vnode is held (note that for the root mount covers_vnode
119 struct vnode *root_vnode;
120 struct vnode *covers_vnode;
144 * - vnode::covered_by of any vnode in sVnodeTable will not be modified.
151 /** \brief Guards the vnode::covered_by field of any vnode
153 * The holder is allowed to read access the vnode::covered_by field of any
154 * vnode. Additionally holding sMountOpLock allows for write access.
163 * to any unbusy vnode in that table, save
178 static struct vnode *sRoot;
202 static fssh_status_t dir_read(struct vnode *vnode, void *cookie,
246 static fssh_status_t vnode_path_to_vnode(struct vnode *vnode, char *path,
247 bool traverseLeafLink, int count, struct vnode **_vnode,
249 static fssh_status_t dir_vnode_to_path(struct vnode *vnode, char *buffer,
252 bool traverseLeafLink, struct vnode **_vnode,
254 static void inc_vnode_ref_count(struct vnode *vnode);
255 static fssh_status_t dec_vnode_ref_count(struct vnode *vnode, bool reenter);
256 static inline void put_vnode(struct vnode *vnode);
369 VNodePutter(struct vnode *vnode = NULL) : fVNode(vnode) {}
376 void SetTo(struct vnode *vnode)
379 fVNode = vnode;
390 struct vnode *Detach()
392 struct vnode *vnode = fVNode;
394 return vnode;
398 struct vnode *fVNode;
541 struct vnode *vnode = (struct vnode *)_vnode;
544 if (vnode->device == key->device && vnode->id == key->vnode)
554 struct vnode *vnode = (struct vnode *)_vnode;
559 if (vnode != NULL)
560 return VHASH(vnode->device, vnode->id) % range;
562 return VHASH(key->device, key->vnode) % range;
569 add_vnode_to_mount_list(struct vnode *vnode, struct fs_mount *mount)
573 list_add_link_to_head(&mount->vnodes, &vnode->mount_link);
580 remove_vnode_from_mount_list(struct vnode *vnode, struct fs_mount *mount)
584 list_remove_link(&vnode->mount_link);
585 vnode->mount_link.next = vnode->mount_link.prev = NULL;
592 create_new_vnode(struct vnode **_vnode, fssh_mount_id mountID, fssh_vnode_id vnodeID)
596 struct vnode *vnode = (struct vnode *)malloc(sizeof(struct vnode));
597 if (vnode == NULL)
601 fssh_memset(vnode, 0, sizeof(struct vnode));
602 vnode->device = mountID;
603 vnode->id = vnodeID;
605 // add the vnode to the mount structure
607 vnode->mount = find_mount(mountID);
608 if (!vnode->mount || vnode->mount->unmounting) {
610 free(vnode);
614 hash_insert(sVnodeTable, vnode);
615 add_vnode_to_mount_list(vnode, vnode->mount);
619 vnode->ref_count = 1;
620 *_vnode = vnode;
626 /** Frees the vnode and all resources it has acquired, and removes
627 * it from the vnode hash as well as from its mount structure.
632 free_vnode(struct vnode *vnode, bool reenter)
634 ASSERT(vnode->ref_count == 0 && vnode->busy);
636 // write back any changes in this vnode's cache -- but only
637 // if the vnode won't be deleted, in which case the changes
640 if (!vnode->remove && HAS_FS_CALL(vnode, fsync))
641 FS_CALL_NO_PARAMS(vnode, fsync);
643 if (!vnode->unpublished) {
644 if (vnode->remove)
645 FS_CALL(vnode, remove_vnode, reenter);
647 FS_CALL(vnode, put_vnode, reenter);
650 // The file system has removed the resources of the vnode now, so we can
651 // make it available again (and remove the busy vnode from the hash)
653 hash_remove(sVnodeTable, vnode);
656 remove_vnode_from_mount_list(vnode, vnode->mount);
658 free(vnode);
662 /** \brief Decrements the reference counter of the given vnode and deletes it,
665 * The caller must, of course, own a reference to the vnode to call this
669 * \param vnode the vnode.
676 dec_vnode_ref_count(struct vnode *vnode, bool reenter)
680 int32_t oldRefCount = fssh_atomic_add(&vnode->ref_count, -1);
682 TRACE(("dec_vnode_ref_count: vnode %p, ref now %ld\n", vnode, vnode->ref_count));
685 if (vnode->busy)
686 fssh_panic("dec_vnode_ref_count: called on busy vnode %p\n", vnode);
690 // Just insert the vnode into an unused list if we don't need
692 if (vnode->remove) {
693 vnode->busy = true;
696 list_add_item(&sUnusedVnodeList, vnode);
700 vnode = (struct vnode *)list_remove_head_item(&sUnusedVnodeList);
701 vnode->busy = true;
710 free_vnode(vnode, reenter);
718 /** \brief Increments the reference counter of the given vnode.
720 * The caller must either already have a reference to the vnode or hold
723 * \param vnode the vnode.
727 inc_vnode_ref_count(struct vnode *vnode)
729 fssh_atomic_add(&vnode->ref_count, 1);
730 TRACE(("inc_vnode_ref_count: vnode %p, ref now %ld\n", vnode, vnode->ref_count));
734 /** \brief Looks up a vnode by mount and node ID in the sVnodeTable.
741 * \return The vnode structure, if it was found in the hash table, \c NULL
745 static struct vnode *
751 key.vnode = vnodeID;
753 return (vnode *)hash_lookup(sVnodeTable, &key);
757 /** \brief Retrieves a vnode for a given mount ID, node ID pair.
765 * \param _vnode Pointer to a vnode* variable into which the pointer to the
766 * retrieved vnode structure shall be written.
773 get_vnode(fssh_mount_id mountID, fssh_vnode_id vnodeID, struct vnode **_vnode, int reenter)
782 struct vnode *vnode = lookup_vnode(mountID, vnodeID);
783 if (vnode && vnode->busy) {
786 // vnode doesn't seem to become unbusy
787 fssh_panic("vnode %d:%" FSSH_B_PRIdINO " is not becoming unbusy!\n",
796 TRACE(("get_vnode: tried to lookup vnode, got %p\n", vnode));
800 if (vnode) {
801 if (vnode->ref_count == 0) {
802 // this vnode has been unused before
803 list_remove_item(&sUnusedVnodeList, vnode);
806 inc_vnode_ref_count(vnode);
808 // we need to create a new vnode and read it in
809 status = create_new_vnode(&vnode, mountID, vnodeID);
813 vnode->busy = true;
818 status = FS_MOUNT_CALL(vnode->mount, get_vnode, vnodeID, vnode, &type,
820 if (status == FSSH_B_OK && vnode->private_node == NULL)
828 vnode->type = type;
829 vnode->busy = false;
834 TRACE(("get_vnode: returning %p\n", vnode));
836 *_vnode = vnode;
840 hash_remove(sVnodeTable, vnode);
841 remove_vnode_from_mount_list(vnode, vnode->mount);
844 if (vnode)
845 free(vnode);
851 /** \brief Decrements the reference counter of the given vnode and deletes it,
854 * The caller must, of course, own a reference to the vnode to call this
858 * \param vnode the vnode.
862 put_vnode(struct vnode *vnode)
864 dec_vnode_ref_count(vnode, false);
882 struct vnode *vnodeToDisconnect)
887 /** \brief Resolves a mount point vnode to the volume root vnode it is covered
890 * Given an arbitrary vnode, the function checks, whether the node is covered
894 * \param vnode The vnode in question.
895 * \return The volume root vnode the vnode cover is covered by, if it is
899 static struct vnode *
900 resolve_mount_point_to_volume_root(struct vnode *vnode)
902 if (!vnode)
905 struct vnode *volumeRoot = NULL;
908 if (vnode->covered_by) {
909 volumeRoot = vnode->covered_by;
918 /** \brief Resolves a mount point vnode to the volume root vnode it is covered
921 * Given an arbitrary vnode (identified by mount and node ID), the function
930 * \param mountID The mount ID of the vnode in question.
931 * \param nodeID The node ID of the vnode in question.
944 struct vnode *node;
950 struct vnode *resolvedNode = resolve_mount_point_to_volume_root(node);
966 /** \brief Resolves a volume root vnode to the underlying mount point vnode.
968 * Given an arbitrary vnode, the function checks, whether the node is the
972 * \param vnode The vnode in question (caller must have a reference).
973 * \return The mount point vnode the vnode covers, if it is indeed a volume
977 static struct vnode *
978 resolve_volume_root_to_mount_point(struct vnode *vnode)
980 if (!vnode)
983 struct vnode *mountPoint = NULL;
985 struct fs_mount *mount = vnode->mount;
986 if (vnode == mount->root_vnode && mount->covers_vnode) {
1045 entry_ref_to_vnode(fssh_mount_id mountID, fssh_vnode_id directoryID, const char *name, struct vnode **_vnode)
1051 // get the directory vnode and let vnode_path_to_vnode() do the rest
1052 struct vnode *directory;
1063 lookup_dir_entry(struct vnode* dir, const char* name, struct vnode** _vnode)
1075 fssh_panic("lookup_dir_entry(): could not lookup vnode (mountid %d "
1084 /*! Returns the vnode for the relative path starting at the specified \a vnode.
1089 Note, this reduces the ref_count of the starting \a vnode, no matter if
1093 vnode_path_to_vnode(struct vnode *vnode, char *path, bool traverseLeafLink,
1094 int count, struct vnode **_vnode, fssh_vnode_id *_parentID)
1097 fssh_vnode_id lastParentID = vnode->id;
1099 FUNCTION(("vnode_path_to_vnode(vnode = %p, path = %s)\n", vnode, path));
1102 put_vnode(vnode);
1107 struct vnode *nextVnode;
1128 // vnode so we pass the '..' path to the underlying filesystem
1130 && vnode->mount->root_vnode == vnode
1131 && vnode->mount->covers_vnode) {
1132 nextVnode = vnode->mount->covers_vnode;
1134 put_vnode(vnode);
1135 vnode = nextVnode;
1138 // Check if we have the right to search the current directory vnode.
1141 if (HAS_FS_CALL(vnode, access))
1142 status = FS_CALL(vnode, access, FSSH_X_OK);
1144 // Tell the filesystem to get the vnode of this path component (if we got the
1147 status = lookup_dir_entry(vnode, path, &nextVnode);
1150 put_vnode(vnode);
1155 if (FSSH_S_ISLNK(vnode->type)
1184 put_vnode(vnode);
1192 // directory ("vnode" still points to that one).
1197 put_vnode(vnode);
1201 vnode = sRoot;
1202 inc_vnode_ref_count(vnode);
1204 inc_vnode_ref_count(vnode);
1206 // of the vnode, no matter if we succeeded or not
1208 status = vnode_path_to_vnode(vnode, path, traverseLeafLink, count + 1,
1214 put_vnode(vnode);
1218 lastParentID = vnode->id;
1221 put_vnode(vnode);
1224 vnode = nextVnode;
1227 struct vnode *mountPoint = resolve_mount_point_to_volume_root(vnode);
1229 put_vnode(vnode);
1230 vnode = mountPoint;
1234 *_vnode = vnode;
1243 path_to_vnode(char *path, bool traverseLink, struct vnode **_vnode,
1246 struct vnode *start = NULL;
1281 /** Returns the vnode in the next to last segment of the path, and returns
1287 path_to_dir_vnode(char *path, struct vnode **_vnode, char *filename, bool kernel)
1297 /** \brief Retrieves the directory vnode and the leaf name of an entry referred
1307 * directory vnode.
1313 * \param _vnode A pointer to a variable the directory vnode shall be written
1323 fd_and_path_to_dir_vnode(int fd, char *path, struct vnode **_vnode,
1339 /** Returns a vnode's name in the d_name field of a supplied dirent buffer.
1343 get_vnode_name(struct vnode *vnode, struct vnode *parent,
1349 // See if vnode is the root of a mount and move to the covered
1350 // vnode so we get the underlying file system
1352 if (vnode->mount->root_vnode == vnode && vnode->mount->covers_vnode != NULL) {
1353 vnode = vnode->mount->covers_vnode;
1354 inc_vnode_ref_count(vnode);
1355 vnodePutter.SetTo(vnode);
1358 if (HAS_FS_CALL(vnode, get_vnode_name)) {
1359 // The FS supports getting the name of a vnode.
1360 return FS_CALL(vnode, get_vnode_name, buffer->d_name,
1364 // The FS doesn't support getting the name of a vnode. So we search the
1365 // parent directory for the vnode, if the caller let us.
1384 if (vnode->id == buffer->d_ino) {
1390 FS_CALL(vnode, close_dir, cookie);
1391 FS_CALL(vnode, free_dir_cookie, cookie);
1398 get_vnode_name(struct vnode *vnode, struct vnode *parent, char *name,
1404 fssh_status_t status = get_vnode_name(vnode, parent, buffer, sizeof(buffer));
1415 /** Gets the full path to a given directory vnode.
1416 * It uses the fs_get_vnode_name() call to get the name of a vnode; if a
1432 dir_vnode_to_path(struct vnode *vnode, char *buffer, fssh_size_t bufferSize)
1434 FUNCTION(("dir_vnode_to_path(%p, %p, %lu)\n", vnode, buffer, bufferSize));
1436 if (vnode == NULL || buffer == NULL)
1452 inc_vnode_ref_count(vnode);
1455 struct vnode *mountPoint = resolve_volume_root_to_mount_point(vnode);
1457 put_vnode(vnode);
1458 vnode = mountPoint;
1467 struct vnode *parentVnode;
1470 // lookup the parent vnode
1471 status = lookup_dir_entry(vnode, "..", &parentVnode);
1476 status = get_vnode_name(vnode, parentVnode,
1487 bool hitRoot = (parentVnode == vnode);
1489 // release the current vnode, we only need its parent from now on
1490 put_vnode(vnode);
1491 vnode = parentVnode;
1537 put_vnode(vnode);
1586 get_fd_and_vnode(int fd, struct vnode **_vnode, bool kernel)
1598 // if this is still valid to do (accessing the vnode without ref_count
1600 *_vnode = descriptor->u.vnode;
1605 static struct vnode *
1609 struct vnode *vnode;
1615 vnode = fd_vnode(descriptor);
1616 if (vnode != NULL)
1617 inc_vnode_ref_count(vnode);
1620 return vnode;
1624 /** Gets the vnode from an FD + path combination. If \a fd is lower than zero,
1633 struct vnode **_vnode, fssh_vnode_id *_parentID, bool kernel)
1644 struct vnode *vnode = get_vnode_from_fd(fd, kernel);
1645 if (!vnode)
1649 return vnode_path_to_vnode(vnode, path, traverseLeafLink, 0,
1655 *_vnode = vnode;
1664 get_new_fd(int type, struct fs_mount *mount, struct vnode *vnode,
1670 // if the vnode is locked, we don't allow creating a new file descriptor for it
1671 if (vnode && vnode->mandatory_locked_by != NULL)
1678 if (vnode)
1679 descriptor->u.vnode = vnode;
1685 // vnode types
1894 // test if the vnode already exists and bail out if this is the case!
1899 struct vnode *vnode = lookup_vnode(volume->id, vnodeID);
1900 if (vnode != NULL) {
1901 fssh_panic("vnode %d:%" FSSH_B_PRIdINO " already exists (node = %p, "
1902 "vnode->node = %p)!", (int)volume->id, vnodeID, privateNode,
1903 vnode->private_node);
1906 fssh_status_t status = create_new_vnode(&vnode, volume->id, vnodeID);
1908 vnode->private_node = privateNode;
1909 vnode->ops = ops;
1910 vnode->busy = true;
1911 vnode->unpublished = true;
1929 struct vnode *vnode = lookup_vnode(volume->id, vnodeID);
1932 if (vnode != NULL && vnode->busy && vnode->unpublished
1933 && vnode->private_node == privateNode) {
1935 } else if (vnode == NULL && privateNode != NULL) {
1936 status = create_new_vnode(&vnode, volume->id, vnodeID);
1938 vnode->private_node = privateNode;
1939 vnode->ops = ops;
1940 vnode->busy = true;
1941 vnode->unpublished = true;
1954 vnode);
1961 subVolume->ops->delete_sub_vnode(subVolume, vnode);
1969 vnode->type = type;
1970 vnode->busy = false;
1971 vnode->unpublished = false;
1984 struct vnode *vnode;
1989 fssh_status_t status = get_vnode(volume->id, vnodeID, &vnode, true);
1995 if (HAS_FS_CALL(vnode, get_super_vnode)) {
1997 fssh_status_t status = FS_CALL(vnode, get_super_vnode, volume,
2000 fssh_panic("get_vnode(): Failed to get super node for vnode %p, "
2001 "volume: %p", vnode, volume);
2002 put_vnode(vnode);
2009 *privateNode = vnode->private_node;
2018 struct vnode *vnode;
2021 vnode = lookup_vnode(volume->id, vnodeID);
2024 if (vnode == NULL)
2027 inc_vnode_ref_count(vnode);
2035 struct vnode *vnode;
2038 vnode = lookup_vnode(volume->id, vnodeID);
2041 if (vnode == NULL)
2044 dec_vnode_ref_count(vnode, true);
2052 struct vnode *vnode;
2057 vnode = lookup_vnode(volume->id, vnodeID);
2058 if (vnode == NULL)
2061 if (vnode->covered_by != NULL) {
2062 // this vnode is in use
2067 vnode->remove = true;
2068 if (vnode->unpublished) {
2069 // prepare the vnode for deletion
2070 vnode->busy = true;
2077 // if the vnode hasn't been published yet, we delete it here
2078 fssh_atomic_add(&vnode->ref_count, -1);
2079 free_vnode(vnode, true);
2089 struct vnode *vnode;
2093 vnode = lookup_vnode(volume->id, vnodeID);
2094 if (vnode)
2095 vnode->remove = false;
2109 if (struct vnode* vnode = lookup_vnode(volume->id, vnodeID)) {
2111 *removed = vnode->remove;
2127 struct vnode* vnode = static_cast<struct vnode*>(_vnode);
2128 return vnode->mount->volume;
2257 /** Acquires another reference to the vnode that has to be released
2264 inc_vnode_ref_count((struct vnode *)_vnode);
2291 vfs_get_vnode_from_fd(int fd, bool kernel, void **vnode)
2293 *vnode = get_vnode_from_fd(fd, kernel);
2295 if (*vnode == NULL)
2314 struct vnode *vnode;
2315 fssh_status_t status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
2319 *_vnode = vnode;
2327 struct vnode *vnode;
2329 fssh_status_t status = get_vnode(mountID, vnodeID, &vnode, false);
2333 *_vnode = vnode;
2342 struct vnode *vnode = (struct vnode *)_vnode;
2344 return FS_CALL(vnode, read_pages,
2353 struct vnode *vnode = (struct vnode *)_vnode;
2355 return FS_CALL(vnode, write_pages,
2365 (struct vnode **)_vnode);
2373 struct vnode *vnode = (struct vnode *)_vnode;
2375 *_mountID = vnode->device;
2376 *_vnodeID = vnode->id;
2380 /** Looks up a vnode with the given mount and vnode ID.
2388 struct vnode **_vnode)
2391 struct vnode *vnode = lookup_vnode(mountID, vnodeID);
2394 if (vnode == NULL)
2397 *_vnode = vnode;
2421 struct vnode *vnode = mount->root_vnode;
2424 status = path_to_vnode(buffer, true, &vnode, NULL, true);
2426 inc_vnode_ref_count(vnode);
2427 // vnode_path_to_vnode() releases a reference to the starting vnode
2428 status = vnode_path_to_vnode(vnode, buffer, true, 0, &vnode, NULL);
2436 if (vnode->device != volume->id) {
2438 put_vnode(vnode);
2443 status = ::fssh_get_vnode(volume, vnode->id, _node);
2444 put_vnode(vnode);
2462 struct vnode *dir, *file;
2578 // get the dir vnode and the leaf name
2579 struct vnode *dirNode;
2583 TRACE(("vfs_normalize_path(): failed to get dir vnode: %s\n", strerror(error)));
2588 // vnode and ignore the leaf later
2593 TRACE(("vfs_normalize_path(): failed to get dir vnode for \".\" or \"..\": %s\n",
2624 put_vnode((struct vnode *)_vnode);
2652 struct vnode *vnode = (struct vnode *)_vnode;
2654 FUNCTION(("vfs_get_file_map: vnode %p, vecs %p, offset %lld, size = %u\n", vnode, vecs, offset, (unsigned)size));
2656 return FS_CALL(vnode, get_file_map, offset, size, vecs, _count);
2663 struct vnode *vnode = (struct vnode *)_vnode;
2665 fssh_status_t status = FS_CALL(vnode, read_stat, stat);
2669 stat->fssh_st_dev = vnode->device;
2670 stat->fssh_st_ino = vnode->id;
2680 return get_vnode_name((struct vnode *)_vnode, NULL, name, nameSize);
2688 struct vnode *vnode;
2695 // get the vnode matching the dir's node_ref
2697 // special cases "." and "..": we can directly get the vnode of the
2699 status = entry_ref_to_vnode(device, inode, leaf, &vnode);
2702 status = get_vnode(device, inode, &vnode, false);
2707 status = dir_vnode_to_path(vnode, path, pathLength);
2708 put_vnode(vnode);
2709 // we don't need the vnode anymore
2727 /** If the given descriptor locked its vnode, that lock will be released.
2733 struct vnode *vnode = fd_vnode(descriptor);
2735 if (vnode != NULL && vnode->mandatory_locked_by == descriptor)
2736 vnode->mandatory_locked_by = NULL;
2876 sVnodeTable = hash_init(VNODE_HASH_TABLE_SIZE, fssh_offsetof(struct vnode, next),
2879 fssh_panic("vfs_init: error creating vnode hash table\n");
2881 list_init_etc(&sUnusedVnodeList, fssh_offsetof(struct vnode, unused_link));
2907 /** Calls fs_open() on the given vnode and returns a new
2912 create_vnode(struct vnode *directory, const char *name, int openMode, int perms, bool kernel)
2914 struct vnode *vnode;
2927 vnode = lookup_vnode(directory->device, newID);
2930 if (vnode == NULL) {
2931 fssh_dprintf("vfs: fs_create() returned success but there is no vnode!");
2935 if ((status = get_new_fd(FDTYPE_FILE, NULL, vnode, cookie, openMode, kernel)) >= 0)
2940 FS_CALL(vnode, close, cookie);
2941 FS_CALL(vnode, free_cookie, cookie);
2942 put_vnode(vnode);
2950 /** Calls fs_open() on the given vnode and returns a new
2955 open_vnode(struct vnode *vnode, int openMode, bool kernel)
2960 status = FS_CALL(vnode, open, openMode, &cookie);
2964 status = get_new_fd(FDTYPE_FILE, NULL, vnode, cookie, openMode, kernel);
2966 FS_CALL(vnode, close, cookie);
2967 FS_CALL(vnode, free_cookie, cookie);
2973 /** Calls fs open_dir() on the given vnode and returns a new
2978 open_dir_vnode(struct vnode *vnode, bool kernel)
2983 status = FS_CALL(vnode, open_dir, &cookie);
2988 status = get_new_fd(FDTYPE_DIR, NULL, vnode, cookie, 0, kernel);
2992 FS_CALL(vnode, close_dir, cookie);
2993 FS_CALL(vnode, free_dir_cookie, cookie);
2999 /** Calls fs open_attr_dir() on the given vnode and returns a new
3005 open_attr_dir_vnode(struct vnode *vnode, bool kernel)
3010 if (!HAS_FS_CALL(vnode, open_attr_dir))
3013 status = FS_CALL(vnode, open_attr_dir, &cookie);
3018 status = get_new_fd(FDTYPE_ATTR_DIR, NULL, vnode, cookie, 0, kernel);
3022 FS_CALL(vnode, close_attr_dir, cookie);
3023 FS_CALL(vnode, free_attr_dir_cookie, cookie);
3032 struct vnode *directory;
3053 struct vnode *directory;
3073 struct vnode *vnode;
3082 // get the vnode matching the entry_ref
3083 status = entry_ref_to_vnode(mountID, directoryID, name, &vnode);
3087 status = open_vnode(vnode, openMode, kernel);
3089 put_vnode(vnode);
3104 // get the vnode matching the vnode + path combination
3105 struct vnode *vnode = NULL;
3107 status = fd_and_path_to_vnode(fd, path, traverse, &vnode, &parentID, kernel);
3111 // open the vnode
3112 status = open_vnode(vnode, openMode, kernel);
3115 put_vnode(vnode);
3124 struct vnode *vnode = descriptor->u.vnode;
3129 if (HAS_FS_CALL(vnode, close))
3130 status = FS_CALL(vnode, close, descriptor->cookie);
3139 struct vnode *vnode = descriptor->u.vnode;
3141 if (vnode != NULL) {
3142 FS_CALL(vnode, free_cookie, descriptor->cookie);
3143 put_vnode(vnode);
3151 struct vnode *vnode = descriptor->u.vnode;
3154 return FS_CALL(vnode, read, descriptor->cookie, pos, buffer, length);
3161 struct vnode *vnode = descriptor->u.vnode;
3164 return FS_CALL(vnode, write, descriptor->cookie, pos, buffer, length);
3185 struct vnode *vnode = descriptor->u.vnode;
3189 if (!HAS_FS_CALL(vnode, read_stat))
3192 status = FS_CALL(vnode, read_stat, &stat);
3218 struct vnode *vnode;
3226 status = get_vnode(mountID, parentID, &vnode, kernel);
3230 if (HAS_FS_CALL(vnode, create_dir))
3231 status = FS_CALL(vnode, create_dir, name, perms);
3235 put_vnode(vnode);
3244 struct vnode *vnode;
3249 status = fd_and_path_to_dir_vnode(fd, path, &vnode, filename, kernel);
3253 if (HAS_FS_CALL(vnode, create_dir))
3254 status = FS_CALL(vnode, create_dir, filename, perms);
3258 put_vnode(vnode);
3266 struct vnode *vnode;
3274 // get the vnode matching the entry_ref/node_ref
3276 status = entry_ref_to_vnode(mountID, parentID, name, &vnode);
3278 status = get_vnode(mountID, parentID, &vnode, false);
3282 status = open_dir_vnode(vnode, kernel);
3284 put_vnode(vnode);
3297 // get the vnode matching the vnode + path combination
3298 struct vnode *vnode = NULL;
3300 status = fd_and_path_to_vnode(fd, path, true, &vnode, &parentID, kernel);
3305 status = open_dir_vnode(vnode, kernel);
3307 put_vnode(vnode);
3316 struct vnode *vnode = descriptor->u.vnode;
3320 if (HAS_FS_CALL(vnode, close_dir))
3321 return FS_CALL(vnode, close_dir, descriptor->cookie);
3330 struct vnode *vnode = descriptor->u.vnode;
3332 if (vnode != NULL) {
3333 FS_CALL(vnode, free_dir_cookie, descriptor->cookie);
3334 put_vnode(vnode);
3343 return dir_read(descriptor->u.vnode, descriptor->cookie, buffer, bufferSize, _count);
3348 fix_dirent(struct vnode *parent, struct fssh_dirent *entry)
3363 struct vnode *vnode;
3365 0, &vnode, NULL);
3368 entry->d_dev = vnode->device;
3369 entry->d_ino = vnode->id;
3373 struct vnode *vnode = NULL;
3374 fssh_status_t status = get_vnode(entry->d_dev, entry->d_ino, &vnode, false);
3379 if (vnode->covered_by) {
3380 entry->d_dev = vnode->covered_by->device;
3381 entry->d_ino = vnode->covered_by->id;
3385 put_vnode(vnode);
3391 dir_read(struct vnode *vnode, void *cookie, struct fssh_dirent *buffer,
3394 if (!HAS_FS_CALL(vnode, read_dir))
3397 fssh_status_t error = FS_CALL(vnode, read_dir,cookie,buffer,bufferSize,_count);
3404 fix_dirent(vnode, buffer);
3414 struct vnode *vnode = descriptor->u.vnode;
3416 if (HAS_FS_CALL(vnode, rewind_dir))
3417 return FS_CALL(vnode, rewind_dir,descriptor->cookie);
3427 struct vnode *directory;
3470 struct vnode *vnode = descriptor->u.vnode;
3472 if (HAS_FS_CALL(vnode, ioctl)) {
3473 return FS_CALL(vnode, ioctl,
3485 struct vnode *vnode;
3491 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
3523 if (HAS_FS_CALL(vnode, set_flags)) {
3527 status = FS_CALL(vnode, set_flags, descriptor->cookie, (int)argument);
3578 struct vnode *vnode;
3583 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
3587 if (HAS_FS_CALL(vnode, fsync))
3588 status = FS_CALL_NO_PARAMS(vnode, fsync);
3601 struct vnode *vnode;
3603 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
3612 if (fssh_atomic_test_and_set64((vint64_t *)&vnode->mandatory_locked_by,
3615 if (fssh_atomic_test_and_set((vint32_t *)&vnode->mandatory_locked_by,
3629 struct vnode *vnode;
3631 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
3640 if (fssh_atomic_test_and_set64((vint64_t *)&vnode->mandatory_locked_by,
3643 if (fssh_atomic_test_and_set((vint32_t *)&vnode->mandatory_locked_by,
3657 struct vnode *vnode;
3660 status = fd_and_path_to_vnode(fd, path, false, &vnode, NULL, kernel);
3664 if (HAS_FS_CALL(vnode, read_symlink)) {
3665 status = FS_CALL(vnode, read_symlink, buffer, _bufferSize);
3669 put_vnode(vnode);
3680 struct vnode *vnode;
3685 status = fd_and_path_to_dir_vnode(fd, path, &vnode, name, kernel);
3689 if (HAS_FS_CALL(vnode, create_symlink))
3690 status = FS_CALL(vnode, create_symlink, name, toPath, mode);
3694 put_vnode(vnode);
3705 struct vnode *directory, *vnode;
3714 status = path_to_vnode(toPath, true, &vnode, NULL, kernel);
3718 if (directory->mount != vnode->mount) {
3724 status = FS_CALL(directory, link, name, vnode);
3729 put_vnode(vnode);
3741 struct vnode *vnode;
3746 status = fd_and_path_to_dir_vnode(fd, path, &vnode, filename, kernel);
3750 if (HAS_FS_CALL(vnode, unlink))
3751 status = FS_CALL(vnode, unlink, filename);
3755 put_vnode(vnode);
3764 struct vnode *vnode;
3767 status = path_to_vnode(path, true, &vnode, NULL, kernel);
3771 if (HAS_FS_CALL(vnode, access))
3772 status = FS_CALL(vnode, access, mode);
3776 put_vnode(vnode);
3785 struct vnode *fromVnode, *toVnode;
3822 struct vnode *vnode = descriptor->u.vnode;
3831 fssh_status_t status = FS_CALL(vnode, read_stat, stat);
3835 stat->fssh_st_dev = vnode->device;
3836 stat->fssh_st_ino = vnode->id;
3847 struct vnode *vnode = descriptor->u.vnode;
3849 FUNCTION(("common_write_stat(vnode = %p, stat = %p, statMask = %d)\n", vnode, stat, statMask));
3850 if (!HAS_FS_CALL(vnode, write_stat))
3853 return FS_CALL(vnode, write_stat, stat, statMask);
3861 struct vnode *vnode;
3866 status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, NULL, kernel);
3870 status = FS_CALL(vnode, read_stat, stat);
3874 stat->fssh_st_dev = vnode->device;
3875 stat->fssh_st_ino = vnode->id;
3878 put_vnode(vnode);
3887 struct vnode *vnode;
3892 status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, NULL, kernel);
3896 if (HAS_FS_CALL(vnode, write_stat))
3897 status = FS_CALL(vnode, write_stat, stat, statMask);
3901 put_vnode(vnode);
3910 struct vnode *vnode;
3915 status = fd_and_path_to_vnode(fd, path, true, &vnode, NULL, kernel);
3919 status = open_attr_dir_vnode(vnode, kernel);
3921 put_vnode(vnode);
3930 struct vnode *vnode = descriptor->u.vnode;
3934 if (HAS_FS_CALL(vnode, close_attr_dir))
3935 return FS_CALL(vnode, close_attr_dir, descriptor->cookie);
3944 struct vnode *vnode = descriptor->u.vnode;
3946 if (vnode != NULL) {
3947 FS_CALL(vnode, free_attr_dir_cookie, descriptor->cookie);
3948 put_vnode(vnode);
3957 struct vnode *vnode = descriptor->u.vnode;
3961 if (HAS_FS_CALL(vnode, read_attr_dir))
3962 return FS_CALL(vnode, read_attr_dir, descriptor->cookie, buffer, bufferSize, _count);
3971 struct vnode *vnode = descriptor->u.vnode;
3975 if (HAS_FS_CALL(vnode, rewind_attr_dir))
3976 return FS_CALL(vnode, rewind_attr_dir, descriptor->cookie);
3985 struct vnode *vnode;
3992 vnode = get_vnode_from_fd(fd, kernel);
3993 if (vnode == NULL)
3996 if (!HAS_FS_CALL(vnode, create_attr)) {
4001 status = FS_CALL(vnode, create_attr, name, type, openMode, &cookie);
4005 if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
4008 FS_CALL(vnode, close_attr, cookie);
4009 FS_CALL(vnode, free_attr_cookie, cookie);
4011 FS_CALL(vnode, remove_attr, name);
4014 put_vnode(vnode);
4023 struct vnode *vnode;
4030 vnode = get_vnode_from_fd(fd, kernel);
4031 if (vnode == NULL)
4034 if (!HAS_FS_CALL(vnode, open_attr)) {
4039 status = FS_CALL(vnode, open_attr, name, openMode, &cookie);
4044 if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
4047 FS_CALL(vnode, close_attr, cookie);
4048 FS_CALL(vnode, free_attr_cookie, cookie);
4051 put_vnode(vnode);
4060 struct vnode *vnode = descriptor->u.vnode;
4064 if (HAS_FS_CALL(vnode, close_attr))
4065 return FS_CALL(vnode, close_attr, descriptor->cookie);
4074 struct vnode *vnode = descriptor->u.vnode;
4076 if (vnode != NULL) {
4077 FS_CALL(vnode, free_attr_cookie, descriptor->cookie);
4078 put_vnode(vnode);
4086 struct vnode *vnode = descriptor->u.vnode;
4089 if (!HAS_FS_CALL(vnode, read_attr))
4092 return FS_CALL(vnode, read_attr, descriptor->cookie, pos, buffer, length);
4099 struct vnode *vnode = descriptor->u.vnode;
4102 if (!HAS_FS_CALL(vnode, write_attr))
4105 return FS_CALL(vnode, write_attr, descriptor->cookie, pos, buffer, length);
4123 struct vnode *vnode = descriptor->u.vnode;
4127 if (!HAS_FS_CALL(vnode, read_stat))
4130 status = FS_CALL(vnode, read_attr_stat, descriptor->cookie, &stat);
4156 struct vnode *vnode = descriptor->u.vnode;
4160 if (!HAS_FS_CALL(vnode, read_attr_stat))
4163 return FS_CALL(vnode, read_attr_stat, descriptor->cookie, stat);
4171 struct vnode *vnode = descriptor->u.vnode;
4175 if (!HAS_FS_CALL(vnode, write_attr_stat))
4178 return FS_CALL(vnode, write_attr_stat, descriptor->cookie, stat, statMask);
4186 struct vnode *vnode;
4194 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
4198 if (HAS_FS_CALL(vnode, remove_attr))
4199 status = FS_CALL(vnode, remove_attr, name);
4213 struct vnode *fromVnode, *toVnode;
4309 //put_vnode(vnode);
4473 //put_vnode(vnode);
4555 list_init_etc(&mount->vnodes, fssh_offsetof(struct vnode, mount_link));
4610 struct vnode *coveredVnode;
4690 struct vnode *vnode;
4695 err = path_to_vnode(path, true, &vnode, NULL, kernel);
4701 mount = find_mount(vnode->device);
4703 fssh_panic("vfs_unmount: find_mount() failed on root vnode @%p of mount\n", vnode);
4705 if (mount->root_vnode != vnode) {
4707 put_vnode(vnode);
4711 // grab the vnode master mutex to keep someone from creating
4712 // a vnode while we're figuring out if we can continue
4722 vnode = NULL;
4723 while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode)) != NULL) {
4724 // The root vnode ref_count needs to be 2 here: one for the file
4726 if (vnode->busy
4727 || ((vnode->ref_count != 0 && mount->root_vnode != vnode)
4728 || (vnode->ref_count != 2 && mount->root_vnode == vnode))) {
4774 while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode)) != NULL) {
4775 vnode->busy = true;
4777 if (vnode->ref_count == 0) {
4778 // this vnode has been unused before
4779 list_remove_item(&sUnusedVnodeList, vnode);
4797 while ((vnode = (struct vnode *)list_get_first_item(&mount->vnodes)) != NULL) {
4798 free_vnode(vnode, false);
4836 struct vnode *previousVnode = NULL;
4838 // synchronize access to vnode list
4841 struct vnode *vnode = (struct vnode *)list_get_next_item(&mount->vnodes,
4845 if (vnode != NULL)
4846 id = vnode->id;
4850 if (vnode == NULL)
4853 // acquire a reference to the vnode
4855 if (get_vnode(mount->id, id, &vnode, true) == FSSH_B_OK) {
4859 if (HAS_FS_CALL(vnode, fsync))
4860 FS_CALL_NO_PARAMS(vnode, fsync);
4862 // the next vnode might change until we lock the vnode list again,
4863 // but this vnode won't go away since we keep a reference to it.
4864 previousVnode = vnode;
4866 fssh_dprintf("syncing of mount %d stopped due to vnode %"
4987 struct vnode *vnode = NULL;
4988 struct vnode *oldDirectory;
4994 // Get vnode for passed path, and bail if it failed
4995 status = fd_and_path_to_vnode(fd, path, true, &vnode, NULL, kernel);
4999 status = FS_CALL(vnode, read_stat, &stat);
5015 context->cwd = vnode;
5025 put_vnode(vnode);