diff options
author | Matthew L. Creech <mlcreech@gmail.com> | 2011-03-04 17:55:02 -0500 |
---|---|---|
committer | Artem Bityutskiy <Artem.Bityutskiy@nokia.com> | 2011-03-11 03:52:07 -0500 |
commit | d882962f6af2b484b62a7fb05ef959e1bf355fc4 (patch) | |
tree | 040a303908493e5edca3fe5c7aeecab2912bd3b0 /fs/ubifs/ubifs.h | |
parent | 2765df7da540687c4d57ca840182122f074c5b9c (diff) |
UBIFS: handle allocation failures in UBIFS write path
Running kernel 2.6.37, my PPC-based device occasionally gets an
order-2 allocation failure in UBIFS, which causes the root FS to
become unwritable:
kswapd0: page allocation failure. order:2, mode:0x4050
Call Trace:
[c787dc30] [c00085b8] show_stack+0x7c/0x194 (unreliable)
[c787dc70] [c0061aec] __alloc_pages_nodemask+0x4f0/0x57c
[c787dd00] [c0061b98] __get_free_pages+0x20/0x50
[c787dd10] [c00e4f88] ubifs_jnl_write_data+0x54/0x200
[c787dd50] [c00e82d4] do_writepage+0x94/0x198
[c787dd90] [c00675e4] shrink_page_list+0x40c/0x77c
[c787de40] [c0067de0] shrink_inactive_list+0x1e0/0x370
[c787de90] [c0068224] shrink_zone+0x2b4/0x2b8
[c787df00] [c0068854] kswapd+0x408/0x5d4
[c787dfb0] [c0037bcc] kthread+0x80/0x84
[c787dff0] [c000ef44] kernel_thread+0x4c/0x68
Similar problems were encountered last April by Tomasz Stanislawski:
http://patchwork.ozlabs.org/patch/50965/
This patch implements Artem's suggested fix: fall back to a
mutex-protected static buffer, allocated at mount time. I tested it
by forcing execution down the failure path, and didn't see any ill
effects.
Artem: massaged the patch a little, improved it so that we'd not
allocate the write reserve buffer when we are in R/O mode.
Signed-off-by: Matthew L. Creech <mlcreech@gmail.com>
Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
Diffstat (limited to 'fs/ubifs/ubifs.h')
-rw-r--r-- | fs/ubifs/ubifs.h | 14 |
1 files changed, 14 insertions, 0 deletions
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h index 362495078489..8c40ad3c6721 100644 --- a/fs/ubifs/ubifs.h +++ b/fs/ubifs/ubifs.h | |||
@@ -151,6 +151,12 @@ | |||
151 | */ | 151 | */ |
152 | #define WORST_COMPR_FACTOR 2 | 152 | #define WORST_COMPR_FACTOR 2 |
153 | 153 | ||
154 | /* | ||
155 | * How much memory is needed for a buffer where we comress a data node. | ||
156 | */ | ||
157 | #define COMPRESSED_DATA_NODE_BUF_SZ \ | ||
158 | (UBIFS_DATA_NODE_SZ + UBIFS_BLOCK_SIZE * WORST_COMPR_FACTOR) | ||
159 | |||
154 | /* Maximum expected tree height for use by bottom_up_buf */ | 160 | /* Maximum expected tree height for use by bottom_up_buf */ |
155 | #define BOTTOM_UP_HEIGHT 64 | 161 | #define BOTTOM_UP_HEIGHT 64 |
156 | 162 | ||
@@ -1005,6 +1011,11 @@ struct ubifs_debug_info; | |||
1005 | * @bu_mutex: protects the pre-allocated bulk-read buffer and @c->bu | 1011 | * @bu_mutex: protects the pre-allocated bulk-read buffer and @c->bu |
1006 | * @bu: pre-allocated bulk-read information | 1012 | * @bu: pre-allocated bulk-read information |
1007 | * | 1013 | * |
1014 | * @write_reserve_mutex: protects @write_reserve_buf | ||
1015 | * @write_reserve_buf: on the write path we allocate memory, which might | ||
1016 | * sometimes be unavailable, in which case we use this | ||
1017 | * write reserve buffer | ||
1018 | * | ||
1008 | * @log_lebs: number of logical eraseblocks in the log | 1019 | * @log_lebs: number of logical eraseblocks in the log |
1009 | * @log_bytes: log size in bytes | 1020 | * @log_bytes: log size in bytes |
1010 | * @log_last: last LEB of the log | 1021 | * @log_last: last LEB of the log |
@@ -1256,6 +1267,9 @@ struct ubifs_info { | |||
1256 | struct mutex bu_mutex; | 1267 | struct mutex bu_mutex; |
1257 | struct bu_info bu; | 1268 | struct bu_info bu; |
1258 | 1269 | ||
1270 | struct mutex write_reserve_mutex; | ||
1271 | void *write_reserve_buf; | ||
1272 | |||
1259 | int log_lebs; | 1273 | int log_lebs; |
1260 | long long log_bytes; | 1274 | long long log_bytes; |
1261 | int log_last; | 1275 | int log_last; |