btrfs: Remove btrfs_fs_info::open_ioctl_trans
[sfrench/cifs-2.6.git] / fs / btrfs / transaction.c
index 87f94228abe9ab8a305674c9d856206ad22537d7..f4b1225a3bec3e6a2caef10e42acefdf6aee73b4 100644 (file)
 
 static const unsigned int btrfs_blocked_trans_types[TRANS_STATE_MAX] = {
        [TRANS_STATE_RUNNING]           = 0U,
-       [TRANS_STATE_BLOCKED]           = (__TRANS_USERSPACE |
-                                          __TRANS_START),
-       [TRANS_STATE_COMMIT_START]      = (__TRANS_USERSPACE |
-                                          __TRANS_START |
-                                          __TRANS_ATTACH),
-       [TRANS_STATE_COMMIT_DOING]      = (__TRANS_USERSPACE |
-                                          __TRANS_START |
+       [TRANS_STATE_BLOCKED]           =  __TRANS_START,
+       [TRANS_STATE_COMMIT_START]      = (__TRANS_START | __TRANS_ATTACH),
+       [TRANS_STATE_COMMIT_DOING]      = (__TRANS_START |
                                           __TRANS_ATTACH |
                                           __TRANS_JOIN),
-       [TRANS_STATE_UNBLOCKED]         = (__TRANS_USERSPACE |
-                                          __TRANS_START |
+       [TRANS_STATE_UNBLOCKED]         = (__TRANS_START |
                                           __TRANS_ATTACH |
                                           __TRANS_JOIN |
                                           __TRANS_JOIN_NOLOCK),
-       [TRANS_STATE_COMPLETED]         = (__TRANS_USERSPACE |
-                                          __TRANS_START |
+       [TRANS_STATE_COMPLETED]         = (__TRANS_START |
                                           __TRANS_ATTACH |
                                           __TRANS_JOIN |
                                           __TRANS_JOIN_NOLOCK),
@@ -126,9 +120,9 @@ static void clear_btree_io_tree(struct extent_io_tree *tree)
        spin_unlock(&tree->lock);
 }
 
-static noinline void switch_commit_roots(struct btrfs_transaction *trans,
-                                        struct btrfs_fs_info *fs_info)
+static noinline void switch_commit_roots(struct btrfs_transaction *trans)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_root *root, *tmp;
 
        down_write(&fs_info->commit_root_sem);
@@ -319,7 +313,7 @@ static int record_root_in_trans(struct btrfs_trans_handle *trans,
        if ((test_bit(BTRFS_ROOT_REF_COWS, &root->state) &&
            root->last_trans < trans->transid) || force) {
                WARN_ON(root == fs_info->extent_root);
-               WARN_ON(root->commit_root != root->node);
+               WARN_ON(!force && root->commit_root != root->node);
 
                /*
                 * see below for IN_TRANS_SETUP usage rules
@@ -449,11 +443,7 @@ static int may_wait_transaction(struct btrfs_fs_info *fs_info, int type)
        if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags))
                return 0;
 
-       if (type == TRANS_USERSPACE)
-               return 1;
-
-       if (type == TRANS_START &&
-           !atomic_read(&fs_info->open_ioctl_trans))
+       if (type == TRANS_START)
                return 1;
 
        return 0;
@@ -593,7 +583,7 @@ again:
 got_it:
        btrfs_record_root_in_trans(h, root);
 
-       if (!current->journal_info && type != TRANS_USERSPACE)
+       if (!current->journal_info)
                current->journal_info = h;
        return h;
 
@@ -670,12 +660,6 @@ struct btrfs_trans_handle *btrfs_join_transaction_nolock(struct btrfs_root *root
                                 BTRFS_RESERVE_NO_FLUSH, true);
 }
 
-struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root)
-{
-       return start_transaction(root, 0, TRANS_USERSPACE,
-                                BTRFS_RESERVE_NO_FLUSH, true);
-}
-
 /*
  * btrfs_attach_transaction() - catch the running transaction
  *
@@ -781,8 +765,7 @@ out:
 
 void btrfs_throttle(struct btrfs_fs_info *fs_info)
 {
-       if (!atomic_read(&fs_info->open_ioctl_trans))
-               wait_current_trans(fs_info);
+       wait_current_trans(fs_info);
 }
 
 static int should_end_transaction(struct btrfs_trans_handle *trans)
@@ -885,8 +868,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
 
        btrfs_trans_release_chunk_metadata(trans);
 
-       if (lock && !atomic_read(&info->open_ioctl_trans) &&
-           should_end_transaction(trans) &&
+       if (lock && should_end_transaction(trans) &&
            READ_ONCE(cur_trans->state) == TRANS_STATE_RUNNING) {
                spin_lock(&info->trans_lock);
                if (cur_trans->state == TRANS_STATE_RUNNING)
@@ -1091,12 +1073,12 @@ int btrfs_wait_tree_log_extents(struct btrfs_root *log_root, int mark)
  *
  * @trans: transaction whose dirty pages we'd like to write
  */
-static int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
-                                           struct btrfs_fs_info *fs_info)
+static int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans)
 {
        int ret;
        int ret2;
        struct extent_io_tree *dirty_pages = &trans->transaction->dirty_pages;
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct blk_plug plug;
 
        blk_start_plug(&plug);
@@ -1161,9 +1143,9 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans,
  * failures will cause the file system to go offline. We still need
  * to clean up the delayed refs.
  */
-static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans,
-                                        struct btrfs_fs_info *fs_info)
+static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct list_head *dirty_bgs = &trans->transaction->dirty_bgs;
        struct list_head *io_bgs = &trans->transaction->io_bgs;
        struct list_head *next;
@@ -1257,9 +1239,9 @@ void btrfs_add_dead_root(struct btrfs_root *root)
 /*
  * update all the cowonly tree roots on disk
  */
-static noinline int commit_fs_roots(struct btrfs_trans_handle *trans,
-                                   struct btrfs_fs_info *fs_info)
+static noinline int commit_fs_roots(struct btrfs_trans_handle *trans)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_root *gang[8];
        int i;
        int ret;
@@ -1371,13 +1353,21 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans,
        if (!test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags))
                return 0;
 
+       /*
+        * Ensure dirty @src will be commited.  Or, after comming
+        * commit_fs_roots() and switch_commit_roots(), any dirty but not
+        * recorded root will never be updated again, causing an outdated root
+        * item.
+        */
+       record_root_in_trans(trans, src, 1);
+
        /*
         * We are going to commit transaction, see btrfs_commit_transaction()
         * comment for reason locking tree_log_mutex
         */
        mutex_lock(&fs_info->tree_log_mutex);
 
-       ret = commit_fs_roots(trans, fs_info);
+       ret = commit_fs_roots(trans);
        if (ret)
                goto out;
        ret = btrfs_qgroup_account_extents(trans, fs_info);
@@ -1403,11 +1393,11 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans,
         * like chunk and root tree, as they won't affect qgroup.
         * And we don't write super to avoid half committed status.
         */
-       ret = commit_cowonly_roots(trans, fs_info);
+       ret = commit_cowonly_roots(trans);
        if (ret)
                goto out;
-       switch_commit_roots(trans->transaction, fs_info);
-       ret = btrfs_write_and_wait_transaction(trans, fs_info);
+       switch_commit_roots(trans->transaction);
+       ret = btrfs_write_and_wait_transaction(trans);
        if (ret)
                btrfs_handle_fs_error(fs_info, ret,
                        "Error while writing out transaction for qgroup");
@@ -1436,9 +1426,10 @@ out:
  * the creation of the pending snapshots, just return 0.
  */
 static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
-                                  struct btrfs_fs_info *fs_info,
                                   struct btrfs_pending_snapshot *pending)
 {
+
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_key key;
        struct btrfs_root_item *new_root_item;
        struct btrfs_root *tree_root = fs_info->tree_root;
@@ -1530,7 +1521,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
         * otherwise we corrupt the FS during
         * snapshot
         */
-       ret = btrfs_run_delayed_items(trans, fs_info);
+       ret = btrfs_run_delayed_items(trans);
        if (ret) {      /* Transaction aborted */
                btrfs_abort_transaction(trans, ret);
                goto fail;
@@ -1705,8 +1696,7 @@ no_free_objectid:
 /*
  * create all the snapshots we've scheduled for creation
  */
-static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
-                                            struct btrfs_fs_info *fs_info)
+static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans)
 {
        struct btrfs_pending_snapshot *pending, *next;
        struct list_head *head = &trans->transaction->pending_snapshots;
@@ -1714,7 +1704,7 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
 
        list_for_each_entry_safe(pending, next, head, list) {
                list_del(&pending->list);
-               ret = create_pending_snapshot(trans, fs_info, pending);
+               ret = create_pending_snapshot(trans, pending);
                if (ret)
                        break;
        }
@@ -1867,10 +1857,9 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans,
 }
 
 
-static void cleanup_transaction(struct btrfs_trans_handle *trans,
-                               struct btrfs_root *root, int err)
+static void cleanup_transaction(struct btrfs_trans_handle *trans, int err)
 {
-       struct btrfs_fs_info *fs_info = root->fs_info;
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_transaction *cur_trans = trans->transaction;
        DEFINE_WAIT(wait);
 
@@ -1910,7 +1899,7 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans,
        btrfs_put_transaction(cur_trans);
        btrfs_put_transaction(cur_trans);
 
-       trace_btrfs_transaction_commit(root);
+       trace_btrfs_transaction_commit(trans->root);
 
        if (current->journal_info == trans)
                current->journal_info = NULL;
@@ -2014,12 +2003,13 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
                        run_it = 1;
                mutex_unlock(&fs_info->ro_block_group_mutex);
 
-               if (run_it)
+               if (run_it) {
                        ret = btrfs_start_dirty_block_groups(trans);
-       }
-       if (ret) {
-               btrfs_end_transaction(trans);
-               return ret;
+                       if (ret) {
+                               btrfs_end_transaction(trans);
+                               return ret;
+                       }
+               }
        }
 
        spin_lock(&fs_info->trans_lock);
@@ -2067,7 +2057,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
        if (ret)
                goto cleanup_transaction;
 
-       ret = btrfs_run_delayed_items(trans, fs_info);
+       ret = btrfs_run_delayed_items(trans);
        if (ret)
                goto cleanup_transaction;
 
@@ -2075,7 +2065,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
                   extwriter_counter_read(cur_trans) == 0);
 
        /* some pending stuffs might be added after the previous flush. */
