From 4f208dcc6bf572fbe8178cfea703f139803863ba Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 23 Mar 2022 16:19:29 +0000 Subject: 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 Reviewed-by: David Sterba Signed-off-by: David Sterba --- fs/btrfs/inode.c | 12 +++++++++--- 1 file 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; -- cgit v1.2.3-58-ga151