From fd4f53a7a02495d3dfcd5b41d053aff41ca609e5 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sun, 22 Mar 2009 18:10:00 +0000 Subject: [PATCH] Implemented ReadSymlink() and Access(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29655 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../userlandfs/server/fuse/FUSEFileSystem.cpp | 58 +++++++++---------- .../userlandfs/server/fuse/FUSEVolume.cpp | 55 +++++++++++++++--- 2 files changed, 77 insertions(+), 36 deletions(-) diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEFileSystem.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEFileSystem.cpp index 8201f1af9d..09dd21f718 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEFileSystem.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEFileSystem.cpp @@ -341,10 +341,10 @@ FUSEFileSystem::_InitCapabilities() // fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_WRITE_FS_INFO, // fFS->ops.wfsstat); // fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_SYNC, fFS->ops.sync); -// + fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_GET_VNODE, true); // emulated -// + // // index directory & index operations // fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_OPEN_INDEX_DIR, // fFS->ops.open_indexdir); @@ -363,8 +363,8 @@ FUSEFileSystem::_InitCapabilities() // fFS->ops.remove_index); // fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_INDEX_STAT, // fFS->ops.stat_index); -// -// // query operations + + // query operations // fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_OPEN_QUERY, // fFS->ops.open_query); // fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_CLOSE_QUERY, @@ -374,8 +374,8 @@ FUSEFileSystem::_InitCapabilities() // fVolumeCapabilities.Set(FS_VOLUME_CAPABILITY_READ_QUERY, // fFS->ops.read_query); // // missing: FS_VOLUME_CAPABILITY_REWIND_QUERY, -// -// // vnode operations + + // vnode operations fNodeCapabilities.Set(FS_VNODE_CAPABILITY_LOOKUP, true); // emulated fNodeCapabilities.Set(FS_VNODE_CAPABILITY_GET_VNODE_NAME, true); @@ -385,41 +385,41 @@ FUSEFileSystem::_InitCapabilities() fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REMOVE_VNODE, true); // emulated -// // VM file access -// // missing: FS_VNODE_CAPABILITY_CAN_PAGE, -// // missing: FS_VNODE_CAPABILITY_READ_PAGES, -// // missing: FS_VNODE_CAPABILITY_WRITE_PAGES, -// -// // cache file access -// // missing: FS_VNODE_CAPABILITY_GET_FILE_MAP, -// -// // common operations + // VM file access + // missing: FS_VNODE_CAPABILITY_CAN_PAGE, + // missing: FS_VNODE_CAPABILITY_READ_PAGES, + // missing: FS_VNODE_CAPABILITY_WRITE_PAGES, + + // cache file access + // missing: FS_VNODE_CAPABILITY_GET_FILE_MAP, + + // common operations // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_IOCTL, fFS->ops.ioctl); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SET_FLAGS, fFS->ops.setflags); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_SELECT, fFS->ops.select); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_DESELECT, fFS->ops.deselect); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FSYNC, fFS->ops.fsync); -// -// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_SYMLINK, fFS->ops.readlink); + + fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_SYMLINK, fFS->ops.readlink); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_SYMLINK, fFS->ops.symlink); -// + // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_LINK, fFS->ops.link); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_UNLINK, fFS->ops.unlink); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_RENAME, fFS->ops.rename); -// -// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_ACCESS, fFS->ops.access); + + fNodeCapabilities.Set(FS_VNODE_CAPABILITY_ACCESS, fFS->ops.access); fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_STAT, fFS->ops.getattr); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE_STAT, fFS->ops.wstat); -// -// // file operations + + // file operations // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE, fFS->ops.create); fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN, fFS->ops.open); fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE, fFS->ops.flush); fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_COOKIE, fFS->ops.release); fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ, fFS->ops.read); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE, fFS->ops.write); -// -// // directory operations + + // directory operations // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CREATE_DIR, fFS->ops.mkdir); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REMOVE_DIR, fFS->ops.rmdir); bool readDirSupport = fFS->ops.opendir != NULL || fFS->ops.readdir != NULL @@ -430,8 +430,8 @@ FUSEFileSystem::_InitCapabilities() fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_DIR_COOKIE, readDirSupport); fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_DIR, readDirSupport); fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REWIND_DIR, readDirSupport); -// -// // attribute directory operations + + // attribute directory operations // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_ATTR_DIR, // fFS->ops.open_attrdir); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_CLOSE_ATTR_DIR, @@ -442,8 +442,8 @@ FUSEFileSystem::_InitCapabilities() // fFS->ops.read_attrdir); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REWIND_ATTR_DIR, // fFS->ops.rewind_attrdir); -// -// // attribute operations + + // attribute operations // // we emulate open_attr() and free_attr_dir_cookie() if either read_attr() // // or write_attr() is present // bool hasAttributes = (fFS->ops.read_attr || fFS->ops.write_attr); @@ -453,7 +453,7 @@ FUSEFileSystem::_InitCapabilities() // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_ATTR_COOKIE, hasAttributes); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR, fFS->ops.read_attr); // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE_ATTR, fFS->ops.write_attr); -// + // fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR_STAT, // fFS->ops.stat_attr); // // missing: FS_VNODE_CAPABILITY_WRITE_ATTR_STAT diff --git a/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.cpp b/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.cpp index 7f4353b4be..22f1d0f873 100644 --- a/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.cpp +++ b/src/add-ons/kernel/file_systems/userlandfs/server/fuse/FUSEVolume.cpp @@ -523,11 +523,35 @@ FUSEVolume::FSync(void* node) status_t -FUSEVolume::ReadSymlink(void* node, char* buffer, size_t bufferSize, - size_t* bytesRead) +FUSEVolume::ReadSymlink(void* _node, char* buffer, size_t bufferSize, + size_t* _bytesRead) { - // TODO: Implement! - return B_UNSUPPORTED; + FUSENode* node = (FUSENode*)_node; + + AutoLocker locker(fLock); + + // get a path for the node + char path[B_PATH_NAME_LENGTH]; + size_t pathLen; + status_t error = _BuildPath(node, path, pathLen); + if (error != B_OK) + RETURN_ERROR(error); + + locker.Unlock(); + + // read the symlink + int fuseError = fuse_fs_readlink(fFS, path, buffer, bufferSize); + if (fuseError != 0) { + *_bytesRead = 0; + return fuseError; + } + + // fuse_fs_readlink() is supposed to return a NULL-terminated string, which + // the Haiku interface doesn't require. We have to return the string length, + // though. + *_bytesRead = strnlen(buffer, bufferSize); + + return B_OK; } @@ -566,10 +590,27 @@ FUSEVolume::Rename(void* oldDir, const char* oldName, void* newDir, status_t -FUSEVolume::Access(void* node, int mode) +FUSEVolume::Access(void* _node, int mode) { - // TODO: Implement! - return B_UNSUPPORTED; + FUSENode* node = (FUSENode*)_node; + + AutoLocker locker(fLock); + + // get a path for the node + char path[B_PATH_NAME_LENGTH]; + size_t pathLen; + status_t error = _BuildPath(node, path, pathLen); + if (error != B_OK) + RETURN_ERROR(error); + + locker.Unlock(); + + // call the access hook on the path + int fuseError = fuse_fs_access(fFS, path, mode); + if (fuseError != 0) + return fuseError; + + return B_OK; }