Lines Matching defs:vnode

55 #define HAS_FS_CALL(vnode, op)			(vnode->ops->op != NULL)
58 #define FS_CALL(vnode, op, params...) \
59 vnode->ops->op(vnode->mount->volume, vnode, params)
60 #define FS_CALL_NO_PARAMS(vnode, op) \
61 vnode->ops->op(vnode->mount->volume, vnode)
75 struct vnode : fssh_fs_vnode {
76 struct vnode *next;
83 struct vnode *covered_by;
96 fssh_vnode_id vnode;
104 (e.g. by holding a reference to a vnode of that mount) (read) access
107 making the access path vnode->mount->covers_vnode->mount->... safe if a
108 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);
1188 put_vnode(vnode);
1196 // directory ("vnode" still points to that one).
1201 put_vnode(vnode);
1205 vnode = sRoot;
1206 inc_vnode_ref_count(vnode);
1208 inc_vnode_ref_count(vnode);
1210 // of the vnode, no matter if we succeeded or not
1212 status = vnode_path_to_vnode(vnode, path, traverseLeafLink, count + 1,
1218 put_vnode(vnode);
1222 lastParentID = vnode->id;
1225 put_vnode(vnode);
1228 vnode = nextVnode;
1231 struct vnode *mountPoint = resolve_mount_point_to_volume_root(vnode);
1233 put_vnode(vnode);
1234 vnode = mountPoint;
1238 *_vnode = vnode;
1247 path_to_vnode(char *path, bool traverseLink, struct vnode **_vnode,
1250 struct vnode *start = NULL;
1285 /** Returns the vnode in the next to last segment of the path, and returns
1291 path_to_dir_vnode(char *path, struct vnode **_vnode, char *filename, bool kernel)
1301 /** \brief Retrieves the directory vnode and the leaf name of an entry referred
1311 * directory vnode.
1317 * \param _vnode A pointer to a variable the directory vnode shall be written
1327 fd_and_path_to_dir_vnode(int fd, char *path, struct vnode **_vnode,
1343 /** Returns a vnode's name in the d_name field of a supplied dirent buffer.
1347 get_vnode_name(struct vnode *vnode, struct vnode *parent,
1353 // See if vnode is the root of a mount and move to the covered
1354 // vnode so we get the underlying file system
1356 if (vnode->mount->root_vnode == vnode && vnode->mount->covers_vnode != NULL) {
1357 vnode = vnode->mount->covers_vnode;
1358 inc_vnode_ref_count(vnode);
1359 vnodePutter.SetTo(vnode);
1362 if (HAS_FS_CALL(vnode, get_vnode_name)) {
1363 // The FS supports getting the name of a vnode.
1364 return FS_CALL(vnode, get_vnode_name, buffer->d_name,
1368 // The FS doesn't support getting the name of a vnode. So we search the
1369 // parent directory for the vnode, if the caller let us.
1388 if (vnode->id == buffer->d_ino) {
1394 FS_CALL(vnode, close_dir, cookie);
1395 FS_CALL(vnode, free_dir_cookie, cookie);
1402 get_vnode_name(struct vnode *vnode, struct vnode *parent, char *name,
1408 fssh_status_t status = get_vnode_name(vnode, parent, buffer, sizeof(buffer));
1419 /** Gets the full path to a given directory vnode.
1420 * It uses the fs_get_vnode_name() call to get the name of a vnode; if a
1436 dir_vnode_to_path(struct vnode *vnode, char *buffer, fssh_size_t bufferSize)
1438 FUNCTION(("dir_vnode_to_path(%p, %p, %lu)\n", vnode, buffer, bufferSize));
1440 if (vnode == NULL || buffer == NULL)
1456 inc_vnode_ref_count(vnode);
1459 struct vnode *mountPoint = resolve_volume_root_to_mount_point(vnode);
1461 put_vnode(vnode);
1462 vnode = mountPoint;
1471 struct vnode *parentVnode;
1473 // lookup the parent vnode
1474 status = lookup_dir_entry(vnode, "..", &parentVnode);
1479 status = get_vnode_name(vnode, parentVnode,
1489 bool hitRoot = (parentVnode == vnode);
1491 // release the current vnode, we only need its parent from now on
1492 put_vnode(vnode);
1493 vnode = parentVnode;
1539 put_vnode(vnode);
1588 get_fd_and_vnode(int fd, struct vnode **_vnode, bool kernel)
1600 // if this is still valid to do (accessing the vnode without ref_count
1602 *_vnode = descriptor->u.vnode;
1607 static struct vnode *
1611 struct vnode *vnode;
1617 vnode = fd_vnode(descriptor);
1618 if (vnode != NULL)
1619 inc_vnode_ref_count(vnode);
1622 return vnode;
1626 /** Gets the vnode from an FD + path combination. If \a fd is lower than zero,
1635 struct vnode **_vnode, fssh_vnode_id *_parentID, bool kernel)
1646 struct vnode *vnode = get_vnode_from_fd(fd, kernel);
1647 if (!vnode)
1651 return vnode_path_to_vnode(vnode, path, traverseLeafLink, 0,
1657 *_vnode = vnode;
1666 get_new_fd(int type, struct fs_mount *mount, struct vnode *vnode,
1672 // if the vnode is locked, we don't allow creating a new file descriptor for it
1673 if (vnode && vnode->mandatory_locked_by != NULL)
1680 if (vnode)
1681 descriptor->u.vnode = vnode;
1687 // vnode types
1896 // test if the vnode already exists and bail out if this is the case!
1901 struct vnode *vnode = lookup_vnode(volume->id, vnodeID);
1902 if (vnode != NULL) {
1903 fssh_panic("vnode %d:%" FSSH_B_PRIdINO " already exists (node = %p, "
1904 "vnode->node = %p)!", (int)volume->id, vnodeID, privateNode,
1905 vnode->private_node);
1908 fssh_status_t status = create_new_vnode(&vnode, volume->id, vnodeID);
1910 vnode->private_node = privateNode;
1911 vnode->ops = ops;
1912 vnode->busy = true;
1913 vnode->unpublished = true;
1931 struct vnode *vnode = lookup_vnode(volume->id, vnodeID);
1934 if (vnode != NULL && vnode->busy && vnode->unpublished
1935 && vnode->private_node == privateNode) {
1937 } else if (vnode == NULL && privateNode != NULL) {
1938 status = create_new_vnode(&vnode, volume->id, vnodeID);
1940 vnode->private_node = privateNode;
1941 vnode->ops = ops;
1942 vnode->busy = true;
1943 vnode->unpublished = true;
1956 vnode);
1963 subVolume->ops->delete_sub_vnode(subVolume, vnode);
1971 vnode->type = type;
1972 vnode->busy = false;
1973 vnode->unpublished = false;
1986 struct vnode *vnode;
1991 fssh_status_t status = get_vnode(volume->id, vnodeID, &vnode, true);
1997 if (HAS_FS_CALL(vnode, get_super_vnode)) {
1999 fssh_status_t status = FS_CALL(vnode, get_super_vnode, volume,
2002 fssh_panic("get_vnode(): Failed to get super node for vnode %p, "
2003 "volume: %p", vnode, volume);
2004 put_vnode(vnode);
2011 *privateNode = vnode->private_node;
2020 struct vnode *vnode;
2023 vnode = lookup_vnode(volume->id, vnodeID);
2026 if (vnode == NULL)
2029 inc_vnode_ref_count(vnode);
2037 struct vnode *vnode;
2040 vnode = lookup_vnode(volume->id, vnodeID);
2043 if (vnode == NULL)
2046 dec_vnode_ref_count(vnode, true);
2054 struct vnode *vnode;
2059 vnode = lookup_vnode(volume->id, vnodeID);
2060 if (vnode == NULL)
2063 if (vnode->covered_by != NULL) {
2064 // this vnode is in use
2069 vnode->remove = true;
2070 if (vnode->unpublished) {
2071 // prepare the vnode for deletion
2072 vnode->busy = true;
2079 // if the vnode hasn't been published yet, we delete it here
2080 fssh_atomic_add(&vnode->ref_count, -1);
2081 free_vnode(vnode, true);
2091 struct vnode *vnode;
2095 vnode = lookup_vnode(volume->id, vnodeID);
2096 if (vnode)
2097 vnode->remove = false;
2111 if (struct vnode* vnode = lookup_vnode(volume->id, vnodeID)) {
2113 *removed = vnode->remove;
2129 struct vnode* vnode = static_cast<struct vnode*>(_vnode);
2130 return vnode->mount->volume;
2304 /** Acquires another reference to the vnode that has to be released
2311 inc_vnode_ref_count((struct vnode *)_vnode);
2338 vfs_get_vnode_from_fd(int fd, bool kernel, void **vnode)
2340 *vnode = get_vnode_from_fd(fd, kernel);
2342 if (*vnode == NULL)
2361 struct vnode *vnode;
2362 fssh_status_t status = path_to_vnode(buffer, true, &vnode, NULL, kernel);
2366 *_vnode = vnode;
2374 struct vnode *vnode;
2376 fssh_status_t status = get_vnode(mountID, vnodeID, &vnode, false);
2380 *_vnode = vnode;
2389 struct vnode *vnode = (struct vnode *)_vnode;
2391 return FS_CALL(vnode, read_pages,
2400 struct vnode *vnode = (struct vnode *)_vnode;
2402 return FS_CALL(vnode, write_pages,
2412 (struct vnode **)_vnode);
2420 struct vnode *vnode = (struct vnode *)_vnode;
2422 *_mountID = vnode->device;
2423 *_vnodeID = vnode->id;
2427 /** Looks up a vnode with the given mount and vnode ID.
2435 struct vnode **_vnode)
2438 struct vnode *vnode = lookup_vnode(mountID, vnodeID);
2441 if (vnode == NULL)
2444 *_vnode = vnode;
2468 struct vnode *vnode = mount->root_vnode;
2471 status = path_to_vnode(buffer, true, &vnode, NULL, true);
2473 inc_vnode_ref_count(vnode);
2474 // vnode_path_to_vnode() releases a reference to the starting vnode
2475 status = vnode_path_to_vnode(vnode, buffer, true, 0, &vnode, NULL);
2483 if (vnode->device != volume->id) {
2485 put_vnode(vnode);
2490 status = ::fssh_get_vnode(volume, vnode->id, _node);
2491 put_vnode(vnode);
2509 struct vnode *dir, *file;
2625 // get the dir vnode and the leaf name
2626 struct vnode *dirNode;
2630 TRACE(("vfs_normalize_path(): failed to get dir vnode: %s\n", strerror(error)));
2635 // vnode and ignore the leaf later
2640 TRACE(("vfs_normalize_path(): failed to get dir vnode for \".\" or \"..\": %s\n",
2671 put_vnode((struct vnode *)_vnode);
2699 struct vnode *vnode = (struct vnode *)_vnode;
2701 FUNCTION(("vfs_get_file_map: vnode %p, vecs %p, offset %lld, size = %u\n", vnode, vecs, offset, (unsigned)size));
2703 return FS_CALL(vnode, get_file_map, offset, size, vecs, _count);
2710 struct vnode *vnode = (struct vnode *)_vnode;
2712 fssh_status_t status = FS_CALL(vnode, read_stat, stat);
2716 stat->fssh_st_dev = vnode->device;
2717 stat->fssh_st_ino = vnode->id;
2727 return get_vnode_name((struct vnode *)_vnode, NULL, name, nameSize);
2735 struct vnode *vnode;
2742 // get the vnode matching the dir's node_ref
2744 // special cases "." and "..": we can directly get the vnode of the
2746 status = entry_ref_to_vnode(device, inode, leaf, &vnode);
2749 status = get_vnode(device, inode, &vnode, false);
2754 status = dir_vnode_to_path(vnode, path, pathLength);
2755 put_vnode(vnode);
2756 // we don't need the vnode anymore
2774 /** If the given descriptor locked its vnode, that lock will be released.
2780 struct vnode *vnode = fd_vnode(descriptor);
2782 if (vnode != NULL && vnode->mandatory_locked_by == descriptor)
2783 vnode->mandatory_locked_by = NULL;
2923 sVnodeTable = hash_init(VNODE_HASH_TABLE_SIZE, fssh_offsetof(struct vnode, next),
2926 fssh_panic("vfs_init: error creating vnode hash table\n");
2928 list_init_etc(&sUnusedVnodeList, fssh_offsetof(struct vnode, unused_link));
2954 /** Calls fs_open() on the given vnode and returns a new
2959 create_vnode(struct vnode *directory, const char *name, int openMode, int perms, bool kernel)
2961 struct vnode *vnode;
2974 vnode = lookup_vnode(directory->device, newID);
2977 if (vnode == NULL) {
2978 fssh_dprintf("vfs: fs_create() returned success but there is no vnode!");
2982 if ((status = get_new_fd(FDTYPE_FILE, NULL, vnode, cookie, openMode, kernel)) >= 0)
2987 FS_CALL(vnode, close, cookie);
2988 FS_CALL(vnode, free_cookie, cookie);
2989 put_vnode(vnode);
2997 /** Calls fs_open() on the given vnode and returns a new
3002 open_vnode(struct vnode *vnode, int openMode, bool kernel)
3007 status = FS_CALL(vnode, open, openMode, &cookie);
3011 status = get_new_fd(FDTYPE_FILE, NULL, vnode, cookie, openMode, kernel);
3013 FS_CALL(vnode, close, cookie);
3014 FS_CALL(vnode, free_cookie, cookie);
3020 /** Calls fs open_dir() on the given vnode and returns a new
3025 open_dir_vnode(struct vnode *vnode, bool kernel)
3030 status = FS_CALL(vnode, open_dir, &cookie);
3035 status = get_new_fd(FDTYPE_DIR, NULL, vnode, cookie, 0, kernel);
3039 FS_CALL(vnode, close_dir, cookie);
3040 FS_CALL(vnode, free_dir_cookie, cookie);
3046 /** Calls fs open_attr_dir() on the given vnode and returns a new
3052 open_attr_dir_vnode(struct vnode *vnode, bool kernel)
3057 if (!HAS_FS_CALL(vnode, open_attr_dir))
3060 status = FS_CALL(vnode, open_attr_dir, &cookie);
3065 status = get_new_fd(FDTYPE_ATTR_DIR, NULL, vnode, cookie, 0, kernel);
3069 FS_CALL(vnode, close_attr_dir, cookie);
3070 FS_CALL(vnode, free_attr_dir_cookie, cookie);
3079 struct vnode *directory;
3100 struct vnode *directory;
3120 struct vnode *vnode;
3129 // get the vnode matching the entry_ref
3130 status = entry_ref_to_vnode(mountID, directoryID, name, &vnode);
3134 status = open_vnode(vnode, openMode, kernel);
3136 put_vnode(vnode);
3151 // get the vnode matching the vnode + path combination
3152 struct vnode *vnode = NULL;
3154 status = fd_and_path_to_vnode(fd, path, traverse, &vnode, &parentID, kernel);
3158 // open the vnode
3159 status = open_vnode(vnode, openMode, kernel);
3162 put_vnode(vnode);
3171 struct vnode *vnode = descriptor->u.vnode;
3176 if (HAS_FS_CALL(vnode, close))
3177 status = FS_CALL(vnode, close, descriptor->cookie);
3186 struct vnode *vnode = descriptor->u.vnode;
3188 if (vnode != NULL) {
3189 FS_CALL(vnode, free_cookie, descriptor->cookie);
3190 put_vnode(vnode);
3198 struct vnode *vnode = descriptor->u.vnode;
3201 return FS_CALL(vnode, read, descriptor->cookie, pos, buffer, length);
3208 struct vnode *vnode = descriptor->u.vnode;
3211 return FS_CALL(vnode, write, descriptor->cookie, pos, buffer, length);
3232 struct vnode *vnode = descriptor->u.vnode;
3236 if (!HAS_FS_CALL(vnode, read_stat))
3239 status = FS_CALL(vnode, read_stat, &stat);
3265 struct vnode *vnode;
3273 status = get_vnode(mountID, parentID, &vnode, kernel);
3277 if (HAS_FS_CALL(vnode, create_dir))
3278 status = FS_CALL(vnode, create_dir, name, perms);
3282 put_vnode(vnode);
3291 struct vnode *vnode;
3296 status = fd_and_path_to_dir_vnode(fd, path, &vnode, filename, kernel);
3300 if (HAS_FS_CALL(vnode, create_dir))
3301 status = FS_CALL(vnode, create_dir, filename, perms);
3305 put_vnode(vnode);
3313 struct vnode *vnode;
3321 // get the vnode matching the entry_ref/node_ref
3323 status = entry_ref_to_vnode(mountID, parentID, name, &vnode);
3325 status = get_vnode(mountID, parentID, &vnode, false);
3329 status = open_dir_vnode(vnode, kernel);
3331 put_vnode(vnode);
3344 // get the vnode matching the vnode + path combination
3345 struct vnode *vnode = NULL;
3347 status = fd_and_path_to_vnode(fd, path, true, &vnode, &parentID, kernel);
3352 status = open_dir_vnode(vnode, kernel);
3354 put_vnode(vnode);
3363 struct vnode *vnode = descriptor->u.vnode;
3367 if (HAS_FS_CALL(vnode, close_dir))
3368 return FS_CALL(vnode, close_dir, descriptor->cookie);
3377 struct vnode *vnode = descriptor->u.vnode;
3379 if (vnode != NULL) {
3380 FS_CALL(vnode, free_dir_cookie, descriptor->cookie);
3381 put_vnode(vnode);
3390 return dir_read(descriptor->u.vnode, descriptor->cookie, buffer, bufferSize, _count);
3395 fix_dirent(struct vnode *parent, struct fssh_dirent *entry)
3410 struct vnode *vnode;
3412 0, &vnode, NULL);
3415 entry->d_dev = vnode->device;
3416 entry->d_ino = vnode->id;
3420 struct vnode *vnode = NULL;
3421 fssh_status_t status = get_vnode(entry->d_dev, entry->d_ino, &vnode, false);
3426 if (vnode->covered_by) {
3427 entry->d_dev = vnode->covered_by->device;
3428 entry->d_ino = vnode->covered_by->id;
3432 put_vnode(vnode);
3438 dir_read(struct vnode *vnode, void *cookie, struct fssh_dirent *buffer,
3441 if (!HAS_FS_CALL(vnode, read_dir))
3444 fssh_status_t error = FS_CALL(vnode, read_dir,cookie,buffer,bufferSize,_count);
3451 fix_dirent(vnode, buffer);
3461 struct vnode *vnode = descriptor->u.vnode;
3463 if (HAS_FS_CALL(vnode, rewind_dir))
3464 return FS_CALL(vnode, rewind_dir,descriptor->cookie);
3474 struct vnode *directory;
3517 struct vnode *vnode = descriptor->u.vnode;
3519 if (HAS_FS_CALL(vnode, ioctl)) {
3520 return FS_CALL(vnode, ioctl,
3532 struct vnode *vnode;
3538 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
3570 if (HAS_FS_CALL(vnode, set_flags)) {
3574 status = FS_CALL(vnode, set_flags, descriptor->cookie, (int)argument);
3625 struct vnode *vnode;
3630 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
3634 if (HAS_FS_CALL(vnode, fsync))
3635 status = FS_CALL_NO_PARAMS(vnode, fsync);
3648 struct vnode *vnode;
3650 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
3659 if (fssh_atomic_test_and_set64((int64_t *)&vnode->mandatory_locked_by,
3662 if (fssh_atomic_test_and_set((int32_t *)&vnode->mandatory_locked_by,
3676 struct vnode *vnode;
3678 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
3687 if (fssh_atomic_test_and_set64((int64_t *)&vnode->mandatory_locked_by,
3690 if (fssh_atomic_test_and_set((int32_t *)&vnode->mandatory_locked_by,
3704 struct vnode *vnode;
3707 status = fd_and_path_to_vnode(fd, path, false, &vnode, NULL, kernel);
3711 if (HAS_FS_CALL(vnode, read_symlink)) {
3712 status = FS_CALL(vnode, read_symlink, buffer, _bufferSize);
3716 put_vnode(vnode);
3727 struct vnode *vnode;
3732 status = fd_and_path_to_dir_vnode(fd, path, &vnode, name, kernel);
3736 if (HAS_FS_CALL(vnode, create_symlink))
3737 status = FS_CALL(vnode, create_symlink, name, toPath, mode);
3741 put_vnode(vnode);
3752 struct vnode *directory, *vnode;
3761 status = path_to_vnode(toPath, true, &vnode, NULL, kernel);
3765 if (directory->mount != vnode->mount) {
3771 status = FS_CALL(directory, link, name, vnode);
3776 put_vnode(vnode);
3788 struct vnode *vnode;
3793 status = fd_and_path_to_dir_vnode(fd, path, &vnode, filename, kernel);
3797 if (HAS_FS_CALL(vnode, unlink))
3798 status = FS_CALL(vnode, unlink, filename);
3802 put_vnode(vnode);
3811 struct vnode *vnode;
3814 status = path_to_vnode(path, true, &vnode, NULL, kernel);
3818 if (HAS_FS_CALL(vnode, access))
3819 status = FS_CALL(vnode, access, mode);
3823 put_vnode(vnode);
3832 struct vnode *fromVnode, *toVnode;
3869 struct vnode *vnode = descriptor->u.vnode;
3878 fssh_status_t status = FS_CALL(vnode, read_stat, stat);
3882 stat->fssh_st_dev = vnode->device;
3883 stat->fssh_st_ino = vnode->id;
3894 struct vnode *vnode = descriptor->u.vnode;
3896 FUNCTION(("common_write_stat(vnode = %p, stat = %p, statMask = %d)\n", vnode, stat, statMask));
3897 if (!HAS_FS_CALL(vnode, write_stat))
3900 return FS_CALL(vnode, write_stat, stat, statMask);
3908 struct vnode *vnode;
3913 status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, NULL, kernel);
3917 status = FS_CALL(vnode, read_stat, stat);
3921 stat->fssh_st_dev = vnode->device;
3922 stat->fssh_st_ino = vnode->id;
3925 put_vnode(vnode);
3934 struct vnode *vnode;
3939 status = fd_and_path_to_vnode(fd, path, traverseLeafLink, &vnode, NULL, kernel);
3943 if (HAS_FS_CALL(vnode, write_stat))
3944 status = FS_CALL(vnode, write_stat, stat, statMask);
3948 put_vnode(vnode);
3957 struct vnode *vnode;
3962 status = fd_and_path_to_vnode(fd, path, true, &vnode, NULL, kernel);
3966 status = open_attr_dir_vnode(vnode, kernel);
3968 put_vnode(vnode);
3977 struct vnode *vnode = descriptor->u.vnode;
3981 if (HAS_FS_CALL(vnode, close_attr_dir))
3982 return FS_CALL(vnode, close_attr_dir, descriptor->cookie);
3991 struct vnode *vnode = descriptor->u.vnode;
3993 if (vnode != NULL) {
3994 FS_CALL(vnode, free_attr_dir_cookie, descriptor->cookie);
3995 put_vnode(vnode);
4004 struct vnode *vnode = descriptor->u.vnode;
4008 if (HAS_FS_CALL(vnode, read_attr_dir))
4009 return FS_CALL(vnode, read_attr_dir, descriptor->cookie, buffer, bufferSize, _count);
4018 struct vnode *vnode = descriptor->u.vnode;
4022 if (HAS_FS_CALL(vnode, rewind_attr_dir))
4023 return FS_CALL(vnode, rewind_attr_dir, descriptor->cookie);
4032 struct vnode *vnode;
4039 vnode = get_vnode_from_fd(fd, kernel);
4040 if (vnode == NULL)
4043 if (!HAS_FS_CALL(vnode, create_attr)) {
4048 status = FS_CALL(vnode, create_attr, name, type, openMode, &cookie);
4052 if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
4055 FS_CALL(vnode, close_attr, cookie);
4056 FS_CALL(vnode, free_attr_cookie, cookie);
4058 FS_CALL(vnode, remove_attr, name);
4061 put_vnode(vnode);
4070 struct vnode *vnode;
4077 vnode = get_vnode_from_fd(fd, kernel);
4078 if (vnode == NULL)
4081 if (!HAS_FS_CALL(vnode, open_attr)) {
4086 status = FS_CALL(vnode, open_attr, name, openMode, &cookie);
4091 if ((status = get_new_fd(FDTYPE_ATTR, NULL, vnode, cookie, openMode, kernel)) >= 0)
4094 FS_CALL(vnode, close_attr, cookie);
4095 FS_CALL(vnode, free_attr_cookie, cookie);
4098 put_vnode(vnode);
4107 struct vnode *vnode = descriptor->u.vnode;
4111 if (HAS_FS_CALL(vnode, close_attr))
4112 return FS_CALL(vnode, close_attr, descriptor->cookie);
4121 struct vnode *vnode = descriptor->u.vnode;
4123 if (vnode != NULL) {
4124 FS_CALL(vnode, free_attr_cookie, descriptor->cookie);
4125 put_vnode(vnode);
4133 struct vnode *vnode = descriptor->u.vnode;
4136 if (!HAS_FS_CALL(vnode, read_attr))
4139 return FS_CALL(vnode, read_attr, descriptor->cookie, pos, buffer, length);
4146 struct vnode *vnode = descriptor->u.vnode;
4149 if (!HAS_FS_CALL(vnode, write_attr))
4152 return FS_CALL(vnode, write_attr, descriptor->cookie, pos, buffer, length);
4170 struct vnode *vnode = descriptor->u.vnode;
4174 if (!HAS_FS_CALL(vnode, read_stat))
4177 status = FS_CALL(vnode, read_attr_stat, descriptor->cookie, &stat);
4203 struct vnode *vnode = descriptor->u.vnode;
4207 if (!HAS_FS_CALL(vnode, read_attr_stat))
4210 return FS_CALL(vnode, read_attr_stat, descriptor->cookie, stat);
4218 struct vnode *vnode = descriptor->u.vnode;
4222 if (!HAS_FS_CALL(vnode, write_attr_stat))
4225 return FS_CALL(vnode, write_attr_stat, descriptor->cookie, stat, statMask);
4233 struct vnode *vnode;
4241 descriptor = get_fd_and_vnode(fd, &vnode, kernel);
4245 if (HAS_FS_CALL(vnode, remove_attr))
4246 status = FS_CALL(vnode, remove_attr, name);
4260 struct vnode *fromVnode, *toVnode;
4356 //put_vnode(vnode);
4520 //put_vnode(vnode);
4602 list_init_etc(&mount->vnodes, fssh_offsetof(struct vnode, mount_link));
4657 struct vnode *coveredVnode;
4737 struct vnode *vnode;
4742 err = path_to_vnode(path, true, &vnode, NULL, kernel);
4748 mount = find_mount(vnode->device);
4750 fssh_panic("vfs_unmount: find_mount() failed on root vnode @%p of mount\n", vnode);
4752 if (mount->root_vnode != vnode) {
4754 put_vnode(vnode);
4758 // grab the vnode master mutex to keep someone from creating
4759 // a vnode while we're figuring out if we can continue
4769 vnode = NULL;
4770 while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode)) != NULL) {
4771 // The root vnode ref_count needs to be 2 here: one for the file
4773 if (vnode->busy
4774 || ((vnode->ref_count != 0 && mount->root_vnode != vnode)
4775 || (vnode->ref_count != 2 && mount->root_vnode == vnode))) {
4821 while ((vnode = (struct vnode *)list_get_next_item(&mount->vnodes, vnode)) != NULL) {
4822 vnode->busy = true;
4824 if (vnode->ref_count == 0) {
4825 // this vnode has been unused before
4826 list_remove_item(&sUnusedVnodeList, vnode);
4844 while ((vnode = (struct vnode *)list_get_first_item(&mount->vnodes)) != NULL) {
4845 free_vnode(vnode, false);
4883 struct vnode *previousVnode = NULL;
4885 // synchronize access to vnode list
4888 struct vnode *vnode = (struct vnode *)list_get_next_item(&mount->vnodes,
4892 if (vnode != NULL)
4893 id = vnode->id;
4897 if (vnode == NULL)
4900 // acquire a reference to the vnode
4902 if (get_vnode(mount->id, id, &vnode, true) == FSSH_B_OK) {
4906 if (HAS_FS_CALL(vnode, fsync))
4907 FS_CALL_NO_PARAMS(vnode, fsync);
4909 // the next vnode might change until we lock the vnode list again,
4910 // but this vnode won't go away since we keep a reference to it.
4911 previousVnode = vnode;
4913 fssh_dprintf("syncing of mount %d stopped due to vnode %"
5034 struct vnode *vnode = NULL;
5035 struct vnode *oldDirectory;
5041 // Get vnode for passed path, and bail if it failed
5042 status = fd_and_path_to_vnode(fd, path, true, &vnode, NULL, kernel);
5046 status = FS_CALL(vnode, read_stat, &stat);
5062 context->cwd = vnode;
5072 put_vnode(vnode);