All of lore.kernel.org
 help / color / mirror / Atom feed
From: Amir Goldstein <amir73il@gmail.com>
To: Eddie Horng <eddiehorng.tw@gmail.com>
Cc: Trond Myklebust <trondmy@primarydata.com>,
	"bfields@fieldses.org" <bfields@fieldses.org>,
	"miklos@szeredi.hu" <miklos@szeredi.hu>,
	"linux-unionfs@vger.kernel.org" <linux-unionfs@vger.kernel.org>,
	"jlayton@kernel.org" <jlayton@kernel.org>
Subject: Re: readdir returns d_type=DT_UNKNOWN to overlay exported dir (NFSv3)
Date: Thu, 15 Mar 2018 23:48:46 +0200	[thread overview]
Message-ID: <CAOQ4uxhxMKL1-gQdgsChG=EUNH+wVnfxrXkkO-nyas4wdfdtyQ@mail.gmail.com> (raw)
In-Reply-To: <CAOQ4uxhO6rEA+gru45ZuWc-9twRguuPRmfZmQiTfQu+QKTtM7w@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 1307 bytes --]

On Thu, Mar 15, 2018 at 8:40 PM, Amir Goldstein <amir73il@gmail.com> wrote:
> On Thu, Mar 15, 2018 at 4:30 PM, Eddie Horng <eddiehorng.tw@gmail.com> wrote:
[...]
> The problem *is* with nfsd+overlayfs, because nfsd verifies
> in compose_entry_fh() that (dchild->d_inode->i_ino == ino), but it is not.
> In that case, encode_entryplus_baggage() falls back to encoding xdr_zero.
> In overlayfs stat.st_ino is consistent with readdir d_ino since kernel version
> v4.15 and only for all layers on the same fs.
>
> However, there is no guaranty that inode->i_ino is the same as stat.st_ino.
> Overlayfs exposes only stat.st_ino to user (as well as readdir d_ino), but
> never (to my knowledge) does it expose inode->i_ino.
>
> There was a nfsd fix for a somewhat similar problem that went into v4.16-rc1:
> 76c479480b9a nfsd: encode stat->mtime for getattr instead of inode->i_mtime
>
> The solution to the problem is to either convert all references of
> nfsd to i_inode
> with references to st_ino, or make sure to set inode->i_ino correctly for
> overlayfs inodes.
>
> From first glimps, the change in nfsd looks non trivial.
> The change to overlayfs seems doable, but didn't look closely yet.
> Will try to come up with test patch for you.
>

Eddie,

Please try this patch. It worked for me.

Thanks,
Amir.

[-- Attachment #2: 0001-ovl-set-i_ino-to-the-value-of-st_ino-for-NFS-export.patch --]
[-- Type: text/x-patch, Size: 4092 bytes --]

From 5dfe75eaf1aec080d110df343aa339ad7b816670 Mon Sep 17 00:00:00 2001
From: Amir Goldstein <amir73il@gmail.com>
Date: Thu, 15 Mar 2018 23:39:01 +0200
Subject: [PATCH] ovl: set i_ino to the value of st_ino for NFS export

When NFS export is enabled and d_ino is consistent with st_ino
(samefs), set the same value to i_ino, because nfsd readdirplus
compares d_ino values to i_ino values of child entries. When called
from ovl_new_inode(), ino arg is 0, so i_ino will be updated to real
upper inode i_ino on ovl_inode_init() or ovl_inode_update().

Reported-by: Eddie Horng <eddiehorng.tw@gmail.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/overlayfs/inode.c | 21 +++++++++++++++++----
 fs/overlayfs/util.c  |  8 +++++++-
 2 files changed, 24 insertions(+), 5 deletions(-)

diff --git a/fs/overlayfs/inode.c b/fs/overlayfs/inode.c
index 3b1bd469accd..4689716f23d8 100644
--- a/fs/overlayfs/inode.c
+++ b/fs/overlayfs/inode.c
@@ -459,9 +459,20 @@ static inline void ovl_lockdep_annotate_inode_mutex_key(struct inode *inode)
 #endif
 }
 
-static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev)
+static void ovl_fill_inode(struct inode *inode, umode_t mode, dev_t rdev,
+			   unsigned long ino)
 {
-	inode->i_ino = get_next_ino();
+	/*
+	 * When NFS export is enabled and d_ino is consistent with st_ino
+	 * (samefs), set the same value to i_ino, because nfsd readdirplus
+	 * compares d_ino values to i_ino values of child entries. When called
+	 * from ovl_new_inode(), ino arg is 0, so i_ino will be updated to real
+	 * upper inode i_ino on ovl_inode_init() or ovl_inode_update().
+	 */
+	if (inode->i_sb->s_export_op && ovl_same_sb(inode->i_sb))
+		inode->i_ino = ino;
+	else
+		inode->i_ino = get_next_ino();
 	inode->i_mode = mode;
 	inode->i_flags |= S_NOCMTIME;
 #ifdef CONFIG_FS_POSIX_ACL
@@ -597,7 +608,7 @@ struct inode *ovl_new_inode(struct super_block *sb, umode_t mode, dev_t rdev)
 
 	inode = new_inode(sb);
 	if (inode)
-		ovl_fill_inode(inode, mode, rdev);
+		ovl_fill_inode(inode, mode, rdev, 0);
 
 	return inode;
 }
