|
@@ -0,0 +1,121 @@
|
|
|
|
+From eee53f6eb7561f516b9c4bac829ce31c48096130 Mon Sep 17 00:00:00 2001
|
|
|
|
+From: Fabian Frederick <[email protected]>
|
|
|
|
+Date: Tue, 9 May 2017 22:30:03 +0200
|
|
|
|
+Subject: [PATCH] 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: c9f700f840bd ("[JFFS2][XATTR] using 'delete marker' for xdatum/xref deletion")
|
|
|
|
+Reported-by: Tim Gardner <[email protected]>
|
|
|
|
+Reported-by: kernel test robot <[email protected]>
|
|
|
|
+Reported-by: Ron Economos <[email protected]>
|
|
|
|
+Reported-by: Nathan Chancellor <[email protected]>
|
|
|
|
+Reviewed-by: Nick Desaulniers <[email protected]>
|
|
|
|
+Signed-off-by: Fabian Frederick <[email protected]>
|
|
|
|
+Signed-off-by: Christian Marangi <[email protected]>
|
|
|
|
+Cc: [email protected]
|
|
|
|
+---
|
|
|
|
+ fs/jffs2/build.c | 5 ++++-
|
|
|
|
+ fs/jffs2/xattr.c | 13 +++++++++----
|
|
|
|
+ fs/jffs2/xattr.h | 4 ++--
|
|
|
|
+ 3 files changed, 15 insertions(+), 7 deletions(-)
|
|
|
|
+
|
|
|
|
+--- a/fs/jffs2/build.c
|
|
|
|
++++ b/fs/jffs2/build.c
|
|
|
|
+@@ -211,7 +211,10 @@ static int jffs2_build_filesystem(struct
|
|
|
|
+ ic->scan_dents = NULL;
|
|
|
|
+ cond_resched();
|
|
|
|
+ }
|
|
|
|
+- jffs2_build_xattr_subsystem(c);
|
|
|
|
++ ret = jffs2_build_xattr_subsystem(c);
|
|
|
|
++ if (ret)
|
|
|
|
++ goto exit;
|
|
|
|
++
|
|
|
|
+ c->flags &= ~JFFS2_SB_FLAG_BUILDING;
|
|
|
|
+
|
|
|
|
+ dbg_fsbuild("FS build complete\n");
|
|
|
|
+--- a/fs/jffs2/xattr.c
|
|
|
|
++++ b/fs/jffs2/xattr.c
|
|
|
|
+@@ -772,10 +772,10 @@ void jffs2_clear_xattr_subsystem(struct
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ #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 *xref_tmphash[XREF_TMPHASH_SIZE];
|
|
|
|
++ struct jffs2_xattr_ref **xref_tmphash;
|
|
|
|
+ struct jffs2_xattr_datum *xd, *_xd;
|
|
|
|
+ struct jffs2_inode_cache *ic;
|
|
|
|
+ struct jffs2_raw_node_ref *raw;
|
|
|
|
+@@ -784,9 +784,12 @@ void jffs2_build_xattr_subsystem(struct
|
|
|
|
+
|
|
|
|
+ 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 */
|
|
|
|
+- for (i=0; i < XREF_TMPHASH_SIZE; i++)
|
|
|
|
+- xref_tmphash[i] = NULL;
|
|
|
|
+ for (ref=c->xref_temp; ref; ref=_ref) {
|
|
|
|
+ struct jffs2_xattr_ref *tmp;
|
|
|
|
+
|
|
|
|
+@@ -884,6 +887,8 @@ void jffs2_build_xattr_subsystem(struct
|
|
|
|
+ "%u of xref (%u dead, %u orphan) found.\n",
|
|
|
|
+ xdatum_count, xdatum_unchecked_count, xdatum_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,
|
|
|
|
+--- a/fs/jffs2/xattr.h
|
|
|
|
++++ b/fs/jffs2/xattr.h
|
|
|
|
+@@ -71,7 +71,7 @@ static inline int is_xattr_ref_dead(stru
|
|
|
|
+ #ifdef CONFIG_JFFS2_FS_XATTR
|
|
|
|
+
|
|
|
|
+ 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 struct jffs2_xattr_datum *jffs2_setup_xattr_datum(struct jffs2_sb_info *c,
|
|
|
|
+@@ -103,7 +103,7 @@ extern ssize_t jffs2_listxattr(struct de
|
|
|
|
+ #else
|
|
|
|
+
|
|
|
|
+ #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_xattr_do_crccheck_inode(c, ic)
|