[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20200526071754.33819-8-yi.zhang@huawei.com>
Date: Tue, 26 May 2020 15:17:51 +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 07/10] ext4: switch to use ext4_sb_getblk_locked() in ext4_getblk()
For the cases of getting blocks for reading in ext4_getblk()
(e.g. ext4_bread() and ext4_bread_batch()), they are also need to check
the write io error flag before read. Switch to use ext4_sb_getblk_locked()
instead.
Signed-off-by: zhangyi (F) <yi.zhang@...wei.com>
---
fs/ext4/ext4.h | 3 ++-
fs/ext4/inode.c | 22 +++++++++++++---------
fs/ext4/xattr.c | 2 +-
3 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 609c2b555d29..81c1bdfb9397 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -2642,7 +2642,8 @@ extern void ext4_process_freed_data(struct super_block *sb, tid_t commit_tid);
/* inode.c */
int ext4_inode_is_fast_symlink(struct inode *inode);
-struct buffer_head *ext4_getblk(handle_t *, struct inode *, ext4_lblk_t, int);
+struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
+ ext4_lblk_t block, bool lock, int map_flags);
struct buffer_head *ext4_bread(handle_t *, struct inode *, ext4_lblk_t, int);
int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count,
bool wait, struct buffer_head **bhs);
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 97dc77ec7c3e..4989a9633fc7 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -811,7 +811,8 @@ int ext4_get_block_unwritten(struct inode *inode, sector_t iblock,
* `handle' can be NULL if create is zero
*/
struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
- ext4_lblk_t block, int map_flags)
+ ext4_lblk_t block, bool lock,
+ int map_flags)
{
struct ext4_map_blocks map;
struct buffer_head *bh;
@@ -829,7 +830,8 @@ struct buffer_head *ext4_getblk(handle_t *handle, struct inode *inode,
if (err < 0)
return ERR_PTR(err);
- bh = ext4_sb_getblk(inode->i_sb, map.m_pblk);
+ bh = __ext4_sb_getblk(inode->i_sb, map.m_pblk,
+ lock && !(map.m_flags & EXT4_MAP_NEW));
if (unlikely(!bh))
return ERR_PTR(-ENOMEM);
if (map.m_flags & EXT4_MAP_NEW) {
@@ -872,12 +874,12 @@ struct buffer_head *ext4_bread(handle_t *handle, struct inode *inode,
{
struct buffer_head *bh;
- bh = ext4_getblk(handle, inode, block, map_flags);
+ bh = ext4_getblk(handle, inode, block, true, map_flags);
if (IS_ERR(bh))
return bh;
- if (!bh || ext4_buffer_uptodate(bh))
+ if (!bh || buffer_uptodate(bh))
return bh;
- ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1, &bh);
+ ll_rw_one_block(REQ_OP_READ, REQ_META | REQ_PRIO, bh);
wait_on_buffer(bh);
if (buffer_uptodate(bh))
return bh;
@@ -892,7 +894,7 @@ int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count,
int i, err;
for (i = 0; i < bh_count; i++) {
- bhs[i] = ext4_getblk(NULL, inode, block + i, 0 /* map_flags */);
+ bhs[i] = ext4_getblk(NULL, inode, block + i, true, 0);
if (IS_ERR(bhs[i])) {
err = PTR_ERR(bhs[i]);
bh_count = i;
@@ -902,9 +904,9 @@ int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count,
for (i = 0; i < bh_count; i++)
/* Note that NULL bhs[i] is valid because of holes. */
- if (bhs[i] && !ext4_buffer_uptodate(bhs[i]))
- ll_rw_block(REQ_OP_READ, REQ_META | REQ_PRIO, 1,
- &bhs[i]);
+ if (bhs[i] && !buffer_uptodate(bhs[i]))
+ ll_rw_one_block(REQ_OP_READ, REQ_META | REQ_PRIO,
+ bhs[i]);
if (!wait)
return 0;
@@ -923,6 +925,8 @@ int ext4_bread_batch(struct inode *inode, ext4_lblk_t block, int bh_count,
out_brelse:
for (i = 0; i < bh_count; i++) {
+ if (bhs[i] && buffer_locked(bhs[i]))
+ unlock_buffer(bhs[i]);
brelse(bhs[i]);
bhs[i] = NULL;
}
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index e2ba4e631b02..828a23a0e772 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -1358,7 +1358,7 @@ static int ext4_xattr_inode_write(handle_t *handle, struct inode *ea_inode,
brelse(bh);
csize = (bufsize - wsize) > blocksize ? blocksize :
bufsize - wsize;
- bh = ext4_getblk(handle, ea_inode, block, 0);
+ bh = ext4_getblk(handle, ea_inode, block, false, 0);
if (IS_ERR(bh))
return PTR_ERR(bh);
if (!bh) {
--
2.21.3
Powered by blists - more mailing lists