btrfs: Drop fs_info parameter from btrfs_qgroup_account_extents
[sfrench/cifs-2.6.git] / fs / btrfs / transaction.c
index f6a33f474e7bb49fe2744e32b636b5cf6125a5a6..7c815885ac01f9cbdfab5cef85db065d33ced655 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),
@@ -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)
@@ -798,7 +781,6 @@ static int should_end_transaction(struct btrfs_trans_handle *trans)
 int btrfs_should_end_transaction(struct btrfs_trans_handle *trans)
 {
        struct btrfs_transaction *cur_trans = trans->transaction;
-       struct btrfs_fs_info *fs_info = trans->fs_info;
        int updates;
        int err;
 
@@ -810,7 +792,7 @@ int btrfs_should_end_transaction(struct btrfs_trans_handle *trans)
        updates = trans->delayed_ref_updates;
        trans->delayed_ref_updates = 0;
        if (updates) {
-               err = btrfs_run_delayed_refs(trans, fs_info, updates * 2);
+               err = btrfs_run_delayed_refs(trans, updates * 2);
                if (err) /* Error code will also eval true */
                        return err;
        }
@@ -885,8 +867,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 +1072,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);
@@ -1179,7 +1160,7 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans)
        if (ret)
                return ret;
 
-       ret = btrfs_run_delayed_refs(trans, fs_info, (unsigned long)-1);
+       ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
        if (ret)
                return ret;
 
@@ -1198,7 +1179,7 @@ static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans)
                return ret;
 
        /* run_qgroups might have added some more refs */
-       ret = btrfs_run_delayed_refs(trans, fs_info, (unsigned long)-1);
+       ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
        if (ret)
                return ret;
 again:
@@ -1215,7 +1196,7 @@ again:
                ret = update_cowonly_root(trans, root);
                if (ret)
                        return ret;
-               ret = btrfs_run_delayed_refs(trans, fs_info, (unsigned long)-1);
+               ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
                if (ret)
                        return ret;
        }
@@ -1224,7 +1205,7 @@ again:
                ret = btrfs_write_dirty_block_groups(trans, fs_info);
                if (ret)
                        return ret;
-               ret = btrfs_run_delayed_refs(trans, fs_info, (unsigned long)-1);
+               ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
                if (ret)
                        return ret;
        }
@@ -1371,6 +1352,14 @@ 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
@@ -1380,7 +1369,7 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans,
        ret = commit_fs_roots(trans);
        if (ret)
                goto out;
-       ret = btrfs_qgroup_account_extents(trans, fs_info);
+       ret = btrfs_qgroup_account_extents(trans);
        if (ret < 0)
                goto out;
 
@@ -1407,7 +1396,7 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans,
        if (ret)
                goto out;
        switch_commit_roots(trans->transaction);
-       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 for qgroup");
@@ -1627,7 +1616,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                goto fail;
        }
 
-       ret = btrfs_run_delayed_refs(trans, fs_info, (unsigned long)-1);
+       ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
        if (ret) {
                btrfs_abort_transaction(trans, ret);
                goto fail;
@@ -1681,7 +1670,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
                }
        }
 
-       ret = btrfs_run_delayed_refs(trans, fs_info, (unsigned long)-1);
+       ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
        if (ret) {
                btrfs_abort_transaction(trans, ret);
                goto fail;
@@ -1964,7 +1953,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
        /* make a pass through all the delayed refs we have so far
         * any runnings procs may add more while we are here
         */
-       ret = btrfs_run_delayed_refs(trans, fs_info, 0);
+       ret = btrfs_run_delayed_refs(trans, 0);
        if (ret) {
                btrfs_end_transaction(trans);
                return ret;
@@ -1985,7 +1974,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
        if (!list_empty(&trans->new_bgs))
                btrfs_create_pending_block_groups(trans);
 
-       ret = btrfs_run_delayed_refs(trans, fs_info, 0);
+       ret = btrfs_run_delayed_refs(trans, 0);
        if (ret) {
                btrfs_end_transaction(trans);
                return ret;
@@ -2013,12 +2002,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);
@@ -2133,7 +2123,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
                goto scrub_continue;
        }
 
-       ret = btrfs_run_delayed_refs(trans, fs_info, (unsigned long)-1);
+       ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
        if (ret) {
                mutex_unlock(&fs_info->reloc_mutex);
                goto scrub_continue;
@@ -2184,7 +2174,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         * commit_fs_roots() can call btrfs_save_ino_cache(), which generates
         * new delayed refs. Must handle them or qgroup can be wrong.
         */
-       ret = btrfs_run_delayed_refs(trans, fs_info, (unsigned long)-1);
+       ret = btrfs_run_delayed_refs(trans, (unsigned long)-1);
        if (ret) {
                mutex_unlock(&fs_info->tree_log_mutex);
                mutex_unlock(&fs_info->reloc_mutex);
@@ -2195,7 +2185,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans)
         * Since fs roots are all committed, we can get a quite accurate
         * new_roots. So let's do quota accounting.
         */
-       ret = btrfs_qgroup_account_extents(trans, fs_info);
+       ret = btrfs_qgroup_account_extents(trans);
        if (ret < 0) {
                mutex_unlock(&fs_info->tree_log_mutex);
                mutex_unlock(&fs_info->reloc_mutex);
@@ -2261,7 +2251,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");