ovl: simplify lookup
authorMiklos Szeredi <mszeredi@redhat.com>
Fri, 16 Dec 2016 10:02:56 +0000 (11:02 +0100)
committerMiklos Szeredi <mszeredi@redhat.com>
Fri, 16 Dec 2016 10:02:56 +0000 (11:02 +0100)
If encountering a non-directory, then stop looking at lower layers.

In this case the oe->opaque flag is not set anymore, which doesn't matter
since existence of lower file is now checked at remove/rename time.

Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/super.c

index c0463fb80f413e2ffd3802f150bffddcec52b22f..a19fbcde16bd6bb0a9f5accd793a0d43f260709b 100644 (file)
@@ -473,7 +473,9 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
        unsigned int ctr = 0;
        struct inode *inode = NULL;
        bool upperopaque = false;
-       struct dentry *this, *prev = NULL;
+       bool stop = false;
+       bool isdir = false;
+       struct dentry *this;
        unsigned int i;
        int err;
 
@@ -494,23 +496,26 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                        if (ovl_is_whiteout(this)) {
                                dput(this);
                                this = NULL;
-                               upperopaque = true;
-                       } else if (poe->numlower && ovl_is_opaquedir(this)) {
-                               upperopaque = true;
+                               stop = upperopaque = true;
+                       } else if (!d_is_dir(this)) {
+                               stop = true;
+                       } else {
+                               isdir = true;
+                               if (poe->numlower && ovl_is_opaquedir(this))
+                                       stop = upperopaque = true;
                        }
                }
-               upperdentry = prev = this;
+               upperdentry = this;
        }
 
-       if (!upperopaque && poe->numlower) {
+       if (!stop && poe->numlower) {
                err = -ENOMEM;
                stack = kcalloc(poe->numlower, sizeof(struct path), GFP_KERNEL);
                if (!stack)
                        goto out_put_upper;
        }
 
-       for (i = 0; !upperopaque && i < poe->numlower; i++) {
-               bool opaque = false;
+       for (i = 0; !stop && i < poe->numlower; i++) {
                struct path lowerpath = poe->lowerstack[i];
 
                this = ovl_lookup_real(lowerpath.dentry, &dentry->d_name);
@@ -530,35 +535,26 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                        break;
                }
                /*
-                * Only makes sense to check opaque dir if this is not the
-                * lowermost layer.
+                * If this is a non-directory then stop here.
                 */
-               if (i < poe->numlower - 1 && ovl_is_opaquedir(this))
-                       opaque = true;
-
-               if (prev && (!S_ISDIR(prev->d_inode->i_mode) ||
-                            !S_ISDIR(this->d_inode->i_mode))) {
+               if (!d_is_dir(this)) {
+                       if (isdir) {
+                               dput(this);
+                               break;
+                       }
+                       stop = true;
+               } else {
                        /*
-                        * FIXME: check for upper-opaqueness maybe better done
-                        * in remove code.
+                        * Only makes sense to check opaque dir if this is not
+                        * the lowermost layer.
                         */
-                       if (prev == upperdentry)
-                               upperopaque = true;
-                       dput(this);
-                       break;
+                       if (i < poe->numlower - 1 && ovl_is_opaquedir(this))
+                               stop = true;
                }
-               /*
-                * If this is a non-directory then stop here.
-                */
-               if (!S_ISDIR(this->d_inode->i_mode))
-                       opaque = true;
 
                stack[ctr].dentry = this;
                stack[ctr].mnt = lowerpath.mnt;
                ctr++;
-               prev = this;
-               if (opaque)
-                       break;
        }
 
        oe = ovl_alloc_entry(ctr);