userlandfs_fuse_lowlevel: fix opening directories in Tracker
- It is possible to call open() on a directory, but FUSE lowlevel filesystems don't implement that and expect it to be re-routed to the opendir call. BRoster uses this to read the dir/file attributes to identify it, so it could not identify directories properly. - In ReadDir, make sure to not return more entries than asked, as this confuses the userlandfs protocol communication (the kernel does not acknowledge the readdir reply, and then the server hits an assert when receiving the next request instead of the ack). Change-Id: I9c4e9a3f0fc6e9879d4cfbc0d5402a4733d2218a Reviewed-on: https://review.haiku-os.org/c/haiku/+/5482 Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org> Reviewed-by: waddlesplash <waddlesplash@gmail.com>
This commit is contained in:
parent
03f7a1848f
commit
f0ee02b25e
@ -38,7 +38,7 @@ enum {
|
||||
SYNC_VOLUME_REQUEST,
|
||||
SYNC_VOLUME_REPLY,
|
||||
READ_FS_INFO_REQUEST,
|
||||
READ_FS_INFO_REPLY,
|
||||
READ_FS_INFO_REPLY, // 10
|
||||
WRITE_FS_INFO_REQUEST,
|
||||
WRITE_FS_INFO_REPLY,
|
||||
|
||||
@ -50,7 +50,7 @@ enum {
|
||||
READ_VNODE_REQUEST,
|
||||
READ_VNODE_REPLY,
|
||||
WRITE_VNODE_REQUEST,
|
||||
WRITE_VNODE_REPLY,
|
||||
WRITE_VNODE_REPLY, // 20
|
||||
FS_REMOVE_VNODE_REQUEST,
|
||||
FS_REMOVE_VNODE_REPLY,
|
||||
|
||||
@ -62,7 +62,7 @@ enum {
|
||||
ITERATIVE_IO_GET_VECS_REQUEST,
|
||||
ITERATIVE_IO_GET_VECS_REPLY,
|
||||
ITERATIVE_IO_FINISHED_REQUEST,
|
||||
ITERATIVE_IO_FINISHED_REPLY,
|
||||
ITERATIVE_IO_FINISHED_REPLY, // 30
|
||||
|
||||
// nodes
|
||||
IOCTL_REQUEST,
|
||||
@ -74,7 +74,7 @@ enum {
|
||||
DESELECT_REQUEST,
|
||||
DESELECT_REPLY,
|
||||
FSYNC_REQUEST,
|
||||
FSYNC_REPLY,
|
||||
FSYNC_REPLY, // 40
|
||||
|
||||
READ_SYMLINK_REQUEST,
|
||||
READ_SYMLINK_REPLY,
|
||||
@ -85,7 +85,7 @@ enum {
|
||||
UNLINK_REQUEST,
|
||||
UNLINK_REPLY,
|
||||
RENAME_REQUEST,
|
||||
RENAME_REPLY,
|
||||
RENAME_REPLY, // 50
|
||||
|
||||
ACCESS_REQUEST,
|
||||
ACCESS_REPLY,
|
||||
@ -98,7 +98,7 @@ enum {
|
||||
CREATE_REQUEST,
|
||||
CREATE_REPLY,
|
||||
OPEN_REQUEST,
|
||||
OPEN_REPLY,
|
||||
OPEN_REPLY, // 60
|
||||
CLOSE_REQUEST,
|
||||
CLOSE_REPLY,
|
||||
FREE_COOKIE_REQUEST,
|
||||
@ -110,7 +110,7 @@ enum {
|
||||
|
||||
// directories
|
||||
CREATE_DIR_REQUEST,
|
||||
CREATE_DIR_REPLY,
|
||||
CREATE_DIR_REPLY, // 70
|
||||
REMOVE_DIR_REQUEST,
|
||||
REMOVE_DIR_REPLY,
|
||||
OPEN_DIR_REQUEST,
|
||||
@ -120,7 +120,7 @@ enum {
|
||||
FREE_DIR_COOKIE_REQUEST,
|
||||
FREE_DIR_COOKIE_REPLY,
|
||||
READ_DIR_REQUEST,
|
||||
READ_DIR_REPLY,
|
||||
READ_DIR_REPLY, // 80
|
||||
REWIND_DIR_REQUEST,
|
||||
REWIND_DIR_REPLY,
|
||||
|
||||
@ -132,7 +132,7 @@ enum {
|
||||
FREE_ATTR_DIR_COOKIE_REQUEST,
|
||||
FREE_ATTR_DIR_COOKIE_REPLY,
|
||||
READ_ATTR_DIR_REQUEST,
|
||||
READ_ATTR_DIR_REPLY,
|
||||
READ_ATTR_DIR_REPLY, // 90
|
||||
REWIND_ATTR_DIR_REQUEST,
|
||||
REWIND_ATTR_DIR_REPLY,
|
||||
|
||||
@ -144,7 +144,7 @@ enum {
|
||||
CLOSE_ATTR_REQUEST,
|
||||
CLOSE_ATTR_REPLY,
|
||||
FREE_ATTR_COOKIE_REQUEST,
|
||||
FREE_ATTR_COOKIE_REPLY,
|
||||
FREE_ATTR_COOKIE_REPLY, // 100
|
||||
READ_ATTR_REQUEST,
|
||||
READ_ATTR_REPLY,
|
||||
WRITE_ATTR_REQUEST,
|
||||
@ -154,7 +154,7 @@ enum {
|
||||
WRITE_ATTR_STAT_REQUEST,
|
||||
WRITE_ATTR_STAT_REPLY,
|
||||
RENAME_ATTR_REQUEST,
|
||||
RENAME_ATTR_REPLY,
|
||||
RENAME_ATTR_REPLY, // 110
|
||||
REMOVE_ATTR_REQUEST,
|
||||
REMOVE_ATTR_REPLY,
|
||||
|
||||
@ -166,7 +166,7 @@ enum {
|
||||
FREE_INDEX_DIR_COOKIE_REQUEST,
|
||||
FREE_INDEX_DIR_COOKIE_REPLY,
|
||||
READ_INDEX_DIR_REQUEST,
|
||||
READ_INDEX_DIR_REPLY,
|
||||
READ_INDEX_DIR_REPLY, // 120
|
||||
REWIND_INDEX_DIR_REQUEST,
|
||||
REWIND_INDEX_DIR_REPLY,
|
||||
CREATE_INDEX_REQUEST,
|
||||
@ -178,7 +178,7 @@ enum {
|
||||
|
||||
// queries
|
||||
OPEN_QUERY_REQUEST,
|
||||
OPEN_QUERY_REPLY,
|
||||
OPEN_QUERY_REPLY, // 130
|
||||
CLOSE_QUERY_REQUEST,
|
||||
CLOSE_QUERY_REPLY,
|
||||
FREE_QUERY_COOKIE_REQUEST,
|
||||
@ -190,7 +190,7 @@ enum {
|
||||
|
||||
// node monitoring
|
||||
NODE_MONITORING_EVENT_REQUEST,
|
||||
NODE_MONITORING_EVENT_REPLY,
|
||||
NODE_MONITORING_EVENT_REPLY, // 140
|
||||
|
||||
// userland -> kernel requests
|
||||
// notifications
|
||||
@ -205,7 +205,7 @@ enum {
|
||||
GET_VNODE_REQUEST,
|
||||
GET_VNODE_REPLY,
|
||||
PUT_VNODE_REQUEST,
|
||||
PUT_VNODE_REPLY,
|
||||
PUT_VNODE_REPLY, // 150
|
||||
ACQUIRE_VNODE_REQUEST,
|
||||
ACQUIRE_VNODE_REPLY,
|
||||
NEW_VNODE_REQUEST,
|
||||
@ -215,7 +215,7 @@ enum {
|
||||
REMOVE_VNODE_REQUEST,
|
||||
REMOVE_VNODE_REPLY,
|
||||
UNREMOVE_VNODE_REQUEST,
|
||||
UNREMOVE_VNODE_REPLY,
|
||||
UNREMOVE_VNODE_REPLY, // 160
|
||||
GET_VNODE_REMOVED_REQUEST,
|
||||
GET_VNODE_REMOVED_REPLY,
|
||||
|
||||
@ -227,7 +227,7 @@ enum {
|
||||
FILE_CACHE_SET_ENABLED_REQUEST,
|
||||
FILE_CACHE_SET_ENABLED_REPLY,
|
||||
FILE_CACHE_SET_SIZE_REQUEST,
|
||||
FILE_CACHE_SET_SIZE_REPLY,
|
||||
FILE_CACHE_SET_SIZE_REPLY, // 170
|
||||
FILE_CACHE_SYNC_REQUEST,
|
||||
FILE_CACHE_SYNC_REPLY,
|
||||
FILE_CACHE_READ_REQUEST,
|
||||
@ -239,7 +239,7 @@ enum {
|
||||
DO_ITERATIVE_FD_IO_REQUEST,
|
||||
DO_ITERATIVE_FD_IO_REPLY,
|
||||
READ_FROM_IO_REQUEST_REQUEST,
|
||||
READ_FROM_IO_REQUEST_REPLY,
|
||||
READ_FROM_IO_REQUEST_REPLY, // 180
|
||||
WRITE_TO_IO_REQUEST_REQUEST,
|
||||
WRITE_TO_IO_REQUEST_REPLY,
|
||||
NOTIFY_IO_REQUEST_REQUEST,
|
||||
@ -255,7 +255,7 @@ enum {
|
||||
RECEIPT_ACK_REPLY,
|
||||
|
||||
// invalid request ID (e.g. for request handlers)
|
||||
NO_REQUEST,
|
||||
NO_REQUEST, // 190
|
||||
};
|
||||
|
||||
namespace UserlandFSUtil {
|
||||
|
@ -506,8 +506,7 @@ FUSEFileSystem::_InitCapabilities()
|
||||
bool hasAttributes = fLowLevelOps.listxattr != NULL;
|
||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_OPEN_ATTR_DIR, hasAttributes);
|
||||
// not needed: FS_VNODE_CAPABILITY_CLOSE_ATTR_DIR
|
||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_ATTR_DIR_COOKIE,
|
||||
hasAttributes);
|
||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_FREE_ATTR_DIR_COOKIE, hasAttributes);
|
||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR_DIR, hasAttributes);
|
||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_REWIND_ATTR_DIR, hasAttributes);
|
||||
|
||||
@ -521,8 +520,7 @@ FUSEFileSystem::_InitCapabilities()
|
||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR, fLowLevelOps.getxattr);
|
||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_WRITE_ATTR, fLowLevelOps.write_attr);
|
||||
|
||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR_STAT,
|
||||
fLowLevelOps.getxattr);
|
||||
fNodeCapabilities.Set(FS_VNODE_CAPABILITY_READ_ATTR_STAT, fLowLevelOps.getxattr);
|
||||
// // missing: FS_VNODE_CAPABILITY_WRITE_ATTR_STAT
|
||||
// fNodeCapabilities.Set(FS_VNODE_CAPABILITY_RENAME_ATTR, fLowLevelOps.rename_attr);
|
||||
} else {
|
||||
|
@ -1654,12 +1654,14 @@ FUSEVolume::Open(void* _node, int openMode, void** _cookie)
|
||||
size_t pathLen;
|
||||
|
||||
int fuseError;
|
||||
struct fuse_file_info llCookie;
|
||||
struct fuse_file_info llCookie = { 0 };
|
||||
// FIXME store this in the FileCookie for lowlevel streams, we'll need it in read, write...
|
||||
if (fOps != NULL) {
|
||||
llCookie.flags = openMode;
|
||||
// TODO do we need to perform a conversion here?
|
||||
fuseError = fuse_ll_open(fOps, node->id, &llCookie);
|
||||
if (S_ISDIR(node->type))
|
||||
fuseError = fuse_ll_opendir(fOps, node->id, &llCookie);
|
||||
else
|
||||
fuseError = fuse_ll_open(fOps, node->id, &llCookie);
|
||||
} else {
|
||||
AutoLocker<Locker> locker(fLock);
|
||||
|
||||
@ -2154,8 +2156,8 @@ FUSEVolume::ReadDir(void* _node, void* _cookie, void* buffer, size_t bufferSize,
|
||||
// currentEntryOffset.
|
||||
if (fuseError > 0) {
|
||||
struct dirent* dirent = (struct dirent*)buffer;
|
||||
countRead = 0;
|
||||
while ((char*)dirent + dirent->d_reclen <= (char*)buffer + fuseError) {
|
||||
while (countRead < count
|
||||
&& (char*)dirent + dirent->d_reclen <= (char*)buffer + fuseError) {
|
||||
countRead++;
|
||||
dirent = (struct dirent*)(((char*)dirent) + dirent->d_reclen);
|
||||
if (dirent->d_reclen == 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user