jffs2: reduce stack usage in jffs2_build_xattr_subsystem()

Use kcalloc() for allocation/flush of 128 pointers table to
reduce stack usage.

Function now returns -ENOMEM or 0 on success.

stackusage
Before:
./fs/jffs2/xattr.c:775  jffs2_build_xattr_subsystem     1208
dynamic,bounded

After:
./fs/jffs2/xattr.c:775  jffs2_build_xattr_subsystem     192
dynamic,bounded

Also update definition when CONFIG_JFFS2_FS_XATTR is not enabled

Tested with an MTD mount point and some user set/getfattr.

Many current target on OpenWRT also suffer from a compilation warning
(that become an error with CONFIG_WERROR) with the following output:

fs/jffs2/xattr.c: In function 'jffs2_build_xattr_subsystem':
fs/jffs2/xattr.c:887:1: error: the frame size of 1088 bytes is larger than 1024 bytes [-Werror=frame-larger-than=]
  887 | }
      | ^

Using dynamic allocation fix this compilation warning.

Fixes: c9f700f840 ("[JFFS2][XATTR] using 'delete marker' for xdatum/xref deletion")
Reported-by: Tim Gardner <tim.gardner@canonical.com>
Reported-by: kernel test robot <lkp@intel.com>
Reported-by: Ron Economos <re@w6rz.net>
Reported-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Nick Desaulniers <ndesaulniers@google.com>
Signed-off-by: Fabian Frederick <fabf@skynet.be>
Signed-off-by: Christian Marangi <ansuelsmth@gmail.com>
Cc: stable@vger.kernel.org
Message-Id: <20230506045612.16616-1-ansuelsmth@gmail.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Fabian Frederick 2023-05-06 06:56:12 +02:00 committed by Christian Brauner
parent 55650b2fdd
commit 1168f09541
3 changed files with 15 additions and 7 deletions

View File

@ -211,7 +211,10 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
ic->scan_dents = NULL; ic->scan_dents = NULL;
cond_resched(); cond_resched();
} }
jffs2_build_xattr_subsystem(c); ret = jffs2_build_xattr_subsystem(c);
if (ret)
goto exit;
c->flags &= ~JFFS2_SB_FLAG_BUILDING; c->flags &= ~JFFS2_SB_FLAG_BUILDING;
dbg_fsbuild("FS build complete\n"); dbg_fsbuild("FS build complete\n");

View File

@ -772,10 +772,10 @@ void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c)
} }
#define XREF_TMPHASH_SIZE (128) #define XREF_TMPHASH_SIZE (128)
void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c) int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
{ {
struct jffs2_xattr_ref *ref, *_ref; struct jffs2_xattr_ref *ref, *_ref;
struct jffs2_xattr_ref *xref_tmphash[XREF_TMPHASH_SIZE]; struct jffs2_xattr_ref **xref_tmphash;
struct jffs2_xattr_datum *xd, *_xd; struct jffs2_xattr_datum *xd, *_xd;
struct jffs2_inode_cache *ic; struct jffs2_inode_cache *ic;
struct jffs2_raw_node_ref *raw; struct jffs2_raw_node_ref *raw;
@ -784,9 +784,12 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING)); BUG_ON(!(c->flags & JFFS2_SB_FLAG_BUILDING));
xref_tmphash = kcalloc(XREF_TMPHASH_SIZE,
sizeof(struct jffs2_xattr_ref *), GFP_KERNEL);
if (!xref_tmphash)
return -ENOMEM;
/* Phase.1 : Merge same xref */ /* Phase.1 : Merge same xref */
for (i=0; i < XREF_TMPHASH_SIZE; i++)
xref_tmphash[i] = NULL;
for (ref=c->xref_temp; ref; ref=_ref) { for (ref=c->xref_temp; ref; ref=_ref) {
struct jffs2_xattr_ref *tmp; struct jffs2_xattr_ref *tmp;
@ -884,6 +887,8 @@ void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c)
"%u of xref (%u dead, %u orphan) found.\n", "%u of xref (%u dead, %u orphan) found.\n",
xdatum_count, xdatum_unchecked_count, xdatum_orphan_count, xdatum_count, xdatum_unchecked_count, xdatum_orphan_count,
xref_count, xref_dead_count, xref_orphan_count); xref_count, xref_dead_count, xref_orphan_count);
kfree(xref_tmphash);
return 0;
} }
struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,

View File

@ -71,7 +71,7 @@ static inline int is_xattr_ref_dead(struct jffs2_xattr_ref *ref)
#ifdef CONFIG_JFFS2_FS_XATTR #ifdef CONFIG_JFFS2_FS_XATTR
extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c); extern void jffs2_init_xattr_subsystem(struct jffs2_sb_info *c);
extern void jffs2_build_xattr_subsystem(struct jffs2_sb_info *c); extern int jffs2_build_xattr_subsystem(struct jffs2_sb_info *c);
extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c); extern void jffs2_clear_xattr_subsystem(struct jffs2_sb_info *c);
extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c, extern struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
@ -103,7 +103,7 @@ extern ssize_t jffs2_listxattr(struct dentry *, char *, size_t);
#else #else
#define jffs2_init_xattr_subsystem(c) #define jffs2_init_xattr_subsystem(c)
#define jffs2_build_xattr_subsystem(c) #define jffs2_build_xattr_subsystem(c) (0)
#define jffs2_clear_xattr_subsystem(c) #define jffs2_clear_xattr_subsystem(c)
#define jffs2_xattr_do_crccheck_inode(c, ic) #define jffs2_xattr_do_crccheck_inode(c, ic)