From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: Al Viro <viro@zeniv.linux.org.uk>,
linux-unionfs@vger.kernel.org, linux-fsdevel@vger.kernel.org
Subject: [PATCH v2 07/20] ovl: verify index dir matches upper dir
Date: Wed, 7 Jun 2017 10:51:11 +0300 [thread overview]
Message-ID: <1496821884-5178-8-git-send-email-amir73il@gmail.com> (raw)
In-Reply-To: <1496821884-5178-1-git-send-email-amir73il@gmail.com>
An index dir contains persistent hardlinks to files in upper dir.
Therefore, we must never mount an existing index dir with a differnt
upper dir.
Store the upper root dir file handle in index dir inode when index
dir is created and verify the file handle before using an existing
index dir on mount.
Add an 'is_upper' flag to the overlay file handle encoding and set it
when encoding the upper root file handle. This is not critical for index
dir verification, but it is good practice towards a standard overlayfs
file handle format for NFS export.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/overlayfs/copy_up.c | 12 ++++++++++--
fs/overlayfs/namei.c | 4 ++--
fs/overlayfs/overlayfs.h | 6 ++++--
fs/overlayfs/super.c | 21 ++++++++++++++++-----
4 files changed, 32 insertions(+), 11 deletions(-)
diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c
index ee0b894e1d99..eedc26e15dad 100644
--- a/fs/overlayfs/copy_up.c
+++ b/fs/overlayfs/copy_up.c
@@ -233,7 +233,7 @@ int ovl_set_attr(struct dentry *upperdentry, struct kstat *stat)
return err;
}
-struct ovl_fh *ovl_encode_fh(struct dentry *lower)
+struct ovl_fh *ovl_encode_fh(struct dentry *lower, bool is_upper)
{
struct ovl_fh *fh;
int fh_type, fh_len, dwords;
@@ -272,6 +272,14 @@ struct ovl_fh *ovl_encode_fh(struct dentry *lower)
fh->magic = OVL_FH_MAGIC;
fh->type = fh_type;
fh->flags = OVL_FH_FLAG_CPU_ENDIAN;
+ /*
+ * When we will want to decode an overlay dentry from this handle
+ * and all layers are on the same fs, if we get a disconncted real
+ * dentry when we decode fid, the only way to tell if we should assign
+ * it to upperdentry or to lowerstack is by checking this flag.
+ */
+ if (is_upper)
+ fh->flags |= OVL_FH_FLAG_PATH_UPPER;
fh->len = fh_len;
fh->uuid = *uuid;
memcpy(fh->fid, buf, buflen);
@@ -293,7 +301,7 @@ static int ovl_set_origin(struct dentry *dentry, struct dentry *lower,
* up and a pure upper inode.
*/
if (ovl_can_decode_fh(lower->d_sb)) {
- fh = ovl_encode_fh(lower);
+ fh = ovl_encode_fh(lower, false);
if (IS_ERR(fh))
return PTR_ERR(fh);
}
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index 1b8017a57a02..61f4988527f4 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -327,7 +327,7 @@ static int ovl_check_origin(struct dentry *dentry, struct dentry *upperdentry,
* Return 0 on match, -ESTALE on mismatch, < 0 on error.
*/
int ovl_verify_origin(struct dentry *dentry, struct vfsmount *mnt,
- struct dentry *origin)
+ struct dentry *origin, bool is_upper)
{
struct inode *inode = NULL;
struct ovl_fh *fh = NULL;
@@ -343,7 +343,7 @@ int ovl_verify_origin(struct dentry *dentry, struct vfsmount *mnt,
goto fail;
}
- fh = ovl_encode_fh(origin);
+ fh = ovl_encode_fh(origin, is_upper);
if (IS_ERR(fh)) {
err = PTR_ERR(fh);
fh = NULL;
diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h
index 1eb8250464be..6fd7c9e748c1 100644
--- a/fs/overlayfs/overlayfs.h
+++ b/fs/overlayfs/overlayfs.h
@@ -38,6 +38,8 @@ enum ovl_path_type {
/* CPU byte order required for fid decoding: */
#define OVL_FH_FLAG_BIG_ENDIAN (1 << 0)
#define OVL_FH_FLAG_ANY_ENDIAN (1 << 1)
+/* Is the real inode encoded in fid an upper inode? */
+#define OVL_FH_FLAG_PATH_UPPER (1 << 2)
#define OVL_FH_FLAG_ALL (OVL_FH_FLAG_BIG_ENDIAN | OVL_FH_FLAG_ANY_ENDIAN)
@@ -236,7 +238,7 @@ static inline bool ovl_is_impuredir(struct dentry *dentry)
/* namei.c */
int ovl_verify_origin(struct dentry *dentry, struct vfsmount *mnt,
- struct dentry *origin);
+ struct dentry *origin, bool is_upper);
int ovl_path_next(int idx, struct dentry *dentry, struct path *path, int *idxp);
struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags);
bool ovl_lower_positive(struct dentry *dentry);
@@ -295,4 +297,4 @@ int ovl_copy_up(struct dentry *dentry);
int ovl_copy_up_flags(struct dentry *dentry, int flags);
int ovl_copy_xattr(struct dentry *old, struct dentry *new);
int ovl_set_attr(struct dentry *upper, struct kstat *stat);
-struct ovl_fh *ovl_encode_fh(struct dentry *lower);
+struct ovl_fh *ovl_encode_fh(struct dentry *lower, bool is_upper);
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 137371419657..b411b6d5f7b1 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -419,19 +419,20 @@ static int ovl_parse_opt(char *opt, struct ovl_config *config)
* If dir has no stored file handle, encode and store origin file handle.
*/
static int ovl_verify_set_origin(struct dentry *dir, struct vfsmount *mnt,
- struct dentry *origin, const char *name)
+ struct dentry *origin, const char *name,
+ bool is_upper)
{
const struct ovl_fh *fh = NULL;
int err;
- err = ovl_verify_origin(dir, mnt, origin);
+ err = ovl_verify_origin(dir, mnt, origin, is_upper);
if (!err)
return 0;
if (err != -ENODATA)
goto fail;
- fh = ovl_encode_fh(origin);
+ fh = ovl_encode_fh(origin, is_upper);
err = PTR_ERR(fh);
if (IS_ERR(fh))
goto fail;
@@ -1062,7 +1063,7 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
/* Verify lower root is upper root origin */
err = ovl_verify_set_origin(upperpath.dentry,
ufs->lower_mnt[0], stack[0].dentry,
- "lower root");
+ "lower root", false);
if (err)
goto out_put_lower_mnt;
@@ -1072,8 +1073,18 @@ static int ovl_fill_super(struct super_block *sb, void *data, int silent)
if (IS_ERR(ufs->indexdir))
goto out_put_lower_mnt;
- if (!ufs->indexdir)
+ if (ufs->indexdir) {
+ /* Verify upper root is index dir origin */
+ err = ovl_verify_set_origin(ufs->indexdir,
+ ufs->upper_mnt,
+ upperpath.dentry,
+ "upper root", true);
+ if (err)
+ goto out_put_indexdir;
+ } else {
pr_warn("overlayfs: try deleting index dir or mounting with '-o index=off' to disable inodes index.\n");
+ }
+
}
if (remote)
--
2.7.4
next prev parent reply other threads:[~2017-06-07 7:51 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-06-07 7:51 [PATCH v2 00/20] Overlayfs inodes index Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 01/20] vfs: introduce inode 'inuse' lock Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 02/20] ovl: get exclusive ownership on upper/work dirs Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 03/20] ovl: relax same fs constrain for ovl_check_origin() Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 04/20] ovl: generalize ovl_create_workdir() Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 05/20] ovl: introduce the inodes index dir feature Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 06/20] ovl: verify upper root dir matches lower root dir Amir Goldstein
2017-06-07 7:51 ` Amir Goldstein [this message]
2017-06-07 7:51 ` [PATCH v2 08/20] ovl: lookup index entry for non-dir Amir Goldstein
2017-06-08 12:11 ` Miklos Szeredi
2017-06-08 14:48 ` Amir Goldstein
2017-06-08 15:17 ` Miklos Szeredi
2017-06-08 16:09 ` Amir Goldstein
2017-06-09 8:43 ` Miklos Szeredi
2017-06-09 9:38 ` Amir Goldstein
2017-06-09 11:49 ` Miklos Szeredi
2017-06-09 13:14 ` Miklos Szeredi
2017-06-09 13:24 ` Amir Goldstein
2017-06-09 13:29 ` Miklos Szeredi
2017-06-09 22:56 ` Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 09/20] ovl: move inode helpers to inode.c Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 10/20] ovl: use ovl_inode_init() for initializing new inode Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 11/20] ovl: hash overlay non-dir inodes by copy up origin inode Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 12/20] ovl: fix nlink leak in ovl_rename() Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 13/20] ovl: adjust overlay inode nlink for indexed inodes Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 14/20] ovl: defer upper dir lock to tempfile link Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 15/20] ovl: factor out ovl_copy_up_inode() helper Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 16/20] ovl: generalize ovl_copy_up_locked() using actors Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 17/20] ovl: generalize ovl_copy_up_one() " Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 18/20] ovl: implement index dir copy up method Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 19/20] ovl: handle race of concurrent lower hardlinks copy up Amir Goldstein
2017-06-07 7:51 ` [PATCH v2 20/20] ovl: constant inode number for hardlinks Amir Goldstein
2017-06-07 7:54 ` [PATCH v2 00/20] Overlayfs inodes index Miklos Szeredi
2017-06-07 7:58 ` Amir Goldstein
2017-06-07 14:58 ` Amir Goldstein
2017-06-08 15:00 ` [PATCH v2 21/23] ovl: use inodes index on readonly mount Amir Goldstein
2017-06-08 15:00 ` [PATCH v2 22/23] ovl: move copy up helpers to copy_up.c Amir Goldstein
2017-06-08 15:00 ` [PATCH v2 23/23] ovl: copy up on read operations on indexed lower Amir Goldstein
2017-06-07 17:17 ` [PATCH v2 00/20] Overlayfs inodes index J. Bruce Fields
2017-06-07 18:36 ` Amir Goldstein
2017-06-07 18:59 ` J. Bruce Fields
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=1496821884-5178-8-git-send-email-amir73il@gmail.com \
--to=amir73il@gmail.com \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-unionfs@vger.kernel.org \
--cc=miklos@szeredi.hu \
--cc=viro@zeniv.linux.org.uk \
/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;
as well as URLs for NNTP newsgroup(s).