summaryrefslogtreecommitdiff
path: root/fs/btrfs
diff options
context:
space:
mode:
authorFilipe Manana <fdmanana@suse.com>2022-03-23 16:19:29 +0000
committerDavid Sterba <dsterba@suse.com>2022-05-16 17:03:10 +0200
commit4f208dcc6bf572fbe8178cfea703f139803863ba (patch)
tree58c998fbdae0f6dbef738d201c2d86c37b99bf1a /fs/btrfs
parent59d35c5171e65f3a208b6f44d028278f129bdeab (diff)
btrfs: avoid blocking when allocating context for nowait dio read/write
When doing a NOWAIT direct IO read/write, we allocate a context object (struct btrfs_dio_data) with GFP_NOFS, which can result in blocking waiting for memory allocation (GFP_NOFS is __GFP_RECLAIM | __GFP_IO). This is undesirable for the NOWAIT semantics, so do the allocation with GFP_NOWAIT if we are serving a NOWAIT request and if the allocation fails return -EAGAIN, so that the caller can fallback to a blocking context and retry with a non-blocking write. Signed-off-by: Filipe Manana <fdmanana@suse.com> Reviewed-by: David Sterba <dsterba@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/inode.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 1922c7004bf5..4254c3c7b9f7 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -7588,9 +7588,15 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
}
}
- dio_data = kzalloc(sizeof(*dio_data), GFP_NOFS);
- if (!dio_data)
- return -ENOMEM;
+ if (flags & IOMAP_NOWAIT) {
+ dio_data = kzalloc(sizeof(*dio_data), GFP_NOWAIT);
+ if (!dio_data)
+ return -EAGAIN;
+ } else {
+ dio_data = kzalloc(sizeof(*dio_data), GFP_NOFS);
+ if (!dio_data)
+ return -ENOMEM;
+ }
iomap->private = dio_data;