lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200526071754.33819-6-yi.zhang@huawei.com>
Date:   Tue, 26 May 2020 15:17:49 +0800
From:   "zhangyi (F)" <yi.zhang@...wei.com>
To:     <linux-ext4@...r.kernel.org>
CC:     <tytso@....edu>, <jack@...e.cz>, <adilger.kernel@...ger.ca>,
        <yi.zhang@...wei.com>, <zhangxiaoxu5@...wei.com>
Subject: [PATCH 05/10] ext4: replace sb_bread*() with ext4_sb_bread*()

For the cases of sb_bread() and sb_bread_unmovable(), we also need to
check the buffer is actually uptodate or not and fix the uptodate flag.

Add a wrapper function ext4_sb_bread_unmovable() and replace all
sb_bread*() with ext4_sb_bread*().

Signed-off-by: zhangyi (F) <yi.zhang@...wei.com>
---
 fs/ext4/ext4.h     | 17 +++++++++++++++--
 fs/ext4/indirect.c |  6 +++---
 fs/ext4/resize.c   | 12 ++++++------
 fs/ext4/super.c    | 33 +++++++++++++++++++--------------
 4 files changed, 43 insertions(+), 25 deletions(-)

diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 2ee76efd029b..609c2b555d29 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2763,8 +2763,9 @@ extern struct buffer_head *__ext4_sb_getblk_gfp(struct super_block *sb,
 						gfp_t gfp);
 extern struct buffer_head *__ext4_sb_getblk(struct super_block *sb,
 					     sector_t block, bool lock);
-extern struct buffer_head *ext4_sb_bread(struct super_block *sb,
-					 sector_t block, int op_flags);
+extern struct buffer_head *__ext4_sb_bread_gfp(struct super_block *sb,
+					       sector_t block, int op_flags,
+					       gfp_t gfp);
 extern int ext4_seq_options_show(struct seq_file *seq, void *offset);
 extern int ext4_calculate_overhead(struct super_block *sb);
 extern void ext4_superblock_csum_set(struct super_block *sb);
@@ -2969,6 +2970,18 @@ ext4_sb_getblk_locked(struct super_block *sb, sector_t block)
 	return __ext4_sb_getblk(sb, block, true);
 }
 
