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-15 15:41:08

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'.

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.
By the way, the random 16 byte UUID still have very little chance to
conflict.

Could we keep the first 4 byte of the UUID of nfs/tmpfs alwasy ZERO?  ,
the first 4 byte zero will limit the conflict inside nfs/tmpfs, and it is
easy to diag.

Here we use the first same 8 byte for UUID of btrfs and nfs/btrfs, 
so it is easy to diag too.

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