]> git.ipfire.org Git - thirdparty/kernel/linux.git/blobdiff - fs/overlayfs/super.c
ovl: mark xwhiteouts directory with overlay.opaque='x'
[thirdparty/kernel/linux.git] / fs / overlayfs / super.c
index 4ab66e3d4cff9854a99bcc1505963927476bf1d5..2eef6c70b2aed54027b9ec2b1b544101ea32aefc 100644 (file)
@@ -1249,6 +1249,7 @@ static struct dentry *ovl_get_root(struct super_block *sb,
                                   struct ovl_entry *oe)
 {
        struct dentry *root;
+       struct ovl_fs *ofs = OVL_FS(sb);
        struct ovl_path *lowerpath = ovl_lowerstack(oe);
        unsigned long ino = d_inode(lowerpath->dentry)->i_ino;
        int fsid = lowerpath->layer->fsid;
@@ -1270,6 +1271,20 @@ static struct dentry *ovl_get_root(struct super_block *sb,
                        ovl_set_flag(OVL_IMPURE, d_inode(root));
        }
 
+       /* Look for xwhiteouts marker except in the lowermost layer */
+       for (int i = 0; i < ovl_numlower(oe) - 1; i++, lowerpath++) {
+               struct path path = {
+                       .mnt = lowerpath->layer->mnt,
+                       .dentry = lowerpath->dentry,
+               };
+
+               /* overlay.opaque=x means xwhiteouts directory */
+               if (ovl_get_opaquedir_val(ofs, &path) == 'x') {
+                       ovl_layer_set_xwhiteouts(ofs, lowerpath->layer);
+                       ovl_dentry_set_xwhiteouts(root);
+               }
+       }
+
        /* Root is always merge -> can have whiteouts */
        ovl_set_flag(OVL_WHITEOUTS, d_inode(root));
        ovl_dentry_set_flag(OVL_E_CONNECTED, root);