From: Wang Yugui <wangyugui@e16-tech.com>
To: "NeilBrown" <neilb@suse.de>
Cc: linux-nfs@vger.kernel.org
Subject: Re: any idea about auto export multiple btrfs snapshots?
Date: Mon, 21 Jun 2021 16:34:41 +0800 [thread overview]
Message-ID: <20210621163441.428C.409509F4@e16-tech.com> (raw)
In-Reply-To: <162425240757.17441.3695249639927377778@noble.neil.brown.name>
[-- Attachment #1: Type: text/plain, Size: 1065 bytes --]
Hi,
> > > It seems more fixes are needed.
> >
> > I think the problem is that the submount doesn't appear in /proc/mounts.
> > "nfsd_fh()" in nfs-utils needs to be able to map from the uuid for a
> > filesystem to the mount point. To do this it walks through /proc/mounts
> > checking the uuid of each filesystem. If a filesystem isn't listed
> > there, it obviously fails.
> >
> > I guess you could add code to nfs-utils to do whatever "btrfs subvol
> > list" does to make up for the fact that btrfs doesn't register in
> > /proc/mounts.
>
> Another approach might be to just change svcxdr_encode_fattr3() and
> nfsd4_encode_fattr() in the 'FSIDSOJURCE_UUID' case to check if
> dentry->d_inode has a different btrfs volume id to
> exp->ex_path.dentry->d_inode.
> If it does, then mix the volume id into the fsid somehow.
>
> With that, you wouldn't want the first change I suggested.
This is what I have done. and it is based on linux 5.10.44
but it still not work, so still more jobs needed.
Best Regards
Wang Yugui (wangyugui@e16-tech.com)
2021/06/21
[-- Attachment #2: 0001-nfsd-btrfs-subvol-support.patch --]
[-- Type: application/octet-stream, Size: 4741 bytes --]
From 57e6b3cec9b8ac396b661c190511af80839ddbe5 Mon Sep 17 00:00:00 2001
From: wangyugui <wangyugui@e16-tech.com>
Date: Thu, 17 Jun 2021 08:33:06 +0800
Subject: [PATCH] nfsd: btrfs subvol support
(struct statfs).f_fsid: uniq between btrfs subvols
(struct stat).st_dev: uniq between btrfs subvols
(struct statx).stx_mnt_id: NOT uniq between btrfs subvols, but yet not used in nfs/nfsd
kernel samples/vfs/test-statx.c
stx_rdev_major/stx_rdev_minor seems be truncated by something
like old_encode_dev()/old_decode_dev()?
TODO: (struct nfs_fattr).fsid
TODO: FSIDSOURCE_FSID in nfs3xdr.c/nfsxdr.c
---
fs/namei.c | 2 ++
fs/nfsd/nfs3xdr.c | 2 +-
fs/nfsd/nfs4xdr.c | 10 ++++++++--
fs/nfsd/vfs.c | 6 ++++++
include/linux/fs.h | 13 +++++++++++++
5 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/fs/namei.c b/fs/namei.c
index fe132e3..6974a95 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1105,6 +1105,8 @@ int follow_up(struct path *path)
struct mount *parent;
struct dentry *mountpoint;
+ if(unlikely(d_is_btrfs_subvol(path->dentry)))
+ return 0;
read_seqlock_excl(&mount_lock);
parent = mnt->mnt_parent;
if (parent == mnt) {
diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c
index 716566d..45666b3 100644
--- a/fs/nfsd/nfs3xdr.c
+++ b/fs/nfsd/nfs3xdr.c
@@ -877,7 +877,7 @@ compose_entry_fh(struct nfsd3_readdirres *cd, struct svc_fh *fhp,
dchild = lookup_positive_unlocked(name, dparent, namlen);
if (IS_ERR(dchild))
return rv;
- if (d_mountpoint(dchild))
+ if (d_mountpoint(dchild) || unlikely(d_is_btrfs_subvol(dchild)))
goto out;
if (dchild->d_inode->i_ino != ino)
goto out;
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 5f5169b..939d095 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -2728,6 +2728,7 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
.dentry = dentry,
};
struct nfsd_net *nn = net_generic(SVC_NET(rqstp), nfsd_net_id);
+ bool is_btrfs_subvol= d_is_btrfs_subvol(dentry);
BUG_ON(bmval1 & NFSD_WRITEONLY_ATTRS_WORD1);
BUG_ON(!nfsd_attrs_supported(minorversion, bmval));
@@ -2744,7 +2745,8 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
if ((bmval0 & (FATTR4_WORD0_FILES_AVAIL | FATTR4_WORD0_FILES_FREE |
FATTR4_WORD0_FILES_TOTAL | FATTR4_WORD0_MAXNAME)) ||
(bmval1 & (FATTR4_WORD1_SPACE_AVAIL | FATTR4_WORD1_SPACE_FREE |
- FATTR4_WORD1_SPACE_TOTAL))) {
+ FATTR4_WORD1_SPACE_TOTAL)) ||
+ unlikely(is_btrfs_subvol)) {
err = vfs_statfs(&path, &statfs);
if (err)
goto out_nfserr;
@@ -2885,7 +2887,11 @@ nfsd4_encode_fattr(struct xdr_stream *xdr, struct svc_fh *fhp,
p = xdr_encode_hyper(p, NFS4_REFERRAL_FSID_MINOR);
} else switch(fsid_source(fhp)) {
case FSIDSOURCE_FSID:
- p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
+ if (unlikely(is_btrfs_subvol)){
+ *p++ = cpu_to_be32(statfs.f_fsid.val[0]);
+ *p++ = cpu_to_be32(statfs.f_fsid.val[1]);
+ } else
+ p = xdr_encode_hyper(p, (u64)exp->ex_fsid);
p = xdr_encode_hyper(p, (u64)0);
break;
case FSIDSOURCE_DEV:
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index 1ecacee..ae34ffc 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -68,6 +68,10 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
err = follow_down(&path);
if (err < 0)
goto out;
+ if (unlikely(d_is_btrfs_subvol(dentry))){
+ path_put(&path);
+ goto out;
+ } else
if (path.mnt == exp->ex_path.mnt && path.dentry == dentry &&
nfsd_mountpoint(dentry, exp) == 2) {
/* This is only a mountpoint in some other namespace */
@@ -160,6 +164,8 @@ int nfsd_mountpoint(struct dentry *dentry, struct svc_export *exp)
return 1;
if (nfsd4_is_junction(dentry))
return 1;
+ if (d_is_btrfs_subvol(dentry))
+ return 1;
if (d_mountpoint(dentry))
/*
* Might only be a mountpoint in a different namespace,
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8bde32c..b0d52e9 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -3399,6 +3399,19 @@ static inline bool is_root_inode(struct inode *inode)
return inode == inode->i_sb->s_root->d_inode;
}
+/*
+ * same logical as fs/btrfs is_subvolume_inode(struct inode *inode)
+ * #define BTRFS_FIRST_FREE_OBJECTID 256ULL
+ * #define BTRFS_SUPER_MAGIC 0x9123683E
+ */
+static inline bool d_is_btrfs_subvol(const struct dentry *dentry)
+{
+ bool ret = dentry->d_inode && unlikely(dentry->d_inode->i_ino == 256ULL) &&
+ dentry->d_sb && dentry->d_sb->s_magic == 0x9123683E;
+ //printk(KERN_INFO "d_is_btrfs_subvol(%s)=%d\n", dentry->d_name.name, ret);
+ return ret;
+}
+
static inline bool dir_emit(struct dir_context *ctx,
const char *name, int namelen,
u64 ino, unsigned type)
--
2.30.2
[-- Attachment #3: 0002-trace-nfsd-btrfs-subvol-support.txt --]
[-- Type: application/octet-stream, Size: 3431 bytes --]
From 6e709554e4c7d5efd3b030fc08b6e6493879a025 Mon Sep 17 00:00:00 2001
From: wangyugui <wangyugui@e16-tech.com>
Date: Thu, 17 Jun 2021 08:33:06 +0800
Subject: [PATCH] trace nfsd: btrfs subvol support
[ 268.994169] follow_down(xfs2)=0
[ 268.997405] nfsd_cross_mnt(xfs2)=0
*[ 269.000840] nfsd4_encode_dirent_fattr(/) ignore_crossmnt=0
why /
*[ 269.006477] nfs_d_automount(xfs2)
why not happen when btrfs subvol
[ 269.009892] follow_down(xfs2)=0
[ 269.013055] nfsd_cross_mnt(xfs2)=0
[ 483.037221] follow_down(sub1)=0
[ 483.040428] nfsd_cross_mnt(sub1)=0
[ 483.043855] nfsd4_encode_dirent_fattr(sub1) ignore_crossmnt=0
[ 483.049635] nfsd4_encode_dirent_fattr(.snapshot) ignore_crossmnt=0
[ 483.055847] nfsd4_encode_dirent_fattr(dir1) ignore_crossmnt=0
[ 483.062669] follow_down(sub2)=0
[ 483.066800] nfsd_cross_mnt(sub2)=0
btrfs subvols =>force crossmnt
subvol nfs/umount: os shutdonw or manual nfs/umount?
special status(BTRFS_LAST_FREE_OBJECTID,only return to nfs)?
#define BTRFS_LAST_FREE_OBJECTID -256ULL
(struct file )->(struct inode *f_inode)->(struct super_block *i_sb;)->(unsigned long s_magic)
btrfs->xfs =>still need crossmnt
xfs->btrfs =>still need crossmnt
NFSEXP_CROSSMOUNT
NFSD_JUNCTION_XATTR_NAME
AT_NO_AUTOMOUNT
NFS_ATTR_FATTR_MOUNTPOINT
S_AUTOMOUNT
---
fs/nfs/dir.c | 2 ++
fs/nfs/namespace.c | 1 +
fs/nfsd/nfs4xdr.c | 3 +++
fs/nfsd/vfs.c | 1 +
4 files changed, 7 insertions(+)
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index c837675..975440d 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -1799,6 +1799,8 @@ nfs4_do_lookup_revalidate(struct inode *dir, struct dentry *dentry,
if (!(flags & LOOKUP_OPEN) || (flags & LOOKUP_DIRECTORY))
goto full_reval;
+ if (dentry->d_inode && dentry->d_inode->i_ino == 256ULL && dentry->d_sb)
+ printk(KERN_INFO "nfs4_do_lookup_revalidate(%s)=%lx\n", dentry->d_name.name, dentry->d_sb->s_magic);
if (d_mountpoint(dentry))
goto full_reval;
diff --git a/fs/nfs/namespace.c b/fs/nfs/namespace.c
index 2bcbe38..f69715c 100644
--- a/fs/nfs/namespace.c
+++ b/fs/nfs/namespace.c
@@ -152,6 +152,7 @@ struct vfsmount *nfs_d_automount(struct path *path)
int timeout = READ_ONCE(nfs_mountpoint_expiry_timeout);
int ret;
+ printk(KERN_INFO "nfs_d_automount(%s)\n", path->dentry->d_name.name);
if (IS_ROOT(path->dentry))
return ERR_PTR(-ESTALE);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 939d095..cb5b328 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3316,6 +3316,8 @@ nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
*/
if (nfsd_mountpoint(dentry, exp)) {
int err;
+ // if(d_is_btrfs_subvol(dentry))
+ // cd->rd_bmval[1] |= FATTR4_WORD1_MOUNTED_ON_FILEID;
if (!(exp->ex_flags & NFSEXP_V4ROOT)
&& !attributes_need_mount(cd->rd_bmval)) {
@@ -3343,6 +3345,7 @@ nfsd4_encode_dirent_fattr(struct xdr_stream *xdr, struct nfsd4_readdir *cd,
out_put:
dput(dentry);
exp_put(exp);
+ printk(KERN_INFO "nfsd4_encode_dirent_fattr(%s) ignore_crossmnt=%d\n", dentry->d_name.name, ignore_crossmnt);
return nfserr;
}
diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
index ae34ffc..c12a394 100644
--- a/fs/nfsd/vfs.c
+++ b/fs/nfsd/vfs.c
@@ -111,6 +111,7 @@ nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
path_put(&path);
exp_put(exp2);
out:
+ printk(KERN_INFO "nfsd_cross_mnt(%s)=%d\n", dentry->d_name.name, err);
return err;
}
--
2.30.2
next prev parent reply other threads:[~2021-06-21 8:34 UTC|newest]
Thread overview: 60+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-06-13 3:53 any idea about auto export multiple btrfs snapshots? Wang Yugui
2021-06-14 22:50 ` NeilBrown
2021-06-15 15:13 ` Wang Yugui
2021-06-15 15:41 ` Wang Yugui
2021-06-16 5:47 ` Wang Yugui
2021-06-17 3:02 ` NeilBrown
2021-06-17 4:28 ` Wang Yugui
2021-06-18 0:32 ` NeilBrown
2021-06-18 7:26 ` Wang Yugui
2021-06-18 13:34 ` Wang Yugui
2021-06-19 6:47 ` Wang Yugui
2021-06-20 12:27 ` Wang Yugui
2021-06-21 4:52 ` NeilBrown
2021-06-21 5:13 ` NeilBrown
2021-06-21 8:34 ` Wang Yugui [this message]
2021-06-22 1:28 ` NeilBrown
2021-06-22 3:22 ` Wang Yugui
2021-06-22 7:14 ` Wang Yugui
2021-06-23 0:59 ` NeilBrown
2021-06-23 6:14 ` Wang Yugui
2021-06-23 6:29 ` NeilBrown
2021-06-23 9:34 ` Wang Yugui
2021-06-23 23:38 ` NeilBrown
2021-06-23 15:35 ` J. Bruce Fields
2021-06-23 22:04 ` NeilBrown
2021-06-23 22:25 ` J. Bruce Fields
2021-06-23 23:29 ` NeilBrown
2021-06-23 23:41 ` Frank Filz
2021-06-24 0:01 ` J. Bruce Fields
2021-06-24 21:58 ` Patrick Goetz
2021-06-24 23:27 ` NeilBrown
2021-06-21 14:35 ` Frank Filz
2021-06-21 14:55 ` Wang Yugui
2021-06-21 17:49 ` Frank Filz
2021-06-21 22:41 ` Wang Yugui
2021-06-22 17:34 ` Frank Filz
2021-06-22 22:48 ` Wang Yugui
2021-06-17 2:15 ` Wang Yugui
[not found] ` <20210310074620.GA2158@tik.uni-stuttgart.de>
[not found] ` <162632387205.13764.6196748476850020429@noble.neil.brown.name>
2021-07-15 14:09 ` [PATCH/RFC] NFSD: handle BTRFS subvolumes better Josef Bacik
2021-07-15 16:45 ` Christoph Hellwig
2021-07-15 17:11 ` Josef Bacik
2021-07-15 17:24 ` Christoph Hellwig
2021-07-15 18:01 ` Josef Bacik
2021-07-15 22:37 ` NeilBrown
2021-07-19 15:40 ` Josef Bacik
2021-07-19 20:00 ` J. Bruce Fields
2021-07-19 20:44 ` Josef Bacik
2021-07-19 23:53 ` NeilBrown
2021-07-19 15:49 ` J. Bruce Fields
2021-07-20 0:02 ` NeilBrown
2021-07-19 9:16 ` Christoph Hellwig
2021-07-19 23:54 ` NeilBrown
2021-07-20 6:23 ` Christoph Hellwig
2021-07-20 7:17 ` NeilBrown
2021-07-20 8:00 ` Christoph Hellwig
2021-07-20 23:11 ` NeilBrown
2021-07-20 22:10 ` J. Bruce Fields
2021-07-15 23:02 ` NeilBrown
2021-07-15 15:45 ` J. Bruce Fields
2021-07-15 23:08 ` NeilBrown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210621163441.428C.409509F4@e16-tech.com \
--to=wangyugui@e16-tech.com \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox