RedHat in RHEL9.4 has backported overlayfs data-only lower layers
feature (ms commit 37ebf056d6cf ("ovl: introduce data-only lower layers")), so 
we have to adjust our dynamic path resolving feature.

Additionally store number of lowerpaths as it now differs from saved
number of lowerstacks due to data-only lower layers presence.

Fixes: 5f2c7b5e4d33 ("overlayfs: add dynamic path resolving in mount
options")
https://virtuozzo.atlassian.net/browse/PSBM-157244

Signed-off-by: Konstantin Khorenko <khore...@virtuozzo.com>
---
 fs/overlayfs/ovl_entry.h | 13 ++++++++++++-
 fs/overlayfs/super.c     | 10 ++++++----
 fs/overlayfs/util.c      | 18 ++++++++++++++++++
 3 files changed, 36 insertions(+), 5 deletions(-)

diff --git a/fs/overlayfs/ovl_entry.h b/fs/overlayfs/ovl_entry.h
index f30de89e1f72..9d95ccdb3e3f 100644
--- a/fs/overlayfs/ovl_entry.h
+++ b/fs/overlayfs/ovl_entry.h
@@ -52,8 +52,9 @@ struct ovl_path {
 };
 
 struct ovl_entry {
+       unsigned int __numlowerpaths;
        unsigned int __numlower;
-       struct path *lowerpaths;
+       struct path *__lowerpaths;
        struct ovl_path __lowerstack[];
 };
 
@@ -125,6 +126,16 @@ static inline bool ovl_should_sync(struct ovl_fs *ofs)
        return !ofs->config.ovl_volatile;
 }
 
+static inline unsigned int ovl_numlowerpaths(struct ovl_entry *oe)
+{
+       return oe ? oe->__numlowerpaths : 0;
+}
+
+static inline struct path *ovl_lowerpaths(struct ovl_entry *oe)
+{
+       return ovl_numlowerpaths(oe) ? oe->__lowerpaths : NULL;
+}
+
 static inline unsigned int ovl_numlower(struct ovl_entry *oe)
 {
        return oe ? oe->__numlower : 0;
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index e9e8602291e0..b3dcd11bf5e0 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -386,7 +386,8 @@ static int ovl_show_options(struct seq_file *m, struct 
dentry *dentry)
        struct ovl_entry *oe = OVL_E(sb->s_root);
 
        if (ovl_dyn_path_opts) {
-               print_paths_option(m, "lowerdir", oe->lowerpaths, 
ovl_numlower(oe));
+               print_paths_option(m, "lowerdir", ovl_lowerpaths(oe),
+                                  ovl_numlowerpaths(oe));
                if (ofs->config.upperdir) {
                        print_path_option(m, "upperdir", &ofs->upperpath);
                        print_path_option(m, "workdir", &ofs->workbasepath);
@@ -400,8 +401,8 @@ static int ovl_show_options(struct seq_file *m, struct 
dentry *dentry)
        }
 
        if (ovl_mnt_id_path_opts) {
-               print_mnt_ids_option(m, "lowerdir_mnt_id", oe->lowerpaths,
-                                    ovl_numlower(oe));
+               print_mnt_ids_option(m, "lowerdir_mnt_id", ovl_lowerpaths(oe),
+                                    ovl_numlowerpaths(oe));
                /*
                 * We don't need to show mnt_id for workdir because it
                 * on the same mount as upperdir.
@@ -1854,7 +1855,8 @@ static struct ovl_entry *ovl_get_lowerstack(struct 
super_block *sb,
                lowerstack[i].dentry = dget(stack[i].dentry);
                lowerstack[i].layer = &ofs->layers[i+1];
        }
-       oe->lowerpaths = stack;
+       oe->__numlowerpaths = numlower;
+       oe->__lowerpaths = stack;
 
 out:
        return oe;
diff --git a/fs/overlayfs/util.c b/fs/overlayfs/util.c
index 3676eaa83f7d..2480041d70ae 100644
--- a/fs/overlayfs/util.c
+++ b/fs/overlayfs/util.c
@@ -114,6 +114,23 @@ void ovl_stack_free(struct ovl_path *stack, unsigned int n)
        kfree(stack);
 }
 
+void ovl_lowerpaths_put(struct path *lowerpaths, unsigned int n)
+{
+       unsigned int i;
+
+       for (i = 0; i < n; i++)
+               path_put(&lowerpaths[i]);
+}
+
+void ovl_lowerpaths_free(struct path *lowerpaths, unsigned int n)
+{
+       if (!n)
+               return;
+
+       ovl_lowerpaths_put(lowerpaths, n);
+       kfree(lowerpaths);
+}
+
 struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
 {
        size_t size = offsetof(struct ovl_entry, __lowerstack[numlower]);
@@ -128,6 +145,7 @@ struct ovl_entry *ovl_alloc_entry(unsigned int numlower)
 void ovl_free_entry(struct ovl_entry *oe)
 {
        ovl_stack_put(ovl_lowerstack(oe), ovl_numlower(oe));
+       ovl_lowerpaths_free(ovl_lowerpaths(oe), ovl_numlowerpaths(oe));
        kfree(oe);
 }
 
-- 
2.43.5

_______________________________________________
Devel mailing list
Devel@openvz.org
https://lists.openvz.org/mailman/listinfo/devel

Reply via email to