Thread (38 messages) 38 messages, 6 authors, 2021-06-24

Re: any idea about auto export multiple btrfs snapshots?

From: Wang Yugui <hidden>
Date: 2021-06-16 05:47:11

Hi,
Hi, NeilBrown
quoted
On Sun, 13 Jun 2021, Wang Yugui wrote:
quoted
Hi,

Any idea about auto export multiple btrfs snapshots?

One related patch is yet not merged to nfs-utils 2.5.3.
From:   "NeilBrown" <redacted>
Subject: [PATCH/RFC v2 nfs-utils] Fix NFSv4 export of tmpfs filesystems.

In this patch, an UUID is auto generated when a tmpfs have no UUID.

for btrfs, multiple subvolume snapshot have the same filesystem UUID.
Could we generate an UUID for btrfs subvol with 'filesystem UUID' + 'subvol ID'?
You really need to ask this question of btrfs developers.  'mountd'
already has a special-case exception for btrfs, to prefer the uuid
provided by statfs64() rather than the uuid extracted from the block
device.  It would be quite easy to add another exception.
But it would only be reasonable to do that if the btrfs team told us how
that wanted us to generate a UUID for a given mount point, and promised
that would always provide a unique stable result.
This is completely separate from the tmpfs patch you identified.
Thanks a lot for the replay.

Now btrfs statfs64() return 8 byte unique/stable result.

It is based on two parts.
1) 16 byte blkid of file system. this is uniq/stable between btrfs filesystems.
2) 8 byte of btrfs sub volume objectid. this is uniq/stable inside a
btrfs filesystem.

the code of linux/fs/btrfs
static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)

    /* We treat it as constant endianness (it doesn't matter _which_)
       because we want the fsid to come out the same whether mounted
       on a big-endian or little-endian host */
    buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]);
    buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]);
    /* Mask in the root object ID too, to disambiguate subvols */
    buf->f_fsid.val[0] ^=
        BTRFS_I(d_inode(dentry))->root->root_key.objectid >> 32;
    buf->f_fsid.val[1] ^=
        BTRFS_I(d_inode(dentry))->root->root_key.objectid;


for nfs, we need a 16 byte UUID now.

The best way I though:
16 byte blkid , math add 8 byte btrfs sub volume objectid.
but there is yet no a simple/easy way to get the raw value of 'btrfs sub
volume objectid'.
The btrfs subvol objectid (8byte) can be extracted from the
statfs.f_fsid(8 byte) with the help of blkid(16btye) of the btrfs file
system just do a revert cacl in btrfs_statfs().

if we need 8 byte id for btrfs subvol, just use statfs.f_fsid.

if we need 16 byte id for btrfs subvol, use the blkid(16btye) of the
btrfs filesystem, plus the btrfs subvol objectid (8byte) , and keep 
the result in 16 byte.

Best Regards
Wang Yugui (wangyugui@e16-tech.com)
2021/06/16


A simple but good enough way:
1) first 8 byte copy from blkid
2) second 8 byte copy from btrfs_statfs()
	the uniq/stable of multiple subvolume inside a btrfs filesystem is kept.

Best Regards
Wang Yugui (wangyugui@e16-tech.com)
2021/06/15
  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help