btrfs: Fix delalloc inodes invalidation during transaction abort
[sfrench/cifs-2.6.git] / fs / btrfs / delayed-inode.c
index 0530f6f2e4ba8bff7e93cd11151db804ca70ffac..a8d492dbd3e7c100715011a9ddad8a22d82932dd 100644 (file)
@@ -1,20 +1,7 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2011 Fujitsu.  All rights reserved.
  * Written by Miao Xie <miaox@cn.fujitsu.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
  */
 
 #include <linux/slab.h>
@@ -23,6 +10,7 @@
 #include "disk-io.h"
 #include "transaction.h"
 #include "ctree.h"
+#include "qgroup.h"
 
 #define BTRFS_DELAYED_WRITEBACK                512
 #define BTRFS_DELAYED_BACKGROUND       128
@@ -42,7 +30,7 @@ int __init btrfs_delayed_inode_init(void)
        return 0;
 }
 
-void btrfs_delayed_inode_exit(void)
+void __cold btrfs_delayed_inode_exit(void)
 {
        kmem_cache_destroy(delayed_node_cache);
 }
@@ -552,11 +540,12 @@ static struct btrfs_delayed_item *__btrfs_next_delayed_item(
 }
 
 static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
-                                              struct btrfs_fs_info *fs_info,
+                                              struct btrfs_root *root,
                                               struct btrfs_delayed_item *item)
 {
        struct btrfs_block_rsv *src_rsv;
        struct btrfs_block_rsv *dst_rsv;
+       struct btrfs_fs_info *fs_info = root->fs_info;
        u64 num_bytes;
        int ret;
 
@@ -567,6 +556,12 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
        dst_rsv = &fs_info->delayed_block_rsv;
 
        num_bytes = btrfs_calc_trans_metadata_size(fs_info, 1);
+
+       /*
+        * Here we migrate space rsv from transaction rsv, since have already
+        * reserved space when starting a transaction.  So no need to reserve
+        * qgroup space here.
+        */
        ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, 1);
        if (!ret) {
                trace_btrfs_space_reservation(fs_info, "delayed_item",
@@ -578,15 +573,20 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
        return ret;
 }
 
-static void btrfs_delayed_item_release_metadata(struct btrfs_fs_info *fs_info,
+static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
                                                struct btrfs_delayed_item *item)
 {
        struct btrfs_block_rsv *rsv;
+       struct btrfs_fs_info *fs_info = root->fs_info;
 
        if (!item->bytes_reserved)
                return;
 
        rsv = &fs_info->delayed_block_rsv;
+       /*
+        * Check btrfs_delayed_item_reserve_metadata() to see why we don't need
+        * to release/reserve qgroup space.
+        */
        trace_btrfs_space_reservation(fs_info, "delayed_item",
                                      item->key.objectid, item->bytes_reserved,
                                      0);
@@ -622,6 +622,10 @@ static int btrfs_delayed_inode_reserve_metadata(
         */
        if (!src_rsv || (!trans->bytes_reserved &&
                         src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) {
+               ret = btrfs_qgroup_reserve_meta_prealloc(root,
+                               fs_info->nodesize, true);
+               if (ret < 0)
+                       return ret;
                ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes,
                                          BTRFS_RESERVE_NO_FLUSH);
                /*
@@ -630,14 +634,18 @@ static int btrfs_delayed_inode_reserve_metadata(
                 * EAGAIN to make us stop the transaction we have, so return
                 * ENOSPC instead so that btrfs_dirty_inode knows what to do.
                 */
-               if (ret == -EAGAIN)
+               if (ret == -EAGAIN) {
                        ret = -ENOSPC;
+                       btrfs_qgroup_free_meta_prealloc(root, num_bytes);
+               }
                if (!ret) {
                        node->bytes_reserved = num_bytes;
                        trace_btrfs_space_reservation(fs_info,
                                                      "delayed_inode",
                                                      btrfs_ino(inode),
                                                      num_bytes, 1);
+               } else {
+                       btrfs_qgroup_free_meta_prealloc(root, fs_info->nodesize);
                }
                return ret;
        }
@@ -653,7 +661,8 @@ static int btrfs_delayed_inode_reserve_metadata(
 }
 
 static void btrfs_delayed_inode_release_metadata(struct btrfs_fs_info *fs_info,
-                                               struct btrfs_delayed_node *node)
+                                               struct btrfs_delayed_node *node,
+                                               bool qgroup_free)
 {
        struct btrfs_block_rsv *rsv;
 
@@ -665,6 +674,12 @@ static void btrfs_delayed_inode_release_metadata(struct btrfs_fs_info *fs_info,
                                      node->inode_id, node->bytes_reserved, 0);
        btrfs_block_rsv_release(fs_info, rsv,
                                node->bytes_reserved);
+       if (qgroup_free)
+               btrfs_qgroup_free_meta_prealloc(node->root,
+                               node->bytes_reserved);
+       else
+               btrfs_qgroup_convert_reserved_meta(node->root,
+                               node->bytes_reserved);
        node->bytes_reserved = 0;
 }
 
@@ -766,7 +781,7 @@ static int btrfs_batch_insert_items(struct btrfs_root *root,
                                    curr->data_len);
                slot++;
 
-               btrfs_delayed_item_release_metadata(fs_info, curr);
+               btrfs_delayed_item_release_metadata(root, curr);
 
                list_del(&curr->tree_list);
                btrfs_release_delayed_item(curr);
@@ -788,7 +803,6 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
                                     struct btrfs_path *path,
                                     struct btrfs_delayed_item *delayed_item)
 {
-       struct btrfs_fs_info *fs_info = root->fs_info;
        struct extent_buffer *leaf;
        char *ptr;
        int ret;
@@ -806,7 +820,7 @@ static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
                            delayed_item->data_len);
        btrfs_mark_buffer_dirty(leaf);
 
-       btrfs_delayed_item_release_metadata(fs_info, delayed_item);
+       btrfs_delayed_item_release_metadata(root, delayed_item);
        return 0;
 }
 
