diff options
Diffstat (limited to 'fs/ext4/page-io.c')
-rw-r--r-- | fs/ext4/page-io.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index d77d15f4b674..e4fc8ea45d78 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/kernel.h> | 23 | #include <linux/kernel.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/mm.h> | 25 | #include <linux/mm.h> |
26 | #include <linux/backing-dev.h> | ||
26 | 27 | ||
27 | #include "ext4_jbd2.h" | 28 | #include "ext4_jbd2.h" |
28 | #include "xattr.h" | 29 | #include "xattr.h" |
@@ -432,8 +433,8 @@ int ext4_bio_write_page(struct ext4_io_submit *io, | |||
432 | * the page size, the remaining memory is zeroed when mapped, and | 433 | * the page size, the remaining memory is zeroed when mapped, and |
433 | * writes to that region are not written out to the file." | 434 | * writes to that region are not written out to the file." |
434 | */ | 435 | */ |
435 | if (len < PAGE_CACHE_SIZE) | 436 | if (len < PAGE_SIZE) |
436 | zero_user_segment(page, len, PAGE_CACHE_SIZE); | 437 | zero_user_segment(page, len, PAGE_SIZE); |
437 | /* | 438 | /* |
438 | * In the first loop we prepare and mark buffers to submit. We have to | 439 | * In the first loop we prepare and mark buffers to submit. We have to |
439 | * mark all buffers in the page before submitting so that | 440 | * mark all buffers in the page before submitting so that |
@@ -470,9 +471,20 @@ int ext4_bio_write_page(struct ext4_io_submit *io, | |||
470 | 471 | ||
471 | if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) && | 472 | if (ext4_encrypted_inode(inode) && S_ISREG(inode->i_mode) && |
472 | nr_to_submit) { | 473 | nr_to_submit) { |
473 | data_page = ext4_encrypt(inode, page); | 474 | gfp_t gfp_flags = GFP_NOFS; |
475 | |||
476 | retry_encrypt: | ||
477 | data_page = ext4_encrypt(inode, page, gfp_flags); | ||
474 | if (IS_ERR(data_page)) { | 478 | if (IS_ERR(data_page)) { |
475 | ret = PTR_ERR(data_page); | 479 | ret = PTR_ERR(data_page); |
480 | if (ret == -ENOMEM && wbc->sync_mode == WB_SYNC_ALL) { | ||
481 | if (io->io_bio) { | ||
482 | ext4_io_submit(io); | ||
483 | congestion_wait(BLK_RW_ASYNC, HZ/50); | ||
484 | } | ||
485 | gfp_flags |= __GFP_NOFAIL; | ||
486 | goto retry_encrypt; | ||
487 | } | ||
476 | data_page = NULL; | 488 | data_page = NULL; |
477 | goto out; | 489 | goto out; |
478 | } | 490 | } |