Whamcloud - gitweb
LU-7343 osd-ldiskfs: handle ldiskfs_append failure 48/17148/5
authorFan Yong <fan.yong@intel.com>
Fri, 2 Oct 2015 05:21:21 +0000 (13:21 +0800)
committerOleg Drokin <oleg.drokin@intel.com>
Mon, 30 Nov 2015 17:18:30 +0000 (17:18 +0000)
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 <fan.yong@intel.com>
Change-Id: I4dca43bcfd31aafd999f54934a51d258071dab22
Reviewed-on: http://review.whamcloud.com/17148
Tested-by: Jenkins
Reviewed-by: Yang Sheng <yang.sheng@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
lustre/osd-ldiskfs/osd_iam.c
lustre/osd-ldiskfs/osd_iam_lfix.c
lustre/osd-ldiskfs/osd_iam_lvar.c
lustre/osd-ldiskfs/osd_internal.h

index 2c2ff27..360b7a4 100644 (file)
@@ -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:
index ba408b2..3416c0d 100644 (file)
@@ -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;
 }
index 9551a8b..688c0b5 100644 (file)
@@ -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 = {
index e0cc714..7ad0c24 100644 (file)
@@ -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) \