From: Fan Yong Date: Fri, 2 Oct 2015 05:21:21 +0000 (+0800) Subject: LU-7343 osd-ldiskfs: handle ldiskfs_append failure X-Git-Tag: 2.7.64~30 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=113aac9c212d63ec880a9731bd9a364f9b9a99bf;ds=sidebyside LU-7343 osd-ldiskfs: handle ldiskfs_append failure In new linux kernel (linux-3.1x, x>=0), the ldiskfs exported function ldiskfs_append() return error# via the return value, instead of via the output parameter @err as it does on other kernels (linux-2.6). Under such case, the caller should not assume non-NULL returned value is valid buffer head, it can stands for error#. So check that properly. Signed-off-by: Fan Yong Change-Id: I4dca43bcfd31aafd999f54934a51d258071dab22 Reviewed-on: http://review.whamcloud.com/17148 Tested-by: Jenkins Reviewed-by: Yang Sheng Tested-by: Maloo Reviewed-by: Andreas Dilger --- diff --git a/lustre/osd-ldiskfs/osd_iam.c b/lustre/osd-ldiskfs/osd_iam.c index 2c2ff27..360b7a4 100644 --- a/lustre/osd-ldiskfs/osd_iam.c +++ b/lustre/osd-ldiskfs/osd_iam.c @@ -1732,7 +1732,12 @@ got: return bh; newblock: - bh = osd_ldiskfs_append(h, inode, b, e); + bh = osd_ldiskfs_append(h, inode, b); + if (IS_ERR(bh)) { + *e = PTR_ERR(bh); + bh = NULL; + } + return bh; fail: diff --git a/lustre/osd-ldiskfs/osd_iam_lfix.c b/lustre/osd-ldiskfs/osd_iam_lfix.c index ba408b2..3416c0d 100644 --- a/lustre/osd-ldiskfs/osd_iam_lfix.c +++ b/lustre/osd-ldiskfs/osd_iam_lfix.c @@ -862,20 +862,29 @@ int iam_lfix_create(struct inode *obj, sb = obj->i_sb; bsize = sb->s_blocksize; - root_node = osd_ldiskfs_append(handle, obj, &blknr, &result); - leaf_node = osd_ldiskfs_append(handle, obj, &blknr, &result); - if (root_node != NULL && leaf_node != NULL) { - lfix_root(root_node->b_data, bsize, keysize, ptrsize, recsize); - lfix_leaf(leaf_node->b_data, bsize, keysize, ptrsize, recsize); - ldiskfs_mark_inode_dirty(handle, obj); - result = ldiskfs_handle_dirty_metadata(handle, NULL, root_node); - if (result == 0) - result = ldiskfs_handle_dirty_metadata(handle, NULL, - leaf_node); - if (result != 0) - ldiskfs_std_error(sb, result); - } - brelse(leaf_node); - brelse(root_node); - return result; + root_node = osd_ldiskfs_append(handle, obj, &blknr); + if (IS_ERR(root_node)) + GOTO(out, result = PTR_ERR(root_node)); + + leaf_node = osd_ldiskfs_append(handle, obj, &blknr); + if (IS_ERR(leaf_node)) + GOTO(out_root, result = PTR_ERR(leaf_node)); + + lfix_root(root_node->b_data, bsize, keysize, ptrsize, recsize); + lfix_leaf(leaf_node->b_data, bsize, keysize, ptrsize, recsize); + ldiskfs_mark_inode_dirty(handle, obj); + result = ldiskfs_handle_dirty_metadata(handle, NULL, root_node); + if (result == 0) + result = ldiskfs_handle_dirty_metadata(handle, NULL, leaf_node); + if (result != 0) + ldiskfs_std_error(sb, result); + + brelse(leaf_node); + + GOTO(out_root, result); + +out_root: + brelse(root_node); +out: + return result; } diff --git a/lustre/osd-ldiskfs/osd_iam_lvar.c b/lustre/osd-ldiskfs/osd_iam_lvar.c index 9551a8b..688c0b5 100644 --- a/lustre/osd-ldiskfs/osd_iam_lvar.c +++ b/lustre/osd-ldiskfs/osd_iam_lvar.c @@ -1017,22 +1017,31 @@ int iam_lvar_create(struct inode *obj, sb = obj->i_sb; bsize = sb->s_blocksize; - root_node = osd_ldiskfs_append(handle, obj, &blknr, &result); - leaf_node = osd_ldiskfs_append(handle, obj, &blknr, &result); - if (root_node != NULL && leaf_node != NULL) { - lvar_root(root_node->b_data, bsize, keysize, ptrsize, recsize); - lvar_leaf(leaf_node->b_data, bsize, keysize, ptrsize, recsize); - ldiskfs_mark_inode_dirty(handle, obj); - result = ldiskfs_handle_dirty_metadata(handle, NULL, root_node); - if (result == 0) - result = ldiskfs_handle_dirty_metadata(handle, NULL, - leaf_node); - if (result != 0) - ldiskfs_std_error(sb, result); - } - brelse(leaf_node); - brelse(root_node); - return result; + root_node = osd_ldiskfs_append(handle, obj, &blknr); + if (IS_ERR(root_node)) + GOTO(out, result = PTR_ERR(root_node)); + + leaf_node = osd_ldiskfs_append(handle, obj, &blknr); + if (IS_ERR(leaf_node)) + GOTO(out_root, result = PTR_ERR(leaf_node)); + + lvar_root(root_node->b_data, bsize, keysize, ptrsize, recsize); + lvar_leaf(leaf_node->b_data, bsize, keysize, ptrsize, recsize); + ldiskfs_mark_inode_dirty(handle, obj); + result = ldiskfs_handle_dirty_metadata(handle, NULL, root_node); + if (result == 0) + result = ldiskfs_handle_dirty_metadata(handle, NULL, leaf_node); + if (result != 0) + ldiskfs_std_error(sb, result); + + brelse(leaf_node); + + GOTO(out_root, result); + +out_root: + brelse(root_node); +out: + return result; } static struct iam_operations lvar_ops = { diff --git a/lustre/osd-ldiskfs/osd_internal.h b/lustre/osd-ldiskfs/osd_internal.h index e0cc714..7ad0c24 100644 --- a/lustre/osd-ldiskfs/osd_internal.h +++ b/lustre/osd-ldiskfs/osd_internal.h @@ -765,7 +765,7 @@ static inline void i_gid_write(struct inode *inode, gid_t gid) #ifdef LDISKFS_HT_MISC # define osd_journal_start_sb(sb, type, nblock) \ ldiskfs_journal_start_sb(sb, type, nblock) -# define osd_ldiskfs_append(handle, inode, nblock, err) \ +# define osd_ldiskfs_append(handle, inode, nblock) \ ldiskfs_append(handle, inode, nblock) # define osd_ldiskfs_find_entry(dir, name, de, inlined, lock) \ __ldiskfs_find_entry(dir, name, de, inlined, lock) @@ -777,8 +777,21 @@ static inline void i_gid_write(struct inode *inode, gid_t gid) # define LDISKFS_HT_MISC 0 # define osd_journal_start_sb(sb, type, nblock) \ ldiskfs_journal_start_sb(sb, nblock) -# define osd_ldiskfs_append(handle, inode, nblock, err) \ - ldiskfs_append(handle, inode, nblock, err) + +static inline struct buffer_head *osd_ldiskfs_append(handle_t *handle, + struct inode *inode, + ldiskfs_lblk_t *nblock) +{ + struct buffer_head *bh; + int err = 0; + + bh = ldiskfs_append(handle, inode, nblock, &err); + if (bh == NULL) + bh = ERR_PTR(err); + + return bh; +} + # define osd_ldiskfs_find_entry(dir, name, de, inlined, lock) \ __ldiskfs_find_entry(dir, name, de, lock) # define osd_journal_start(inode, type, nblocks) \