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/overlayfs.h | 2 +- fs/overlayfs/ovl_entry.h | 13 ++++++++++++- fs/overlayfs/super.c | 9 ++++++--- fs/overlayfs/util.c | 21 ++++++++++++++++++--- 4 files changed, 37 insertions(+), 8 deletions(-) v2 changes: * ovl_free_entry() appeared to be not the only way to free ovl_entry, the second function is ovl_free_inode(), so include the kfree() there as well * create a single function ovl_stacks_put() for both lowerstack and lowerpaths put and rename ovl_stack_put() to prevent desync in the future diff --git a/fs/overlayfs/overlayfs.h b/fs/overlayfs/overlayfs.h index 163858e97e89..2e7aa23eb755 100644 --- a/fs/overlayfs/overlayfs.h +++ b/fs/overlayfs/overlayfs.h @@ -402,7 +402,7 @@ bool ovl_index_all(struct super_block *sb); bool ovl_verify_lower(struct super_block *sb); struct ovl_path *ovl_stack_alloc(unsigned int n); void ovl_stack_cpy(struct ovl_path *dst, struct ovl_path *src, unsigned int n); -void ovl_stack_put(struct ovl_path *stack, unsigned int n); +void ovl_stacks_put(struct ovl_entry *oe); void ovl_stack_free(struct ovl_path *stack, unsigned int n); struct ovl_entry *ovl_alloc_entry(unsigned int numlower); void ovl_free_entry(struct ovl_entry *oe); 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..2aeec05c1a34 100644 --- a/fs/overlayfs/super.c +++ b/fs/overlayfs/super.c @@ -213,6 +213,7 @@ static void ovl_free_inode(struct inode *inode) struct ovl_inode *oi = OVL_I(inode); kfree(oi->redirect); + kfree(ovl_lowerpaths(oi->oe)); kfree(oi->oe); mutex_destroy(&oi->lock); kmem_cache_free(ovl_inode_cachep, oi); @@ -223,7 +224,7 @@ static void ovl_destroy_inode(struct inode *inode) struct ovl_inode *oi = OVL_I(inode); dput(oi->__upperdentry); - ovl_stack_put(ovl_lowerstack(oi->oe), ovl_numlower(oi->oe)); + ovl_stacks_put(oi->oe); if (S_ISDIR(inode->i_mode)) ovl_dir_cache_free(inode); else @@ -386,7 +387,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); @@ -1854,7 +1856,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..21acc780ebfc 100644 --- a/fs/overlayfs/util.c +++ b/fs/overlayfs/util.c @@ -100,7 +100,7 @@ void ovl_stack_cpy(struct ovl_path *dst, struct ovl_path *src, unsigned int n) dget(src[i].dentry); } -void ovl_stack_put(struct ovl_path *stack, unsigned int n) +void __ovl_stack_put(struct ovl_path *stack, unsigned int n) { unsigned int i; @@ -110,10 +110,24 @@ void ovl_stack_put(struct ovl_path *stack, unsigned int n) void ovl_stack_free(struct ovl_path *stack, unsigned int n) { - ovl_stack_put(stack, n); + __ovl_stack_put(stack, 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_stacks_put(struct ovl_entry *oe) +{ + __ovl_stack_put(ovl_lowerstack(oe), ovl_numlower(oe)); + __ovl_lowerpaths_put(ovl_lowerpaths(oe), ovl_numlowerpaths(oe)); +} + struct ovl_entry *ovl_alloc_entry(unsigned int numlower) { size_t size = offsetof(struct ovl_entry, __lowerstack[numlower]); @@ -127,7 +141,8 @@ 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_stacks_put(oe); + kfree(ovl_lowerpaths(oe)); kfree(oe); } -- 2.43.5 _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel