Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to mount btrfs filesystems spread across more than one partition with lklfuse #518

Open
bqv opened this issue Apr 11, 2023 · 6 comments
Assignees

Comments

@bqv
Copy link

bqv commented Apr 11, 2023

My example has three partitions. Passing partition 1 gives "BTRFS error (device vda1): devid 2 uuid is missing". Similar for partitions 2 and 3, but "devid 1".

All these devices are on one physical disk, but passing the full disk to lklfuse obviously won't work, and I'm having trouble how to wrangle the code to find that agreeable

@tavip
Copy link
Member

tavip commented Apr 11, 2023

This requires support for adding multiple disks. Then using the physical disk and multiple partitions should work. I’ll look into more details at this tomorrow.

Could you please share instructions on how to get btrfs split across multiple partitions?

@tavip tavip self-assigned this Apr 11, 2023
@bqv
Copy link
Author

bqv commented Apr 11, 2023

Assuming you have btrfsprogs, with an existing btrfs filesystem mounted at /mnt, you can add a new device as-is with btrfs device add /dev/<blk> /mnt

Thanks!

@bqv
Copy link
Author

bqv commented Jun 16, 2023

Is there a plan for implementing this?

@ddiss
Copy link

ddiss commented May 31, 2024

One option for adding devices to an existing lklfuse process at runtime is a FUSE xattr hack, e.g.:

setfattr -n lklfuse.dev.add -v /dev/sdX /mnt/

It might then also be possible to forward BTRFS_IOC_ADD_DEV ioctls through to the underlying LKL mount via a FUSE ioctl hook.

@MathewKing
Copy link

I have been experimenting with lkl and btrfs and I found that the btrfs command uses ioctl to interact with the btrfs file system. In its current state the btrfs command does not recognize a lklfuse mounted btrfs volume. I created a modified version of btrfs from here https://github.com/kdave/btrfs-progs to allow sending ioctl to the lklfuse filesystem.

From there I discovered that lklfuse does not implement ioctl. I thought that there might be a simple way to implement .ioctl in lklfuse_ops. From what I can tell there is a complication because ioctl from fuse uses 2 pointers void *arg for ioctl data from the user and void *data for ioctl data to the user but the internal call sys_ioctl uses a single pointer and the ioctl implementation will use copy_from_user() and copy_to_user().

I think that ioctl in lklfuse can be achieved by implementing raw_copy_from_user() and raw_copy_to_user() in arch/lkl. New lkl functions will need to be implemented to map the *arg and *data pointers together so when raw_copy_from_user is called, data is read from *arg and when raw_copy_to_user is called, data is written to *data.

I am not an expert on fuse or the kernel so I may be missing something. I am going to try and get ioctl working in lklfuse well enough that btrfs filesystem usage works and if I do I will post a pull request.

@MathewKing
Copy link

I haven't had time to look into this much recently but I want to provide a quick update.

I did finally get ioctl to start to work with lklfuse. My initial assessment of needing 2 pointers was incorrect; only the *data pointer is needed. I haven't dug into the *arg pointer but I was able to get ioctl working without it.

I then ran into an issue where lkl stored a file handle directly in the fh field of fuse_file_info when opening files but a pointer to lkl_dir when opening a directory. I have a very crude fix for that and I have attached that patch, 0001-Crude-ioctl-support-for-lklfuse.patch. With this patch I was able to get some btrfs commands to work on an lklfuse mounted filesystem, for example I could run btrfs fi us without errors. However when I would run btrfs fi du I would get an 'Operation not supported' error.

I dug into this a little bit but I did not get very far. Essentially there is an ioctl command, FS_IOC_FIEMAP, that is not supported by fuse in the kernel. There has been some effort to get it supported but it hasn't seemed to go anywhere, see libfuse/libfuse#72.

To get this to work on the btrfs-progs side I just made the following change for testing purposes.

diff --git a/common/open-utils.c b/common/open-utils.c
index 8490be4a..448f3154 100644
--- a/common/open-utils.c
+++ b/common/open-utils.c
@@ -209,7 +209,7 @@ int btrfs_open_path(const char *path, bool read_write, bool dir_only)
                return -errno;
        }
 
-       if (stfs.f_type != BTRFS_SUPER_MAGIC) {
+       if (stfs.f_type != FUSE_SUPER_MAGIC) {
                error("not a btrfs filesystem: %s", path);
                return -EINVAL;
        }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants