Whamcloud - gitweb
LU-7343 osd-ldiskfs: handle ldiskfs_append failure
[fs/lustre-release.git] / lustre / osd-ldiskfs / osd_iam.c
index a92df9c..360b7a4 100644 (file)
@@ -27,7 +27,7 @@
  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
  * Use is subject to license terms.
  *
- * Copyright (c) 2011, 2012, Intel Corporation.
+ * Copyright (c) 2011, 2015, Intel Corporation.
  */
 /*
  * This file is part of Lustre, http://www.lustre.org/
 #include <linux/string.h>
 #include <linux/quotaops.h>
 #include <linux/buffer_head.h>
+
+#include <ldiskfs/ldiskfs.h>
+#include <ldiskfs/xattr.h>
+#undef ENTRY
+
 #include "osd_internal.h"
 
-#include "xattr.h"
-#include "acl.h"
+#include <ldiskfs/acl.h>
 
 /*
  * List of all registered formats.
@@ -163,7 +167,6 @@ void iam_format_register(struct iam_format *fmt)
 {
        list_add(&fmt->if_linkage, &iam_formats);
 }
-EXPORT_SYMBOL(iam_format_register);
 
 static struct buffer_head *
 iam_load_idle_blocks(struct iam_container *c, iam_ptr_t blk)
@@ -171,7 +174,7 @@ iam_load_idle_blocks(struct iam_container *c, iam_ptr_t blk)
        struct inode *inode = c->ic_object;
        struct iam_idle_head *head;
        struct buffer_head *bh;
-       int err;
+       int err = 0;
 
        LASSERT(mutex_is_locked(&c->ic_idle_mutex));
 
@@ -183,6 +186,7 @@ iam_load_idle_blocks(struct iam_container *c, iam_ptr_t blk)
                CERROR("%.16s: cannot load idle blocks, blk = %u, err = %d\n",
                       LDISKFS_SB(inode->i_sb)->s_es->s_volume_name, blk, err);
                c->ic_idle_failed = 1;
+               err = err ? err : -EIO;
                return ERR_PTR(err);
        }
 
@@ -263,7 +267,6 @@ int iam_container_init(struct iam_container *c,
        mutex_init(&c->ic_idle_mutex);
        return 0;
 }
-EXPORT_SYMBOL(iam_container_init);
 
 /*
  * Determine container format.
@@ -272,7 +275,6 @@ int iam_container_setup(struct iam_container *c)
 {
         return iam_format_guess(c);
 }
-EXPORT_SYMBOL(iam_container_setup);
 
 /*
  * Finalize container @c, release all resources.
@@ -284,7 +286,6 @@ void iam_container_fini(struct iam_container *c)
        brelse(c->ic_root_bh);
        c->ic_root_bh = NULL;
 }
-EXPORT_SYMBOL(iam_container_fini);
 
 void iam_path_init(struct iam_path *path, struct iam_container *c,
                    struct iam_path_descr *pd)
@@ -350,12 +351,10 @@ struct iam_path_descr *iam_ipd_alloc(void *area, int keysize)
                 ipd->ipd_key_scratch[i] = karea;
         return ipd;
 }
-EXPORT_SYMBOL(iam_ipd_alloc);
 
 void iam_ipd_free(struct iam_path_descr *ipd)
 {
 }
-EXPORT_SYMBOL(iam_ipd_free);
 
 int iam_node_read(struct iam_container *c, iam_ptr_t ptr,
                   handle_t *h, struct buffer_head **bh)
@@ -376,7 +375,7 @@ int iam_node_read(struct iam_container *c, iam_ptr_t ptr,
 
         *bh = ldiskfs_bread(h, c->ic_object, (int)ptr, 0, &result);
         if (*bh == NULL)
-                result = -EIO;
+               result = result ? result : -EIO;
         return result;
 }
 
@@ -605,7 +604,7 @@ static int iam_txn_dirty(handle_t *handle,
 {
         int result;
 
-        result = ldiskfs_journal_dirty_metadata(handle, bh);
+       result = ldiskfs_handle_dirty_metadata(handle, NULL, bh);
         if (result != 0)
                 ldiskfs_std_error(iam_path_obj(path)->i_sb, result);
         return result;
@@ -725,7 +724,6 @@ int  iam_it_init(struct iam_iterator *it, struct iam_container *c, __u32 flags,
         iam_path_init(&it->ii_path, c, pd);
         return 0;
 }
-EXPORT_SYMBOL(iam_it_init);
 
 /*
  * Finalize iterator and release all resources.
@@ -737,7 +735,6 @@ void iam_it_fini(struct iam_iterator *it)
         assert_corr(it_state(it) == IAM_IT_DETACHED);
         iam_path_fini(&it->ii_path);
 }
-EXPORT_SYMBOL(iam_it_fini);
 
 /*
  * this locking primitives are used to protect parts
@@ -1196,7 +1193,6 @@ int iam_it_get(struct iam_iterator *it, const struct iam_key *k)
                          it_keycmp(it, k) <= 0));
         return result;
 }
-EXPORT_SYMBOL(iam_it_get);
 
 /*
  * Attach iterator by index key.
@@ -1235,7 +1231,6 @@ int iam_it_get_at(struct iam_iterator *it, const struct iam_key *k)
         assert_corr(ergo(result >= 0, it_state(it) == IAM_IT_ATTACHED));
         return result;
 }
-EXPORT_SYMBOL(iam_it_get_at);
 
 /*
  * Duplicates iterator.
@@ -1276,7 +1271,6 @@ void iam_it_put(struct iam_iterator *it)
                 iam_leaf_fini(&it->ii_path.ip_leaf);
         }
 }
-EXPORT_SYMBOL(iam_it_put);
 
 static struct iam_ikey *iam_it_ikey_get(const struct iam_iterator *it,
                                         struct iam_ikey *ikey);
@@ -1412,7 +1406,7 @@ static void iam_unlock_array(struct iam_container *ic,
 int iam_index_next(struct iam_container *c, struct iam_path *path)
 {
         iam_ptr_t cursor;
-        struct dynlock_handle *lh[DX_MAX_TREE_HEIGHT] = { 0, };
+       struct dynlock_handle *lh[DX_MAX_TREE_HEIGHT] = { NULL, };
         int result;
         struct inode *object;
 
@@ -1554,7 +1548,6 @@ int iam_it_next(struct iam_iterator *it)
                          it_ikeycmp(it, ik_orig) >= 0));
         return result;
 }
-EXPORT_SYMBOL(iam_it_next);
 
 /*
  * Return pointer to the record under iterator.
@@ -1568,7 +1561,6 @@ struct iam_rec *iam_it_rec_get(const struct iam_iterator *it)
         assert_corr(it_at_rec(it));
         return iam_leaf_rec(&it->ii_path.ip_leaf);
 }
-EXPORT_SYMBOL(iam_it_rec_get);
 
 static void iam_it_reccpy(struct iam_iterator *it, const struct iam_rec *r)
 {
@@ -1606,7 +1598,6 @@ int iam_it_rec_set(handle_t *h,
         }
         return result;
 }
-EXPORT_SYMBOL(iam_it_rec_set);
 
 /*
  * Return pointer to the index key under iterator.
@@ -1636,7 +1627,6 @@ struct iam_key *iam_it_key_get(const struct iam_iterator *it)
         assert_corr(it_at_rec(it));
         return iam_leaf_key(&it->ii_path.ip_leaf);
 }
-EXPORT_SYMBOL(iam_it_key_get);
 
 /*
  * Return size of key under iterator (in bytes)
@@ -1651,7 +1641,6 @@ int iam_it_key_size(const struct iam_iterator *it)
         assert_corr(it_at_rec(it));
         return iam_leaf_key_size(&it->ii_path.ip_leaf);
 }
-EXPORT_SYMBOL(iam_it_key_size);
 
 static struct buffer_head *
 iam_new_node(handle_t *h, struct iam_container *c, iam_ptr_t *b, int *e)
@@ -1682,14 +1671,16 @@ iam_new_node(handle_t *h, struct iam_container *c, iam_ptr_t *b, int *e)
                --count;
                *b = le32_to_cpu(head->iih_blks[count]);
                head->iih_count = cpu_to_le16(count);
-               *e = ldiskfs_journal_dirty_metadata(h, c->ic_idle_bh);
+               *e = ldiskfs_handle_dirty_metadata(h, inode, c->ic_idle_bh);
                if (*e != 0)
                        goto fail;
 
                mutex_unlock(&c->ic_idle_mutex);
                bh = ldiskfs_bread(NULL, inode, *b, 0, e);
-               if (bh == NULL)
+               if (bh == NULL) {
+                       *e = *e ? *e : -EIO;
                        return NULL;
+               }
                goto got;
        }
 
@@ -1706,7 +1697,7 @@ iam_new_node(handle_t *h, struct iam_container *c, iam_ptr_t *b, int *e)
        iam_lock_bh(c->ic_root_bh);
        *idle_blocks = head->iih_next;
        iam_unlock_bh(c->ic_root_bh);
-       *e = ldiskfs_journal_dirty_metadata(h, c->ic_root_bh);
+       *e = ldiskfs_handle_dirty_metadata(h, inode, c->ic_root_bh);
        if (*e != 0) {
                iam_lock_bh(c->ic_root_bh);
                *idle_blocks = cpu_to_le32(*b);
@@ -1741,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:
@@ -1815,12 +1811,12 @@ static int iam_new_leaf(handle_t *handle, struct iam_leaf *leaf)
                                iam_unlock_htree(path->ip_container, lh);
                         do_corr(schedule());
                         err = iam_txn_dirty(handle, path, new_leaf);
-                        brelse(new_leaf);
                         if (err == 0)
                                 err = ldiskfs_mark_inode_dirty(handle, obj);
                         do_corr(schedule());
                 } else
                         err = -ENOMEM;
+               brelse(new_leaf);
         }
         assert_inv(iam_leaf_check(leaf));
         assert_inv(iam_leaf_check(&iam_leaf_path(leaf)->ip_leaf));
@@ -1893,8 +1889,8 @@ int split_index_node(handle_t *handle, struct iam_path *path,
 
         struct iam_entry *entries;   /* old block contents */
         struct iam_entry *entries2;  /* new block contents */
