diff options
author | Theodore Ts'o <tytso@mit.edu> | 2010-07-27 11:56:05 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-07-27 11:56:05 -0400 |
commit | 47def82672b3ba4e7c5e9a4fe48a556f8684d0d6 (patch) | |
tree | a0cfdaca8be99980c09d2b38ff676834c85ab2c4 /fs/jbd2/journal.c | |
parent | 40389687382bf0ae71458e7c0f828137a438a956 (diff) | |
download | lwn-47def82672b3ba4e7c5e9a4fe48a556f8684d0d6.tar.gz lwn-47def82672b3ba4e7c5e9a4fe48a556f8684d0d6.zip |
jbd2: Remove __GFP_NOFAIL from jbd2 layer
__GFP_NOFAIL is going away, so add our own retry loop. Also add
jbd2__journal_start() and jbd2__journal_restart() which take a gfp
mask, so that file systems can optionally (re)start transaction
handles using GFP_KERNEL. If they do this, then they need to be
prepared to handle receiving an PTR_ERR(-ENOMEM) error, and be ready
to reflect that error up to userspace.
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/jbd2/journal.c')
-rw-r--r-- | fs/jbd2/journal.c | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index f7bf15787d68..a79d3345b55a 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -41,6 +41,7 @@ #include <linux/hash.h> #include <linux/log2.h> #include <linux/vmalloc.h> +#include <linux/backing-dev.h> #define CREATE_TRACE_POINTS #include <trace/events/jbd2.h> @@ -48,8 +49,6 @@ #include <asm/uaccess.h> #include <asm/page.h> -EXPORT_SYMBOL(jbd2_journal_start); -EXPORT_SYMBOL(jbd2_journal_restart); EXPORT_SYMBOL(jbd2_journal_extend); EXPORT_SYMBOL(jbd2_journal_stop); EXPORT_SYMBOL(jbd2_journal_lock_updates); @@ -311,7 +310,17 @@ int jbd2_journal_write_metadata_buffer(transaction_t *transaction, */ J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in)); - new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL); +retry_alloc: + new_bh = alloc_buffer_head(GFP_NOFS); + if (!new_bh) { + /* + * Failure is not an option, but __GFP_NOFAIL is going + * away; so we retry ourselves here. + */ + congestion_wait(BLK_RW_ASYNC, HZ/50); + goto retry_alloc; + } + /* keep subsequent assertions sane */ new_bh->b_state = 0; init_buffer(new_bh, NULL, NULL); |