From: Amir Goldstein <amir73il@gmail.com>
To: Miklos Szeredi <miklos@szeredi.hu>
Cc: linux-unionfs@vger.kernel.org
Subject: [PATCH 05/11] ovl: lookup index for directories
Date: Tue, 17 Oct 2017 19:00:16 +0300 [thread overview]
Message-ID: <1508256022-10267-6-git-send-email-amir73il@gmail.com> (raw)
In-Reply-To: <1508256022-10267-1-git-send-email-amir73il@gmail.com>
A directory index is a directory type entry in index dir
with a "trusted.overlay.origin" xattr containing an encoded ovl_fh
of the merge directory upper dir.
On lookup of non-dir files, lower file is followed by origin file handle.
On lookup of dir entries, lower dir is found by name and then compared
to origin file handle. We only trust dir index if we verified that lower
dir matches origin file handle, otherwise index is inconsistent and we
ignore it.
Directory index entries are going to be used for NFS export.
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
fs/overlayfs/namei.c | 52 +++++++++++++++++++++++++++++++++++++++-------------
1 file changed, 39 insertions(+), 13 deletions(-)
diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index c73f490695c6..1afc6d6e99b9 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -518,6 +518,7 @@ static struct dentry *ovl_lookup_index(struct dentry *dentry,
struct dentry *index;
struct inode *inode;
struct qstr name;
+ bool is_dir = d_is_dir(origin);
int err;
err = ovl_get_index_name(origin, &name);
@@ -540,15 +541,11 @@ static struct dentry *ovl_lookup_index(struct dentry *dentry,
inode = d_inode(index);
if (d_is_negative(index)) {
- if (upper && d_inode(origin)->i_nlink > 1) {
+ if (!is_dir && upper && d_inode(origin)->i_nlink > 1) {
pr_warn_ratelimited("overlayfs: hard link with origin but no index (%pd2).\n",
upper);
}
goto out_dput;
- } else if (upper && d_inode(upper) != inode) {
- pr_warn_ratelimited("overlayfs: broken hard link - ignoring index (%pd2).\n",
- upper);
- goto out_dput;
} else if (ovl_dentry_weird(index) || ovl_is_whiteout(index) ||
((inode->i_mode ^ d_inode(origin)->i_mode) & S_IFMT)) {
/*
@@ -562,8 +559,16 @@ static struct dentry *ovl_lookup_index(struct dentry *dentry,
index, d_inode(index)->i_mode & S_IFMT,
d_inode(origin)->i_mode & S_IFMT);
goto fail;
+ } else if (upper && is_dir) {
+ /* Verify that dir index origin points to upper dir */
+ err = ovl_verify_origin(index, upper, true, false);
+ if (err)
+ goto fail;
+ } else if (upper && d_inode(upper) != inode) {
+ pr_warn_ratelimited("overlayfs: broken hard link - ignoring index (%pd2).\n",
+ upper);
+ goto out_dput;
}
-
out:
kfree(name.name);
return index;
@@ -613,6 +618,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
struct ovl_entry *roe = dentry->d_sb->s_root->d_fsdata;
struct path *stack = NULL;
struct dentry *upperdir, *upperdentry = NULL;
+ struct dentry *origin = NULL;
struct dentry *index = NULL;
unsigned int ctr = 0;
struct inode *inode = NULL;
@@ -659,6 +665,8 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
*/
err = ovl_check_origin(upperdentry, roe->lowerstack,
roe->numlower, &stack, &ctr);
+ if (ctr)
+ origin = stack[0].dentry;
if (err)
goto out;
}
@@ -692,15 +700,26 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
if (!this)
continue;
+ if (!ctr)
+ origin = this;
+
/*
* Verify that uppermost lower matches the copy up origin fh.
* If no origin fh is stored in upper, store fh of lower dir.
+ * If origin fh exists and does not match lower dir, depending
+ * on verify_dir config, we either not merge this lower or we
+ * merge it, but we do not use it as index key.
*/
if (this && upperdentry && !ctr) {
err = ovl_verify_origin(upperdentry, this, false, true);
- if (err && ovl_verify_dir(dentry->d_sb)) {
- dput(this);
- break;
+ if (err) {
+ if (ovl_verify_dir(dentry->d_sb)) {
+ /* Don't merge with unverified lower */
+ dput(this);
+ break;
+ }
+ /* Don't use unverified lower as index key */
+ origin = NULL;
}
}
@@ -733,6 +752,8 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
roe->numlower, &stack, &ctr);
if (err)
goto out_put;
+
+ origin = stack[0].dentry;
/*
* XXX: We do not continue layers lookup from decoded origin for
* more than a single lower layer. This would require setting
@@ -742,10 +763,15 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
*/
}
- /* Lookup index by lower inode and verify it matches upper inode */
- if (ctr && !d.is_dir && ovl_indexdir(dentry->d_sb)) {
- struct dentry *origin = stack[0].dentry;
-
+ /*
+ * Lookup index by lower inode and verify it matches upper inode.
+ * We only trust dir index if we verified that lower dir matches
+ * origin, otherwise index is inconsistent and we ignore it.
+ *
+ * TODO: update origin and index in case lower dir has changed and
+ * store new generation number xattr in index for NFS export.
+ */
+ if (ctr && ovl_indexdir(dentry->d_sb) && origin) {
index = ovl_lookup_index(dentry, upperdentry, origin);
if (IS_ERR(index)) {
err = PTR_ERR(index);
--
2.7.4
next prev parent reply other threads:[~2017-10-17 15:59 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-17 16:00 [PATCH 00/11] Implement overlayfs index=all mount option Amir Goldstein
2017-10-17 16:00 ` [PATCH 01/11] ovl: fix EIO from lookup of non-indexed upper Amir Goldstein
2017-10-17 16:00 ` [PATCH 02/11] ovl: verify whiteout index entries on mount Amir Goldstein
2017-10-17 16:00 ` [PATCH 03/11] ovl: create ovl_need_index() helper Amir Goldstein
2017-10-17 16:00 ` [PATCH 04/11] ovl: add support for mount option index=all Amir Goldstein
2017-10-17 16:00 ` Amir Goldstein [this message]
2017-10-17 16:00 ` [PATCH 06/11] ovl: verify directory index entries on mount Amir Goldstein
2017-10-19 10:35 ` Amir Goldstein
2017-10-17 16:00 ` [PATCH 07/11] ovl: index directories on copy up Amir Goldstein
2017-10-17 16:00 ` [PATCH 08/11] ovl: cleanup dir index when dir nlink drops to zero Amir Goldstein
2017-10-17 16:00 ` [PATCH 09/11] ovl: whiteout index when union " Amir Goldstein
2017-10-17 16:00 ` [PATCH 10/11] ovl: whiteout orphan index entries on mount Amir Goldstein
2017-10-17 16:00 ` [PATCH 11/11] ovl: cleanup stale whiteout " 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=1508256022-10267-6-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;
as well as URLs for NNTP newsgroup(s).