]> git.ipfire.org Git - thirdparty/kernel/linux.git/blobdiff - fs/overlayfs/super.c
fs: remove the inode argument to ->d_real() method
[thirdparty/kernel/linux.git] / fs / overlayfs / super.c
index 4ab66e3d4cff9854a99bcc1505963927476bf1d5..df2ad2f6079829f0eee5566d782f215b28796acb 100644 (file)
@@ -28,41 +28,38 @@ MODULE_LICENSE("GPL");
 
 struct ovl_dir_cache;
 
-static struct dentry *ovl_d_real(struct dentry *dentry,
-                                const struct inode *inode)
+static struct dentry *ovl_d_real(struct dentry *dentry, enum d_real_type type)
 {
-       struct dentry *real = NULL, *lower;
+       struct dentry *upper, *lower;
        int err;
 
-       /*
-        * vfs is only expected to call d_real() with NULL from d_real_inode()
-        * and with overlay inode from file_dentry() on an overlay file.
-        *
-        * TODO: remove @inode argument from d_real() API, remove code in this
-        * function that deals with non-NULL @inode and remove d_real() call
-        * from file_dentry().
-        */
-       if (inode && d_inode(dentry) == inode)
-               return dentry;
-       else if (inode)
+       switch (type) {
+       case D_REAL_DATA:
+       case D_REAL_METADATA:
+               break;
+       default:
                goto bug;
+       }
 
        if (!d_is_reg(dentry)) {
                /* d_real_inode() is only relevant for regular files */
                return dentry;
        }
 
-       real = ovl_dentry_upper(dentry);
-       if (real && (inode == d_inode(real)))
-               return real;
+       upper = ovl_dentry_upper(dentry);
+       if (upper && (type == D_REAL_METADATA ||
+                     ovl_has_upperdata(d_inode(dentry))))
+               return upper;
 
-       if (real && !inode && ovl_has_upperdata(d_inode(dentry)))
-               return real;
+       if (type == D_REAL_METADATA) {
+               lower = ovl_dentry_lower(dentry);
+               goto real_lower;
+       }
 
        /*
-        * Best effort lazy lookup of lowerdata for !inode case to return
+        * Best effort lazy lookup of lowerdata for D_REAL_DATA case to return
         * the real lowerdata dentry.  The only current caller of d_real() with
-        * NULL inode is d_real_inode() from trace_uprobe and this caller is
+        * D_REAL_DATA is d_real_inode() from trace_uprobe and this caller is
         * likely going to be followed reading from the file, before placing
         * uprobes on offset within the file, so lowerdata should be available
         * when setting the uprobe.
@@ -73,18 +70,13 @@ static struct dentry *ovl_d_real(struct dentry *dentry,
        lower = ovl_dentry_lowerdata(dentry);
        if (!lower)
                goto bug;
-       real = lower;
 
-       /* Handle recursion */
-       real = d_real(real, inode);
+real_lower:
+       /* Handle recursion into stacked lower fs */
+       return d_real(lower, type);
 
-       if (!inode || inode == d_inode(real))
-               return real;
 bug:
-       WARN(1, "%s(%pd4, %s:%lu): real dentry (%p/%lu) not found\n",
-            __func__, dentry, inode ? inode->i_sb->s_id : "NULL",
-            inode ? inode->i_ino : 0, real,
-            real && d_inode(real) ? d_inode(real)->i_ino : 0);
+       WARN(1, "%s(%pd4, %d): real dentry not found\n", __func__, dentry, type);
        return dentry;
 }