-         struct iam_frame *frame, *safe;
-        struct buffer_head *bh_new[DX_MAX_TREE_HEIGHT] = {0};
+       struct iam_frame *frame, *safe;
+       struct buffer_head *bh_new[DX_MAX_TREE_HEIGHT] = {NULL};
         u32 newblock[DX_MAX_TREE_HEIGHT] = {0};
         struct dynlock_handle *lock[DX_MAX_TREE_HEIGHT] = {NULL,};
         struct dynlock_handle *new_lock[DX_MAX_TREE_HEIGHT] = {NULL,};
@@ -2068,7 +2064,7 @@ int split_index_node(handle_t *handle, struct iam_path *path,
                         ++ frame;
                         assert_inv(dx_node_check(path, frame));
                         bh_new[0] = NULL; /* buffer head is "consumed" */
-                        err = ldiskfs_journal_dirty_metadata(handle, bh2);
+                       err = ldiskfs_handle_dirty_metadata(handle, NULL, bh2);
                         if (err)
                                 goto journal_error;
                         do_corr(schedule());
@@ -2100,16 +2096,17 @@ int split_index_node(handle_t *handle, struct iam_path *path,
                         dxtrace(dx_show_index ("node", frame->entries));
                         dxtrace(dx_show_index ("node",
                                ((struct dx_node *) bh2->b_data)->entries));
-                        err = ldiskfs_journal_dirty_metadata(handle, bh2);
+                       err = ldiskfs_handle_dirty_metadata(handle, NULL, bh2);
                         if (err)
                                 goto journal_error;
                         do_corr(schedule());
-                        err = ldiskfs_journal_dirty_metadata(handle, parent->bh);
+                       err = ldiskfs_handle_dirty_metadata(handle, NULL,
+                                                           parent->bh);
                         if (err)
                                 goto journal_error;
                 }
                 do_corr(schedule());
-                err = ldiskfs_journal_dirty_metadata(handle, bh);
+               err = ldiskfs_handle_dirty_metadata(handle, NULL, bh);
                 if (err)
                         goto journal_error;
         }
