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 f658cc8..95dce24 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 fc25fb9..9be52d8 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 defd4e2..5c36fb3 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 cfb3420..100a492 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 7398de3..2b79a93 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 f97ad8b..ae1058f 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 5a6f34c..fb12e7f 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;