* Add an additional argument to get_vnode() that gets the fs_vnode_ops of the
node. That is needed for a layered filesystem to be able to construct a full fs_vnode out of a volume/inode pair. * Adapt places where get_vnode is used. Sadly this is a C API and we can't just use a default NULL for that argument. * Introduce a flag B_VNODE_WANTS_OVERLAY_SUB_NODE that can be returned in the flags field of a fs get_vnode call. A filesystem can use this flag to indicate that it doesn't support the full set of fs features (attributes, write support) and it'd like to have unsupported calls emulated by an overlay sub node. * Add a perliminary overlay filesystem that emulates file attributes using files on a filesystem where attributes aren't supported. It does currently only support reading attributes/attribute directories though. All other calls are just passed through to the super filesystem. * Adjust places where a HAS_FS_CALL() is taken as a guarantee that the operation is supported. For the overlay filesystem we may later return a B_UNSUPPORTED, so make sure that in that case proper fallback options are taken. * Make the iso9660 filesystem request overlay sub nodes. This can be fine tuned later to only trigger where there are features on a CD that need emulation at all. If you happened to know the attribute file format and location you could build an iso with read-only attribute support now. Note that this won't be enough to get a bootable iso-only image as the query and index support is yet missing. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29177 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c8530759dd
commit
00405f2286
@ -43,6 +43,7 @@ struct file_io_vec {
|
||||
// flags for publish_vnode() and fs_volume_ops::get_vnode()
|
||||
#define B_VNODE_PUBLISH_REMOVED 0x01
|
||||
#define B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE 0x02
|
||||
#define B_VNODE_WANTS_OVERLAY_SUB_NODE 0x04
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -307,7 +308,7 @@ extern status_t publish_vnode(fs_volume *volume, ino_t vnodeID,
|
||||
void *privateNode, fs_vnode_ops *ops, int type,
|
||||
uint32 flags);
|
||||
extern status_t get_vnode(fs_volume *volume, ino_t vnodeID,
|
||||
void **_privateNode);
|
||||
void **_privateNode, fs_vnode_ops **_vnodeOps);
|
||||
extern status_t put_vnode(fs_volume *volume, ino_t vnodeID);
|
||||
extern status_t acquire_vnode(fs_volume *volume, ino_t vnodeID);
|
||||
extern status_t remove_vnode(fs_volume *volume, ino_t vnodeID);
|
||||
|
@ -344,7 +344,8 @@ extern fssh_status_t fssh_publish_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID, void *privateNode,
|
||||
fssh_fs_vnode_ops *ops, int type, uint32_t flags);
|
||||
extern fssh_status_t fssh_get_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID, void **_privateNode);
|
||||
fssh_vnode_id vnodeID, void **_privateNode,
|
||||
fssh_fs_vnode_ops **_vnodeOps);
|
||||
extern fssh_status_t fssh_put_vnode(fssh_fs_volume *volume,
|
||||
fssh_vnode_id vnodeID);
|
||||
extern fssh_status_t fssh_acquire_vnode(fssh_fs_volume *volume,
|
||||
|
@ -2701,7 +2701,7 @@ AttributeIterator::GetNext(char* name, size_t* _length, uint32* _type,
|
||||
// if you haven't yet access to the attributes directory, get it
|
||||
if (fAttributes == NULL) {
|
||||
if (get_vnode(volume->FSVolume(), volume->ToVnode(fInode->Attributes()),
|
||||
(void**)&fAttributes) != B_OK) {
|
||||
(void**)&fAttributes, NULL) != B_OK) {
|
||||
FATAL(("get_vnode() failed in AttributeIterator::GetNext(ino_t"
|
||||
" = %Ld,name = \"%s\")\n", fInode->ID(), name));
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
@ -354,7 +354,8 @@ public:
|
||||
{
|
||||
Unset();
|
||||
|
||||
return fStatus = get_vnode(volume->FSVolume(), id, (void**)&fInode);
|
||||
return fStatus = get_vnode(volume->FSVolume(), id, (void**)&fInode,
|
||||
NULL);
|
||||
}
|
||||
|
||||
status_t SetTo(Volume* volume, block_run run)
|
||||
|
@ -556,7 +556,7 @@ bfs_lookup(fs_volume* _volume, fs_vnode* _directory, const char* file,
|
||||
locker.Unlock();
|
||||
|
||||
Inode* inode;
|
||||
status = get_vnode(volume->FSVolume(), *_vnodeID, (void**)&inode);
|
||||
status = get_vnode(volume->FSVolume(), *_vnodeID, (void**)&inode, NULL);
|
||||
if (status != B_OK) {
|
||||
REPORT_ERROR(status);
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
@ -1493,7 +1493,7 @@ cdda_lookup(fs_volume* _volume, fs_vnode* _dir, const char* name, ino_t* _id)
|
||||
if (inode == NULL)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
|
||||
status = get_vnode(volume->FSVolume(), inode->ID(), NULL);
|
||||
status = get_vnode(volume->FSVolume(), inode->ID(), NULL, NULL);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
|
@ -310,7 +310,7 @@ Volume::Mount(const char* deviceName, uint32 flags)
|
||||
if ((fBlockCache = opener.InitCache(NumBlocks(), fBlockSize)) == NULL)
|
||||
return B_ERROR;
|
||||
|
||||
status = get_vnode(fFSVolume, EXT2_ROOT_NODE, (void**)&fRootNode);
|
||||
status = get_vnode(fFSVolume, EXT2_ROOT_NODE, (void**)&fRootNode, NULL);
|
||||
if (status != B_OK) {
|
||||
TRACE("could not create root node: get_vnode() failed!\n");
|
||||
return status;
|
||||
|
@ -319,7 +319,7 @@ ext2_lookup(fs_volume* _volume, fs_vnode* _directory, const char* name,
|
||||
break;
|
||||
}
|
||||
|
||||
return get_vnode(volume->FSVolume(), *_vnodeID, NULL);
|
||||
return get_vnode(volume->FSVolume(), *_vnodeID, NULL, NULL);
|
||||
}
|
||||
|
||||
|
||||
|
@ -433,7 +433,7 @@ findfile(nspace *vol, vnode *dir, const char *file, ino_t *vnid,
|
||||
if (vnid)
|
||||
*vnid = found_vnid;
|
||||
if (node)
|
||||
result = get_vnode(vol->volume, found_vnid, (void **)node);
|
||||
result = get_vnode(vol->volume, found_vnid, (void **)node, NULL);
|
||||
result = B_OK;
|
||||
} else {
|
||||
result = ENOENT;
|
||||
|
@ -890,7 +890,7 @@ dosfs_create(fs_volume *_vol, fs_vnode *_dir, const char *name, int omode,
|
||||
*vnid = dummy.vnid;
|
||||
dummy.magic = ~VNODE_MAGIC;
|
||||
|
||||
result = get_vnode(_vol, *vnid, (void **)&file);
|
||||
result = get_vnode(_vol, *vnid, (void **)&file, NULL);
|
||||
if (result < B_OK) {
|
||||
if (vol->fs_flags & FS_FLAGS_OP_SYNC)
|
||||
_dosfs_sync(vol);
|
||||
@ -1155,7 +1155,7 @@ dosfs_rename(fs_volume *_vol, fs_vnode *_odir, const char *oldname,
|
||||
if (vnid == vol->root_vnode.vnid)
|
||||
break;
|
||||
|
||||
result = get_vnode(_vol, vnid, (void **)&dir);
|
||||
result = get_vnode(_vol, vnid, (void **)&dir, NULL);
|
||||
if (result < B_OK)
|
||||
goto bi1;
|
||||
parent = dir->dir_vnid;
|
||||
|
@ -224,12 +224,12 @@ fs_walk(fs_volume *_vol, fs_vnode *_base, const char *file, ino_t *_vnodeID)
|
||||
// base directory
|
||||
TRACE(("fs_walk - found \".\" file.\n"));
|
||||
*_vnodeID = baseNode->id;
|
||||
return get_vnode(_vol, *_vnodeID, (void **)&newNode);
|
||||
return get_vnode(_vol, *_vnodeID, NULL, NULL);
|
||||
} else if (strcmp(file, "..") == 0) {
|
||||
// parent directory
|
||||
TRACE(("fs_walk - found \"..\" file.\n"));
|
||||
*_vnodeID = baseNode->parID;
|
||||
return get_vnode(_vol, *_vnodeID, (void **)&newNode);
|
||||
return get_vnode(_vol, *_vnodeID, NULL, NULL);
|
||||
}
|
||||
|
||||
// look up file in the directory
|
||||
@ -272,7 +272,7 @@ fs_walk(fs_volume *_vol, fs_vnode *_base, const char *file, ino_t *_vnodeID)
|
||||
TRACE(("fs_walk - New vnode id is %Ld\n", *_vnodeID));
|
||||
|
||||
result = get_vnode(_vol, *_vnodeID,
|
||||
(void **)&newNode);
|
||||
(void **)&newNode, NULL);
|
||||
if (result == B_OK) {
|
||||
newNode->parID = baseNode->id;
|
||||
done = true;
|
||||
@ -349,7 +349,7 @@ fs_read_vnode(fs_volume *_vol, ino_t vnodeID, fs_vnode *_node,
|
||||
_node->private_node = newNode;
|
||||
_node->ops = &gISO9660VnodeOps;
|
||||
*_type = newNode->attr.stat[FS_DATA_FORMAT].st_mode & ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||
*_flags = 0;
|
||||
*_flags = B_VNODE_WANTS_OVERLAY_SUB_NODE;
|
||||
|
||||
if ((newNode->flags & ISO_ISDIR) == 0) {
|
||||
newNode->cache = file_cache_create(ns->id, vnodeID,
|
||||
|
@ -898,7 +898,7 @@ fs_walk(fs_volume *_volume, fs_vnode *_base, const char *file, ino_t *vnid)
|
||||
isLink=S_ISLNK(st.st_mode);
|
||||
}
|
||||
|
||||
if ((result=get_vnode (_volume,*vnid,(void **)&dummy))<B_OK)
|
||||
if ((result=get_vnode (_volume,*vnid,(void **)&dummy,NULL))<B_OK)
|
||||
return result;
|
||||
|
||||
return B_OK;
|
||||
@ -1755,7 +1755,7 @@ fs_create(fs_volume *_volume, fs_vnode *_dir, const char *name, int omode, int p
|
||||
|
||||
*vnid=st.st_ino;
|
||||
|
||||
if ((result=get_vnode(_volume,*vnid,&dummy))<B_OK)
|
||||
if ((result=get_vnode(_volume,*vnid,&dummy,NULL))<B_OK)
|
||||
return result;
|
||||
|
||||
if (S_ISDIR(st.st_mode))
|
||||
@ -1901,7 +1901,7 @@ fs_unlink(fs_volume *_volume, fs_vnode *_dir, const char *name)
|
||||
|
||||
insert_node (ns,newNode);
|
||||
|
||||
if ((result=get_vnode(_volume,st.st_ino,(void **)&dummy))<B_OK)
|
||||
if ((result=get_vnode(_volume,st.st_ino,(void **)&dummy,NULL))<B_OK)
|
||||
{
|
||||
XDRInPacketDestroy (&reply);
|
||||
XDROutPacketDestroy (&call);
|
||||
@ -2195,7 +2195,7 @@ fs_rmdir(fs_volume *_volume, fs_vnode *_dir, const char *name)
|
||||
|
||||
insert_node (ns,newNode);
|
||||
|
||||
if ((result=get_vnode(_volume,st.st_ino,(void **)&dummy))<B_OK)
|
||||
if ((result=get_vnode(_volume,st.st_ino,(void **)&dummy,NULL))<B_OK)
|
||||
{
|
||||
XDRInPacketDestroy(&reply);
|
||||
XDROutPacketDestroy(&call);
|
||||
@ -2341,7 +2341,7 @@ fs_symlink(fs_volume *_volume, fs_vnode *_dir, const char *name, const char *pat
|
||||
if (result==B_OK)
|
||||
{
|
||||
void *dummy;
|
||||
if ((result=get_vnode(_volume,st.st_ino,&dummy))<B_OK)
|
||||
if ((result=get_vnode(_volume,st.st_ino,&dummy,NULL))<B_OK)
|
||||
return result;
|
||||
|
||||
XDRInPacketDestroy (&reply);
|
||||
|
@ -294,7 +294,7 @@ Volume::GetKeyOffsetForName(const char *name, int len, uint64 *result)
|
||||
status_t
|
||||
Volume::GetVNode(ino_t id, VNode **node)
|
||||
{
|
||||
return get_vnode(GetFSVolume(), id, (void**)node);
|
||||
return get_vnode(GetFSVolume(), id, (void**)node, NULL);
|
||||
}
|
||||
|
||||
// PutVNode
|
||||
|
@ -407,7 +407,8 @@ add_partition(struct devfs* fs, struct devfs_vnode* device, const char* name,
|
||||
|
||||
// increase reference count of raw device -
|
||||
// the partition device really needs it
|
||||
status = get_vnode(fs->volume, device->id, (void**)&partition->raw_device);
|
||||
status = get_vnode(fs->volume, device->id, (void**)&partition->raw_device,
|
||||
NULL);
|
||||
if (status < B_OK)
|
||||
goto err1;
|
||||
|
||||
@ -937,7 +938,7 @@ devfs_lookup(fs_volume *_volume, fs_vnode *_dir, const char *name, ino_t *_id)
|
||||
{
|
||||
struct devfs *fs = (struct devfs *)_volume->private_volume;
|
||||
struct devfs_vnode *dir = (struct devfs_vnode *)_dir->private_node;
|
||||
struct devfs_vnode *vnode, *vdummy;
|
||||
struct devfs_vnode *vnode;
|
||||
status_t status;
|
||||
|
||||
TRACE(("devfs_lookup: entry dir %p, name '%s'\n", dir, name));
|
||||
@ -958,7 +959,7 @@ devfs_lookup(fs_volume *_volume, fs_vnode *_dir, const char *name, ino_t *_id)
|
||||
return B_ENTRY_NOT_FOUND;
|
||||
}
|
||||
|
||||
status = get_vnode(fs->volume, vnode->id, (void**)&vdummy);
|
||||
status = get_vnode(fs->volume, vnode->id, NULL, NULL);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
@ -1062,7 +1063,7 @@ devfs_create(fs_volume* _volume, fs_vnode* _dir, const char* name, int openMode,
|
||||
if (openMode & O_EXCL)
|
||||
return B_FILE_EXISTS;
|
||||
|
||||
status = get_vnode(fs->volume, vnode->id, NULL);
|
||||
status = get_vnode(fs->volume, vnode->id, NULL, NULL);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
@ -2091,7 +2092,7 @@ devfs_unpublish_device(BaseDevice* device, bool disconnect)
|
||||
{
|
||||
devfs_vnode* node;
|
||||
status_t status = get_vnode(sDeviceFileSystem->volume, device->ID(),
|
||||
(void**)&node);
|
||||
(void**)&node, NULL);
|
||||
if (status != B_OK)
|
||||
return status;
|
||||
|
||||
|
@ -12,6 +12,7 @@ KernelMergeObject kernel_fs.o :
|
||||
fifo.cpp
|
||||
KPath.cpp
|
||||
node_monitor.cpp
|
||||
overlay.cpp
|
||||
rootfs.cpp
|
||||
socket.cpp
|
||||
vfs.cpp
|
||||
|
1097
src/system/kernel/fs/overlay.cpp
Normal file
1097
src/system/kernel/fs/overlay.cpp
Normal file
File diff suppressed because it is too large
Load Diff
16
src/system/kernel/fs/overlay.h
Normal file
16
src/system/kernel/fs/overlay.h
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright 2009, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Michael Lotz <mmlr@mlotz.ch>
|
||||
*/
|
||||
|
||||
#ifndef _VFS_OVERLAY_H
|
||||
#define _VFS_OVERLAY_H
|
||||
|
||||
#include <fs_interface.h>
|
||||
|
||||
status_t create_overlay_vnode(fs_volume *superVolume, fs_vnode *vnode);
|
||||
|
||||
#endif // _VFS_OVERLAY_H
|
@ -284,8 +284,7 @@ remove_node(struct rootfs *fs, struct rootfs_vnode *directory,
|
||||
{
|
||||
// schedule this vnode to be removed when it's ref goes to zero
|
||||
|
||||
void* dummy;
|
||||
bool gotNode = (get_vnode(fs->volume, vnode->id, &dummy) == B_OK);
|
||||
bool gotNode = (get_vnode(fs->volume, vnode->id, NULL, NULL) == B_OK);
|
||||
|
||||
status_t status = B_OK;
|
||||
if (gotNode)
|
||||
@ -432,7 +431,7 @@ rootfs_lookup(fs_volume *_volume, fs_vnode *_dir, const char *name, ino_t *_id)
|
||||
{
|
||||
struct rootfs *fs = (struct rootfs *)_volume->private_volume;
|
||||
struct rootfs_vnode *dir = (struct rootfs_vnode *)_dir->private_node;
|
||||
struct rootfs_vnode *vnode,*vdummy;
|
||||
struct rootfs_vnode *vnode;
|
||||
status_t status;
|
||||
|
||||
TRACE(("rootfs_lookup: entry dir %p, name '%s'\n", dir, name));
|
||||
@ -448,7 +447,7 @@ rootfs_lookup(fs_volume *_volume, fs_vnode *_dir, const char *name, ino_t *_id)
|
||||
goto err;
|
||||
}
|
||||
|
||||
status = get_vnode(fs->volume, vnode->id, (void**)&vdummy);
|
||||
status = get_vnode(fs->volume, vnode->id, NULL, NULL);
|
||||
if (status < B_OK)
|
||||
goto err;
|
||||
|
||||
|
@ -54,6 +54,7 @@
|
||||
|
||||
#include "fifo.h"
|
||||
#include "io_requests.h"
|
||||
#include "overlay.h"
|
||||
|
||||
|
||||
//#define TRACE_VFS
|
||||
@ -1180,6 +1181,9 @@ create_special_sub_node(struct vnode* vnode, uint32 flags)
|
||||
if (S_ISFIFO(vnode->type))
|
||||
return create_fifo_vnode(vnode->mount->volume, vnode);
|
||||
|
||||
if ((flags & B_VNODE_WANTS_OVERLAY_SUB_NODE) != 0)
|
||||
return create_overlay_vnode(vnode->mount->volume, vnode);
|
||||
|
||||
return B_BAD_VALUE;
|
||||
}
|
||||
|
||||
@ -1253,7 +1257,8 @@ restart:
|
||||
bool publishSpecialSubNode = false;
|
||||
if (gotNode) {
|
||||
vnode->type = type;
|
||||
publishSpecialSubNode = is_special_node_type(type)
|
||||
publishSpecialSubNode = (is_special_node_type(type)
|
||||
|| (flags & B_VNODE_WANTS_OVERLAY_SUB_NODE) != 0)
|
||||
&& (flags & B_VNODE_DONT_CREATE_SPECIAL_SUB_NODE) == 0;
|
||||
}
|
||||
|
||||
@ -2485,8 +2490,9 @@ get_vnode_name(struct vnode *vnode, struct vnode *parent, struct dirent *buffer,
|
||||
|
||||
if (HAS_FS_CALL(vnode, get_vnode_name)) {
|
||||
// The FS supports getting the name of a vnode.
|
||||
return FS_CALL(vnode, get_vnode_name, buffer->d_name,
|
||||
(char*)buffer + bufferSize - buffer->d_name);
|
||||
if (FS_CALL(vnode, get_vnode_name, buffer->d_name,
|
||||
(char*)buffer + bufferSize - buffer->d_name) == B_OK)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
// The FS doesn't support getting the name of a vnode. So we search the
|
||||
@ -3584,7 +3590,8 @@ publish_vnode(fs_volume *volume, ino_t vnodeID, void *privateNode,
|
||||
|
||||
|
||||
extern "C" status_t
|
||||
get_vnode(fs_volume *volume, ino_t vnodeID, void **_fsNode)
|
||||
get_vnode(fs_volume *volume, ino_t vnodeID, void **_privateNode,
|
||||
fs_vnode_ops **_vnodeOps)
|
||||
{
|
||||
struct vnode *vnode;
|
||||
|
||||
@ -3608,10 +3615,16 @@ get_vnode(fs_volume *volume, ino_t vnodeID, void **_fsNode)
|
||||
return status;
|
||||
}
|
||||
|
||||
if (_fsNode != NULL)
|
||||
*_fsNode = resolvedNode.private_node;
|
||||
} else if (_fsNode != NULL)
|
||||
*_fsNode = vnode->private_node;
|
||||
if (_privateNode != NULL)
|
||||
*_privateNode = resolvedNode.private_node;
|
||||
if (_vnodeOps != NULL)
|
||||
*_vnodeOps = resolvedNode.ops;
|
||||
} else {
|
||||
if (_privateNode != NULL)
|
||||
*_privateNode = vnode->private_node;
|
||||
if (_vnodeOps != NULL)
|
||||
*_vnodeOps = vnode->ops;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
@ -4005,7 +4018,7 @@ vfs_get_fs_node_from_path(fs_volume *volume, const char *path, bool kernel,
|
||||
}
|
||||
|
||||
// Use get_vnode() to resolve the cookie for the right layer.
|
||||
status = get_vnode(volume, vnode->id, _node);
|
||||
status = get_vnode(volume, vnode->id, _node, NULL);
|
||||
put_vnode(vnode);
|
||||
|
||||
return status;
|
||||
|
@ -401,14 +401,16 @@ synchronous_io(io_request* request, DoIO& io)
|
||||
status_t
|
||||
vfs_vnode_io(struct vnode* vnode, void* cookie, io_request* request)
|
||||
{
|
||||
if (!HAS_FS_CALL(vnode, io)) {
|
||||
status_t result = B_ERROR;
|
||||
if (!HAS_FS_CALL(vnode, io)
|
||||
|| (result = FS_CALL(vnode, io, cookie, request)) == B_UNSUPPORTED) {
|
||||
// no io() call -- fall back to synchronous I/O
|
||||
IOBuffer* buffer = request->Buffer();
|
||||
VnodeIO io(request->IsWrite(), buffer->IsPhysical(), vnode, cookie);
|
||||
return synchronous_io(request, io);
|
||||
}
|
||||
|
||||
return FS_CALL(vnode, io, cookie, request);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1985,7 +1985,8 @@ fssh_publish_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID,
|
||||
|
||||
|
||||
extern "C" fssh_status_t
|
||||
fssh_get_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID, void **fsNode)
|
||||
fssh_get_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID,
|
||||
void **privateNode, fssh_fs_vnode_ops **vnodeOps)
|
||||
{
|
||||
struct vnode *vnode;
|
||||
|
||||
@ -2009,9 +2010,16 @@ fssh_get_vnode(fssh_fs_volume *volume, fssh_vnode_id vnodeID, void **fsNode)
|
||||
return status;
|
||||
}
|
||||
|
||||
*fsNode = resolvedNode.private_node;
|
||||
} else
|
||||
*fsNode = vnode->private_node;
|
||||
if (privateNode != NULL)
|
||||
*privateNode = resolvedNode.private_node;
|
||||
if (vnodeOps != NULL)
|
||||
*vnodeOps = resolvedNode.ops;
|
||||
} else {
|
||||
if (privateNode != NULL)
|
||||
*privateNode = vnode->private_node;
|
||||
if (vnodeOps != NULL)
|
||||
*vnodeOps = vnode->ops;
|
||||
}
|
||||
|
||||
return FSSH_B_OK;
|
||||
}
|
||||
@ -2443,7 +2451,7 @@ vfs_get_fs_node_from_path(fssh_fs_volume *volume, const char *path, bool kernel,
|
||||
}
|
||||
|
||||
// Use get_vnode() to resolve the cookie for the right layer.
|
||||
status = ::fssh_get_vnode(volume, vnode->id, _node);
|
||||
status = ::fssh_get_vnode(volume, vnode->id, _node, NULL);
|
||||
put_vnode(vnode);
|
||||
|
||||
return FSSH_B_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user