From: Vivek Goyal <vgoyal@redhat.com>
To: linux-unionfs@vger.kernel.org
Cc: miklos@szeredi.hu, amir73il@gmail.com, vgoyal@redhat.com
Subject: [PATCH v14 25/31] ovl: Check redirect on index as well
Date: Thu, 26 Apr 2018 15:10:07 -0400 [thread overview]
Message-ID: <20180426191013.13219-26-vgoyal@redhat.com> (raw)
In-Reply-To: <20180426191013.13219-1-vgoyal@redhat.com>
Right now we seem to check redirect only if upperdentry is found. But it
is possible that there is no upperdentry but later we found an index.
We need to check redirect on index as well and set it in ovl_inode->redirect.
Otherwise link code can assume that dentry does not have redirect and
place a new one which breaks things. In my testing overlay/033 test
started failing in xfstests. Following are the details.
For example do following.
$ mkdir lower upper work merged
- Make lower dir with 4 links.
$ echo "foo" > lower/l0.txt
$ ln lower/l0.txt lower/l1.txt
$ ln lower/l0.txt lower/l2.txt
$ ln lower/l0.txt lower/l3.txt
- Mount with index on and metacopy on.
$ mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work,index=on,metacopy=on none merged
- Link lower
$ ln merged/l0.txt merged/l4.txt
(This will metadata copy up of l0.txt and put an absolute redirect
/l0.txt)
$ echo 2 > /proc/sys/vm/drop/caches
$ ls merged/l1.txt
(Now l1.txt will be looked up. There is no upper dentry but there is
lower dentry and index will be found. We don't check for redirect on
index, hence ovl_inode->redirect will be NULL.)
- Link Upper
$ ln merged/l4.txt merged/l5.txt
(Lookup of l4.txt will use inode from l1.txt lookup which is still in
cache. It has ovl_inode->redirect NULL, hence link will put a new
redirect and replace /l0.txt with /l4.txt
- Drop caches.
echo 2 > /proc/sys/vm/drop_caches
- List l1.txt and it returns -ESTALE
$ ls merged/l0.txt
(It returns stale because, we found a metacopy of l0.txt in upper
and it has redirect l4.txt but there is no file named l4.txt in
lower layer. So lower data copy is not found and -ESTALE is returned.)
So problem here is that we did not process redirect on index. Check
redirect on index as well and then problem is fixed.
Signed-off-by: Vivek Goyal <vgoyal@redhat.com>
---
fs/overlayfs/namei.c | 9 ++++++++-
fs/overlayfs/overlayfs.h | 1 +
fs/overlayfs/util.c | 42 ++++++++++++++++++++++++++++++++++++++++++
3 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index 41cbde97a212..c6ad8117a1f5 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -1067,8 +1067,15 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
if (upperdentry)
ovl_dentry_set_upper_alias(dentry);
- else if (index)
+ else if (index) {
upperdentry = dget(index);
+ upperredirect = ovl_get_redirect_xattr(upperdentry);
+ if (IS_ERR(upperredirect)) {
+ err = PTR_ERR(upperredirect);
+ upperredirect = NULL;
+ goto out_free_oe;
+ }
+ }
if (upperdentry || ctr) {
struct dentry *lowerdata = NULL;
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index e2c6a2f5addf..a0f3a6fa3029 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -284,6 +284,7 @@ int ovl_lock_rename_workdir(struct dentry *workdir, struct dentry *upperdir);
void ovl_copytimes(struct inode *inode);
int ovl_check_metacopy_xattr(struct dentry *dentry);
bool ovl_is_metacopy_dentry(struct dentry *dentry);
+char *ovl_get_redirect_xattr(struct dentry *dentry);
static inline void ovl_copytimes_with_parent(struct dentry *dentry)
{
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 69acce1c9026..1a5691a9e425 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -889,3 +889,45 @@ bool ovl_is_metacopy_dentry(struct dentry *dentry)
return (oe->numlower > 1);
}
+
+char *ovl_get_redirect_xattr(struct dentry *dentry)
+{
+ int res;
+ char *s, *next, *buf = NULL;
+
+ res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, NULL, 0);
+ if (res < 0) {
+ if (res == -ENODATA || res == -EOPNOTSUPP)
+ return NULL;
+ return ERR_PTR(res);
+ }
+
+ buf = kzalloc(res + 1, GFP_KERNEL);
+ if (!buf)
+ return ERR_PTR(-ENOMEM);
+
+ res = vfs_getxattr(dentry, OVL_XATTR_REDIRECT, buf, res);
+ if (res < 0) {
+ kfree(buf);
+ return ERR_PTR(res);
+ }
+ if (res == 0)
+ goto invalid;
+
+ if (buf[0] == '/') {
+ for (s = buf; *s++ == '/'; s = next) {
+ next = strchrnul(s, '/');
+ if (s == next)
+ goto invalid;
+ }
+ } else {
+ if (strchr(buf, '/') != NULL)
+ goto invalid;
+ }
+
+ return buf;
+invalid:
+ pr_warn_ratelimited("overlayfs: invalid redirect (%s)\n", buf);
+ kfree(buf);
+ return ERR_PTR(-EINVAL);
+}
--
2.13.6
next prev parent reply other threads:[~2018-04-26 19:10 UTC|newest]
Thread overview: 67+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-04-26 19:09 [PATCH v14 00/31] overlayfs: Delayed copy up of data Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 01/31] ovl: Initialize ovl_inode->redirect in ovl_get_inode() Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 02/31] ovl: Move the copy up helpers to copy_up.c Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 03/31] ovl: Provide a mount option metacopy=on/off for metadata copyup Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 04/31] ovl: During copy up, first copy up metadata and then data Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 05/31] ovl: Copy up only metadata during copy up where it makes sense Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 06/31] ovl: Add helper ovl_already_copied_up() Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 07/31] ovl: A new xattr OVL_XATTR_METACOPY for file on upper Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 08/31] ovl: Use out_err instead of out_nomem Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 09/31] ovl: Modify ovl_lookup() and friends to lookup metacopy dentry Vivek Goyal
2018-04-28 8:14 ` Amir Goldstein
2018-04-30 14:02 ` Vivek Goyal
2018-04-30 18:08 ` Amir Goldstein
2018-05-01 14:37 ` Amir Goldstein
2018-05-03 15:12 ` Vivek Goyal
2018-05-03 20:07 ` Amir Goldstein
2018-05-04 7:04 ` Amir Goldstein
2018-05-04 15:54 ` Vivek Goyal
2018-05-04 18:47 ` Amir Goldstein
2018-05-02 19:09 ` Vivek Goyal
2018-05-02 19:40 ` Vivek Goyal
2018-05-02 19:57 ` Amir Goldstein
2018-05-03 14:33 ` Vivek Goyal
2018-05-03 20:05 ` Amir Goldstein
2018-04-30 19:32 ` Vivek Goyal
2018-04-30 20:21 ` Amir Goldstein
2018-04-26 19:09 ` [PATCH v14 10/31] ovl: Copy up meta inode data from lowest data inode Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 11/31] ovl: Add helper ovl_dentry_lowerdata() to get lower data dentry Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 12/31] ovl: Add an helper to get real " Vivek Goyal
2018-04-26 20:33 ` Amir Goldstein
2018-04-30 13:06 ` Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 13/31] ovl: Fix ovl_getattr() to get number of blocks from lower Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 14/31] ovl: Store lower data inode in ovl_inode Vivek Goyal
2018-04-26 20:31 ` Amir Goldstein
2018-04-26 19:09 ` [PATCH v14 15/31] ovl: Add helper ovl_inode_real_data() Vivek Goyal
2018-04-26 20:35 ` Amir Goldstein
2018-04-26 19:09 ` [PATCH v14 16/31] ovl: Always open file/inode which contains data and not metacopy Vivek Goyal
2018-04-28 8:49 ` Amir Goldstein
2018-05-03 20:31 ` Vivek Goyal
2018-04-26 19:09 ` [PATCH v14 17/31] ovl: Do not expose metacopy only dentry from d_real() Vivek Goyal
2018-04-28 7:36 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 18/31] ovl: Move some dir related ovl_lookup_single() code in else block Vivek Goyal
2018-04-28 7:34 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 19/31] ovl: Check redirects for metacopy files Vivek Goyal
2018-04-28 8:32 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 20/31] ovl: Treat metacopy dentries as type OVL_PATH_MERGE Vivek Goyal
2018-04-26 19:10 ` [PATCH v14 21/31] ovl: Add an inode flag OVL_CONST_INO Vivek Goyal
2018-04-28 8:33 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 22/31] ovl: Do not set dentry type ORIGIN for broken hardlinks Vivek Goyal
2018-04-28 9:14 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 23/31] ovl: Set redirect on metacopy files upon rename Vivek Goyal
2018-04-28 8:25 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 24/31] ovl: Set redirect on upper inode when it is linked Vivek Goyal
2018-04-28 8:40 ` Amir Goldstein
2018-04-26 19:10 ` Vivek Goyal [this message]
2018-04-28 9:26 ` [PATCH v14 25/31] ovl: Check redirect on index as well Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 26/31] ovl: Allow ovl_open_realfile() to open metacopy inode Vivek Goyal
2018-04-28 9:05 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 27/31] ovl: Issue fsync on upper metacopy inode as well Vivek Goyal
2018-04-28 8:54 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 28/31] ovl: Disbale metacopy for MAP_SHARED mmap() Vivek Goyal
2018-04-28 9:28 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 29/31] ovl: Do not do metadata only copy-up for truncate operation Vivek Goyal
2018-04-28 8:35 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 30/31] ovl: Do not do metacopy only for ioctl modifying file attr Vivek Goyal
2018-04-28 8:31 ` Amir Goldstein
2018-04-26 19:10 ` [PATCH v14 31/31] ovl: Enable metadata only feature Vivek Goyal
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=20180426191013.13219-26-vgoyal@redhat.com \
--to=vgoyal@redhat.com \
--cc=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