ext4: Use scoped memory APIs in ext4_da_write_begin()
authorMatthew Wilcox (Oracle) <willy@infradead.org>
Tue, 22 Feb 2022 15:36:28 +0000 (10:36 -0500)
committerMatthew Wilcox (Oracle) <willy@infradead.org>
Sun, 8 May 2022 18:28:19 +0000 (14:28 -0400)
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@infradead.org>
Acked-by: Theodore Ts'o <tytso@mit.edu>
fs/ext4/ext4.h
fs/ext4/inline.c
fs/ext4/inode.c

index a743b1e3b89ec2d58e8f427ba345e55801a62a41..90677e30e52d7d5230e6c97436d7c2be9b08b3ca 100644 (file)
@@ -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,
index 93694ceb5a34249e01e05e57b2f1e5cfb9cb8c7e..d965ba08f68fb68d7059130da2338194190a70e2 100644 (file)
@@ -906,7 +906,6 @@ out:
 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 @@ retry_journal:
        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 @@ retry_journal:
                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;
index 646ece9b3455ffc04007f330974e3f2284e01bc1..21ebcb3c59bae61076442ab122bae5978c289e72 100644 (file)
@@ -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;