Re: any idea about auto export multiple btrfs snapshots?

Wang Yugui
2021-06-15T15:13:22Z

Hi, NeilBrown

> On Sun, 13 Jun 2021, Wang Yugui wrote:
> > Hi,
> >
> > Any idea about auto export multiple btrfs snapshots?
> >
> > One related patch is yet not merged to nfs-utils 2.5.3.
> > From: "NeilBrown" <neilb@suse.de>
> > 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.

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