Lines Matching defs:vnode

84 #define HAS_FS_CALL(vnode, op)			(vnode->ops->op != NULL)
88 # define FS_CALL(vnode, op, params...) \
89 ( HAS_FS_CALL(vnode, op) ? \
90 vnode->ops->op(vnode->mount->volume, vnode, params) \
91 : (panic("FS_CALL: vnode %p op " #op " is NULL", vnode), 0))
92 # define FS_CALL_NO_PARAMS(vnode, op) \
93 ( HAS_FS_CALL(vnode, op) ? \
94 vnode->ops->op(vnode->mount->volume, vnode) \
95 : (panic("FS_CALL_NO_PARAMS: vnode %p op " #op " is NULL", vnode), 0))
105 # define FS_CALL(vnode, op, params...) \
106 vnode->ops->op(vnode->mount->volume, vnode, params)
107 # define FS_CALL_NO_PARAMS(vnode, op) \
108 vnode->ops->op(vnode->mount->volume, vnode)
121 typedef DoublyLinkedList<vnode> VnodeList;
128 (e.g. by holding a reference to a vnode of that mount) (read) access
130 while mounted the mount holds a reference to the root_vnode->covers vnode,
131 and thus making the access path vnode->mount->root_vnode->covers->mount->...
132 safe if a reference to vnode is held (note that for the root mount
166 struct vnode* root_vnode;
167 struct vnode* covers_vnode; // immutable
239 any unbusy vnode in that table, save to the immutable fields (device, id,
242 well as the busy, removed, unused flags, and the vnode's type can also be
243 write accessed when holding a read lock to sVnodeLock *and* having the vnode
266 ino_t vnode;
271 typedef struct vnode ValueType;
278 return VHASH(key.device, key.vnode);
281 size_t Hash(ValueType* vnode) const
283 return VHASH(vnode->device, vnode->id);
288 bool Compare(KeyType key, ValueType* vnode) const
290 return vnode->device == key.device && vnode->id == key.vnode;
338 static struct vnode* sRoot;
372 static status_t dir_read(struct io_context* ioContext, struct vnode* vnode,
417 static status_t vnode_path_to_vnode(struct vnode* vnode, char* path,
420 static status_t dir_vnode_to_path(struct vnode* vnode, char* buffer,
424 static void inc_vnode_ref_count(struct vnode* vnode);
425 static status_t dec_vnode_ref_count(struct vnode* vnode, bool alwaysFree,
427 static inline void put_vnode(struct vnode* vnode);
430 static int open_vnode(struct vnode* vnode, int openMode, bool kernel);
600 PagesIOTraceEntry(struct vnode* vnode, void* cookie, off_t pos,
605 fVnode(vnode),
606 fMountID(vnode->mount->id),
607 fNodeID(vnode->id),
622 out.Print("vfs pages io %5s: vnode: %p (%" B_PRId32 ", %" B_PRId64 "), "
642 struct vnode* fVnode;
658 ReadPages(struct vnode* vnode, void* cookie, off_t pos,
663 PagesIOTraceEntry(vnode, cookie, pos, vecs, count, flags,
678 WritePages(struct vnode* vnode, void* cookie, off_t pos,
683 PagesIOTraceEntry(vnode, cookie, pos, vecs, count, flags,
727 struct vnode* rootNode = mount->root_vnode;
840 add_vnode_to_mount_list(struct vnode* vnode, struct fs_mount* mount)
843 mount->vnodes.Add(vnode);
848 remove_vnode_from_mount_list(struct vnode* vnode, struct fs_mount* mount)
851 mount->vnodes.Remove(vnode);
855 /*! \brief Looks up a vnode by mount and node ID in the sVnodeTable.
862 \return The vnode structure, if it was found in the hash table, \c NULL
865 static struct vnode*
873 key.vnode = vnodeID;
879 /*! \brief Checks whether or not a busy vnode should be waited for (again).
882 still wait for the vnode becoming unbusy.
890 // vnode doesn't seem to become unbusy
891 dprintf("vnode %" B_PRIdDEV ":%" B_PRIdINO
900 /*! Creates a new vnode with the given mount and node ID.
907 \param vnodeID The vnode ID.
908 \param _vnode Will be set to the new vnode on success.
909 \param _nodeCreated Will be set to \c true when the returned vnode has
912 \return \c B_OK, when the vnode was successfully created and inserted or
917 create_new_vnode_and_lock(dev_t mountID, ino_t vnodeID, struct vnode*& _vnode,
922 struct vnode* vnode = (struct vnode*)object_cache_alloc(sVnodeCache, 0);
923 if (vnode == NULL)
927 memset(vnode, 0, sizeof(struct vnode));
928 vnode->device = mountID;
929 vnode->id = vnodeID;
930 vnode->ref_count = 1;
931 vnode->SetBusy(true);
936 struct vnode* existingVnode = lookup_vnode(mountID, vnodeID);
938 object_cache_free(sVnodeCache, vnode, 0);
946 vnode->mount = find_mount(mountID);
947 if (!vnode->mount || vnode->mount->unmounting) {
950 object_cache_free(sVnodeCache, vnode, 0);
954 // add the vnode to the mount's node list and the hash table
955 sVnodeTable->Insert(vnode);
956 add_vnode_to_mount_list(vnode, vnode->mount);
960 _vnode = vnode;
963 // keep the vnode lock locked
968 /*! Frees the vnode and all resources it has acquired, and removes
969 it from the vnode hash as well as from its mount structure.
973 free_vnode(struct vnode* vnode, bool reenter)
975 ASSERT_PRINT(vnode->ref_count == 0 && vnode->IsBusy(), "vnode: %p\n",
976 vnode);
977 ASSERT_PRINT(vnode->advisory_locking == NULL, "vnode: %p\n", vnode);
979 // write back any changes in this vnode's cache -- but only
980 // if the vnode won't be deleted, in which case the changes
983 if (!vnode->IsRemoved() && HAS_FS_CALL(vnode, fsync))
984 FS_CALL_NO_PARAMS(vnode, fsync);
986 // Note: If this vnode has a cache attached, there will still be two
987 // references to that cache at this point. The last one belongs to the vnode
990 // to the vnode. The file cache, however, released its reference (cf.
991 // file_cache_create()), so that this vnode's ref count has the chance to
994 // existing) vnode reference. To avoid problems, we set the vnode's ref
996 vnode->ref_count = 2;
998 if (!vnode->IsUnpublished()) {
999 if (vnode->IsRemoved())
1000 FS_CALL(vnode, remove_vnode, reenter);
1002 FS_CALL(vnode, put_vnode, reenter);
1005 // If the vnode has a VMCache attached, make sure that it won't try to get
1007 // long as the vnode is busy and in the hash, that won't happen, but as
1008 // soon as we've removed it from the hash, it could reload the vnode -- with
1010 if (vnode->cache != NULL && vnode->cache->type == CACHE_TYPE_VNODE)
1011 ((VMVnodeCache*)vnode->cache)->VnodeDeleted();
1013 // The file system has removed the resources of the vnode now, so we can
1014 // make it available again (by removing the busy vnode from the hash).
1016 sVnodeTable->Remove(vnode);
1020 if (vnode->cache)
1021 vnode->cache->ReleaseRef();
1023 vnode->cache = NULL;
1025 remove_vnode_from_mount_list(vnode, vnode->mount);
1027 object_cache_free(sVnodeCache, vnode, 0);
1031 /*! \brief Decrements the reference counter of the given vnode and deletes it,
1034 The caller must, of course, own a reference to the vnode to call this
1038 \param vnode the vnode.
1039 \param alwaysFree don't move this vnode into the unused list, but really
1046 dec_vnode_ref_count(struct vnode* vnode, bool alwaysFree, bool reenter)
1049 AutoLocker<Vnode> nodeLocker(vnode);
1051 int32 oldRefCount = atomic_add(&vnode->ref_count, -1);
1053 ASSERT_PRINT(oldRefCount > 0, "vnode %p\n", vnode);
1055 TRACE(("dec_vnode_ref_count: vnode %p, ref now %" B_PRId32 "\n", vnode,
1056 vnode->ref_count));
1061 if (vnode->IsBusy())
1062 panic("dec_vnode_ref_count: called on busy vnode %p\n", vnode);
1067 // Just insert the vnode into an unused list if we don't need
1069 if (vnode->IsRemoved() || alwaysFree) {
1070 vnode_to_be_freed(vnode);
1071 vnode->SetBusy(true);
1074 freeUnusedNodes = vnode_unused(vnode);
1080 free_vnode(vnode, reenter);
1088 /*! \brief Increments the reference counter of the given vnode.
1094 - by holding the vnode's lock (which also requires read locking sVnodeLock)
1102 \param vnode the vnode.
1105 inc_vnode_ref_count(struct vnode* vnode)
1107 atomic_add(&vnode->ref_count, 1);
1108 TRACE(("inc_vnode_ref_count: vnode %p, ref now %" B_PRId32 "\n", vnode,
1109 vnode->ref_count));
1122 create_special_sub_node(struct vnode* vnode, uint32 flags)
1124 if (S_ISFIFO(vnode->Type()))
1125 return create_fifo_vnode(vnode->mount->volume, vnode);
1131 /*! \brief Retrieves a vnode for a given mount ID, node ID pair.
1139 \param _vnode Pointer to a vnode* variable into which the pointer to the
1140 retrieved vnode structure shall be written.
1146 get_vnode(dev_t mountID, ino_t vnodeID, struct vnode** _vnode, bool canWait,
1156 struct vnode* vnode = lookup_vnode(mountID, vnodeID);
1157 AutoLocker<Vnode> nodeLocker(vnode);
1159 if (vnode && vnode->IsBusy()) {
1162 const bool doNotWait = vnode->IsRemoved() && !vnode->IsUnpublished();
1167 dprintf("vnode %" B_PRIdDEV ":%" B_PRIdINO " is busy!\n",
1178 TRACE(("get_vnode: tried to lookup vnode, got %p\n", vnode));
1182 if (vnode) {
1183 if (vnode->ref_count == 0) {
1184 // this vnode has been unused before
1185 vnode_used(vnode);
1187 inc_vnode_ref_count(vnode);
1192 // we need to create a new vnode and read it in
1196 status = create_new_vnode_and_lock(mountID, vnodeID, vnode,
1211 status = FS_MOUNT_CALL(vnode->mount, get_vnode, vnodeID, vnode, &type,
1213 if (status == B_OK && vnode->private_node == NULL)
1219 vnode->SetType(type);
1225 status = create_special_sub_node(vnode, flags);
1229 FS_CALL(vnode, put_vnode, reenter);
1232 sVnodeTable->Remove(vnode);
1233 remove_vnode_from_mount_list(vnode, vnode->mount);
1236 object_cache_free(sVnodeCache, vnode, 0);
1241 vnode->Lock();
1243 vnode->SetRemoved((flags & B_VNODE_PUBLISH_REMOVED) != 0);
1244 vnode->SetBusy(false);
1246 vnode->Unlock();
1250 TRACE(("get_vnode: returning %p\n", vnode));
1252 *_vnode = vnode;
1257 /*! \brief Decrements the reference counter of the given vnode and deletes it,
1260 The caller must, of course, own a reference to the vnode to call this
1264 \param vnode the vnode.
1267 put_vnode(struct vnode* vnode)
1269 dec_vnode_ref_count(vnode, false, false);
1313 struct vnode* vnode = (struct vnode*)list_get_first_item(
1317 if (vnode == NULL)
1321 AutoLocker<Vnode> nodeLocker(vnode);
1324 // tail of the unused queue, the vnode should still be at its head.
1328 // recently used unused vnode and we rather don't free it.
1330 if (vnode != list_get_first_item(&sUnusedVnodeList))
1334 ASSERT(!vnode->IsBusy());
1337 inc_vnode_ref_count(vnode);
1338 vnode_used(vnode);
1344 if (vnode->cache != NULL)
1345 vnode->cache->WriteModified();
1347 dec_vnode_ref_count(vnode, true, false);
1348 // this should free the vnode when it's still unused
1355 /*! Gets the vnode the given vnode is covering.
1359 The function returns a reference to the retrieved vnode (if any), the caller
1362 \param vnode The vnode whose covered node shall be returned.
1363 \return The covered vnode, or \c NULL if the given vnode doesn't cover any
1364 vnode.
1367 get_covered_vnode_locked(Vnode* vnode)
1369 if (Vnode* coveredNode = vnode->covers) {
1381 /*! Gets the vnode the given vnode is covering.
1386 The function returns a reference to the retrieved vnode (if any), the caller
1389 \param vnode The vnode whose covered node shall be returned.
1390 \return The covered vnode, or \c NULL if the given vnode doesn't cover any
1391 vnode.
1394 get_covered_vnode(Vnode* vnode)
1396 if (!vnode->IsCovering())
1400 return get_covered_vnode_locked(vnode);
1404 /*! Gets the vnode the given vnode is covered by.
1408 The function returns a reference to the retrieved vnode (if any), the caller
1411 \param vnode The vnode whose covering node shall be returned.
1412 \return The covering vnode, or \c NULL if the given vnode isn't covered by
1413 any vnode.
1416 get_covering_vnode_locked(Vnode* vnode)
1418 if (Vnode* coveringNode = vnode->covered_by) {
1430 /*! Gets the vnode the given vnode is covered by.
1435 The function returns a reference to the retrieved vnode (if any), the caller
1438 \param vnode The vnode whose covering node shall be returned.
1439 \return The covering vnode, or \c NULL if the given vnode isn't covered by
1440 any vnode.
1443 get_covering_vnode(Vnode* vnode)
1445 if (!vnode->IsCovered())
1449 return get_covering_vnode_locked(vnode);
1478 /*! Returns the advisory_locking object of the \a vnode in case it
1482 Note, you must not have the vnode mutex locked when calling
1486 get_advisory_locking(struct vnode* vnode)
1489 vnode->Lock();
1491 struct advisory_locking* locking = vnode->advisory_locking;
1494 vnode->Unlock();
1511 given \a vnode.
1512 Returns B_OK in case of success - also if the vnode got such an
1517 create_advisory_locking(struct vnode* vnode)
1519 if (vnode == NULL)
1525 while (get_advisory_locking(vnode) == NULL) {
1526 // no locking object set on the vnode yet, create one
1544 AutoLocker<Vnode> nodeLocker(vnode);
1545 if (vnode->advisory_locking == NULL) {
1546 vnode->advisory_locking = locking;
1552 // The vnode already had a locking object. That's just as well.
1575 test_advisory_lock(struct vnode* vnode, struct flock* flock)
1579 struct advisory_locking* locking = get_advisory_locking(vnode);
1612 release_advisory_lock(struct vnode* vnode, struct io_context* context,
1615 FUNCTION(("release_advisory_lock(vnode = %p, flock = %p)\n", vnode, flock));
1617 struct advisory_locking* locking = get_advisory_locking(vnode);
1689 locking = get_advisory_locking(vnode);
1692 AutoLocker<Vnode> nodeLocker(vnode);
1696 vnode->advisory_locking = NULL;
1700 // we've detached the locking from the vnode, so we can
1716 /*! Acquires an advisory lock for the \a vnode. If \a wait is \c true, it
1726 acquire_advisory_lock(struct vnode* vnode, io_context* context,
1729 FUNCTION(("acquire_advisory_lock(vnode = %p, flock = %p, wait = %s)\n",
1730 vnode, flock, wait ? "yes" : "no"));
1741 // if this vnode has an advisory_locking structure attached,
1743 status = create_advisory_locking(vnode);
1747 locking = vnode->advisory_locking;
1825 struct vnode* vnode = descriptor->u.vnode;
1829 if (!HAS_FS_CALL(vnode, read_stat))
1832 status = FS_CALL(vnode, read_stat, &stat);
1864 struct vnode* vnodeToDisconnect, struct vnode*& vnode,
1865 struct vnode* fallBack, bool lockRootLock)
1867 struct vnode* givenVnode = vnode;
1875 while (vnode != NULL && vnode->mount == mount
1876 && (vnodeToDisconnect == NULL || vnodeToDisconnect == vnode)) {
1877 if (vnode->covers != NULL) {
1878 // redirect the vnode to the covered vnode
1879 vnode = vnode->covers;
1881 vnode = fallBack;
1887 if (vnodeReplaced && vnode != NULL)
1888 inc_vnode_ref_count(vnode);
1913 struct vnode* vnodeToDisconnect)
1943 struct vnode* vnode = fd_vnode(descriptor);
1945 if (vnode == vnodeToDisconnect)
1947 } else if ((vnode != NULL && vnode->mount == mount)
1948 || (vnode == NULL && descriptor->u.mount == mount))
1961 struct vnode*
1970 struct vnode* root = context->root;
2058 // get the directory vnode and let vnode_path_to_vnode() do the rest
2059 struct vnode* directory;
2071 and returns the respective vnode.
2072 On success a reference to the vnode is acquired for the caller.
2075 lookup_dir_entry(struct vnode* dir, const char* name, struct vnode** _vnode)
2096 panic("lookup_dir_entry(): could not lookup vnode (mountid 0x%" B_PRIx32
2109 /*! Returns the vnode for the relative \a path starting at the specified \a vnode.
2119 Note, this reduces the ref_count of the starting \a vnode, no matter if
2129 vnode_path_to_vnode(struct vnode* start, char* path, bool traverseLeafLink,
2133 FUNCTION(("vnode_path_to_vnode(vnode = %p, path = %s)\n", vnode, path));
2136 VnodePutter vnode(start);
2144 ino_t lastParentID = vnode->id;
2169 // See if the '..' is at a covering vnode move to the covered
2170 // vnode so we pass the '..' path to the underlying filesystem.
2173 if (vnode.Get() == ioContext->root) {
2179 if (Vnode* coveredVnode = get_covered_vnode(vnode.Get()))
2180 vnode.SetTo(coveredVnode);
2183 // check if vnode is really a directory
2184 if (status == B_OK && !S_ISDIR(vnode->Type()))
2187 // Check if we have the right to search the current directory vnode.
2190 if (status == B_OK && HAS_FS_CALL(vnode, access))
2191 status = FS_CALL(vnode.Get(), access, X_OK);
2193 // Tell the filesystem to get the vnode of this path component (if we
2197 struct vnode* temp = NULL;
2198 status = lookup_dir_entry(vnode.Get(), path, &temp);
2205 _vnode.SetTo(vnode.Detach());
2243 // directory ("vnode" still points to that one).
2249 vnode.Unset();
2255 vnode.SetTo(ioContext->root);
2256 inc_vnode_ref_count(vnode.Get());
2262 inc_vnode_ref_count(vnode.Get());
2264 // ref_count of the vnode, no matter if we succeeded or not
2268 nextVnode.SetTo(vnode.Get());
2270 status = vnode_path_to_vnode(vnode.Get(), path, true, count + 1,
2282 lastParentID = vnode->id;
2285 vnode.Unset();
2288 vnode.SetTo(nextVnode.Detach());
2291 if (Vnode* coveringNode = get_covering_vnode(vnode.Get()))
2292 vnode.SetTo(coveringNode);
2295 _vnode.SetTo(vnode.Detach());
2304 vnode_path_to_vnode(struct vnode* vnode, char* path, bool traverseLeafLink,
2307 return vnode_path_to_vnode(vnode, path, traverseLeafLink, 0,
2316 struct vnode* start = NULL;
2360 /*! Returns the vnode in the next to last segment of the path, and returns
2376 /*! \brief Retrieves the directory vnode and the leaf name of an entry referred
2386 directory vnode.
2392 \param _vnode A pointer to a variable the directory vnode shall be written
2419 /*! \brief Retrieves the directory vnode and the leaf name of an entry referred
2420 to by a vnode + path pair.
2422 \a path must be given in either case. \a vnode might be omitted, in which
2425 of the directory referred to by \a vnode. If \a path is absolute \a vnode is
2429 directory vnode.
2431 Note, this reduces the ref_count of the starting \a vnode, no matter if
2434 \param vnode The vnode. May be \c NULL.
2438 \param _vnode A pointer to a variable the directory vnode shall be written
2447 vnode_and_path_to_dir_vnode(struct vnode* vnode, char* path,
2450 VnodePutter vnodePutter(vnode);
2456 if (vnode == NULL || path[0] == '/')
2464 return vnode_path_to_vnode(vnode, path, true, kernel, _vnode, NULL);
2468 /*! Returns a vnode's name in the d_name field of a supplied dirent buffer.
2471 get_vnode_name(struct vnode* vnode, struct vnode* parent, struct dirent* buffer,
2477 // See if the vnode is covering another vnode and move to the covered
2478 // vnode so we get the underlying file system
2480 if (Vnode* coveredVnode = get_covered_vnode(vnode)) {
2481 vnode = coveredVnode;
2482 vnodePutter.SetTo(vnode);
2485 if (HAS_FS_CALL(vnode, get_vnode_name)) {
2486 // The FS supports getting the name of a vnode.
2487 if (FS_CALL(vnode, get_vnode_name, buffer->d_name,
2492 // The FS doesn't support getting the name of a vnode. So we search the
2493 // parent directory for the vnode, if the caller let us.
2505 // want the entries to be fixed. We have already resolved vnode to
2516 if (vnode->id == buffer->d_ino) {
2530 get_vnode_name(struct vnode* vnode, struct vnode* parent, char* name,
2536 status_t status = get_vnode_name(vnode, parent, dirent, sizeof(buffer),
2548 /*! Gets the full path to a given directory vnode.
2549 It uses the fs_get_vnode_name() call to get the name of a vnode; if a
2564 dir_vnode_to_path(struct vnode* vnode, char* buffer, size_t bufferSize,
2567 FUNCTION(("dir_vnode_to_path(%p, %p, %lu)\n", vnode, buffer, bufferSize));
2569 if (vnode == NULL || buffer == NULL || bufferSize == 0)
2572 if (!S_ISDIR(vnode->Type()))
2584 inc_vnode_ref_count(vnode);
2592 if (vnode == ioContext->root)
2595 if (Vnode* coveredVnode = get_covered_vnode(vnode)) {
2596 put_vnode(vnode);
2597 vnode = coveredVnode;
2600 // lookup the parent vnode
2601 struct vnode* parentVnode;
2602 status = lookup_dir_entry(vnode, "..", &parentVnode);
2606 if (parentVnode == vnode) {
2617 status = get_vnode_name(vnode, parentVnode, (struct dirent*)nameBuffer,
2620 // release the current vnode, we only need its parent from now on
2621 put_vnode(vnode);
2622 vnode = parentVnode;
2659 put_vnode(vnode);
2707 get_fd_and_vnode(int fd, struct vnode** _vnode, bool kernel)
2714 struct vnode* vnode = fd_vnode(descriptor);
2715 if (vnode == NULL) {
2721 // if this is still valid to do (accessing the vnode without ref_count
2723 *_vnode = vnode;
2728 static struct vnode*
2732 struct vnode* vnode;
2738 vnode = fd_vnode(descriptor);
2739 if (vnode != NULL)
2740 inc_vnode_ref_count(vnode);
2743 return vnode;
2747 /*! Gets the vnode from an FD + path combination. If \a fd is lower than zero,
2769 struct vnode* vnode = get_vnode_from_fd(fd, kernel);
2770 if (vnode == NULL)
2774 return vnode_path_to_vnode(vnode, path, traverseLeafLink, kernel,
2780 _vnode.SetTo(vnode);
2789 get_new_fd(int type, struct fs_mount* mount, struct vnode* vnode,
2795 // If the vnode is locked, we don't allow creating a new file/directory
2797 if (vnode && vnode->mandatory_locked_by != NULL
2808 if (vnode)
2809 descriptor->u.vnode = vnode;
2815 // vnode types
2846 switch (vnode->Type() & S_IFMT) {
2886 // get dir vnode + leaf name
2893 // get file vnode, if we shall resolve links
2952 resolve_covered_parent(struct vnode* parent, dev_t* _device, ino_t* _node,
2966 VnodePutter vnode;
2968 ioContext, vnode, NULL);
2970 *_device = vnode->device;
2971 *_node = vnode->id;
3082 debug_resolve_vnode_path(struct vnode* vnode, char* buffer, size_t bufferSize,
3089 while (vnode->covers != NULL)
3090 vnode = vnode->covers;
3092 if (vnode == sRoot) {
3101 const char* name = vnode->mount->entry_cache.DebugReverseLookup(
3102 vnode->id, dirID);
3106 vnode->mount->id, vnode->id);
3117 struct vnode* nextVnode = lookup_vnode(vnode->mount->id, dirID);
3120 vnode->mount->id, dirID);
3124 vnode = nextVnode;
3130 _dump_vnode(struct vnode* vnode, bool printPath)
3132 kprintf("VNODE: %p\n", vnode);
3133 kprintf(" device: %" B_PRIdDEV "\n", vnode->device);
3134 kprintf(" id: %" B_PRIdINO "\n", vnode->id);
3135 kprintf(" ref_count: %" B_PRId32 "\n", vnode->ref_count);
3136 kprintf(" private_node: %p\n", vnode->private_node);
3137 kprintf(" mount: %p\n", vnode->mount);
3138 kprintf(" covered_by: %p\n", vnode->covered_by);
3139 kprintf(" covers: %p\n", vnode->covers);
3140 kprintf(" cache: %p\n", vnode->cache);
3141 kprintf(" type: %#" B_PRIx32 "\n", vnode->Type());
3142 kprintf(" flags: %s%s%s\n", vnode->IsRemoved() ? "r" : "-",
3143 vnode->IsBusy() ? "b" : "-", vnode->IsUnpublished() ? "u" : "-");
3144 kprintf(" advisory_lock: %p\n", vnode->advisory_locking);
3146 _dump_advisory_locking(vnode->advisory_locking);
3152 char* path = debug_resolve_vnode_path(vnode, (char*)buffer,
3161 kprintf("Failed to resolve vnode path.\n");
3168 set_debug_variable("_node", (addr_t)vnode->private_node);
3169 set_debug_variable("_mount", (addr_t)vnode->mount);
3170 set_debug_variable("_covered_by", (addr_t)vnode->covered_by);
3171 set_debug_variable("_covers", (addr_t)vnode->covers);
3172 set_debug_variable("_adv_lock", (addr_t)vnode->advisory_locking);
3249 struct vnode* vnode = NULL;
3252 vnode = (struct vnode*)parse_expression(argv[argi]);
3253 if (IS_USER_ADDRESS(vnode)) {
3254 kprintf("invalid vnode address\n");
3257 _dump_vnode(vnode, printPath);
3266 vnode = iterator.Next();
3267 if (vnode->id != id || vnode->device != device)
3270 _dump_vnode(vnode, printPath);
3288 struct vnode* vnode;
3296 vnode = iterator.Next();
3297 if (vnode->device != device)
3301 vnode, vnode->device, vnode->id, vnode->ref_count, vnode->cache,
3302 vnode->private_node, vnode->advisory_locking,
3303 vnode->IsRemoved() ? "r" : "-", vnode->IsBusy() ? "b" : "-",
3304 vnode->IsUnpublished() ? "u" : "-");
3314 struct vnode* vnode;
3331 vnode = iterator.Next();
3332 if (vnode->cache == NULL)
3334 if (device != -1 && vnode->device != device)
3338 vnode, vnode->device, vnode->id, vnode->cache,
3339 (vnode->cache->virtual_end + B_PAGE_SIZE - 1) / B_PAGE_SIZE,
3340 vnode->cache->page_count);
3373 kprintf(" root vnode:\t%p\n", context->root);
3374 kprintf(" cwd vnode:\t%p\n", context->cwd);
3393 ? "mount" : "vnode",
3394 fd->u.vnode);
3444 common_file_io_vec_pages(struct vnode* vnode, void* cookie,
3473 status = FS_CALL(vnode, read_pages, cookie, fileVecs[0].offset,
3566 panic("sparse write attempt: vnode %p", vnode);
3574 status = FS_CALL(vnode, write_pages, cookie, fileOffset,
3577 status = FS_CALL(vnode, read_pages, cookie, fileOffset,
3693 struct vnode* vnode;
3694 status_t status = create_new_vnode_and_lock(volume->id, vnodeID, vnode,
3702 if (!nodeCreated && vnode->IsBusy()) {
3710 // test if the vnode already exists and bail out if this is the case!
3712 panic("vnode %" B_PRIdDEV ":%" B_PRIdINO " already exists (node = %p, "
3713 "vnode->node = %p)!", volume->id, vnodeID, privateNode,
3714 vnode->private_node);
3718 vnode->private_node = privateNode;
3719 vnode->ops = ops;
3720 vnode->SetUnpublished(true);
3738 struct vnode* vnode = lookup_vnode(volume->id, vnodeID);
3741 if (vnode == NULL) {
3748 status_t status = create_new_vnode_and_lock(volume->id, vnodeID, vnode,
3757 vnode->private_node = privateNode;
3758 vnode->ops = ops;
3759 vnode->SetUnpublished(true);
3760 } else if (vnode->IsBusy() && vnode->IsUnpublished()
3761 && vnode->private_node == privateNode && vnode->ops == ops) {
3763 } else if (vnode->IsBusy()) {
3773 vnode->SetType(type);
3774 vnode->SetRemoved((flags & B_VNODE_PUBLISH_REMOVED) != 0);
3789 vnode);
3794 status = create_special_sub_node(vnode, flags);
3800 subVolume->ops->delete_sub_vnode(subVolume, vnode);
3806 AutoLocker<Vnode> nodeLocker(vnode);
3807 vnode->SetBusy(false);
3808 vnode->SetUnpublished(false);
3811 sVnodeTable->Remove(vnode);
3812 remove_vnode_from_mount_list(vnode, vnode->mount);
3813 object_cache_free(sVnodeCache, vnode, 0);
3817 vnode->SetBusy(false);
3818 vnode->SetUnpublished(false);
3830 struct vnode* vnode;
3835 status_t status = get_vnode(volume->id, vnodeID, &vnode, true, true);
3841 if (HAS_FS_CALL(vnode, get_super_vnode)) {
3843 status_t status = FS_CALL(vnode, get_super_vnode, volume,
3846 panic("get_vnode(): Failed to get super node for vnode %p, "
3847 "volume: %p", vnode, volume);
3848 put_vnode(vnode);
3855 *_privateNode = vnode->private_node;
3866 struct vnode* vnode = lookup_vnode(volume->id, vnodeID);
3867 if (vnode == NULL)
3870 inc_vnode_ref_count(vnode);
3878 struct vnode* vnode;
3881 vnode = lookup_vnode(volume->id, vnodeID);
3884 if (vnode == NULL)
3887 dec_vnode_ref_count(vnode, false, true);
3897 struct vnode* vnode = lookup_vnode(volume->id, vnodeID);
3898 if (vnode == NULL)
3901 if (vnode->covered_by != NULL || vnode->covers != NULL) {
3902 // this vnode is in use
3906 vnode->Lock();
3908 vnode->SetRemoved(true);
3911 if (vnode->IsUnpublished()) {
3912 // prepare the vnode for deletion
3914 vnode->SetBusy(true);
3917 vnode->Unlock();
3921 // If the vnode hasn't been published yet, we delete it here
3922 atomic_add(&vnode->ref_count, -1);
3923 free_vnode(vnode, true);
3933 struct vnode* vnode;
3937 vnode = lookup_vnode(volume->id, vnodeID);
3938 if (vnode) {
3939 AutoLocker<Vnode> nodeLocker(vnode);
3940 vnode->SetRemoved(false);
3953 if (struct vnode* vnode = lookup_vnode(volume->id, vnodeID)) {
3955 *_removed = vnode->IsRemoved();
3969 struct vnode* vnode = static_cast<struct vnode*>(_vnode);
3970 return vnode->mount->volume;
4016 struct vnode* vnode;
4018 descriptor = get_fd_and_vnode(fd, &vnode, true);
4022 status_t status = vfs_read_pages(vnode, descriptor->cookie, pos, vecs,
4035 struct vnode* vnode;
4037 descriptor = get_fd_and_vnode(fd, &vnode, true);
4041 status_t status = vfs_write_pages(vnode, descriptor->cookie, pos, vecs,
4055 struct vnode* vnode;
4056 FileDescriptorPutter descriptor(get_fd_and_vnode(fd, &vnode, true));
4060 status_t status = common_file_io_vec_pages(vnode, descriptor->cookie,
4073 struct vnode* vnode;
4074 FileDescriptorPutter descriptor(get_fd_and_vnode(fd, &vnode, true));
4078 status_t status = common_file_io_vec_pages(vnode, descriptor->cookie,
4135 /*! Acquires another reference to the vnode that has to be released
4139 vfs_acquire_vnode(struct vnode* vnode)
4141 inc_vnode_ref_count(vnode);
4167 vfs_get_vnode_from_fd(int fd, bool kernel, struct vnode** vnode)
4169 *vnode = get_vnode_from_fd(fd, kernel);
4171 if (*vnode == NULL)
4179 vfs_get_vnode_from_path(const char* path, bool kernel, struct vnode** _vnode)
4191 VnodePutter vnode;
4192 status_t status = path_to_vnode(buffer, true, vnode, NULL, kernel);
4196 *_vnode = vnode.Detach();
4202 vfs_get_vnode(dev_t mountID, ino_t vnodeID, bool canWait, struct vnode** _vnode)
4204 struct vnode* vnode = NULL;
4206 status_t status = get_vnode(mountID, vnodeID, &vnode, canWait, false);
4210 *_vnode = vnode;
4217 const char* name, struct vnode** _vnode)
4219 VnodePutter vnode;
4220 status_t status = entry_ref_to_vnode(mountID, directoryID, name, false, true, vnode);
4221 *_vnode = vnode.Detach();
4227 vfs_vnode_to_node_ref(struct vnode* vnode, dev_t* _mountID, ino_t* _vnodeID)
4229 *_mountID = vnode->device;
4230 *_vnodeID = vnode->id;
4236 vnode-pointer to a fs_vnode-pointer.
4240 vfs_fsnode_for_vnode(struct vnode* vnode)
4242 return vnode;
4247 Calls fs_open() on the given vnode and returns a new
4251 vfs_open_vnode(struct vnode* vnode, int openMode, bool kernel)
4253 return open_vnode(vnode, openMode, kernel);
4257 /*! Looks up a vnode with the given mount and vnode ID.
4263 vfs_lookup_vnode(dev_t mountID, ino_t vnodeID, struct vnode** _vnode)
4266 struct vnode* vnode = lookup_vnode(mountID, vnodeID);
4269 if (vnode == NULL)
4272 *_vnode = vnode;
4296 VnodePutter vnode;
4299 status = path_to_vnode(buffer, traverseLeafLink, vnode, NULL, kernel);
4302 // vnode_path_to_vnode() releases a reference to the starting vnode
4304 kernel, vnode, NULL);
4312 if (vnode->device != volume->id) {
4318 status = get_vnode(volume, vnode->id, _node);
4480 vfs_resolve_parent(struct vnode* parent, dev_t* device, ino_t* node)
4513 struct vnode** _createdVnode)
4520 // We've got a path. Get the dir vnode and the leaf name.
4529 // get the dir vnode and the leaf name
4567 vfs_put_vnode(struct vnode* vnode)
4569 put_vnode(vnode);
4603 struct vnode* vnode;
4605 status_t status = get_vnode(mountID, vnodeID, &vnode, true, true);
4609 disconnect_mount_or_vnode_fds(vnode->mount, vnode);
4610 put_vnode(vnode);
4626 vfs_can_page(struct vnode* vnode, void* cookie)
4628 FUNCTION(("vfs_canpage: vnode %p\n", vnode));
4630 if (HAS_FS_CALL(vnode, can_page))
4631 return FS_CALL(vnode, can_page, cookie);
4637 vfs_read_pages(struct vnode* vnode, void* cookie, off_t pos,
4641 FUNCTION(("vfs_read_pages: vnode %p, vecs %p, pos %" B_PRIdOFF "\n", vnode,
4651 status = vfs_vnode_io(vnode, cookie, &request);
4657 TPIO(ReadPages(vnode, cookie, pos, vecs, count, flags, bytesRequested,
4665 vfs_write_pages(struct vnode* vnode, void* cookie, off_t pos,
4669 FUNCTION(("vfs_write_pages: vnode %p, vecs %p, pos %" B_PRIdOFF "\n", vnode,
4679 status = vfs_vnode_io(vnode, cookie, &request);
4685 TPIO(WritePages(vnode, cookie, pos, vecs, count, flags, bytesRequested,
4692 /*! Gets the vnode's VMCache object. If it didn't have one, it will be
4698 vfs_get_vnode_cache(struct vnode* vnode, VMCache** _cache, bool allocate)
4700 if (vnode->cache != NULL) {
4701 vnode->cache->AcquireRef();
4702 *_cache = vnode->cache;
4707 vnode->Lock();
4712 if (vnode->cache == NULL) {
4714 // TODO: actually the vnode needs to be busy already here, or
4716 bool wasBusy = vnode->IsBusy();
4717 vnode->SetBusy(true);
4719 vnode->Unlock();
4722 status = vm_create_vnode_cache(vnode, &vnode->cache);
4725 vnode->Lock();
4726 vnode->SetBusy(wasBusy);
4731 vnode->Unlock();
4735 vnode->cache->AcquireRef();
4736 *_cache = vnode->cache;
4743 /*! Sets the vnode's VMCache object, for subsystems that want to manage
4749 vfs_set_vnode_cache(struct vnode* vnode, VMCache* _cache)
4752 vnode->Lock();
4755 if (vnode->cache != NULL) {
4758 vnode->cache = _cache;
4762 vnode->Unlock();
4769 vfs_get_file_map(struct vnode* vnode, off_t offset, size_t size,
4772 FUNCTION(("vfs_get_file_map: vnode %p, vecs %p, offset %" B_PRIdOFF
4773 ", size = %" B_PRIuSIZE "\n", vnode, vecs, offset, size));
4775 return FS_CALL(vnode, get_file_map, offset, size, vecs, _count);
4780 vfs_stat_vnode(struct vnode* vnode, struct stat* stat)
4782 status_t status = FS_CALL(vnode, read_stat, stat);
4786 stat->st_dev = vnode->device;
4787 stat->st_ino = vnode->id;
4800 struct vnode* vnode;
4801 status_t status = get_vnode(device, inode, &vnode, true, false);
4805 status = vfs_stat_vnode(vnode, stat);
4807 put_vnode(vnode);
4813 vfs_get_vnode_name(struct vnode* vnode, char* name, size_t nameSize)
4815 return get_vnode_name(vnode, NULL, name, nameSize, true);
4823 VnodePutter vnode;
4830 // get the vnode matching the dir's node_ref
4832 // special cases "." and "..": we can directly get the vnode of the
4834 status = entry_ref_to_vnode(device, inode, leaf, false, kernel, vnode);
4837 struct vnode* temp = NULL;
4839 vnode.SetTo(temp);
4845 status = dir_vnode_to_path(vnode.Get(), path, pathLength, kernel);
4846 vnode.Unset();
4847 // we don't need the vnode anymore
4865 /*! If the given descriptor locked its vnode, that lock will be released. */
4869 struct vnode* vnode = fd_vnode(descriptor);
4871 if (vnode != NULL && vnode->mandatory_locked_by == descriptor)
4872 vnode->mandatory_locked_by = NULL;
4880 struct vnode* vnode = descriptor->u.vnode;
4881 if (vnode == NULL)
4884 if (HAS_FS_CALL(vnode, release_lock))
4885 return FS_CALL(vnode, release_lock, descriptor->cookie, NULL);
4887 return release_advisory_lock(vnode, context, NULL, NULL);
5103 /*! \brief Resolves a vnode to the vnode it is covered by, if any.
5105 Given an arbitrary vnode (identified by mount and node ID), the function
5106 checks, whether the vnode is covered by another vnode. If it is, the
5107 function returns the mount and node ID of the covering vnode. Otherwise
5114 \param mountID The mount ID of the vnode in question.
5115 \param nodeID The node ID of the vnode in question.
5127 struct vnode* node;
5173 Vnode* vnode;
5174 status_t error = get_vnode(mountID, nodeID, &vnode, true, false);
5177 VnodePutter vnodePutter(vnode);
5189 if (vnode->covers != NULL || coveredVnode->covered_by != NULL
5190 || vnode->mount->unmounting || coveredVnode->mount->unmounting) {
5194 vnode->covers = coveredVnode;
5195 vnode->SetCovering(true);
5197 coveredVnode->covered_by = vnode;
5201 inc_vnode_ref_count(vnode);
5275 vnode::StaticInit();
5279 panic("vfs_init: error creating vnode hash table\n");
5281 struct vnode dummy_vnode;
5296 sizeof(struct vnode), 8, NULL, NULL, NULL);
5298 panic("vfs_init: error creating vnode object_cache\n");
5316 add_debugger_command_etc("vnode", &dump_vnode,
5317 "Print info about the specified vnode",
5318 "[ \"-p\" ] ( <vnode> | <devID> <nodeID> )\n"
5319 "Prints information about the vnode specified by address <vnode> or\n"
5320 "<devID>, <vnodeID> pair. If \"-p\" is given, a path of the vnode is\n"
5327 "list all vnode caches");
5334 "info about vnode usage");
5353 Calls fs_open() on the given vnode and returns a new
5357 open_vnode(struct vnode* vnode, int openMode, bool kernel)
5360 status_t status = FS_CALL(vnode, open, openMode, &cookie);
5364 int fd = get_new_fd(FDTYPE_FILE, NULL, vnode, cookie, openMode, kernel);
5366 FS_CALL(vnode, close, cookie);
5367 FS_CALL(vnode, free_cookie, cookie);
5374 Calls fs_open() on the given vnode and returns a new
5378 create_vnode(struct vnode* directory, const char* name, int openMode,
5383 VnodePutter vnode, dirPutter;
5403 struct vnode* entry = NULL;
5405 vnode.SetTo(entry);
5413 if (S_ISLNK(vnode->Type()) && traverse) {
5414 vnode.Unset();
5423 kernel, vnode, NULL, clonedName);
5425 // vnode is not found, but maybe it has a parent and we can create it from
5426 // there. In that case, vnode_path_to_vnode has set vnode to the latest
5429 directory = vnode.Detach();
5439 if ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
5442 int fd = open_vnode(vnode.Get(), openMode & ~O_CREAT, kernel);
5443 // on success keep the vnode reference for the FD
5445 vnode.Detach();
5470 vnode.SetTo(lookup_vnode(directory->device, newID));
5473 if (!vnode.IsSet()) {
5474 panic("vfs: fs_create() returned success but there is no vnode, "
5479 int fd = get_new_fd(FDTYPE_FILE, NULL, vnode.Get(), cookie, openMode, kernel);
5481 vnode.Detach();
5489 FS_CALL(vnode.Get(), close, cookie);
5490 FS_CALL(vnode.Get(), free_cookie, cookie);
5498 /*! Calls fs open_dir() on the given vnode and returns a new
5502 open_dir_vnode(struct vnode* vnode, bool kernel)
5504 if (!HAS_FS_CALL(vnode, open_dir))
5508 status_t status = FS_CALL(vnode, open_dir, &cookie);
5513 status = get_new_fd(FDTYPE_DIR, NULL, vnode, cookie, O_CLOEXEC, kernel);
5517 FS_CALL(vnode, close_dir, cookie);
5518 FS_CALL(vnode, free_dir_cookie, cookie);
5524 /*! Calls fs open_attr_dir() on the given vnode and returns a new
5529 open_attr_dir_vnode(struct vnode* vnode, bool kernel)
5531 if (!HAS_FS_CALL(vnode, open_attr_dir))
5535 status_t status = FS_CALL(vnode, open_attr_dir, &cookie);
5540 status = get_new_fd(FDTYPE_ATTR_DIR, NULL, vnode, cookie, O_CLOEXEC,
5545 FS_CALL(vnode, close_attr_dir, cookie);
5546 FS_CALL(vnode, free_attr_dir_cookie, cookie);
5560 struct vnode* directory;
5602 // get the vnode matching the entry_ref
5603 VnodePutter vnode;
5605 kernel, vnode);
5609 if ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
5612 int newFD = open_vnode(vnode.Get(), openMode, kernel);
5614 cache_node_opened(vnode.Get(), FDTYPE_FILE, vnode->cache, mountID,
5615 directoryID, vnode->id, name);
5617 // The vnode reference has been transferred to the FD
5618 vnode.Detach();
5633 // get the vnode matching the vnode + path combination
5634 VnodePutter vnode;
5636 status_t status = fd_and_path_to_vnode(fd, path, traverse, vnode,
5641 if ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
5644 // open the vnode
5645 int newFD = open_vnode(vnode.Get(), openMode, kernel);
5647 cache_node_opened(vnode.Get(), FDTYPE_FILE, vnode->cache,
5648 vnode->device, parentID, vnode->id, NULL);
5650 // The vnode reference has been transferred to the FD
5651 vnode.Detach();
5661 struct vnode* vnode = descriptor->u.vnode;
5666 cache_node_closed(vnode, FDTYPE_FILE, vnode->cache, vnode->device,
5667 vnode->id);
5668 if (HAS_FS_CALL(vnode, close)) {
5669 status = FS_CALL(vnode, close, descriptor->cookie);
5674 if (HAS_FS_CALL(vnode, release_lock))
5675 status = FS_CALL(vnode, release_lock, descriptor->cookie, NULL);
5677 status = release_advisory_lock(vnode, NULL, descriptor, NULL);
5686 struct vnode* vnode = descriptor->u.vnode;
5688 if (vnode != NULL) {
5689 FS_CALL(vnode, free_cookie, descriptor->cookie);
5690 put_vnode(vnode);
5699 struct vnode* vnode = descriptor->u.vnode;
5703 if (S_ISDIR(vnode->Type()))
5708 return FS_CALL(vnode, read, descriptor->cookie, pos, buffer, length);
5716 struct vnode* vnode = descriptor->u.vnode;
5720 if (S_ISDIR(vnode->Type()))
5725 if (!HAS_FS_CALL(vnode, write))
5728 return FS_CALL(vnode, write, descriptor->cookie, pos, buffer, length);
5735 struct vnode* vnode = descriptor->u.vnode;
5745 switch (vnode->Type() & S_IFMT) {
5763 if (!HAS_FS_CALL(vnode, read_stat))
5767 status_t status = FS_CALL(vnode, read_stat, &stat);
5777 if (HAS_FS_CALL(vnode, ioctl)) {
5778 status = FS_CALL(vnode, ioctl, descriptor->cookie,
5794 if (HAS_FS_CALL(vnode, ioctl)) {
5796 status = FS_CALL(vnode, ioctl, descriptor->cookie,
5809 if (!HAS_FS_CALL(vnode, read_stat) || isDevice)
5813 status = FS_CALL(vnode, read_stat, &stat);
5845 struct vnode* vnode = descriptor->u.vnode;
5848 if (!HAS_FS_CALL(vnode, select)) {
5855 return FS_CALL(vnode, select, descriptor->cookie, event, sync);
5863 struct vnode* vnode = descriptor->u.vnode;
5865 if (!HAS_FS_CALL(vnode, deselect))
5868 return FS_CALL(vnode, deselect, descriptor->cookie, event, sync);
5876 struct vnode* vnode;
5885 status = get_vnode(mountID, parentID, &vnode, true, false);
5889 if (HAS_FS_CALL(vnode, create_dir))
5890 status = FS_CALL(vnode, create_dir, name, perms);
5894 put_vnode(vnode);
5908 VnodePutter vnode;
5909 status = fd_and_path_to_dir_vnode(fd, path, vnode, filename, kernel);
5913 if (HAS_FS_CALL(vnode, create_dir)) {
5914 status = FS_CALL(vnode.Get(), create_dir, filename, perms);
5930 // get the vnode matching the entry_ref/node_ref
5931 VnodePutter vnode;
5935 vnode);
5937 struct vnode* temp = NULL;
5939 vnode.SetTo(temp);
5944 int newFD = open_dir_vnode(vnode.Get(), kernel);
5946 cache_node_opened(vnode.Get(), FDTYPE_DIR, vnode->cache, mountID, parentID,
5947 vnode->id, name);
5949 // The vnode reference has been transferred to the FD
5950 vnode.Detach();
5963 // get the vnode matching the vnode + path combination
5964 VnodePutter vnode;
5966 status_t status = fd_and_path_to_vnode(fd, path, true, vnode, &parentID,
5972 int newFD = open_dir_vnode(vnode.Get(), kernel);
5974 cache_node_opened(vnode.Get(), FDTYPE_DIR, vnode->cache, vnode->device,
5975 parentID, vnode->id, NULL);
5977 // The vnode reference has been transferred to the FD
5978 vnode.Detach();
5988 struct vnode* vnode = descriptor->u.vnode;
5992 cache_node_closed(vnode, FDTYPE_DIR, vnode->cache, vnode->device,
5993 vnode->id);
5994 if (HAS_FS_CALL(vnode, close_dir))
5995 return FS_CALL(vnode, close_dir, descriptor->cookie);
6004 struct vnode* vnode = descriptor->u.vnode;
6006 if (vnode != NULL) {
6007 FS_CALL(vnode, free_dir_cookie, descriptor->cookie);
6008 put_vnode(vnode);
6017 return dir_read(ioContext, descriptor->u.vnode, descriptor->cookie, buffer,
6023 fix_dirent(struct vnode* parent, struct dirent* entry,
6030 // If this is the ".." entry and the directory covering another vnode,
6040 struct vnode* vnode = lookup_vnode(entry->d_dev, entry->d_ino);
6041 if (vnode != NULL && vnode->covered_by != NULL) {
6043 vnode = vnode->covered_by;
6044 } while (vnode->covered_by != NULL);
6046 entry->d_dev = vnode->device;
6047 entry->d_ino = vnode->id;
6055 dir_read(struct io_context* ioContext, struct vnode* vnode, void* cookie,
6058 if (!HAS_FS_CALL(vnode, read_dir))
6061 status_t error = FS_CALL(vnode, read_dir, cookie, buffer, bufferSize,
6069 error = fix_dirent(vnode, buffer, ioContext);
6083 struct vnode* vnode = descriptor->u.vnode;
6085 if (HAS_FS_CALL(vnode, rewind_dir)) {
6086 return FS_CALL(vnode, rewind_dir, descriptor->cookie);
6142 struct vnode* vnode = descriptor->u.vnode;
6144 if (HAS_FS_CALL(vnode, ioctl))
6145 return FS_CALL(vnode, ioctl, descriptor->cookie, op, buffer, length);
6165 struct vnode* vnode = fd_vnode(descriptor.Get());
6214 } else if (vnode != NULL && HAS_FS_CALL(vnode, set_flags)) {
6215 status = FS_CALL(vnode, set_flags, descriptor->cookie,
6249 if (vnode != NULL) {
6257 if (HAS_FS_CALL(vnode, test_lock)) {
6258 status = FS_CALL(vnode, test_lock, descriptor->cookie,
6261 status = test_advisory_lock(vnode, &normalizedLock);
6299 if (vnode == NULL) {
6302 if (HAS_FS_CALL(vnode, release_lock)) {
6303 status = FS_CALL(vnode, release_lock, descriptor->cookie,
6306 status = release_advisory_lock(vnode, context, NULL,
6317 if (HAS_FS_CALL(vnode, acquire_lock)) {
6318 status = FS_CALL(vnode, acquire_lock,
6321 status = acquire_advisory_lock(vnode, context, NULL,
6343 struct vnode* vnode;
6344 FileDescriptorPutter descriptor(get_fd_and_vnode(fd, &vnode, kernel));
6349 if (HAS_FS_CALL(vnode, fsync))
6350 status = FS_CALL_NO_PARAMS(vnode, fsync);
6361 struct vnode* vnode;
6362 FileDescriptorPutter descriptor(get_fd_and_vnode(fd, &vnode, kernel));
6370 if (atomic_pointer_test_and_set(&vnode->mandatory_locked_by,
6381 struct vnode* vnode;
6382 FileDescriptorPutter descriptor(get_fd_and_vnode(fd, &vnode, kernel));
6390 if (atomic_pointer_test_and_set(&vnode->mandatory_locked_by,
6406 struct vnode* vnode;
6407 FileDescriptorPutter descriptor(get_fd_and_vnode(fd, &vnode, kernel));
6411 switch (vnode->Type() & S_IFMT) {
6427 if (HAS_FS_CALL(vnode, preallocate)) {
6428 status = FS_CALL(vnode, preallocate, offset, length);
6430 status = HAS_FS_CALL(vnode, write)
6442 VnodePutter vnode;
6445 status = fd_and_path_to_vnode(fd, path, false, vnode, NULL, kernel);
6449 if (HAS_FS_CALL(vnode, read_symlink)) {
6450 status = FS_CALL(vnode.Get(), read_symlink, buffer, _bufferSize);
6469 VnodePutter vnode;
6470 status = fd_and_path_to_dir_vnode(fd, path, vnode, name, kernel);
6474 if (HAS_FS_CALL(vnode, create_symlink))
6475 status = FS_CALL(vnode.Get(), create_symlink, name, toPath, mode);
6477 status = HAS_FS_CALL(vnode, write)
6501 VnodePutter vnode;
6502 status = fd_and_path_to_vnode(toFD, toPath, traverseLeafLink, vnode, NULL,
6507 if (directory->mount != vnode->mount)
6511 status = FS_CALL(directory.Get(), link, name, vnode.Get());
6528 VnodePutter vnode;
6529 status = fd_and_path_to_dir_vnode(fd, path, vnode, filename, kernel);
6533 if (HAS_FS_CALL(vnode, unlink))
6534 status = FS_CALL(vnode.Get(), unlink, filename);
6549 VnodePutter vnode;
6550 status = fd_and_path_to_vnode(fd, path, true, vnode, NULL, kernel);
6554 if (HAS_FS_CALL(vnode, access))
6555 status = FS_CALL(vnode.Get(), access, mode);
6607 struct vnode* vnode = descriptor->u.vnode;
6617 return vfs_stat_vnode(vnode, stat);
6625 struct vnode* vnode = descriptor->u.vnode;
6627 FUNCTION(("common_write_stat(vnode = %p, stat = %p, statMask = %d)\n",
6628 vnode, stat, statMask));
6635 if (!HAS_FS_CALL(vnode, write_stat))
6638 return FS_CALL(vnode, write_stat, stat, statMask);
6649 VnodePutter vnode;
6650 status_t status = fd_and_path_to_vnode(fd, path, traverseLeafLink, vnode,
6655 status = vfs_stat_vnode(vnode.Get(), stat);
6668 VnodePutter vnode;
6669 status_t status = fd_and_path_to_vnode(fd, path, traverseLeafLink, vnode,
6674 if (HAS_FS_CALL(vnode, write_stat))
6675 status = FS_CALL(vnode.Get(), write_stat, stat, statMask);
6689 VnodePutter vnode;
6690 status_t status = fd_and_path_to_vnode(fd, path, traverseLeafLink, vnode,
6695 status = open_attr_dir_vnode(vnode.Get(), kernel);
6697 vnode.Detach();
6706 struct vnode* vnode = descriptor->u.vnode;
6710 if (HAS_FS_CALL(vnode, close_attr_dir))
6711 return FS_CALL(vnode, close_attr_dir, descriptor->cookie);
6720 struct vnode* vnode = descriptor->u.vnode;
6722 if (vnode != NULL) {
6723 FS_CALL(vnode, free_attr_dir_cookie, descriptor->cookie);
6724 put_vnode(vnode);
6733 struct vnode* vnode = descriptor->u.vnode;
6737 if (HAS_FS_CALL(vnode, read_attr_dir))
6738 return FS_CALL(vnode, read_attr_dir, descriptor->cookie, buffer,
6748 struct vnode* vnode = descriptor->u.vnode;
6752 if (HAS_FS_CALL(vnode, rewind_attr_dir))
6753 return FS_CALL(vnode, rewind_attr_dir, descriptor->cookie);
6767 VnodePutter vnode;
6768 status_t status = fd_and_path_to_vnode(fd, path, traverse, vnode, NULL,
6773 if ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
6776 if (!HAS_FS_CALL(vnode, create_attr))
6780 status = FS_CALL(vnode.Get(), create_attr, name, type, openMode, &cookie);
6784 fd = get_new_fd(FDTYPE_ATTR, NULL, vnode.Get(), cookie, openMode, kernel);
6786 vnode.Detach();
6792 FS_CALL(vnode.Get(), close_attr, cookie);
6793 FS_CALL(vnode.Get(), free_attr_cookie, cookie);
6795 FS_CALL(vnode.Get(), remove_attr, name);
6808 VnodePutter vnode;
6809 status_t status = fd_and_path_to_vnode(fd, path, traverse, vnode, NULL,
6814 if ((openMode & O_NOFOLLOW) != 0 && S_ISLNK(vnode->Type()))
6817 if (!HAS_FS_CALL(vnode, open_attr))
6821 status = FS_CALL(vnode.Get(), open_attr, name, openMode, &cookie);
6826 fd = get_new_fd(FDTYPE_ATTR, NULL, vnode.Get(), cookie, openMode, kernel);
6828 vnode.Detach();
6834 FS_CALL(vnode.Get(), close_attr, cookie);
6835 FS_CALL(vnode.Get(), free_attr_cookie, cookie);
6844 struct vnode* vnode = descriptor->u.vnode;
6848 if (HAS_FS_CALL(vnode, close_attr))
6849 return FS_CALL(vnode, close_attr, descriptor->cookie);
6858 struct vnode* vnode = descriptor->u.vnode;
6860 if (vnode != NULL) {
6861 FS_CALL(vnode, free_attr_cookie, descriptor->cookie);
6862 put_vnode(vnode);
6871 struct vnode* vnode = descriptor->u.vnode;
6876 if (!HAS_FS_CALL(vnode, read_attr))
6879 return FS_CALL(vnode, read_attr, descriptor->cookie, pos, buffer, length);
6887 struct vnode* vnode = descriptor->u.vnode;
6892 if (!HAS_FS_CALL(vnode, write_attr))
6895 return FS_CALL(vnode, write_attr, descriptor->cookie, pos, buffer, length);
6913 struct vnode* vnode = descriptor->u.vnode;
6914 if (!HAS_FS_CALL(vnode, read_stat))
6918 status_t status = FS_CALL(vnode, read_attr_stat, descriptor->cookie,
6945 struct vnode* vnode = descriptor->u.vnode;
6949 if (!HAS_FS_CALL(vnode, read_attr_stat))
6952 return FS_CALL(vnode, read_attr_stat, descriptor->cookie, stat);
6960 struct vnode* vnode = descriptor->u.vnode;
6964 if (!HAS_FS_CALL(vnode, write_attr_stat))
6967 return FS_CALL(vnode, write_attr_stat, descriptor->cookie, stat, statMask);
6980 struct vnode* vnode;
6981 FileDescriptorPutter descriptor(get_fd_and_vnode(fd, &vnode, kernel));
6986 if (HAS_FS_CALL(vnode, remove_attr))
6987 status = FS_CALL(vnode, remove_attr, name);
7006 struct vnode* fromVnode;
7011 struct vnode* toVnode;
7152 struct vnode* vnode = descriptor->u.vnode;
7156 if (!HAS_FS_CALL(vnode, read_index_stat))
7160 //return FS_CALL(vnode, read_index_stat, descriptor->cookie, stat);
7167 struct vnode* vnode = descriptor->u.vnode;
7169 if (vnode != NULL) {
7170 FS_CALL(vnode, free_index_cookie, descriptor->cookie);
7171 put_vnode(vnode);
7561 // this is already a covered vnode
7601 // set up the links between the root vnode and the vnode it covers
7604 // the vnode is covered now
7681 panic("fs_unmount: find_mount() failed on root vnode @%p of mount\n",
7722 // grab the vnode master mutex to keep someone from creating
7723 // a vnode while we're figuring out if we can continue
7734 while (struct vnode* vnode = iterator.Next()) {
7735 if (vnode->IsBusy()) {
7736 dprintf("fs_unmount(): inode %" B_PRIdINO " is busy\n", vnode->id);
7741 // check the vnode's ref count -- subtract additional references for
7743 int32 refCount = vnode->ref_count;
7744 if (vnode->covers != NULL)
7746 if (vnode->covered_by != NULL)
7750 dprintf("fs_unmount(): inode %" B_PRIdINO " is still referenced\n", vnode->id);
7789 // structure in unmounting state. Also undo the vnode covers/covered_by
7794 while (struct vnode* vnode = iterator.Next()) {
7796 // vnode and adjust the node ref count accordingly. We will release the
7798 if (Vnode* coveredNode = vnode->covers) {
7799 if (Vnode* coveringNode = vnode->covered_by) {
7804 vnode->ref_count -= 2;
7806 vnode->covered_by = NULL;
7807 vnode->covers = NULL;
7808 vnode->SetCovering(false);
7809 vnode->SetCovered(false);
7811 // We only have a covered vnode. Remove its link to us.
7814 vnode->ref_count--;
7816 // If the other node is an external vnode, we keep its link
7820 vnode->covers = NULL;
7824 } else if (Vnode* coveringNode = vnode->covered_by) {
7825 // We only have a covering vnode. Remove its link to us.
7828 vnode->ref_count--;
7830 // If the other node is an external vnode, we keep its link
7834 vnode->covered_by = NULL;
7839 vnode->SetBusy(true);
7840 vnode_to_be_freed(vnode);
7848 while (struct vnode* vnode = mount->vnodes.Head()) {
7850 if (Vnode* coveredNode = vnode->covers)
7852 if (Vnode* coveringNode = vnode->covered_by)
7855 free_vnode(vnode, false);
7891 struct vnode marker;
7907 // synchronize access to vnode list
7910 struct vnode* vnode;
7912 vnode = mount->vnodes.GetNext(&marker);
7916 vnode = mount->vnodes.First();
7918 while (vnode != NULL && (vnode->cache == NULL
7919 || vnode->IsRemoved() || vnode->IsBusy())) {
7922 vnode = mount->vnodes.GetNext(vnode);
7925 if (vnode != NULL) {
7926 // insert marker vnode again
7927 mount->vnodes.InsertBefore(mount->vnodes.GetNext(vnode), &marker);
7933 if (vnode == NULL)
7936 vnode = lookup_vnode(mount->id, vnode->id);
7937 if (vnode == NULL || vnode->IsBusy())
7940 if (vnode->ref_count == 0) {
7941 // this vnode has been unused before
7942 vnode_used(vnode);
7944 inc_vnode_ref_count(vnode);
7948 if (vnode->cache != NULL && !vnode->IsRemoved())
7949 vnode->cache->WriteModified();
7951 put_vnode(vnode);
8082 struct vnode* vnode = context->cwd;
8083 if (vnode)
8084 inc_vnode_ref_count(vnode);
8088 if (vnode) {
8089 status = dir_vnode_to_path(vnode, buffer, size, kernel);
8090 put_vnode(vnode);
8102 struct vnode* oldDirectory;
8106 // Get vnode for passed path, and bail if it failed
8107 VnodePutter vnode;
8108 status_t status = fd_and_path_to_vnode(fd, path, true, vnode, NULL, kernel);
8112 if (!S_ISDIR(vnode->Type())) {
8118 if (HAS_FS_CALL(vnode, access)) {
8119 status = FS_CALL(vnode.Get(), access, X_OK);
8130 context->cwd = vnode.Detach();
8255 struct vnode* vnode = fd_vnode(descriptor);
8256 if (vnode != NULL) {
8257 info->device = vnode->device;
8258 info->node = vnode->id;
9161 struct vnode* parentVNode = get_vnode_from_fd(parentFD, kernel);
9162 struct vnode* dirVNode = get_vnode_from_fd(fd, kernel);
9168 // get the vnode name
9222 struct vnode* vnode;
9223 FileDescriptorPutter descriptor(get_fd_and_vnode(fd, &vnode, false));
9238 if (HAS_FS_CALL(vnode, release_lock))
9239 status = FS_CALL(vnode, release_lock, descriptor->cookie, &flock);
9241 status = release_advisory_lock(vnode, NULL, descriptor.Get(), &flock);
9243 if (HAS_FS_CALL(vnode, acquire_lock)) {
9244 status = FS_CALL(vnode, acquire_lock, descriptor->cookie, &flock,
9247 status = acquire_advisory_lock(vnode, NULL, descriptor.Get(), &flock,
9499 // split into directory vnode and filename path
9540 struct vnode* vnode;
9541 status = get_vnode(sRoot->mount->id, nodeID, &vnode, true, false);
9544 dprintf("_user_create_pipe(): Failed to lookup vnode (%" B_PRIdDEV ", "
9552 fds[0] = open_vnode(vnode, O_RDONLY, false);
9553 fds[1] = open_vnode(vnode, O_WRONLY, false);
10036 // get the vnode
10037 VnodePutter vnode;
10038 status_t status = path_to_vnode(path, true, vnode, NULL, false);
10045 struct vnode* oldRoot = context->root;
10046 context->root = vnode.Detach();