diff options
author | Misono Tomohiro | 2020-02-27 06:59:27 +0100 |
---|---|---|
committer | Dr. David Alan Gilbert | 2020-03-03 16:13:24 +0100 |
commit | bdfd66788349acc43cd3f1298718ad491663cfcc (patch) | |
tree | b434c62919409565efd51d4840291abed6150857 /tools/virtiofsd/fuse_virtio.c | |
parent | virtiofsd: passthrough_ll: cleanup getxattr/listxattr (diff) | |
download | qemu-bdfd66788349acc43cd3f1298718ad491663cfcc.tar.gz qemu-bdfd66788349acc43cd3f1298718ad491663cfcc.tar.xz qemu-bdfd66788349acc43cd3f1298718ad491663cfcc.zip |
virtiofsd: Fix xattr operations
Current virtiofsd has problems about xattr operations and
they does not work properly for directory/symlink/special file.
The fundamental cause is that virtiofsd uses openat() + f...xattr()
systemcalls for xattr operation but we should not open symlink/special
file in the daemon. Therefore the function is restricted.
Fix this problem by:
1. during setup of each thread, call unshare(CLONE_FS)
2. in xattr operations (i.e. lo_getxattr), if inode is not a regular
file or directory, use fchdir(proc_loot_fd) + ...xattr() +
fchdir(root.fd) instead of openat() + f...xattr()
(Note: for a regular file/directory openat() + f...xattr()
is still used for performance reason)
With this patch, xfstests generic/062 passes on virtiofs.
This fix is suggested by Miklos Szeredi and Stefan Hajnoczi.
The original discussion can be found here:
https://www.redhat.com/archives/virtio-fs/2019-October/msg00046.html
Signed-off-by: Misono Tomohiro <misono.tomohiro@jp.fujitsu.com>
Message-Id: <20200227055927.24566-3-misono.tomohiro@jp.fujitsu.com>
Acked-by: Vivek Goyal <vgoyal@redhat.com>
Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Diffstat (limited to 'tools/virtiofsd/fuse_virtio.c')
-rw-r--r-- | tools/virtiofsd/fuse_virtio.c | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/tools/virtiofsd/fuse_virtio.c b/tools/virtiofsd/fuse_virtio.c index dd1c605dbf..3b6d16a041 100644 --- a/tools/virtiofsd/fuse_virtio.c +++ b/tools/virtiofsd/fuse_virtio.c @@ -426,6 +426,8 @@ err: return ret; } +static __thread bool clone_fs_called; + /* Process one FVRequest in a thread pool */ static void fv_queue_worker(gpointer data, gpointer user_data) { @@ -441,6 +443,17 @@ static void fv_queue_worker(gpointer data, gpointer user_data) assert(se->bufsize > sizeof(struct fuse_in_header)); + if (!clone_fs_called) { + int ret; + + /* unshare FS for xattr operation */ + ret = unshare(CLONE_FS); + /* should not fail */ + assert(ret == 0); + + clone_fs_called = true; + } + /* * An element contains one request and the space to send our response * They're spread over multiple descriptors in a scatter/gather set |