]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/blobdiff - fs/btrfs/delayed-inode.c
btrfs: fixup/remove module.h usage as required
[mirror_ubuntu-artful-kernel.git] / fs / btrfs / delayed-inode.c
index 34836036f01bc5bec6fff8768e1365cf69d500c0..0b278b117cbe609611764cf45127f89a133eed5f 100644 (file)
@@ -875,7 +875,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
                                     struct btrfs_delayed_item *delayed_item)
 {
        struct extent_buffer *leaf;
-       struct btrfs_item *item;
        char *ptr;
        int ret;
 
@@ -886,7 +885,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
 
        leaf = path->nodes[0];
 
-       item = btrfs_item_nr(leaf, path->slots[0]);
        ptr = btrfs_item_ptr(leaf, path->slots[0], char);
 
        write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr,
@@ -1065,32 +1063,25 @@ static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)
        }
 }
 
-static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
-                                     struct btrfs_root *root,
-                                     struct btrfs_path *path,
-                                     struct btrfs_delayed_node *node)
+static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
+                                       struct btrfs_root *root,
+                                       struct btrfs_path *path,
+                                       struct btrfs_delayed_node *node)
 {
        struct btrfs_key key;
        struct btrfs_inode_item *inode_item;
        struct extent_buffer *leaf;
        int ret;
 
-       mutex_lock(&node->mutex);
-       if (!node->inode_dirty) {
-               mutex_unlock(&node->mutex);
-               return 0;
-       }
-
        key.objectid = node->inode_id;
        btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY);
        key.offset = 0;
+
        ret = btrfs_lookup_inode(trans, root, path, &key, 1);
        if (ret > 0) {
                btrfs_release_path(path);
-               mutex_unlock(&node->mutex);
                return -ENOENT;
        } else if (ret < 0) {
-               mutex_unlock(&node->mutex);
                return ret;
        }
 
@@ -1105,11 +1096,47 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
 
        btrfs_delayed_inode_release_metadata(root, node);
        btrfs_release_delayed_inode(node);
-       mutex_unlock(&node->mutex);
 
        return 0;
 }
 