@@ -2242,7 +2239,6 @@ int iam_it_rec_insert(handle_t *h, struct iam_iterator *it,
                          it_keycmp(it, k) == 0));
         return result;
 }
-EXPORT_SYMBOL(iam_it_rec_insert);
 
 static inline int iam_idle_blocks_limit(struct inode *inode)
 {
@@ -2477,7 +2473,6 @@ int iam_it_rec_delete(handle_t *h, struct iam_iterator *it)
                     it_state(it) == IAM_IT_DETACHED);
         return result;
 }
-EXPORT_SYMBOL(iam_it_rec_delete);
 
 /*
  * Convert iterator to cookie.
@@ -2498,7 +2493,6 @@ iam_pos_t iam_it_store(const struct iam_iterator *it)
         result = 0;
         return *(iam_pos_t *)iam_it_ikey_get(it, (void *)&result);
 }
-EXPORT_SYMBOL(iam_it_store);
 
 /*
  * Restore iterator from cookie.
@@ -2515,7 +2509,6 @@ int iam_it_load(struct iam_iterator *it, iam_pos_t pos)
         assert_corr(iam_it_container(it)->ic_descr->id_ikey_size <= sizeof pos);
         return iam_it_iget(it, (struct iam_ikey *)&pos);
 }
-EXPORT_SYMBOL(iam_it_load);
 
 /***********************************************************************/
 /* invariants                                                          */
@@ -2601,7 +2594,6 @@ int iam_lookup(struct iam_container *c, const struct iam_key *k,
         iam_it_fini(&it);
         return result;
 }
-EXPORT_SYMBOL(iam_lookup);
 
 /*
  * Insert new record @r with key @k into container @c (within context of
@@ -2630,7 +2622,6 @@ int iam_insert(handle_t *h, struct iam_container *c, const struct iam_key *k,
         iam_it_fini(&it);
         return result;
 }
-EXPORT_SYMBOL(iam_insert);
 
 /*
  * Update record with the key @k in container @c (within context of
@@ -2661,7 +2652,6 @@ int iam_update(handle_t *h, struct iam_container *c, const struct iam_key *k,
         iam_it_fini(&it);
         return result;
 }
-EXPORT_SYMBOL(iam_update);
 
 /*
  * Delete existing record with key @k.
@@ -2686,7 +2676,6 @@ int iam_delete(handle_t *h, struct iam_container *c, const struct iam_key *k,
         iam_it_fini(&it);
         return result;
 }
-EXPORT_SYMBOL(iam_delete);
 
 int iam_root_limit(int rootgap, int blocksize, int size)
 {