Skip to contentSkip to conversation

bufferhead: Add _gfp version for sb_getblk()

PATCH In review Nikolay Borisov 2 participants 6 messages Jun 30, 2015 – Jul 2, 2015 ext4 file system

lore
Share & tools
lore
#0 lore raw

PATCH 1/2 bufferhead: Add _gfp version for sb_getblk()

sb_getblk() is used during ext4 (and possibly other FSes) writeback paths. Sometimes such path require allocating memory and guaranteeing that such allocation won't block. Currently, however, there is no way to provide user flags for sb_getblk which could lead to deadlocks.

This patch implements a sb_getblk_gfp with the only difference it can accept user-provided GFP flags.

---

As per the discussion in this thread (http://marc.info/?l=linux-ext4&m=143563347324528&w=2)
here are the patches which hopefully implement Ted's suggestion.

 include/linux/buffer_head.h |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)
include/linux/buffer_head.h +7 -0
index 73b4522..e6797de 100644
@@ -317,6 +317,13 @@ sb_getblk(struct super_block *sb, sector_t block)
 	return __getblk_gfp(sb->s_bdev, block, sb->s_blocksize, __GFP_MOVABLE);
 }
 
+
+static inline struct buffer_head *
+sb_getblk_gfp(struct super_block *sb, sector_t block, gfp_t gfp)
+{
+	return __getblk_gfp(sb->s_bdev, block, sb->s_blocksize, gfp);
+}
+
 static inline struct buffer_head *
 sb_find_get_block(struct super_block *sb, sector_t block)
 {
Signature · 1 line
1.7.1
#1 lore raw

PATCH 2/2 ext4: make use of sb_getblk_gfp

Switch ext4 to using sb_getblk_gfp with GFP_NOFS added, this fixes possible deadlocks in the page writeback path.

---
 fs/ext4/extents.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)
fs/ext4/extents.c +3 -3
index e003a1e..87ba10d 100644
@@ -503,7 +503,7 @@ __read_extent_tree_block(const char *function, unsigned int line,
 	struct buffer_head		*bh;
 	int				err;
 
-	bh = sb_getblk(inode->i_sb, pblk);
+	bh = sb_getblk_gfp(inode->i_sb, pblk, __GFP_MOVABLE | GFP_NOFS);
 	if (unlikely(!bh))
 		return ERR_PTR(-ENOMEM);
 
@@ -1088,7 +1088,7 @@ static int ext4_ext_split(handle_t *handle, struct inode *inode,
 		err = -EIO;
 		goto cleanup;
 	}
-	bh = sb_getblk(inode->i_sb, newblock);
+	bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS);
 	if (unlikely(!bh)) {
 		err = -ENOMEM;
 		goto cleanup;
@@ -1282,7 +1282,7 @@ static int ext4_ext_grow_indepth(handle_t *handle, struct inode *inode,
 	if (newblock == 0)
 		return err;
 
-	bh = sb_getblk(inode->i_sb, newblock);
+	bh = sb_getblk_gfp(inode->i_sb, newblock, __GFP_MOVABLE | GFP_NOFS);
 	if (unlikely(!bh))
 		return -ENOMEM;
 	lock_buffer(bh);
Signature · 1 line
1.7.1
maintainer
#2 lore raw

Re: [PATCH 2/2] ext4: make use of sb_getblk_gfp

Quoted 4 lines · Nikolay Borisov

Switch ext4 to using sb_getblk_gfp with GFP_NOFS added, this fixes possible deadlocks in the page writeback path.

I've added this to the ext4.git tree, thanks.

- Ted

#3 lore raw

Re: [PATCH 2/2] ext4: make use of sb_getblk_gfp

Quoted 9 lines · Theodore Ts'o
Quoted 4 lines · Nikolay Borisov

Switch ext4 to using sb_getblk_gfp with GFP_NOFS added, this fixes possible deadlocks in the page writeback path.

I've added this to the ext4.git tree, thanks.

- Ted

Thanks!

Just a question that popped to my mind after discussing with a colleague
- Is GFP_NOFS enough here or should it be GFP_NOIO? Presumably the latter is a stronger guarantee that we are not going to hit any fs/writeback related code?

Nikolay

maintainer
#4 lore raw

Re: [PATCH 2/2] ext4: make use of sb_getblk_gfp

Quoted 5 lines · Nikolay Borisov

Just a question that popped to my mind after discussing with a colleague
- Is GFP_NOFS enough here or should it be GFP_NOIO? Presumably the latter is a stronger guarantee that we are not going to hit any fs/writeback related code?

GFP_NOFS is fine here; file system code calls the I/O codepaths, but device driver code doesn't call fs code. Put another way, if there are pages that are backed by a block device, which can be cleaned without going through the FS code paths, it's fine to let that happen while we are inside file system code.

- Ted

maintainer
#5 lore raw
In reply to Nikolay Borisov
Quoted 9 lines · Nikolay Borisov

sb_getblk() is used during ext4 (and possibly other FSes) writeback paths. Sometimes such path require allocating memory and guaranteeing that such allocation won't block. Currently, however, there is no way to provide user flags for sb_getblk which could lead to deadlocks.

This patch implements a sb_getblk_gfp with the only difference it can accept user-provided GFP flags.

I've added this to the ext4.git tree, thanks.

- Ted