Instead of setting AOP_FLAG_NOFS, use memalloc_nofs_save() and memalloc_nofs_restore() to prevent GFP_FS allocations recursing into the filesystem with a journal already started. Signed-off-by: Matthew Wilcox (Oracle) <willy@xxxxxxxxxxxxx> Acked-by: Theodore Ts'o <tytso@xxxxxxx> --- fs/ext4/ext4.h | 1 - fs/ext4/inline.c | 16 ++++++++-------- fs/ext4/inode.c | 3 +-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index a743b1e3b89e..90677e30e52d 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -3604,7 +3604,6 @@ ext4_journalled_write_inline_data(struct inode *inode, extern int ext4_da_write_inline_data_begin(struct address_space *mapping, struct inode *inode, loff_t pos, unsigned len, - unsigned flags, struct page **pagep, void **fsdata); extern int ext4_try_add_inline_entry(handle_t *handle, diff --git a/fs/ext4/inline.c b/fs/ext4/inline.c index 93694ceb5a34..d965ba08f68f 100644 --- a/fs/ext4/inline.c +++ b/fs/ext4/inline.c @@ -906,7 +906,6 @@ static int ext4_da_convert_inline_data_to_extent(struct address_space *mapping, int ext4_da_write_inline_data_begin(struct address_space *mapping, struct inode *inode, loff_t pos, unsigned len, - unsigned flags, struct page **pagep, void **fsdata) { @@ -915,6 +914,7 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping, struct page *page; struct ext4_iloc iloc; int retries = 0; + unsigned int flags; ret = ext4_get_inode_loc(inode, &iloc); if (ret) @@ -931,12 +931,6 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping, if (ret && ret != -ENOSPC) goto out_journal; - /* - * We cannot recurse into the filesystem as the transaction - * is already started. - */ - flags |= AOP_FLAG_NOFS; - if (ret == -ENOSPC) { ext4_journal_stop(handle); ret = ext4_da_convert_inline_data_to_extent(mapping, @@ -948,7 +942,13 @@ int ext4_da_write_inline_data_begin(struct address_space *mapping, goto out; } - page = grab_cache_page_write_begin(mapping, 0, flags); + /* + * We cannot recurse into the filesystem as the transaction + * is already started. + */ + flags = memalloc_nofs_save(); + page = grab_cache_page_write_begin(mapping, 0, 0); + memalloc_nofs_restore(flags); if (!page) { ret = -ENOMEM; goto out_journal; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 646ece9b3455..21ebcb3c59ba 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2954,8 +2954,7 @@ static int ext4_da_write_begin(struct file *file, struct address_space *mapping, trace_ext4_da_write_begin(inode, pos, len, flags); if (ext4_test_inode_state(inode, EXT4_STATE_MAY_INLINE_DATA)) { - ret = ext4_da_write_inline_data_begin(mapping, inode, - pos, len, flags, + ret = ext4_da_write_inline_data_begin(mapping, inode, pos, len, pagep, fsdata); if (ret < 0) return ret; -- 2.34.1