+static inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
+                                            struct btrfs_root *root,
+                                            struct btrfs_path *path,
+                                            struct btrfs_delayed_node *node)
+{
+       int ret;
+
+       mutex_lock(&node->mutex);
+       if (!node->inode_dirty) {
+               mutex_unlock(&node->mutex);
+               return 0;
+       }
+
+       ret = __btrfs_update_delayed_inode(trans, root, path, node);
+       mutex_unlock(&node->mutex);
+       return ret;
+}
+
+static inline int
+__btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
+                                  struct btrfs_path *path,
+                                  struct btrfs_delayed_node *node)
+{
+       int ret;
+
+       ret = btrfs_insert_delayed_items(trans, path, node->root, node);
+       if (ret)
+               return ret;
+
+       ret = btrfs_delete_delayed_items(trans, path, node->root, node);
+       if (ret)
+               return ret;
+
+       ret = btrfs_update_delayed_inode(trans, node->root, path, node);
+       return ret;
+}
+
 /*
  * Called when committing the transaction.
  * Returns 0 on success.
@@ -1119,7 +1146,6 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
 static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
                                     struct btrfs_root *root, int nr)
 {
-       struct btrfs_root *curr_root = root;
        struct btrfs_delayed_root *delayed_root;
        struct btrfs_delayed_node *curr_node, *prev_node;
        struct btrfs_path *path;
@@ -1142,15 +1168,8 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
 
        curr_node = btrfs_first_delayed_node(delayed_root);
        while (curr_node && (!count || (count && nr--))) {
-               curr_root = curr_node->root;
-               ret = btrfs_insert_delayed_items(trans, path, curr_root,
-                                                curr_node);
-               if (!ret)
-                       ret = btrfs_delete_delayed_items(trans, path,
-                                               curr_root, curr_node);
-               if (!ret)
-                       ret = btrfs_update_delayed_inode(trans, curr_root,
-                                               path, curr_node);
+               ret = __btrfs_commit_inode_delayed_items(trans, path,
+                                                        curr_node);
                if (ret) {
                        btrfs_release_delayed_node(curr_node);
                        curr_node = NULL;
@@ -1183,51 +1202,93 @@ int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
        return __btrfs_run_delayed_items(trans, root, nr);
 }
 
-static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
-                                             struct btrfs_delayed_node *node)
+int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
+                                    struct inode *inode)
 {
+       struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
        struct btrfs_path *path;
        struct btrfs_block_rsv *block_rsv;
        int ret;
 
+       if (!delayed_node)
+               return 0;
+
+       mutex_lock(&delayed_node->mutex);
+       if (!delayed_node->count) {
+               mutex_unlock(&delayed_node->mutex);
+               btrfs_release_delayed_node(delayed_node);
+               return 0;
+       }
+       mutex_unlock(&delayed_node->mutex);
+
        path = btrfs_alloc_path();
        if (!path)
                return -ENOMEM;
        path->leave_spinning = 1;
 
        block_rsv = trans->block_rsv;
-       trans->block_rsv = &node->root->fs_info->delayed_block_rsv;
+       trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv;
 
-       ret = btrfs_insert_delayed_items(trans, path, node->root, node);
-       if (!ret)
-               ret = btrfs_delete_delayed_items(trans, path, node->root, node);
-       if (!ret)
-               ret = btrfs_update_delayed_inode(trans, node->root, path, node);
-       btrfs_free_path(path);
+       ret = __btrfs_commit_inode_delayed_items(trans, path, delayed_node);
 
+       btrfs_release_delayed_node(delayed_node);
+       btrfs_free_path(path);
        trans->block_rsv = block_rsv;
+
        return ret;
 }
 
-int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
-                                    struct inode *inode)
+int btrfs_commit_inode_delayed_inode(struct inode *inode)
 {
+       struct btrfs_trans_handle *trans;
        struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
+       struct btrfs_path *path;
+       struct btrfs_block_rsv *block_rsv;
        int ret;
 
        if (!delayed_node)
                return 0;
 
        mutex_lock(&delayed_node->mutex);
-       if (!delayed_node->count) {
+       if (!delayed_node->inode_dirty) {
                mutex_unlock(&delayed_node->mutex);
                btrfs_release_delayed_node(delayed_node);
                return 0;
        }
        mutex_unlock(&delayed_node->mutex);
 
-       ret = __btrfs_commit_inode_delayed_items(trans, delayed_node);
+       trans = btrfs_join_transaction(delayed_node->root);
+       if (IS_ERR(trans)) {
+               ret = PTR_ERR(trans);
+               goto out;
+       }
+
+       path = btrfs_alloc_path();
+       if (!path) {
+               ret = -ENOMEM;
+               goto trans_out;
+       }
+       path->leave_spinning = 1;
+
+       block_rsv = trans->block_rsv;
+       trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv;
+
+       mutex_lock(&delayed_node->mutex);
+       if (delayed_node->inode_dirty)
+               ret = __btrfs_update_delayed_inode(trans, delayed_node->root,
+                                                  path, delayed_node);
+       else
+               ret = 0;
+       mutex_unlock(&delayed_node->mutex);
+
+       btrfs_free_path(path);
+       trans->block_rsv = block_rsv;
+trans_out:
+       btrfs_end_transaction(trans, delayed_node->root);
+       btrfs_btree_balance_dirty(delayed_node->root);
+out:
        btrfs_release_delayed_node(delayed_node);
+
        return ret;
 }
 
@@ -1258,7 +1319,6 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
        struct btrfs_root *root;
        struct btrfs_block_rsv *block_rsv;
        int need_requeue = 0;
-       int ret;
 
        async_node = container_of(work, struct btrfs_async_delayed_node, work);
 
@@ -1277,14 +1337,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
        block_rsv = trans->block_rsv;
        trans->block_rsv = &root->fs_info->delayed_block_rsv;
 
-       ret = btrfs_insert_delayed_items(trans, path, root, delayed_node);
-       if (!ret)
-               ret = btrfs_delete_delayed_items(trans, path, root,
-                                                delayed_node);
-
-       if (!ret)
-               btrfs_update_delayed_inode(trans, root, path, delayed_node);
-
+       __btrfs_commit_inode_delayed_items(trans, path, delayed_node);
        /*
         * Maybe new delayed items have been inserted, so we need requeue
         * the work. Besides that, we must dequeue the empty delayed nodes