+static inline struct buffer_head *
+ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags)
+{
+	return __ext4_sb_bread_gfp(sb, block, op_flags, __GFP_MOVABLE);
+}
+
+static inline struct buffer_head *
+ext4_sb_bread_unmovable(struct super_block *sb, sector_t block)
+{
+	return __ext4_sb_bread_gfp(sb, block, 0, 0);
+}
+
 static inline int ext4_has_metadata_csum(struct super_block *sb)
 {
 	WARN_ON_ONCE(ext4_has_feature_metadata_csum(sb) &&
diff --git a/fs/ext4/indirect.c b/fs/ext4/indirect.c
index 8dcbf21439c1..bd4d86211ab8 100644
--- a/fs/ext4/indirect.c
+++ b/fs/ext4/indirect.c
@@ -1012,14 +1012,14 @@ static void ext4_free_branches(handle_t *handle, struct inode *inode,
 			}
 
 			/* Go read the buffer for the next level down */
-			bh = sb_bread(inode->i_sb, nr);
+			bh = ext4_sb_bread(inode->i_sb, nr, 0);
 
 			/*
 			 * A read failure? Report error and clear slot
 			 * (should be rare).
 			 */
-			if (!bh) {
-				ext4_error_inode_block(inode, nr, EIO,
+			if (IS_ERR(bh)) {
+				ext4_error_inode_block(inode, nr, PTR_ERR(bh),
 						       "Read failure");
 				continue;
 			}
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c
index 414198e4d873..ff018e63bb55 100644
--- a/fs/ext4/resize.c
+++ b/fs/ext4/resize.c
@@ -1806,10 +1806,10 @@ int ext4_group_extend(struct super_block *sb, struct ext4_super_block *es,
 			     o_blocks_count + add, add);
 
 	/* See if the device is actually as big as what was requested */
-	bh = sb_bread(sb, o_blocks_count + add - 1);
-	if (!bh) {
+	bh = ext4_sb_bread(sb, o_blocks_count + add - 1, 0);
+	if (IS_ERR(bh)) {
 		ext4_warning(sb, "can't read last block, resize aborted");
-		return -ENOSPC;
+		return PTR_ERR(bh);
 	}
 	brelse(bh);
 
@@ -1932,10 +1932,10 @@ int ext4_resize_fs(struct super_block *sb, ext4_fsblk_t n_blocks_count)
 	int meta_bg;
 
 	/* See if the device is actually as big as what was requested */
-	bh = sb_bread(sb, n_blocks_count - 1);
-	if (!bh) {
+	bh = ext4_sb_bread(sb, n_blocks_count - 1, 0);
+	if (IS_ERR(bh)) {
 		ext4_warning(sb, "can't read last block, resize aborted");
-		return -ENOSPC;
+		return PTR_ERR(bh);
 	}
 	brelse(bh);
 
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 111fff55fada..b9aab334a5d0 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -194,17 +194,18 @@ __ext4_sb_getblk(struct super_block *sb, sector_t block, bool lock)
 }
 
 /*
- * This works like sb_bread() except it uses ERR_PTR for error
- * returns.  Currently with sb_bread it's impossible to distinguish
- * between ENOMEM and EIO situations (since both result in a NULL
- * return.
+ * This works like __bread_gfp() except it allow to pass op_flags and
+ * uses ERR_PTR for error returns.  Currently with sb_bread it's
+ * impossible to distinguish between ENOMEM and EIO situations (since
+ * both result in a NULL return.
  */
 struct buffer_head *
-ext4_sb_bread(struct super_block *sb, sector_t block, int op_flags)
+__ext4_sb_bread_gfp(struct super_block *sb, sector_t block,
+		    int op_flags, gfp_t gfp)
 {
 	struct buffer_head *bh;
 
-	bh = ext4_sb_getblk_locked(sb, block);
+	bh = ext4_sb_getblk_locked_gfp(sb, block, gfp);
 	if (bh == NULL)
 		return ERR_PTR(-ENOMEM);
 	if (buffer_uptodate(bh))
@@ -3777,8 +3778,10 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		logical_sb_block = sb_block;
 	}
 
-	if (!(bh = sb_bread_unmovable(sb, logical_sb_block))) {
-		ext4_msg(sb, KERN_ERR, "unable to read superblock");
+	bh = ext4_sb_bread_unmovable(sb, logical_sb_block);
+	if (IS_ERR(bh)) {
+		ext4_msg(sb, KERN_ERR,
+			 "unable to read superblock: %ld", PTR_ERR(bh));
 		goto out_fail;
 	}
 	/*
@@ -4175,10 +4178,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		brelse(bh);
 		logical_sb_block = sb_block * EXT4_MIN_BLOCK_SIZE;
 		offset = do_div(logical_sb_block, blocksize);
-		bh = sb_bread_unmovable(sb, logical_sb_block);
-		if (!bh) {
+		bh = ext4_sb_bread_unmovable(sb, logical_sb_block);
+		if (IS_ERR(bh)) {
 			ext4_msg(sb, KERN_ERR,
-			       "Can't read superblock on 2nd try");
+				 "Can't read superblock on 2nd try: %ld",
+				 PTR_ERR(bh));
 			goto failed_mount;
 		}
 		es = (struct ext4_super_block *)(bh->b_data + offset);
@@ -4398,10 +4402,11 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
 		struct buffer_head *bh;
 
 		block = descriptor_loc(sb, logical_sb_block, i);
-		bh = sb_bread_unmovable(sb, block);
-		if (!bh) {
+		bh = ext4_sb_bread_unmovable(sb, block);
+		if (IS_ERR(bh)) {
 			ext4_msg(sb, KERN_ERR,
-			       "can't read group descriptor %d", i);
+				 "can't read group descriptor %d: %ld",
+				 i, PTR_ERR(bh));
 			db_count = i;
 			goto failed_mount2;
 		}
-- 
2.21.3

Powered by blists - more mailing lists