]> git.hungrycats.org Git - linux/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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 11 Jul 2023 17:39:44 +0000 (19:39 +0200)
[ Upstream commit b07d5cc93e1b28df47a72c519d09d0a836043613 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
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 c14e90764e356565cf25561ea92793526e760c47..7bf101e756c8ce342758d46d49413d2c66d89c53 100644 (file)
@@ -576,6 +576,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);
@@ -895,6 +896,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 4d0b278f5630ea9a4d1b4f62277cb9646e128d57..e100c55bb924a8b99e9dc397badecfb448d86509 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 f1d9f75f8786ce51ae60723eff63dac5b59c9f7f..49b6956468f9e5af16e6fc18ee03a7eafa1c82fd 100644 (file)
@@ -1885,7 +1885,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 923d66d131c16cc5511af31f1f776a1668437dbd..6a0652bd51f2403943b84b35f3d72f349e143f59 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;