diff mbox

[RFC,05/13] ovl: lookup stable inode by file handle

Message ID 1492387183-18847-6-git-send-email-amir73il@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Amir Goldstein April 16, 2017, 11:59 p.m. UTC
When non directory upper has overlay.fh xattr, lookup that
file handle in lower layers to find the stable inode it refers to.

Signed-off-by: Amir Goldstein <amir73il@gmail.com>
---
 fs/overlayfs/namei.c | 30 ++++++++++++++++++++++--------
 1 file changed, 22 insertions(+), 8 deletions(-)
diff mbox

Patch

diff --git a/fs/overlayfs/namei.c b/fs/overlayfs/namei.c
index fcb7c15..42b6030 100644
--- a/fs/overlayfs/namei.c
+++ b/fs/overlayfs/namei.c
@@ -204,6 +204,9 @@  static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
 	if (d->fh) {
 		kfree(d->fh);
 		d->fh = NULL;
+		/* Follow once by file handle for non-dir */
+		if (!d->is_dir)
+			d->by_fh = false;
 	}
 
 	if (!this->d_inode)
@@ -219,15 +222,21 @@  static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
 		goto put_and_out;
 	}
 	if (!d_can_lookup(this)) {
-		d->stop = true;
-		if (d->is_dir)
+		if (d->is_dir) {
+			d->stop = true;
 			goto put_and_out;
-		goto out;
-	}
-	d->is_dir = true;
-	if (!d->last && ovl_is_opaquedir(this)) {
-		d->stop = d->opaque = true;
-		goto out;
+		}
+		/* Lookup stable inode of non-dir by file handle */
+		if (!d->by_fh) {
+			d->stop = true;
+			goto out;
+		}
+	} else {
+		d->is_dir = true;
+		if (!d->last && ovl_is_opaquedir(this)) {
+			d->stop = d->opaque = true;
+			goto out;
+		}
 	}
 	if (d->last)
 		goto out;
@@ -236,6 +245,11 @@  static int ovl_lookup_single(struct dentry *base, struct ovl_lookup_data *d,
 		if (err)
 			goto out_err;
 	}
+	/* No redirect fh for non-dir means pure upper */
+	if (!d->is_dir) {
+		d->stop = !d->fh;
+		goto out;
+	}
 	if (d->by_path) {
 		err = ovl_check_redirect(this, d, prelen, post);
 		if (err)