From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: linux-unionfs@vger.kernel.org
Subject: [PATCH v3 21/23] ovl: link up indexed lower hardlink on lookup
Date: Wed, 14 Jun 2017 10:26:40 +0300 [thread overview]
Message-ID: <1497425202-16270-22-git-send-email-amir73il@gmail.com> (raw)
In-Reply-To: <1497425202-16270-1-git-send-email-amir73il@gmail.com>
With inodes index feature, all lower and upper hardlinks point to
the same overlay inode. However, when a lower hardlink is accessed
for read operation, the real inode operated on is not the same inode
as the real inode for read operation on an upper hardlink.
When lookup finds a lower hardlink, which is already indexed by
an earlier upper hardlink copy up, call ovl_copy_up() to link the
indexed upper on top of the lower hardlink and then operate on the
upper real inode to avoid this inconsistency.
Invalidate a lower indexed dentry on dcache lookup, so ovl_lookup()
is called to perform the index link up.
The following test demonstrates the upper/lower hardlinks inconsistency:
$ echo -n a > /lower/foo
$ ln /lower/foo /lower/bar
$ cd /mnt
$ echo -n b >> foo
$ tail foo bar # foo is indexed upper, bar is indexed lower
==> foo <==
ab
==> bar <==
a
$ echo -n c >> bar
$ tail foo bar # both aliases are indexed upper
==> foo <==
abc
==> bar <==
abc
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/overlayfs/namei.c | 11 ++++++++++-
fs/overlayfs/super.c | 32 +++++++++++++++++++++++++++-----
2 files changed, 37 insertions(+), 6 deletions(-)
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index 193177883dc7..2f4c02355060 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -654,13 +654,22 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
oe->redirect = upperredirect;
oe->__upperdentry = upperdentry;
memcpy(oe->lowerstack, stack, sizeof(struct path) * ctr);
- dput(index);
kfree(stack);
kfree(d.redirect);
dentry->d_fsdata = oe;
ovl_update_type(dentry, d.is_dir);
d_add(dentry, inode);
+ /* Link up indexed lower early for consistent overlay hardlinks */
+ if (OVL_TYPE_INDEX(type) && !upperdentry) {
+ err = ovl_copy_up(dentry);
+ if (err) {
+ pr_warn_ratelimited("overlayfs: failed link up to index (%pd2, index=%pd2, err=%i)\n",
+ dentry, index, err);
+ }
+ }
+ dput(index);
+
return NULL;
out_free_oe:
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 0f36a09df34c..82b036ee9e52 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -117,6 +117,33 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
return dentry;
}
+static int ovl_dentry_indexed_revalidate(struct dentry *dentry,
+ unsigned int flags)
+{
+ enum ovl_path_type type = ovl_path_type(dentry);
+ bool is_upper;
+
+ if (d_is_dir(dentry) || d_is_negative(dentry))
+ return 1;
+
+ /*
+ * Invalidate lower hardlink after it has been indexed by copy up
+ * of another lower alias. ovl_lookup will trigger copy up of this
+ * path and link the upper path to the upper index inode.
+ */
+ ovl_inode_real(d_inode(dentry), &is_upper);
+ if (is_upper && !OVL_TYPE_UPPER(type))
+ return 0;
+
+ return 1;
+}
+
+static const struct dentry_operations ovl_dentry_operations = {
+ .d_release = ovl_dentry_release,
+ .d_real = ovl_d_real,
+ .d_revalidate = ovl_dentry_indexed_revalidate,
+};
+
static int ovl_dentry_revalidate(struct dentry *dentry, unsigned int flags)
{
struct ovl_entry *oe = dentry->d_fsdata;
@@ -158,11 +185,6 @@ static int ovl_dentry_weak_revalidate(struct dentry *dentry, unsigned int flags)
return ret;
}
-static const struct dentry_operations ovl_dentry_operations = {
- .d_release = ovl_dentry_release,
- .d_real = ovl_d_real,
-};
-
static const struct dentry_operations ovl_reval_dentry_operations = {
.d_release = ovl_dentry_release,
.d_real = ovl_d_real,
--
2.7.4
next prev parent reply other threads:[~2017-06-14 7:27 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-14 7:26 [PATCH v3 00/23] Overlayfs inodes index Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 01/23] vfs: introduce inode 'inuse' lock Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 02/23] ovl: get exclusive ownership on upper/work dirs Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 03/23] ovl: relax same fs constrain for ovl_check_origin() Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 04/23] ovl: generalize ovl_create_workdir() Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 05/23] ovl: introduce the inodes index dir feature Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 06/23] ovl: verify upper root dir matches lower root dir Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 07/23] ovl: verify index dir matches upper dir Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 08/23] ovl: store path type in dentry Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 09/23] ovl: cram dentry state booleans into type flags Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 10/23] ovl: lookup index entry for copy up origin Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 11/23] ovl: allocate an ovl_inode struct Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 12/23] ovl: store upper/lower real inode in ovl_inode_info Amir Goldstein
2017-06-14 11:00 ` Amir Goldstein
2017-06-16 11:55 ` Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 13/23] ovl: use ovl_inode_init() for initializing new inode Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 14/23] ovl: hash overlay non-dir inodes by copy up origin inode Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 15/23] ovl: defer upper dir lock to tempfile link Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 16/23] ovl: factor out ovl_copy_up_inode() helper Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 17/23] ovl: generalize ovl_copy_up_locked() using actors Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 18/23] ovl: generalize ovl_copy_up_one() " Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 19/23] ovl: use ovl_inode mutex to synchronize concurrent copy up Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 20/23] ovl: implement index dir copy up method Amir Goldstein
2017-06-14 7:26 ` Amir Goldstein [this message]
2017-06-19 10:22 ` [PATCH v3 21/23] ovl: link up indexed lower hardlink on lookup Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 22/23] ovl: fix nlink leak in ovl_rename() Amir Goldstein
2017-06-14 7:26 ` [PATCH v3 23/23] ovl: adjust overlay inode nlink for indexed inodes Amir Goldstein
2017-06-14 7:30 ` [PATCH v3 00/23] Overlayfs inodes index Miklos Szeredi
2017-06-14 7:48 ` 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=1497425202-16270-22-git-send-email-amir73il@gmail.com \
--to=amir73il@gmail.com \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
/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