-       ret = btrfs_run_delayed_items(trans, fs_info);
+       ret = btrfs_run_delayed_items(trans);
        if (ret)
                goto cleanup_transaction;
 
@@ -2112,7 +2102,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         * deal with them in create_pending_snapshot(), which is the
         * core function of the snapshot creation.
         */
-       ret = create_pending_snapshots(trans, fs_info);
+       ret = create_pending_snapshots(trans);
        if (ret) {
                mutex_unlock(&fs_info->reloc_mutex);
                goto scrub_continue;
@@ -2128,7 +2118,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         * because all the tree which are snapshoted will be forced to COW
         * the nodes and leaves.
         */
-       ret = btrfs_run_delayed_items(trans, fs_info);
+       ret = btrfs_run_delayed_items(trans);
        if (ret) {
                mutex_unlock(&fs_info->reloc_mutex);
                goto scrub_continue;
@@ -2163,7 +2153,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         */
        mutex_lock(&fs_info->tree_log_mutex);
 
-       ret = commit_fs_roots(trans, fs_info);
+       ret = commit_fs_roots(trans);
        if (ret) {
                mutex_unlock(&fs_info->tree_log_mutex);
                mutex_unlock(&fs_info->reloc_mutex);
@@ -2203,7 +2193,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
                goto scrub_continue;
        }
 
-       ret = commit_cowonly_roots(trans, fs_info);
+       ret = commit_cowonly_roots(trans);
        if (ret) {
                mutex_unlock(&fs_info->tree_log_mutex);
                mutex_unlock(&fs_info->reloc_mutex);
@@ -2235,7 +2225,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
        list_add_tail(&fs_info->chunk_root->dirty_list,
                      &cur_trans->switch_commits);
 
-       switch_commit_roots(cur_trans, fs_info);
+       switch_commit_roots(cur_trans);
 
        ASSERT(list_empty(&cur_trans->dirty_bgs));
        ASSERT(list_empty(&cur_trans->io_bgs));
@@ -2247,7 +2237,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
               sizeof(*fs_info->super_copy));
 
        btrfs_update_commit_device_size(fs_info);
-       btrfs_update_commit_device_bytes_used(fs_info, cur_trans);
+       btrfs_update_commit_device_bytes_used(cur_trans);
 
        clear_bit(BTRFS_FS_LOG1_ERR, &fs_info->flags);
        clear_bit(BTRFS_FS_LOG2_ERR, &fs_info->flags);
@@ -2262,7 +2252,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
 
        wake_up(&fs_info->transaction_wait);
 
-       ret = btrfs_write_and_wait_transaction(trans, fs_info);
+       ret = btrfs_write_and_wait_transaction(trans);
        if (ret) {
                btrfs_handle_fs_error(fs_info, ret,
                                      "Error while writing out transaction");
@@ -2331,7 +2321,7 @@ cleanup_transaction:
        btrfs_warn(fs_info, "Skipping commit of aborted transaction.");
        if (current->journal_info == trans)
                current->journal_info = NULL;
-       cleanup_transaction(trans, trans->root, ret);
+       cleanup_transaction(trans, ret);
 
        return ret;
 }