@@ -710,6 +721,7 @@ struct inode *ovl_get_inode(struct super_block *sb, struct dentry *upperdentry,
 	struct inode *inode;
 	bool bylower = ovl_hash_bylower(sb, upperdentry, lowerdentry, index);
 	bool is_dir;
+	unsigned long ino = 0;
 
 	if (!realinode)
 		realinode = d_inode(lowerdentry);
@@ -748,13 +760,14 @@ struct inode *ovl_get_inode(struct super_block *sb, struct dentry *upperdentry,
 		if (!is_dir)
 			nlink = ovl_get_nlink(lowerdentry, upperdentry, nlink);
 		set_nlink(inode, nlink);
+		ino = key->i_ino;
 	} else {
 		/* Lower hardlink that will be broken on copy up */
 		inode = new_inode(sb);
 		if (!inode)
 			goto out_nomem;
 	}
-	ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev);
+	ovl_fill_inode(inode, realinode->i_mode, realinode->i_rdev, ino);
 	ovl_inode_init(inode, upperdentry, lowerdentry);
 
 	if (upperdentry && ovl_is_impuredir(upperdentry))
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 930784a26623..493f9b76fbf6 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -279,12 +279,16 @@ void ovl_dentry_set_redirect(struct dentry *dentry, const char *redirect)
 void ovl_inode_init(struct inode *inode, struct dentry *upperdentry,
 		    struct dentry *lowerdentry)
 {
+	struct inode *realinode = d_inode(upperdentry ?: lowerdentry);
+
 	if (upperdentry)
 		OVL_I(inode)->__upperdentry = upperdentry;
 	if (lowerdentry)
 		OVL_I(inode)->lower = igrab(d_inode(lowerdentry));
 
-	ovl_copyattr(d_inode(upperdentry ?: lowerdentry), inode);
+	ovl_copyattr(realinode, inode);
+	if (!inode->i_ino)
+		inode->i_ino = realinode->i_ino;
 }
 
 void ovl_inode_update(struct inode *inode, struct dentry *upperdentry)
@@ -299,6 +303,8 @@ void ovl_inode_update(struct inode *inode, struct dentry *upperdentry)
 	smp_wmb();
 	OVL_I(inode)->__upperdentry = upperdentry;
 	if (inode_unhashed(inode)) {
+		if (!inode->i_ino)
+			inode->i_ino = upperinode->i_ino;
 		inode->i_private = upperinode;
 		__insert_inode_hash(inode, (unsigned long) upperinode);
 	}
-- 
2.7.4


  reply	other threads:[~2018-03-15 21:48 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-03-14  8:42 readdir returns d_type=DT_UNKNOWN to overlay exported dir (NFSv3) Eddie Horng
2018-03-14  9:56 ` Amir Goldstein
2018-03-14 11:02 ` Jeff Layton
2018-03-14 14:16   ` Trond Myklebust
2018-03-14 14:30     ` Jeff Layton
2018-03-14 15:03       ` Amir Goldstein
2018-03-14 15:06         ` Trond Myklebust
2018-03-14 15:14           ` Amir Goldstein
2018-03-14 15:40             ` Eddie Horng
2018-03-15  9:23               ` Eddie Horng
2018-03-15  9:47 ` Eddie Horng
2018-03-15 13:13   ` Amir Goldstein
2018-03-15 13:22     ` Trond Myklebust
2018-03-15 14:30       ` Eddie Horng
2018-03-15 18:40         ` Amir Goldstein
2018-03-15 21:48           ` Amir Goldstein [this message]
2018-03-16  6:25             ` Eddie Horng
2018-03-16  7:23               ` Amir Goldstein
2018-03-16  8:06                 ` Eddie Horng
2018-03-16  9:50                   ` Amir Goldstein
2018-03-16 15:06                     ` Eddie Horng
2018-03-16 15:28                       ` Amir Goldstein

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='CAOQ4uxhxMKL1-gQdgsChG=EUNH+wVnfxrXkkO-nyas4wdfdtyQ@mail.gmail.com' \
    --to=amir73il@gmail.com \
    --cc=bfields@fieldses.org \
    --cc=eddiehorng.tw@gmail.com \
    --cc=jlayton@kernel.org \
    --cc=linux-unionfs@vger.kernel.org \
    --cc=miklos@szeredi.hu \
    --cc=trondmy@primarydata.com \
    /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.