]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ovl: update of dentry revalidate flags after copy up
authorAmir Goldstein <amir73il@gmail.com>
Mon, 3 Apr 2023 08:29:59 +0000 (11:29 +0300)
committerAmir Goldstein <amir73il@gmail.com>
Mon, 19 Jun 2023 11:01:12 +0000 (14:01 +0300)
After copy up, we may need to update d_flags if upper dentry is on a
remote fs and lower dentries are not.

Add helpers to allow incremental update of the revalidate flags.

Fixes: bccece1ead36 ("ovl: allow remote upper")
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
fs/overlayfs/copy_up.c
fs/overlayfs/dir.c
fs/overlayfs/export.c
fs/overlayfs/namei.c
fs/overlayfs/overlayfs.h
fs/overlayfs/super.c
fs/overlayfs/util.c

index f658cc8ea4920487810216c0e0d94086730debff..95dce240ba17a4b952bf4c899819be7185cad72f 100644 (file)
@@ -575,6 +575,7 @@ static int ovl_link_up(struct ovl_copy_up_ctx *c)
                        /* Restore timestamps on parent (best effort) */
                        ovl_set_timestamps(ofs, upperdir, &c->pstat);
                        ovl_dentry_set_upper_alias(c->dentry);
+                       ovl_dentry_update_reval(c->dentry, upper);
                }
        }
        inode_unlock(udir);
@@ -894,6 +895,7 @@ static int ovl_do_copy_up(struct ovl_copy_up_ctx *c)
                inode_unlock(udir);
 
                ovl_dentry_set_upper_alias(c->dentry);
+               ovl_dentry_update_reval(c->dentry, ovl_dentry_upper(c->dentry));
        }
 
 out:
index fc25fb95d5fc03c45ea69c36f79a727494e867fc..9be52d8013c8371c363e76a4891a9823aab6ea2b 100644 (file)
@@ -269,8 +269,7 @@ static int ovl_instantiate(struct dentry *dentry, struct inode *inode,
 
        ovl_dir_modified(dentry->d_parent, false);
        ovl_dentry_set_upper_alias(dentry);
-       ovl_dentry_update_reval(dentry, newdentry,
-                       DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+       ovl_dentry_init_reval(dentry, newdentry);
 
        if (!hardlink) {
                /*
index defd4e231ad2cdfe7f74b1c56b37e4b70e3af794..5c36fb3a7bab1f60036c81169b8e9a0649bee47e 100644 (file)
@@ -326,8 +326,7 @@ static struct dentry *ovl_obtain_alias(struct super_block *sb,
        if (upper_alias)
                ovl_dentry_set_upper_alias(dentry);
 
-       ovl_dentry_update_reval(dentry, upper,
-                       DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+       ovl_dentry_init_reval(dentry, upper);
 
        return d_instantiate_anon(dentry, inode);
 
index cfb3420b7df0e3314a560677626c7435218e7507..100a492d2b2a6618f13ddc6071dbb8d0ed2c96b3 100644 (file)
@@ -1122,8 +1122,7 @@ struct dentry *ovl_lookup(struct inode *dir, struct dentry *dentry,
                        ovl_set_flag(OVL_UPPERDATA, inode);
        }
 
-       ovl_dentry_update_reval(dentry, upperdentry,
-                       DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+       ovl_dentry_init_reval(dentry, upperdentry);
 
        revert_creds(old_cred);
        if (origin_path) {
index 7398de3325273c3bce7a2d8e2acff3eeed949139..2b79a9398c1327e5d9916af2d252cc1386b21e37 100644 (file)
@@ -375,8 +375,10 @@ bool ovl_index_all(struct super_block *sb);
 bool ovl_verify_lower(struct super_block *sb);
 struct ovl_entry *ovl_alloc_entry(unsigned int numlower);
 bool ovl_dentry_remote(struct dentry *dentry);
-void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
-                            unsigned int mask);
+void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry);
+void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry);
+void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
+                          unsigned int mask);
 bool ovl_dentry_weird(struct dentry *dentry);
 enum ovl_path_type ovl_path_type(struct dentry *dentry);
 void ovl_path_upper(struct dentry *dentry, struct path *path);
index f97ad8b40dbbd27fd29e025371ee2b79f1866e69..ae1058fbfb5b23cae73bb9b31452902824a280c8 100644 (file)
@@ -1877,7 +1877,7 @@ static struct dentry *ovl_get_root(struct super_block *sb,
        ovl_dentry_set_flag(OVL_E_CONNECTED, root);
        ovl_set_upperdata(d_inode(root));
        ovl_inode_init(d_inode(root), &oip, ino, fsid);
-       ovl_dentry_update_reval(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
+       ovl_dentry_init_flags(root, upperdentry, DCACHE_OP_WEAK_REVALIDATE);
 
        return root;
 }
index 5a6f34c7ed03c239b823c91bf4299cfd592fcbed..fb12e7fa85486adf41d4f7ab7752b9d220f2d9a5 100644 (file)
@@ -94,14 +94,30 @@ struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
        return oe;
 }
 
+#define OVL_D_REVALIDATE (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE)
+
 bool ovl_dentry_remote(struct dentry *dentry)
 {
-       return dentry->d_flags &
-               (DCACHE_OP_REVALIDATE | DCACHE_OP_WEAK_REVALIDATE);
+       return dentry->d_flags & OVL_D_REVALIDATE;
+}
+
+void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *realdentry)
+{
+       if (!ovl_dentry_remote(realdentry))
+               return;
+
+       spin_lock(&dentry->d_lock);
+       dentry->d_flags |= realdentry->d_flags & OVL_D_REVALIDATE;
+       spin_unlock(&dentry->d_lock);
+}
+
+void ovl_dentry_init_reval(struct dentry *dentry, struct dentry *upperdentry)
+{
+       return ovl_dentry_init_flags(dentry, upperdentry, OVL_D_REVALIDATE);
 }
 
-void ovl_dentry_update_reval(struct dentry *dentry, struct dentry *upperdentry,
-                            unsigned int mask)
+void ovl_dentry_init_flags(struct dentry *dentry, struct dentry *upperdentry,
+                          unsigned int mask)
 {
        struct ovl_entry *oe = OVL_E(dentry);
        unsigned int i, flags = 0;