@@ -858,7 +872,6 @@ static int btrfs_batch_delete_items(struct btrfs_trans_handle *trans,
                                    struct btrfs_path *path,
                                    struct btrfs_delayed_item *item)
 {
-       struct btrfs_fs_info *fs_info = root->fs_info;
        struct btrfs_delayed_item *curr, *next;
        struct extent_buffer *leaf;
        struct btrfs_key key;
@@ -908,7 +921,7 @@ static int btrfs_batch_delete_items(struct btrfs_trans_handle *trans,
                goto out;
 
        list_for_each_entry_safe(curr, next, &head, tree_list) {
-               btrfs_delayed_item_release_metadata(fs_info, curr);
+               btrfs_delayed_item_release_metadata(root, curr);
                list_del(&curr->tree_list);
                btrfs_release_delayed_item(curr);
        }
@@ -1051,7 +1064,7 @@ out:
 no_iref:
        btrfs_release_path(path);
 err_out:
-       btrfs_delayed_inode_release_metadata(fs_info, node);
+       btrfs_delayed_inode_release_metadata(fs_info, node, (ret < 0));
        btrfs_release_delayed_inode(node);
 
        return ret;
@@ -1115,9 +1128,9 @@ __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
  * Returns < 0 on error and returns with an aborted transaction with any
  * outstanding delayed items cleaned up.
  */
-static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
-                                    struct btrfs_fs_info *fs_info, int nr)
+static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, int nr)
 {
+       struct btrfs_fs_info *fs_info = trans->fs_info;
        struct btrfs_delayed_root *delayed_root;
        struct btrfs_delayed_node *curr_node, *prev_node;
        struct btrfs_path *path;
@@ -1162,16 +1175,14 @@ static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
        return ret;
 }
 
-int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
-                           struct btrfs_fs_info *fs_info)
+int btrfs_run_delayed_items(struct btrfs_trans_handle *trans)
 {
-       return __btrfs_run_delayed_items(trans, fs_info, -1);
+       return __btrfs_run_delayed_items(trans, -1);
 }
 
-int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
-                              struct btrfs_fs_info *fs_info, int nr)
+int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans, int nr)
 {
-       return __btrfs_run_delayed_items(trans, fs_info, nr);
+       return __btrfs_run_delayed_items(trans, nr);
 }
 
 int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
@@ -1443,7 +1454,7 @@ int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
        btrfs_set_stack_dir_type(dir_item, type);
        memcpy((char *)(dir_item + 1), name, name_len);
 
-       ret = btrfs_delayed_item_reserve_metadata(trans, fs_info, delayed_item);
+       ret = btrfs_delayed_item_reserve_metadata(trans, dir->root, delayed_item);
        /*
         * we have reserved enough space when we start a new transaction,
         * so reserving metadata failure is impossible
@@ -1480,7 +1491,7 @@ static int btrfs_delete_delayed_insertion_item(struct btrfs_fs_info *fs_info,
                return 1;
        }
 
-       btrfs_delayed_item_release_metadata(fs_info, item);
+       btrfs_delayed_item_release_metadata(node->root, item);
        btrfs_release_delayed_item(item);
        mutex_unlock(&node->mutex);
        return 0;
@@ -1515,7 +1526,7 @@ int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
 
        item->key = item_key;
 
-       ret = btrfs_delayed_item_reserve_metadata(trans, fs_info, item);
+       ret = btrfs_delayed_item_reserve_metadata(trans, dir->root, item);
        /*
         * we have reserved enough space when we start a new transaction,
         * so reserving metadata failure is impossible.
@@ -1880,7 +1891,7 @@ static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node)
        mutex_lock(&delayed_node->mutex);
        curr_item = __btrfs_first_delayed_insertion_item(delayed_node);
        while (curr_item) {
-               btrfs_delayed_item_release_metadata(fs_info, curr_item);
+               btrfs_delayed_item_release_metadata(root, curr_item);
                prev_item = curr_item;
                curr_item = __btrfs_next_delayed_item(prev_item);
                btrfs_release_delayed_item(prev_item);
@@ -1888,7 +1899,7 @@ static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node)
 
        curr_item = __btrfs_first_delayed_deletion_item(delayed_node);
        while (curr_item) {
-               btrfs_delayed_item_release_metadata(fs_info, curr_item);
+               btrfs_delayed_item_release_metadata(root, curr_item);
                prev_item = curr_item;
                curr_item = __btrfs_next_delayed_item(prev_item);
                btrfs_release_delayed_item(prev_item);
@@ -1898,7 +1909,7 @@ static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node)
                btrfs_release_delayed_iref(delayed_node);
 
        if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) {
-               btrfs_delayed_inode_release_metadata(fs_info, delayed_node);
+               btrfs_delayed_inode_release_metadata(fs_info, delayed_node, false);
                btrfs_release_delayed_inode(delayed_node);
        }
        mutex_unlock(&delayed_node->mutex);