All of lore.kernel.org
 help / color / mirror / Atom feed
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


  reply	other threads:[~2021-06-21  8:34 UTC|newest]

Thread overview: 94+ 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-03-10  7:46 ` nfs subvolume access? Ulli Horlacher
2021-03-10  7:59   ` Hugo Mills
2021-03-10  8:09     ` Ulli Horlacher
2021-03-10  9:35       ` Graham Cobb
2021-03-10 15:55         ` Ulli Horlacher
2021-03-10 17:29           ` Forza
2021-03-10 17:46             ` Ulli Horlacher
2021-03-10  8:17   ` Ulli Horlacher
2021-03-11  7:46   ` Ulli Horlacher
2021-07-08 22:17     ` cannot use btrfs for nfs server Ulli Horlacher
2021-07-09  0:05       ` Graham Cobb
2021-07-09  4:05         ` NeilBrown
2021-07-09  6:53         ` Ulli Horlacher
2021-07-09  7:23           ` Forza
2021-07-09  7:24             ` Hugo Mills
2021-07-09  7:34             ` Ulli Horlacher
2021-07-09 16:30               ` Chris Murphy
2021-07-10  6:35                 ` Ulli Horlacher
2021-07-11 11:41                   ` Forza
2021-07-12  7:17                     ` Ulli Horlacher
2021-07-09 16:35           ` Chris Murphy
2021-07-10  6:56             ` Ulli Horlacher
2021-07-10 22:17               ` Chris Murphy
2021-07-12  7:25                 ` Ulli Horlacher
2021-07-12 13:06                   ` Graham Cobb
2021-07-12 16:16                     ` Ulli Horlacher
2021-07-12 22:56                       ` g.btrfs
2021-07-13  7:37                         ` Ulli Horlacher
2021-07-19 12:06                           ` Forza
2021-07-19 13:07                             ` Forza
2021-07-19 13:35                               ` Forza
2021-07-27 11:27                             ` Ulli Horlacher
2021-07-09 16:06       ` Lord Vader
2021-07-10  7:03         ` Ulli Horlacher
     [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
2021-06-14 22:50 ` any idea about auto export multiple btrfs snapshots? 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

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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.