Merge tag 'clk-for-linus-3.18' of git://git.linaro.org/people/mike.turquette/linux
[cascardo/linux.git] / fs / btrfs / transaction.c
index d89c6d3..dcaae36 100644 (file)
@@ -386,7 +386,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type,
        int ret;
 
        /* Send isn't supposed to start transactions. */
-       ASSERT(current->journal_info != (void *)BTRFS_SEND_TRANS_STUB);
+       ASSERT(current->journal_info != BTRFS_SEND_TRANS_STUB);
 
        if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state))
                return ERR_PTR(-EROFS);
@@ -408,7 +408,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type,
        if (num_items > 0 && root != root->fs_info->chunk_root) {
                if (root->fs_info->quota_enabled &&
                    is_fstree(root->root_key.objectid)) {
-                       qgroup_reserved = num_items * root->leafsize;
+                       qgroup_reserved = num_items * root->nodesize;
                        ret = btrfs_qgroup_reserve(root, qgroup_reserved);
                        if (ret)
                                return ERR_PTR(ret);
@@ -418,7 +418,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, unsigned int type,
                /*
                 * Do the reservation for the relocation root creation
                 */
-               if (unlikely(need_reserve_reloc_root(root))) {
+               if (need_reserve_reloc_root(root)) {
                        num_bytes += root->nodesize;
                        reloc_reserved = true;
                }
@@ -609,7 +609,6 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid)
                if (transid <= root->fs_info->last_trans_committed)
                        goto out;
 
-               ret = -EINVAL;
                /* find specified transaction */
                spin_lock(&root->fs_info->trans_lock);
                list_for_each_entry(t, &root->fs_info->trans_list, list) {
@@ -625,9 +624,16 @@ int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid)
                        }
                }
                spin_unlock(&root->fs_info->trans_lock);
-               /* The specified transaction doesn't exist */
-               if (!cur_trans)
+
+               /*
+                * The specified transaction doesn't exist, or we
+                * raced with btrfs_commit_transaction
+                */
+               if (!cur_trans) {
+                       if (transid > root->fs_info->last_trans_committed)
+                               ret = -EINVAL;
                        goto out;
+               }
        } else {
                /* find newest transaction that is committing | committed */
                spin_lock(&root->fs_info->trans_lock);
@@ -851,6 +857,8 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
        struct extent_state *cached_state = NULL;
        u64 start = 0;
        u64 end;
+       struct btrfs_inode *btree_ino = BTRFS_I(root->fs_info->btree_inode);
+       bool errors = false;
 
        while (!find_first_extent_bit(dirty_pages, start, &start, &end,
                                      EXTENT_NEED_WAIT, &cached_state)) {
@@ -864,6 +872,26 @@ int btrfs_wait_marked_extents(struct btrfs_root *root,
        }
        if (err)
                werr = err;
+
+       if (root->root_key.objectid == BTRFS_TREE_LOG_OBJECTID) {
+               if ((mark & EXTENT_DIRTY) &&
+                   test_and_clear_bit(BTRFS_INODE_BTREE_LOG1_ERR,
+                                      &btree_ino->runtime_flags))
+                       errors = true;
+
+               if ((mark & EXTENT_NEW) &&
+                   test_and_clear_bit(BTRFS_INODE_BTREE_LOG2_ERR,
+                                      &btree_ino->runtime_flags))
+                       errors = true;
+       } else {
+               if (test_and_clear_bit(BTRFS_INODE_BTREE_ERR,
+                                      &btree_ino->runtime_flags))
+                       errors = true;
+       }
+
+       if (errors && !werr)
+               werr = -EIO;
+
        return werr;
 }
 
@@ -1629,6 +1657,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
 {
        struct btrfs_transaction *cur_trans = trans->transaction;
        struct btrfs_transaction *prev_trans = NULL;
+       struct btrfs_inode *btree_ino = BTRFS_I(root->fs_info->btree_inode);
        int ret;
 
        /* Stop the commit early if ->aborted is set */
@@ -1868,6 +1897,12 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
        memcpy(root->fs_info->super_for_commit, root->fs_info->super_copy,
               sizeof(*root->fs_info->super_copy));
 
+       btrfs_update_commit_device_size(root->fs_info);
+       btrfs_update_commit_device_bytes_used(root, cur_trans);
+
+       clear_bit(BTRFS_INODE_BTREE_LOG1_ERR, &btree_ino->runtime_flags);
+       clear_bit(BTRFS_INODE_BTREE_LOG2_ERR, &btree_ino->runtime_flags);
+
        spin_lock(&root->fs_info->trans_lock);
        cur_trans->state = TRANS_STATE_UNBLOCKED;
        root->fs_info->running_transaction = NULL;
@@ -1981,9 +2016,6 @@ int btrfs_clean_one_deleted_snapshot(struct btrfs_root *root)
                ret = btrfs_drop_snapshot(root, NULL, 0, 0);
        else
                ret = btrfs_drop_snapshot(root, NULL, 1, 0);
-       /*
-        * If we encounter a transaction abort during snapshot cleaning, we
-        * don't want to crash here
-        */
+
        return (ret < 0) ? 0 : 1;
 }