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