16cbd5570SChris Mason /* 26cbd5570SChris Mason * Copyright (C) 2007 Oracle. All rights reserved. 36cbd5570SChris Mason * 46cbd5570SChris Mason * This program is free software; you can redistribute it and/or 56cbd5570SChris Mason * modify it under the terms of the GNU General Public 66cbd5570SChris Mason * License v2 as published by the Free Software Foundation. 76cbd5570SChris Mason * 86cbd5570SChris Mason * This program is distributed in the hope that it will be useful, 96cbd5570SChris Mason * but WITHOUT ANY WARRANTY; without even the implied warranty of 106cbd5570SChris Mason * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 116cbd5570SChris Mason * General Public License for more details. 126cbd5570SChris Mason * 136cbd5570SChris Mason * You should have received a copy of the GNU General Public 146cbd5570SChris Mason * License along with this program; if not, write to the 156cbd5570SChris Mason * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 166cbd5570SChris Mason * Boston, MA 021110-1307, USA. 176cbd5570SChris Mason */ 186cbd5570SChris Mason 1979154b1bSChris Mason #include <linux/fs.h> 205a0e3ad6STejun Heo #include <linux/slab.h> 2134088780SChris Mason #include <linux/sched.h> 22d3c2fdcfSChris Mason #include <linux/writeback.h> 235f39d397SChris Mason #include <linux/pagemap.h> 245f2cc086SChris Mason #include <linux/blkdev.h> 2579154b1bSChris Mason #include "ctree.h" 2679154b1bSChris Mason #include "disk-io.h" 2779154b1bSChris Mason #include "transaction.h" 28925baeddSChris Mason #include "locking.h" 29e02119d5SChris Mason #include "tree-log.h" 3079154b1bSChris Mason 310f7d52f4SChris Mason #define BTRFS_ROOT_TRANS_TAG 0 320f7d52f4SChris Mason 3380b6794dSChris Mason static noinline void put_transaction(struct btrfs_transaction *transaction) 3479154b1bSChris Mason { 352c90e5d6SChris Mason WARN_ON(transaction->use_count == 0); 3679154b1bSChris Mason transaction->use_count--; 3778fae27eSChris Mason if (transaction->use_count == 0) { 388fd17795SChris Mason list_del_init(&transaction->list); 392c90e5d6SChris Mason memset(transaction, 0, sizeof(*transaction)); 402c90e5d6SChris Mason kmem_cache_free(btrfs_transaction_cachep, transaction); 4179154b1bSChris Mason } 4278fae27eSChris Mason } 4379154b1bSChris Mason 44817d52f8SJosef Bacik static noinline void switch_commit_root(struct btrfs_root *root) 45817d52f8SJosef Bacik { 46817d52f8SJosef Bacik free_extent_buffer(root->commit_root); 47817d52f8SJosef Bacik root->commit_root = btrfs_root_node(root); 48817d52f8SJosef Bacik } 49817d52f8SJosef Bacik 50d352ac68SChris Mason /* 51d352ac68SChris Mason * either allocate a new transaction or hop into the existing one 52d352ac68SChris Mason */ 5380b6794dSChris Mason static noinline int join_transaction(struct btrfs_root *root) 5479154b1bSChris Mason { 5579154b1bSChris Mason struct btrfs_transaction *cur_trans; 5679154b1bSChris Mason cur_trans = root->fs_info->running_transaction; 5779154b1bSChris Mason if (!cur_trans) { 582c90e5d6SChris Mason cur_trans = kmem_cache_alloc(btrfs_transaction_cachep, 592c90e5d6SChris Mason GFP_NOFS); 6079154b1bSChris Mason BUG_ON(!cur_trans); 610f7d52f4SChris Mason root->fs_info->generation++; 6215ee9bc7SJosef Bacik cur_trans->num_writers = 1; 6315ee9bc7SJosef Bacik cur_trans->num_joined = 0; 640f7d52f4SChris Mason cur_trans->transid = root->fs_info->generation; 6579154b1bSChris Mason init_waitqueue_head(&cur_trans->writer_wait); 6679154b1bSChris Mason init_waitqueue_head(&cur_trans->commit_wait); 6779154b1bSChris Mason cur_trans->in_commit = 0; 68f9295749SChris Mason cur_trans->blocked = 0; 69d5719762SChris Mason cur_trans->use_count = 1; 7079154b1bSChris Mason cur_trans->commit_done = 0; 7108607c1bSChris Mason cur_trans->start_time = get_seconds(); 7256bec294SChris Mason 736bef4d31SEric Paris cur_trans->delayed_refs.root = RB_ROOT; 7456bec294SChris Mason cur_trans->delayed_refs.num_entries = 0; 75c3e69d58SChris Mason cur_trans->delayed_refs.num_heads_ready = 0; 76c3e69d58SChris Mason cur_trans->delayed_refs.num_heads = 0; 7756bec294SChris Mason cur_trans->delayed_refs.flushing = 0; 78c3e69d58SChris Mason cur_trans->delayed_refs.run_delayed_start = 0; 7956bec294SChris Mason spin_lock_init(&cur_trans->delayed_refs.lock); 8056bec294SChris Mason 813063d29fSChris Mason INIT_LIST_HEAD(&cur_trans->pending_snapshots); 828fd17795SChris Mason list_add_tail(&cur_trans->list, &root->fs_info->trans_list); 83d1310b2eSChris Mason extent_io_tree_init(&cur_trans->dirty_pages, 845f39d397SChris Mason root->fs_info->btree_inode->i_mapping, 855f39d397SChris Mason GFP_NOFS); 8648ec2cf8SChris Mason spin_lock(&root->fs_info->new_trans_lock); 8748ec2cf8SChris Mason root->fs_info->running_transaction = cur_trans; 8848ec2cf8SChris Mason spin_unlock(&root->fs_info->new_trans_lock); 8915ee9bc7SJosef Bacik } else { 9079154b1bSChris Mason cur_trans->num_writers++; 9115ee9bc7SJosef Bacik cur_trans->num_joined++; 9215ee9bc7SJosef Bacik } 9315ee9bc7SJosef Bacik 9479154b1bSChris Mason return 0; 9579154b1bSChris Mason } 9679154b1bSChris Mason 97d352ac68SChris Mason /* 98d397712bSChris Mason * this does all the record keeping required to make sure that a reference 99d397712bSChris Mason * counted root is properly recorded in a given transaction. This is required 100d397712bSChris Mason * to make sure the old root from before we joined the transaction is deleted 101d397712bSChris Mason * when the transaction commits 102d352ac68SChris Mason */ 1035d4f98a2SYan Zheng static noinline int record_root_in_trans(struct btrfs_trans_handle *trans, 1045d4f98a2SYan Zheng struct btrfs_root *root) 1056702ed49SChris Mason { 1065d4f98a2SYan Zheng if (root->ref_cows && root->last_trans < trans->transid) { 1076702ed49SChris Mason WARN_ON(root == root->fs_info->extent_root); 1085d4f98a2SYan Zheng WARN_ON(root->commit_root != root->node); 1095d4f98a2SYan Zheng 1106702ed49SChris Mason radix_tree_tag_set(&root->fs_info->fs_roots_radix, 1116702ed49SChris Mason (unsigned long)root->root_key.objectid, 1126702ed49SChris Mason BTRFS_ROOT_TRANS_TAG); 1135d4f98a2SYan Zheng root->last_trans = trans->transid; 1145d4f98a2SYan Zheng btrfs_init_reloc_root(trans, root); 1156702ed49SChris Mason } 1165d4f98a2SYan Zheng return 0; 1176702ed49SChris Mason } 1185d4f98a2SYan Zheng 1195d4f98a2SYan Zheng int btrfs_record_root_in_trans(struct btrfs_trans_handle *trans, 1205d4f98a2SYan Zheng struct btrfs_root *root) 1215d4f98a2SYan Zheng { 1225d4f98a2SYan Zheng if (!root->ref_cows) 1235d4f98a2SYan Zheng return 0; 1245d4f98a2SYan Zheng 1255d4f98a2SYan Zheng mutex_lock(&root->fs_info->trans_mutex); 1265d4f98a2SYan Zheng if (root->last_trans == trans->transid) { 1275d4f98a2SYan Zheng mutex_unlock(&root->fs_info->trans_mutex); 1285d4f98a2SYan Zheng return 0; 1295d4f98a2SYan Zheng } 1305d4f98a2SYan Zheng 1315d4f98a2SYan Zheng record_root_in_trans(trans, root); 1325d4f98a2SYan Zheng mutex_unlock(&root->fs_info->trans_mutex); 1336702ed49SChris Mason return 0; 1346702ed49SChris Mason } 1356702ed49SChris Mason 136d352ac68SChris Mason /* wait for commit against the current transaction to become unblocked 137d352ac68SChris Mason * when this is done, it is safe to start a new transaction, but the current 138d352ac68SChris Mason * transaction might not be fully on disk. 139d352ac68SChris Mason */ 14037d1aeeeSChris Mason static void wait_current_trans(struct btrfs_root *root) 14179154b1bSChris Mason { 142f9295749SChris Mason struct btrfs_transaction *cur_trans; 14379154b1bSChris Mason 144f9295749SChris Mason cur_trans = root->fs_info->running_transaction; 14537d1aeeeSChris Mason if (cur_trans && cur_trans->blocked) { 146f9295749SChris Mason DEFINE_WAIT(wait); 147f9295749SChris Mason cur_trans->use_count++; 148f9295749SChris Mason while (1) { 149f9295749SChris Mason prepare_to_wait(&root->fs_info->transaction_wait, &wait, 150f9295749SChris Mason TASK_UNINTERRUPTIBLE); 151471fa17dSZhao Lei if (!cur_trans->blocked) 152471fa17dSZhao Lei break; 153f9295749SChris Mason mutex_unlock(&root->fs_info->trans_mutex); 154f9295749SChris Mason schedule(); 155f9295749SChris Mason mutex_lock(&root->fs_info->trans_mutex); 156f9295749SChris Mason } 157471fa17dSZhao Lei finish_wait(&root->fs_info->transaction_wait, &wait); 158f9295749SChris Mason put_transaction(cur_trans); 159f9295749SChris Mason } 16037d1aeeeSChris Mason } 16137d1aeeeSChris Mason 162249ac1e5SJosef Bacik enum btrfs_trans_type { 163249ac1e5SJosef Bacik TRANS_START, 164249ac1e5SJosef Bacik TRANS_JOIN, 165249ac1e5SJosef Bacik TRANS_USERSPACE, 166249ac1e5SJosef Bacik }; 167249ac1e5SJosef Bacik 168a22285a6SYan, Zheng static int may_wait_transaction(struct btrfs_root *root, int type) 16937d1aeeeSChris Mason { 1704bef0848SChris Mason if (!root->fs_info->log_root_recovering && 171249ac1e5SJosef Bacik ((type == TRANS_START && !root->fs_info->open_ioctl_trans) || 172249ac1e5SJosef Bacik type == TRANS_USERSPACE)) 173a22285a6SYan, Zheng return 1; 174a22285a6SYan, Zheng return 0; 175a22285a6SYan, Zheng } 176a22285a6SYan, Zheng 177a22285a6SYan, Zheng static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, 178a22285a6SYan, Zheng u64 num_items, int type) 179a22285a6SYan, Zheng { 180a22285a6SYan, Zheng struct btrfs_trans_handle *h; 181a22285a6SYan, Zheng struct btrfs_transaction *cur_trans; 182a22285a6SYan, Zheng int ret; 183a22285a6SYan, Zheng again: 184a22285a6SYan, Zheng h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); 185a22285a6SYan, Zheng if (!h) 186a22285a6SYan, Zheng return ERR_PTR(-ENOMEM); 187a22285a6SYan, Zheng 188a22285a6SYan, Zheng mutex_lock(&root->fs_info->trans_mutex); 189a22285a6SYan, Zheng if (may_wait_transaction(root, type)) 19037d1aeeeSChris Mason wait_current_trans(root); 191a22285a6SYan, Zheng 19279154b1bSChris Mason ret = join_transaction(root); 19379154b1bSChris Mason BUG_ON(ret); 1940f7d52f4SChris Mason 195a22285a6SYan, Zheng cur_trans = root->fs_info->running_transaction; 196a22285a6SYan, Zheng cur_trans->use_count++; 197a22285a6SYan, Zheng mutex_unlock(&root->fs_info->trans_mutex); 198a22285a6SYan, Zheng 199a22285a6SYan, Zheng h->transid = cur_trans->transid; 200a22285a6SYan, Zheng h->transaction = cur_trans; 20179154b1bSChris Mason h->blocks_used = 0; 202d2fb3437SYan Zheng h->block_group = 0; 203a22285a6SYan, Zheng h->bytes_reserved = 0; 20456bec294SChris Mason h->delayed_ref_updates = 0; 205f0486c68SYan, Zheng h->block_rsv = NULL; 206b7ec40d7SChris Mason 207a22285a6SYan, Zheng smp_mb(); 208a22285a6SYan, Zheng if (cur_trans->blocked && may_wait_transaction(root, type)) { 209a22285a6SYan, Zheng btrfs_commit_transaction(h, root); 210a22285a6SYan, Zheng goto again; 211a22285a6SYan, Zheng } 2129ed74f2dSJosef Bacik 213a22285a6SYan, Zheng if (num_items > 0) { 214*8bb8ab2eSJosef Bacik ret = btrfs_trans_reserve_metadata(h, root, num_items); 215a22285a6SYan, Zheng if (ret == -EAGAIN) { 216a22285a6SYan, Zheng btrfs_commit_transaction(h, root); 217a22285a6SYan, Zheng goto again; 218a22285a6SYan, Zheng } 219a22285a6SYan, Zheng if (ret < 0) { 220a22285a6SYan, Zheng btrfs_end_transaction(h, root); 221a22285a6SYan, Zheng return ERR_PTR(ret); 222a22285a6SYan, Zheng } 223a22285a6SYan, Zheng } 224a22285a6SYan, Zheng 225a22285a6SYan, Zheng mutex_lock(&root->fs_info->trans_mutex); 2265d4f98a2SYan Zheng record_root_in_trans(h, root); 22779154b1bSChris Mason mutex_unlock(&root->fs_info->trans_mutex); 228a22285a6SYan, Zheng 229a22285a6SYan, Zheng if (!current->journal_info && type != TRANS_USERSPACE) 230a22285a6SYan, Zheng current->journal_info = h; 23179154b1bSChris Mason return h; 23279154b1bSChris Mason } 23379154b1bSChris Mason 234f9295749SChris Mason struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root, 235a22285a6SYan, Zheng int num_items) 236f9295749SChris Mason { 237a22285a6SYan, Zheng return start_transaction(root, num_items, TRANS_START); 238f9295749SChris Mason } 239f9295749SChris Mason struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root, 240f9295749SChris Mason int num_blocks) 241f9295749SChris Mason { 242a22285a6SYan, Zheng return start_transaction(root, 0, TRANS_JOIN); 243f9295749SChris Mason } 244f9295749SChris Mason 2459ca9ee09SSage Weil struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *r, 2469ca9ee09SSage Weil int num_blocks) 2479ca9ee09SSage Weil { 248a22285a6SYan, Zheng return start_transaction(r, 0, TRANS_USERSPACE); 2499ca9ee09SSage Weil } 2509ca9ee09SSage Weil 251d352ac68SChris Mason /* wait for a transaction commit to be fully complete */ 25289ce8a63SChris Mason static noinline int wait_for_commit(struct btrfs_root *root, 25389ce8a63SChris Mason struct btrfs_transaction *commit) 25489ce8a63SChris Mason { 25589ce8a63SChris Mason DEFINE_WAIT(wait); 25689ce8a63SChris Mason mutex_lock(&root->fs_info->trans_mutex); 25789ce8a63SChris Mason while (!commit->commit_done) { 25889ce8a63SChris Mason prepare_to_wait(&commit->commit_wait, &wait, 25989ce8a63SChris Mason TASK_UNINTERRUPTIBLE); 26089ce8a63SChris Mason if (commit->commit_done) 26189ce8a63SChris Mason break; 26289ce8a63SChris Mason mutex_unlock(&root->fs_info->trans_mutex); 26389ce8a63SChris Mason schedule(); 26489ce8a63SChris Mason mutex_lock(&root->fs_info->trans_mutex); 26589ce8a63SChris Mason } 26689ce8a63SChris Mason mutex_unlock(&root->fs_info->trans_mutex); 26789ce8a63SChris Mason finish_wait(&commit->commit_wait, &wait); 26889ce8a63SChris Mason return 0; 26989ce8a63SChris Mason } 27089ce8a63SChris Mason 2715d4f98a2SYan Zheng #if 0 272d352ac68SChris Mason /* 273d397712bSChris Mason * rate limit against the drop_snapshot code. This helps to slow down new 274d397712bSChris Mason * operations if the drop_snapshot code isn't able to keep up. 275d352ac68SChris Mason */ 27637d1aeeeSChris Mason static void throttle_on_drops(struct btrfs_root *root) 277ab78c84dSChris Mason { 278ab78c84dSChris Mason struct btrfs_fs_info *info = root->fs_info; 2792dd3e67bSChris Mason int harder_count = 0; 280ab78c84dSChris Mason 2812dd3e67bSChris Mason harder: 282ab78c84dSChris Mason if (atomic_read(&info->throttles)) { 283ab78c84dSChris Mason DEFINE_WAIT(wait); 284ab78c84dSChris Mason int thr; 285ab78c84dSChris Mason thr = atomic_read(&info->throttle_gen); 286ab78c84dSChris Mason 287ab78c84dSChris Mason do { 288ab78c84dSChris Mason prepare_to_wait(&info->transaction_throttle, 289ab78c84dSChris Mason &wait, TASK_UNINTERRUPTIBLE); 290ab78c84dSChris Mason if (!atomic_read(&info->throttles)) { 291ab78c84dSChris Mason finish_wait(&info->transaction_throttle, &wait); 292ab78c84dSChris Mason break; 293ab78c84dSChris Mason } 294ab78c84dSChris Mason schedule(); 295ab78c84dSChris Mason finish_wait(&info->transaction_throttle, &wait); 296ab78c84dSChris Mason } while (thr == atomic_read(&info->throttle_gen)); 2972dd3e67bSChris Mason harder_count++; 2982dd3e67bSChris Mason 2992dd3e67bSChris Mason if (root->fs_info->total_ref_cache_size > 1 * 1024 * 1024 && 3002dd3e67bSChris Mason harder_count < 2) 3012dd3e67bSChris Mason goto harder; 3022dd3e67bSChris Mason 3032dd3e67bSChris Mason if (root->fs_info->total_ref_cache_size > 5 * 1024 * 1024 && 3042dd3e67bSChris Mason harder_count < 10) 3052dd3e67bSChris Mason goto harder; 3062dd3e67bSChris Mason 3072dd3e67bSChris Mason if (root->fs_info->total_ref_cache_size > 10 * 1024 * 1024 && 3082dd3e67bSChris Mason harder_count < 20) 3092dd3e67bSChris Mason goto harder; 310ab78c84dSChris Mason } 311ab78c84dSChris Mason } 3125d4f98a2SYan Zheng #endif 313ab78c84dSChris Mason 31437d1aeeeSChris Mason void btrfs_throttle(struct btrfs_root *root) 31537d1aeeeSChris Mason { 31637d1aeeeSChris Mason mutex_lock(&root->fs_info->trans_mutex); 3179ca9ee09SSage Weil if (!root->fs_info->open_ioctl_trans) 31837d1aeeeSChris Mason wait_current_trans(root); 31937d1aeeeSChris Mason mutex_unlock(&root->fs_info->trans_mutex); 32037d1aeeeSChris Mason } 32137d1aeeeSChris Mason 3228929ecfaSYan, Zheng static int should_end_transaction(struct btrfs_trans_handle *trans, 3238929ecfaSYan, Zheng struct btrfs_root *root) 3248929ecfaSYan, Zheng { 3258929ecfaSYan, Zheng int ret; 3268929ecfaSYan, Zheng ret = btrfs_block_rsv_check(trans, root, 3278929ecfaSYan, Zheng &root->fs_info->global_block_rsv, 0, 5); 3288929ecfaSYan, Zheng return ret ? 1 : 0; 3298929ecfaSYan, Zheng } 3308929ecfaSYan, Zheng 3318929ecfaSYan, Zheng int btrfs_should_end_transaction(struct btrfs_trans_handle *trans, 3328929ecfaSYan, Zheng struct btrfs_root *root) 3338929ecfaSYan, Zheng { 3348929ecfaSYan, Zheng struct btrfs_transaction *cur_trans = trans->transaction; 3358929ecfaSYan, Zheng int updates; 3368929ecfaSYan, Zheng 3378929ecfaSYan, Zheng if (cur_trans->blocked || cur_trans->delayed_refs.flushing) 3388929ecfaSYan, Zheng return 1; 3398929ecfaSYan, Zheng 3408929ecfaSYan, Zheng updates = trans->delayed_ref_updates; 3418929ecfaSYan, Zheng trans->delayed_ref_updates = 0; 3428929ecfaSYan, Zheng if (updates) 3438929ecfaSYan, Zheng btrfs_run_delayed_refs(trans, root, updates); 3448929ecfaSYan, Zheng 3458929ecfaSYan, Zheng return should_end_transaction(trans, root); 3468929ecfaSYan, Zheng } 3478929ecfaSYan, Zheng 34889ce8a63SChris Mason static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, 34989ce8a63SChris Mason struct btrfs_root *root, int throttle) 35079154b1bSChris Mason { 3518929ecfaSYan, Zheng struct btrfs_transaction *cur_trans = trans->transaction; 352ab78c84dSChris Mason struct btrfs_fs_info *info = root->fs_info; 353c3e69d58SChris Mason int count = 0; 354d6e4a428SChris Mason 355c3e69d58SChris Mason while (count < 4) { 356c3e69d58SChris Mason unsigned long cur = trans->delayed_ref_updates; 357c3e69d58SChris Mason trans->delayed_ref_updates = 0; 358c3e69d58SChris Mason if (cur && 359c3e69d58SChris Mason trans->transaction->delayed_refs.num_heads_ready > 64) { 360c3e69d58SChris Mason trans->delayed_ref_updates = 0; 361b7ec40d7SChris Mason 362b7ec40d7SChris Mason /* 363b7ec40d7SChris Mason * do a full flush if the transaction is trying 364b7ec40d7SChris Mason * to close 365b7ec40d7SChris Mason */ 366b7ec40d7SChris Mason if (trans->transaction->delayed_refs.flushing) 367b7ec40d7SChris Mason cur = 0; 368c3e69d58SChris Mason btrfs_run_delayed_refs(trans, root, cur); 369c3e69d58SChris Mason } else { 370c3e69d58SChris Mason break; 371c3e69d58SChris Mason } 372c3e69d58SChris Mason count++; 37356bec294SChris Mason } 37456bec294SChris Mason 375a22285a6SYan, Zheng btrfs_trans_release_metadata(trans, root); 376a22285a6SYan, Zheng 3778929ecfaSYan, Zheng if (!root->fs_info->open_ioctl_trans && 3788929ecfaSYan, Zheng should_end_transaction(trans, root)) 3798929ecfaSYan, Zheng trans->transaction->blocked = 1; 3808929ecfaSYan, Zheng 3818929ecfaSYan, Zheng if (cur_trans->blocked && !cur_trans->in_commit) { 3828929ecfaSYan, Zheng if (throttle) 3838929ecfaSYan, Zheng return btrfs_commit_transaction(trans, root); 3848929ecfaSYan, Zheng else 3858929ecfaSYan, Zheng wake_up_process(info->transaction_kthread); 3868929ecfaSYan, Zheng } 3878929ecfaSYan, Zheng 388ab78c84dSChris Mason mutex_lock(&info->trans_mutex); 3898929ecfaSYan, Zheng WARN_ON(cur_trans != info->running_transaction); 390d5719762SChris Mason WARN_ON(cur_trans->num_writers < 1); 391ccd467d6SChris Mason cur_trans->num_writers--; 39289ce8a63SChris Mason 39379154b1bSChris Mason if (waitqueue_active(&cur_trans->writer_wait)) 39479154b1bSChris Mason wake_up(&cur_trans->writer_wait); 39579154b1bSChris Mason put_transaction(cur_trans); 396ab78c84dSChris Mason mutex_unlock(&info->trans_mutex); 3979ed74f2dSJosef Bacik 3989ed74f2dSJosef Bacik if (current->journal_info == trans) 3999ed74f2dSJosef Bacik current->journal_info = NULL; 400d6025579SChris Mason memset(trans, 0, sizeof(*trans)); 4012c90e5d6SChris Mason kmem_cache_free(btrfs_trans_handle_cachep, trans); 402ab78c84dSChris Mason 40324bbcf04SYan, Zheng if (throttle) 40424bbcf04SYan, Zheng btrfs_run_delayed_iputs(root); 40524bbcf04SYan, Zheng 40679154b1bSChris Mason return 0; 40779154b1bSChris Mason } 40879154b1bSChris Mason 40989ce8a63SChris Mason int btrfs_end_transaction(struct btrfs_trans_handle *trans, 41089ce8a63SChris Mason struct btrfs_root *root) 41189ce8a63SChris Mason { 41289ce8a63SChris Mason return __btrfs_end_transaction(trans, root, 0); 41389ce8a63SChris Mason } 41489ce8a63SChris Mason 41589ce8a63SChris Mason int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, 41689ce8a63SChris Mason struct btrfs_root *root) 41789ce8a63SChris Mason { 41889ce8a63SChris Mason return __btrfs_end_transaction(trans, root, 1); 41989ce8a63SChris Mason } 42089ce8a63SChris Mason 421d352ac68SChris Mason /* 422d352ac68SChris Mason * when btree blocks are allocated, they have some corresponding bits set for 423d352ac68SChris Mason * them in one of two extent_io trees. This is used to make sure all of 424690587d1SChris Mason * those extents are sent to disk but does not wait on them 425d352ac68SChris Mason */ 426690587d1SChris Mason int btrfs_write_marked_extents(struct btrfs_root *root, 4278cef4e16SYan, Zheng struct extent_io_tree *dirty_pages, int mark) 42879154b1bSChris Mason { 4297c4452b9SChris Mason int ret; 430777e6bd7SChris Mason int err = 0; 4317c4452b9SChris Mason int werr = 0; 4327c4452b9SChris Mason struct page *page; 4337c4452b9SChris Mason struct inode *btree_inode = root->fs_info->btree_inode; 434777e6bd7SChris Mason u64 start = 0; 4355f39d397SChris Mason u64 end; 4365f39d397SChris Mason unsigned long index; 4377c4452b9SChris Mason 4387c4452b9SChris Mason while (1) { 439777e6bd7SChris Mason ret = find_first_extent_bit(dirty_pages, start, &start, &end, 4408cef4e16SYan, Zheng mark); 4415f39d397SChris Mason if (ret) 4427c4452b9SChris Mason break; 4435f39d397SChris Mason while (start <= end) { 444777e6bd7SChris Mason cond_resched(); 445777e6bd7SChris Mason 4465f39d397SChris Mason index = start >> PAGE_CACHE_SHIFT; 44735ebb934SChris Mason start = (u64)(index + 1) << PAGE_CACHE_SHIFT; 4484bef0848SChris Mason page = find_get_page(btree_inode->i_mapping, index); 4497c4452b9SChris Mason if (!page) 4507c4452b9SChris Mason continue; 4514bef0848SChris Mason 4524bef0848SChris Mason btree_lock_page_hook(page); 4534bef0848SChris Mason if (!page->mapping) { 4544bef0848SChris Mason unlock_page(page); 4554bef0848SChris Mason page_cache_release(page); 4564bef0848SChris Mason continue; 4574bef0848SChris Mason } 4584bef0848SChris Mason 4596702ed49SChris Mason if (PageWriteback(page)) { 4606702ed49SChris Mason if (PageDirty(page)) 4616702ed49SChris Mason wait_on_page_writeback(page); 4626702ed49SChris Mason else { 4636702ed49SChris Mason unlock_page(page); 4646702ed49SChris Mason page_cache_release(page); 4656702ed49SChris Mason continue; 4666702ed49SChris Mason } 4676702ed49SChris Mason } 4687c4452b9SChris Mason err = write_one_page(page, 0); 4697c4452b9SChris Mason if (err) 4707c4452b9SChris Mason werr = err; 4717c4452b9SChris Mason page_cache_release(page); 4727c4452b9SChris Mason } 4737c4452b9SChris Mason } 474690587d1SChris Mason if (err) 475690587d1SChris Mason werr = err; 476690587d1SChris Mason return werr; 477690587d1SChris Mason } 478690587d1SChris Mason 479690587d1SChris Mason /* 480690587d1SChris Mason * when btree blocks are allocated, they have some corresponding bits set for 481690587d1SChris Mason * them in one of two extent_io trees. This is used to make sure all of 482690587d1SChris Mason * those extents are on disk for transaction or log commit. We wait 483690587d1SChris Mason * on all the pages and clear them from the dirty pages state tree 484690587d1SChris Mason */ 485690587d1SChris Mason int btrfs_wait_marked_extents(struct btrfs_root *root, 4868cef4e16SYan, Zheng struct extent_io_tree *dirty_pages, int mark) 487690587d1SChris Mason { 488690587d1SChris Mason int ret; 489690587d1SChris Mason int err = 0; 490690587d1SChris Mason int werr = 0; 491690587d1SChris Mason struct page *page; 492690587d1SChris Mason struct inode *btree_inode = root->fs_info->btree_inode; 493690587d1SChris Mason u64 start = 0; 494690587d1SChris Mason u64 end; 495690587d1SChris Mason unsigned long index; 496690587d1SChris Mason 497777e6bd7SChris Mason while (1) { 4988cef4e16SYan, Zheng ret = find_first_extent_bit(dirty_pages, start, &start, &end, 4998cef4e16SYan, Zheng mark); 500777e6bd7SChris Mason if (ret) 501777e6bd7SChris Mason break; 502777e6bd7SChris Mason 5038cef4e16SYan, Zheng clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS); 504777e6bd7SChris Mason while (start <= end) { 505777e6bd7SChris Mason index = start >> PAGE_CACHE_SHIFT; 506777e6bd7SChris Mason start = (u64)(index + 1) << PAGE_CACHE_SHIFT; 507777e6bd7SChris Mason page = find_get_page(btree_inode->i_mapping, index); 508777e6bd7SChris Mason if (!page) 509777e6bd7SChris Mason continue; 510777e6bd7SChris Mason if (PageDirty(page)) { 5114bef0848SChris Mason btree_lock_page_hook(page); 5124bef0848SChris Mason wait_on_page_writeback(page); 513777e6bd7SChris Mason err = write_one_page(page, 0); 514777e6bd7SChris Mason if (err) 515777e6bd7SChris Mason werr = err; 516777e6bd7SChris Mason } 517777e6bd7SChris Mason wait_on_page_writeback(page); 518777e6bd7SChris Mason page_cache_release(page); 519777e6bd7SChris Mason cond_resched(); 520777e6bd7SChris Mason } 521777e6bd7SChris Mason } 5227c4452b9SChris Mason if (err) 5237c4452b9SChris Mason werr = err; 5247c4452b9SChris Mason return werr; 52579154b1bSChris Mason } 52679154b1bSChris Mason 527690587d1SChris Mason /* 528690587d1SChris Mason * when btree blocks are allocated, they have some corresponding bits set for 529690587d1SChris Mason * them in one of two extent_io trees. This is used to make sure all of 530690587d1SChris Mason * those extents are on disk for transaction or log commit 531690587d1SChris Mason */ 532690587d1SChris Mason int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, 5338cef4e16SYan, Zheng struct extent_io_tree *dirty_pages, int mark) 534690587d1SChris Mason { 535690587d1SChris Mason int ret; 536690587d1SChris Mason int ret2; 537690587d1SChris Mason 5388cef4e16SYan, Zheng ret = btrfs_write_marked_extents(root, dirty_pages, mark); 5398cef4e16SYan, Zheng ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark); 540690587d1SChris Mason return ret || ret2; 541690587d1SChris Mason } 542690587d1SChris Mason 543d0c803c4SChris Mason int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, 544d0c803c4SChris Mason struct btrfs_root *root) 545d0c803c4SChris Mason { 546d0c803c4SChris Mason if (!trans || !trans->transaction) { 547d0c803c4SChris Mason struct inode *btree_inode; 548d0c803c4SChris Mason btree_inode = root->fs_info->btree_inode; 549d0c803c4SChris Mason return filemap_write_and_wait(btree_inode->i_mapping); 550d0c803c4SChris Mason } 551d0c803c4SChris Mason return btrfs_write_and_wait_marked_extents(root, 5528cef4e16SYan, Zheng &trans->transaction->dirty_pages, 5538cef4e16SYan, Zheng EXTENT_DIRTY); 554d0c803c4SChris Mason } 555d0c803c4SChris Mason 556d352ac68SChris Mason /* 557d352ac68SChris Mason * this is used to update the root pointer in the tree of tree roots. 558d352ac68SChris Mason * 559d352ac68SChris Mason * But, in the case of the extent allocation tree, updating the root 560d352ac68SChris Mason * pointer may allocate blocks which may change the root of the extent 561d352ac68SChris Mason * allocation tree. 562d352ac68SChris Mason * 563d352ac68SChris Mason * So, this loops and repeats and makes sure the cowonly root didn't 564d352ac68SChris Mason * change while the root pointer was being updated in the metadata. 565d352ac68SChris Mason */ 5660b86a832SChris Mason static int update_cowonly_root(struct btrfs_trans_handle *trans, 56779154b1bSChris Mason struct btrfs_root *root) 56879154b1bSChris Mason { 56979154b1bSChris Mason int ret; 5700b86a832SChris Mason u64 old_root_bytenr; 57186b9f2ecSYan, Zheng u64 old_root_used; 5720b86a832SChris Mason struct btrfs_root *tree_root = root->fs_info->tree_root; 57379154b1bSChris Mason 57486b9f2ecSYan, Zheng old_root_used = btrfs_root_used(&root->root_item); 5750b86a832SChris Mason btrfs_write_dirty_block_groups(trans, root); 57656bec294SChris Mason 57779154b1bSChris Mason while (1) { 5780b86a832SChris Mason old_root_bytenr = btrfs_root_bytenr(&root->root_item); 57986b9f2ecSYan, Zheng if (old_root_bytenr == root->node->start && 58086b9f2ecSYan, Zheng old_root_used == btrfs_root_used(&root->root_item)) 58179154b1bSChris Mason break; 58287ef2bb4SChris Mason 5835d4f98a2SYan Zheng btrfs_set_root_node(&root->root_item, root->node); 58479154b1bSChris Mason ret = btrfs_update_root(trans, tree_root, 5850b86a832SChris Mason &root->root_key, 5860b86a832SChris Mason &root->root_item); 58779154b1bSChris Mason BUG_ON(ret); 58856bec294SChris Mason 58986b9f2ecSYan, Zheng old_root_used = btrfs_root_used(&root->root_item); 5904a8c9a62SYan Zheng ret = btrfs_write_dirty_block_groups(trans, root); 59156bec294SChris Mason BUG_ON(ret); 5920b86a832SChris Mason } 593276e680dSYan Zheng 594276e680dSYan Zheng if (root != root->fs_info->extent_root) 595817d52f8SJosef Bacik switch_commit_root(root); 596276e680dSYan Zheng 5970b86a832SChris Mason return 0; 5980b86a832SChris Mason } 5990b86a832SChris Mason 600d352ac68SChris Mason /* 601d352ac68SChris Mason * update all the cowonly tree roots on disk 602d352ac68SChris Mason */ 6035d4f98a2SYan Zheng static noinline int commit_cowonly_roots(struct btrfs_trans_handle *trans, 6040b86a832SChris Mason struct btrfs_root *root) 6050b86a832SChris Mason { 6060b86a832SChris Mason struct btrfs_fs_info *fs_info = root->fs_info; 6070b86a832SChris Mason struct list_head *next; 60884234f3aSYan Zheng struct extent_buffer *eb; 60956bec294SChris Mason int ret; 61084234f3aSYan Zheng 61156bec294SChris Mason ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); 61256bec294SChris Mason BUG_ON(ret); 61387ef2bb4SChris Mason 61484234f3aSYan Zheng eb = btrfs_lock_root_node(fs_info->tree_root); 6159fa8cfe7SChris Mason btrfs_cow_block(trans, fs_info->tree_root, eb, NULL, 0, &eb); 61684234f3aSYan Zheng btrfs_tree_unlock(eb); 61784234f3aSYan Zheng free_extent_buffer(eb); 6180b86a832SChris Mason 61956bec294SChris Mason ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); 62056bec294SChris Mason BUG_ON(ret); 62187ef2bb4SChris Mason 6220b86a832SChris Mason while (!list_empty(&fs_info->dirty_cowonly_roots)) { 6230b86a832SChris Mason next = fs_info->dirty_cowonly_roots.next; 6240b86a832SChris Mason list_del_init(next); 6250b86a832SChris Mason root = list_entry(next, struct btrfs_root, dirty_list); 62687ef2bb4SChris Mason 6270b86a832SChris Mason update_cowonly_root(trans, root); 62879154b1bSChris Mason } 629276e680dSYan Zheng 630276e680dSYan Zheng down_write(&fs_info->extent_commit_sem); 631276e680dSYan Zheng switch_commit_root(fs_info->extent_root); 632276e680dSYan Zheng up_write(&fs_info->extent_commit_sem); 633276e680dSYan Zheng 63479154b1bSChris Mason return 0; 63579154b1bSChris Mason } 63679154b1bSChris Mason 637d352ac68SChris Mason /* 638d352ac68SChris Mason * dead roots are old snapshots that need to be deleted. This allocates 639d352ac68SChris Mason * a dirty root struct and adds it into the list of dead roots that need to 640d352ac68SChris Mason * be deleted 641d352ac68SChris Mason */ 6425d4f98a2SYan Zheng int btrfs_add_dead_root(struct btrfs_root *root) 6435eda7b5eSChris Mason { 644b48652c1SYan Zheng mutex_lock(&root->fs_info->trans_mutex); 6455d4f98a2SYan Zheng list_add(&root->root_list, &root->fs_info->dead_roots); 646b48652c1SYan Zheng mutex_unlock(&root->fs_info->trans_mutex); 6475eda7b5eSChris Mason return 0; 6485eda7b5eSChris Mason } 6495eda7b5eSChris Mason 650d352ac68SChris Mason /* 6515d4f98a2SYan Zheng * update all the cowonly tree roots on disk 652d352ac68SChris Mason */ 6535d4f98a2SYan Zheng static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, 6545d4f98a2SYan Zheng struct btrfs_root *root) 6550f7d52f4SChris Mason { 6560f7d52f4SChris Mason struct btrfs_root *gang[8]; 6575d4f98a2SYan Zheng struct btrfs_fs_info *fs_info = root->fs_info; 6580f7d52f4SChris Mason int i; 6590f7d52f4SChris Mason int ret; 66054aa1f4dSChris Mason int err = 0; 66154aa1f4dSChris Mason 6620f7d52f4SChris Mason while (1) { 6635d4f98a2SYan Zheng ret = radix_tree_gang_lookup_tag(&fs_info->fs_roots_radix, 6645d4f98a2SYan Zheng (void **)gang, 0, 6650f7d52f4SChris Mason ARRAY_SIZE(gang), 6660f7d52f4SChris Mason BTRFS_ROOT_TRANS_TAG); 6670f7d52f4SChris Mason if (ret == 0) 6680f7d52f4SChris Mason break; 6690f7d52f4SChris Mason for (i = 0; i < ret; i++) { 6700f7d52f4SChris Mason root = gang[i]; 6715d4f98a2SYan Zheng radix_tree_tag_clear(&fs_info->fs_roots_radix, 6722619ba1fSChris Mason (unsigned long)root->root_key.objectid, 6730f7d52f4SChris Mason BTRFS_ROOT_TRANS_TAG); 67431153d81SYan Zheng 675e02119d5SChris Mason btrfs_free_log(trans, root); 6765d4f98a2SYan Zheng btrfs_update_reloc_root(trans, root); 677d68fc57bSYan, Zheng btrfs_orphan_commit_root(trans, root); 678e02119d5SChris Mason 679978d910dSYan Zheng if (root->commit_root != root->node) { 680817d52f8SJosef Bacik switch_commit_root(root); 681978d910dSYan Zheng btrfs_set_root_node(&root->root_item, 682978d910dSYan Zheng root->node); 683978d910dSYan Zheng } 68431153d81SYan Zheng 6855d4f98a2SYan Zheng err = btrfs_update_root(trans, fs_info->tree_root, 6860f7d52f4SChris Mason &root->root_key, 6870f7d52f4SChris Mason &root->root_item); 68854aa1f4dSChris Mason if (err) 68954aa1f4dSChris Mason break; 6900f7d52f4SChris Mason } 6919f3a7427SChris Mason } 69254aa1f4dSChris Mason return err; 6930f7d52f4SChris Mason } 6940f7d52f4SChris Mason 695d352ac68SChris Mason /* 696d352ac68SChris Mason * defrag a given btree. If cacheonly == 1, this won't read from the disk, 697d352ac68SChris Mason * otherwise every leaf in the btree is read and defragged. 698d352ac68SChris Mason */ 699e9d0b13bSChris Mason int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) 700e9d0b13bSChris Mason { 701e9d0b13bSChris Mason struct btrfs_fs_info *info = root->fs_info; 702e9d0b13bSChris Mason struct btrfs_trans_handle *trans; 7038929ecfaSYan, Zheng int ret; 704d3c2fdcfSChris Mason unsigned long nr; 705e9d0b13bSChris Mason 7068929ecfaSYan, Zheng if (xchg(&root->defrag_running, 1)) 707e9d0b13bSChris Mason return 0; 7088929ecfaSYan, Zheng 7096b80053dSChris Mason while (1) { 7108929ecfaSYan, Zheng trans = btrfs_start_transaction(root, 0); 7118929ecfaSYan, Zheng if (IS_ERR(trans)) 7128929ecfaSYan, Zheng return PTR_ERR(trans); 7138929ecfaSYan, Zheng 714e9d0b13bSChris Mason ret = btrfs_defrag_leaves(trans, root, cacheonly); 7158929ecfaSYan, Zheng 716d3c2fdcfSChris Mason nr = trans->blocks_used; 717e9d0b13bSChris Mason btrfs_end_transaction(trans, root); 718d3c2fdcfSChris Mason btrfs_btree_balance_dirty(info->tree_root, nr); 719e9d0b13bSChris Mason cond_resched(); 720e9d0b13bSChris Mason 7213f157a2fSChris Mason if (root->fs_info->closing || ret != -EAGAIN) 722e9d0b13bSChris Mason break; 723e9d0b13bSChris Mason } 724e9d0b13bSChris Mason root->defrag_running = 0; 7258929ecfaSYan, Zheng return ret; 726e9d0b13bSChris Mason } 727e9d0b13bSChris Mason 7282c47e605SYan Zheng #if 0 729d352ac68SChris Mason /* 730b7ec40d7SChris Mason * when dropping snapshots, we generate a ton of delayed refs, and it makes 731b7ec40d7SChris Mason * sense not to join the transaction while it is trying to flush the current 732b7ec40d7SChris Mason * queue of delayed refs out. 733b7ec40d7SChris Mason * 734b7ec40d7SChris Mason * This is used by the drop snapshot code only 735b7ec40d7SChris Mason */ 736b7ec40d7SChris Mason static noinline int wait_transaction_pre_flush(struct btrfs_fs_info *info) 737b7ec40d7SChris Mason { 738b7ec40d7SChris Mason DEFINE_WAIT(wait); 739b7ec40d7SChris Mason 740b7ec40d7SChris Mason mutex_lock(&info->trans_mutex); 741b7ec40d7SChris Mason while (info->running_transaction && 742b7ec40d7SChris Mason info->running_transaction->delayed_refs.flushing) { 743b7ec40d7SChris Mason prepare_to_wait(&info->transaction_wait, &wait, 744b7ec40d7SChris Mason TASK_UNINTERRUPTIBLE); 745b7ec40d7SChris Mason mutex_unlock(&info->trans_mutex); 74659bc5c75SChris Mason 747b7ec40d7SChris Mason schedule(); 74859bc5c75SChris Mason 749b7ec40d7SChris Mason mutex_lock(&info->trans_mutex); 750b7ec40d7SChris Mason finish_wait(&info->transaction_wait, &wait); 751b7ec40d7SChris Mason } 752b7ec40d7SChris Mason mutex_unlock(&info->trans_mutex); 753b7ec40d7SChris Mason return 0; 754b7ec40d7SChris Mason } 755b7ec40d7SChris Mason 756b7ec40d7SChris Mason /* 757d352ac68SChris Mason * Given a list of roots that need to be deleted, call btrfs_drop_snapshot on 758d352ac68SChris Mason * all of them 759d352ac68SChris Mason */ 7605d4f98a2SYan Zheng int btrfs_drop_dead_root(struct btrfs_root *root) 7610f7d52f4SChris Mason { 7620f7d52f4SChris Mason struct btrfs_trans_handle *trans; 7635d4f98a2SYan Zheng struct btrfs_root *tree_root = root->fs_info->tree_root; 764d3c2fdcfSChris Mason unsigned long nr; 7655d4f98a2SYan Zheng int ret; 76658176a96SJosef Bacik 7679f3a7427SChris Mason while (1) { 768b7ec40d7SChris Mason /* 769b7ec40d7SChris Mason * we don't want to jump in and create a bunch of 770b7ec40d7SChris Mason * delayed refs if the transaction is starting to close 771b7ec40d7SChris Mason */ 772b7ec40d7SChris Mason wait_transaction_pre_flush(tree_root->fs_info); 7730f7d52f4SChris Mason trans = btrfs_start_transaction(tree_root, 1); 774b7ec40d7SChris Mason 775b7ec40d7SChris Mason /* 776b7ec40d7SChris Mason * we've joined a transaction, make sure it isn't 777b7ec40d7SChris Mason * closing right now 778b7ec40d7SChris Mason */ 779b7ec40d7SChris Mason if (trans->transaction->delayed_refs.flushing) { 780b7ec40d7SChris Mason btrfs_end_transaction(trans, tree_root); 781b7ec40d7SChris Mason continue; 782b7ec40d7SChris Mason } 783b7ec40d7SChris Mason 7845d4f98a2SYan Zheng ret = btrfs_drop_snapshot(trans, root); 785d397712bSChris Mason if (ret != -EAGAIN) 7869f3a7427SChris Mason break; 78758176a96SJosef Bacik 7885d4f98a2SYan Zheng ret = btrfs_update_root(trans, tree_root, 7895d4f98a2SYan Zheng &root->root_key, 7905d4f98a2SYan Zheng &root->root_item); 7915d4f98a2SYan Zheng if (ret) 79254aa1f4dSChris Mason break; 793bcc63abbSYan 794d3c2fdcfSChris Mason nr = trans->blocks_used; 7950f7d52f4SChris Mason ret = btrfs_end_transaction(trans, tree_root); 7960f7d52f4SChris Mason BUG_ON(ret); 7975eda7b5eSChris Mason 798d3c2fdcfSChris Mason btrfs_btree_balance_dirty(tree_root, nr); 7994dc11904SChris Mason cond_resched(); 8000f7d52f4SChris Mason } 8015d4f98a2SYan Zheng BUG_ON(ret); 8025d4f98a2SYan Zheng 8035d4f98a2SYan Zheng ret = btrfs_del_root(trans, tree_root, &root->root_key); 8045d4f98a2SYan Zheng BUG_ON(ret); 8055d4f98a2SYan Zheng 8065d4f98a2SYan Zheng nr = trans->blocks_used; 8075d4f98a2SYan Zheng ret = btrfs_end_transaction(trans, tree_root); 8085d4f98a2SYan Zheng BUG_ON(ret); 8095d4f98a2SYan Zheng 8105d4f98a2SYan Zheng free_extent_buffer(root->node); 8115d4f98a2SYan Zheng free_extent_buffer(root->commit_root); 8125d4f98a2SYan Zheng kfree(root); 8135d4f98a2SYan Zheng 8145d4f98a2SYan Zheng btrfs_btree_balance_dirty(tree_root, nr); 81554aa1f4dSChris Mason return ret; 8160f7d52f4SChris Mason } 8172c47e605SYan Zheng #endif 8180f7d52f4SChris Mason 819d352ac68SChris Mason /* 820d352ac68SChris Mason * new snapshots need to be created at a very specific time in the 821d352ac68SChris Mason * transaction commit. This does the actual creation 822d352ac68SChris Mason */ 82380b6794dSChris Mason static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, 8243063d29fSChris Mason struct btrfs_fs_info *fs_info, 8253063d29fSChris Mason struct btrfs_pending_snapshot *pending) 8263063d29fSChris Mason { 8273063d29fSChris Mason struct btrfs_key key; 82880b6794dSChris Mason struct btrfs_root_item *new_root_item; 8293063d29fSChris Mason struct btrfs_root *tree_root = fs_info->tree_root; 8303063d29fSChris Mason struct btrfs_root *root = pending->root; 8316bdb72deSSage Weil struct btrfs_root *parent_root; 8326bdb72deSSage Weil struct inode *parent_inode; 833a22285a6SYan, Zheng struct dentry *dentry; 8343063d29fSChris Mason struct extent_buffer *tmp; 835925baeddSChris Mason struct extent_buffer *old; 8363063d29fSChris Mason int ret; 837d68fc57bSYan, Zheng u64 to_reserve = 0; 8386bdb72deSSage Weil u64 index = 0; 839a22285a6SYan, Zheng u64 objectid; 8403063d29fSChris Mason 84180b6794dSChris Mason new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); 84280b6794dSChris Mason if (!new_root_item) { 843a22285a6SYan, Zheng pending->error = -ENOMEM; 84480b6794dSChris Mason goto fail; 84580b6794dSChris Mason } 846a22285a6SYan, Zheng 8473063d29fSChris Mason ret = btrfs_find_free_objectid(trans, tree_root, 0, &objectid); 848a22285a6SYan, Zheng if (ret) { 849a22285a6SYan, Zheng pending->error = ret; 8503063d29fSChris Mason goto fail; 851a22285a6SYan, Zheng } 8523063d29fSChris Mason 8533fd0a558SYan, Zheng btrfs_reloc_pre_snapshot(trans, pending, &to_reserve); 854d68fc57bSYan, Zheng btrfs_orphan_pre_snapshot(trans, pending, &to_reserve); 855d68fc57bSYan, Zheng 856d68fc57bSYan, Zheng if (to_reserve > 0) { 857d68fc57bSYan, Zheng ret = btrfs_block_rsv_add(trans, root, &pending->block_rsv, 858*8bb8ab2eSJosef Bacik to_reserve); 859d68fc57bSYan, Zheng if (ret) { 860d68fc57bSYan, Zheng pending->error = ret; 861d68fc57bSYan, Zheng goto fail; 862d68fc57bSYan, Zheng } 863d68fc57bSYan, Zheng } 864d68fc57bSYan, Zheng 8653063d29fSChris Mason key.objectid = objectid; 866a22285a6SYan, Zheng key.offset = (u64)-1; 867a22285a6SYan, Zheng key.type = BTRFS_ROOT_ITEM_KEY; 8683063d29fSChris Mason 869a22285a6SYan, Zheng trans->block_rsv = &pending->block_rsv; 8706bdb72deSSage Weil 871a22285a6SYan, Zheng dentry = pending->dentry; 872a22285a6SYan, Zheng parent_inode = dentry->d_parent->d_inode; 873a22285a6SYan, Zheng parent_root = BTRFS_I(parent_inode)->root; 8746bdb72deSSage Weil record_root_in_trans(trans, parent_root); 875a22285a6SYan, Zheng 8766bdb72deSSage Weil /* 8776bdb72deSSage Weil * insert the directory item 8786bdb72deSSage Weil */ 8796bdb72deSSage Weil ret = btrfs_set_inode_index(parent_inode, &index); 8806bdb72deSSage Weil BUG_ON(ret); 8816bdb72deSSage Weil ret = btrfs_insert_dir_item(trans, parent_root, 882a22285a6SYan, Zheng dentry->d_name.name, dentry->d_name.len, 883a22285a6SYan, Zheng parent_inode->i_ino, &key, 884a22285a6SYan, Zheng BTRFS_FT_DIR, index); 8856bdb72deSSage Weil BUG_ON(ret); 8866bdb72deSSage Weil 887a22285a6SYan, Zheng btrfs_i_size_write(parent_inode, parent_inode->i_size + 888a22285a6SYan, Zheng dentry->d_name.len * 2); 8896bdb72deSSage Weil ret = btrfs_update_inode(trans, parent_root, parent_inode); 8906bdb72deSSage Weil BUG_ON(ret); 8916bdb72deSSage Weil 8926bdb72deSSage Weil record_root_in_trans(trans, root); 8936bdb72deSSage Weil btrfs_set_root_last_snapshot(&root->root_item, trans->transid); 8946bdb72deSSage Weil memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); 8956bdb72deSSage Weil 896925baeddSChris Mason old = btrfs_lock_root_node(root); 8979fa8cfe7SChris Mason btrfs_cow_block(trans, root, old, NULL, 0, &old); 8985d4f98a2SYan Zheng btrfs_set_lock_blocking(old); 8993063d29fSChris Mason 900925baeddSChris Mason btrfs_copy_root(trans, root, old, &tmp, objectid); 901925baeddSChris Mason btrfs_tree_unlock(old); 902925baeddSChris Mason free_extent_buffer(old); 9033063d29fSChris Mason 9045d4f98a2SYan Zheng btrfs_set_root_node(new_root_item, tmp); 905a22285a6SYan, Zheng /* record when the snapshot was created in key.offset */ 906a22285a6SYan, Zheng key.offset = trans->transid; 907a22285a6SYan, Zheng ret = btrfs_insert_root(trans, tree_root, &key, new_root_item); 908925baeddSChris Mason btrfs_tree_unlock(tmp); 9093063d29fSChris Mason free_extent_buffer(tmp); 9100660b5afSChris Mason BUG_ON(ret); 9110660b5afSChris Mason 912a22285a6SYan, Zheng /* 913a22285a6SYan, Zheng * insert root back/forward references 914a22285a6SYan, Zheng */ 915a22285a6SYan, Zheng ret = btrfs_add_root_ref(trans, tree_root, objectid, 916a22285a6SYan, Zheng parent_root->root_key.objectid, 917a22285a6SYan, Zheng parent_inode->i_ino, index, 918a22285a6SYan, Zheng dentry->d_name.name, dentry->d_name.len); 919a22285a6SYan, Zheng BUG_ON(ret); 920a22285a6SYan, Zheng 921a22285a6SYan, Zheng key.offset = (u64)-1; 922a22285a6SYan, Zheng pending->snap = btrfs_read_fs_root_no_name(root->fs_info, &key); 923a22285a6SYan, Zheng BUG_ON(IS_ERR(pending->snap)); 924d68fc57bSYan, Zheng 9253fd0a558SYan, Zheng btrfs_reloc_post_snapshot(trans, pending); 926d68fc57bSYan, Zheng btrfs_orphan_post_snapshot(trans, pending); 9273063d29fSChris Mason fail: 9286bdb72deSSage Weil kfree(new_root_item); 929a22285a6SYan, Zheng btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); 930a22285a6SYan, Zheng return 0; 9313063d29fSChris Mason } 9323063d29fSChris Mason 933d352ac68SChris Mason /* 934d352ac68SChris Mason * create all the snapshots we've scheduled for creation 935d352ac68SChris Mason */ 93680b6794dSChris Mason static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, 9373063d29fSChris Mason struct btrfs_fs_info *fs_info) 9383063d29fSChris Mason { 9393063d29fSChris Mason struct btrfs_pending_snapshot *pending; 9403063d29fSChris Mason struct list_head *head = &trans->transaction->pending_snapshots; 9413de4586cSChris Mason int ret; 9423de4586cSChris Mason 943c6e30871SQinghuang Feng list_for_each_entry(pending, head, list) { 9443de4586cSChris Mason ret = create_pending_snapshot(trans, fs_info, pending); 9453de4586cSChris Mason BUG_ON(ret); 9463de4586cSChris Mason } 9473de4586cSChris Mason return 0; 9483de4586cSChris Mason } 9493de4586cSChris Mason 9505d4f98a2SYan Zheng static void update_super_roots(struct btrfs_root *root) 9515d4f98a2SYan Zheng { 9525d4f98a2SYan Zheng struct btrfs_root_item *root_item; 9535d4f98a2SYan Zheng struct btrfs_super_block *super; 9545d4f98a2SYan Zheng 9555d4f98a2SYan Zheng super = &root->fs_info->super_copy; 9565d4f98a2SYan Zheng 9575d4f98a2SYan Zheng root_item = &root->fs_info->chunk_root->root_item; 9585d4f98a2SYan Zheng super->chunk_root = root_item->bytenr; 9595d4f98a2SYan Zheng super->chunk_root_generation = root_item->generation; 9605d4f98a2SYan Zheng super->chunk_root_level = root_item->level; 9615d4f98a2SYan Zheng 9625d4f98a2SYan Zheng root_item = &root->fs_info->tree_root->root_item; 9635d4f98a2SYan Zheng super->root = root_item->bytenr; 9645d4f98a2SYan Zheng super->generation = root_item->generation; 9655d4f98a2SYan Zheng super->root_level = root_item->level; 9665d4f98a2SYan Zheng } 9675d4f98a2SYan Zheng 968f36f3042SChris Mason int btrfs_transaction_in_commit(struct btrfs_fs_info *info) 969f36f3042SChris Mason { 970f36f3042SChris Mason int ret = 0; 971f36f3042SChris Mason spin_lock(&info->new_trans_lock); 972f36f3042SChris Mason if (info->running_transaction) 973f36f3042SChris Mason ret = info->running_transaction->in_commit; 974f36f3042SChris Mason spin_unlock(&info->new_trans_lock); 975f36f3042SChris Mason return ret; 976f36f3042SChris Mason } 977f36f3042SChris Mason 9788929ecfaSYan, Zheng int btrfs_transaction_blocked(struct btrfs_fs_info *info) 9798929ecfaSYan, Zheng { 9808929ecfaSYan, Zheng int ret = 0; 9818929ecfaSYan, Zheng spin_lock(&info->new_trans_lock); 9828929ecfaSYan, Zheng if (info->running_transaction) 9838929ecfaSYan, Zheng ret = info->running_transaction->blocked; 9848929ecfaSYan, Zheng spin_unlock(&info->new_trans_lock); 9858929ecfaSYan, Zheng return ret; 9868929ecfaSYan, Zheng } 9878929ecfaSYan, Zheng 98879154b1bSChris Mason int btrfs_commit_transaction(struct btrfs_trans_handle *trans, 98979154b1bSChris Mason struct btrfs_root *root) 99079154b1bSChris Mason { 99115ee9bc7SJosef Bacik unsigned long joined = 0; 99215ee9bc7SJosef Bacik unsigned long timeout = 1; 99379154b1bSChris Mason struct btrfs_transaction *cur_trans; 9948fd17795SChris Mason struct btrfs_transaction *prev_trans = NULL; 99579154b1bSChris Mason DEFINE_WAIT(wait); 99615ee9bc7SJosef Bacik int ret; 99789573b9cSChris Mason int should_grow = 0; 99889573b9cSChris Mason unsigned long now = get_seconds(); 999dccae999SSage Weil int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT); 100079154b1bSChris Mason 10015a3f23d5SChris Mason btrfs_run_ordered_operations(root, 0); 10025a3f23d5SChris Mason 100356bec294SChris Mason /* make a pass through all the delayed refs we have so far 100456bec294SChris Mason * any runnings procs may add more while we are here 100556bec294SChris Mason */ 100656bec294SChris Mason ret = btrfs_run_delayed_refs(trans, root, 0); 100756bec294SChris Mason BUG_ON(ret); 100856bec294SChris Mason 1009a22285a6SYan, Zheng btrfs_trans_release_metadata(trans, root); 1010a22285a6SYan, Zheng 1011b7ec40d7SChris Mason cur_trans = trans->transaction; 101256bec294SChris Mason /* 101356bec294SChris Mason * set the flushing flag so procs in this transaction have to 101456bec294SChris Mason * start sending their work down. 101556bec294SChris Mason */ 1016b7ec40d7SChris Mason cur_trans->delayed_refs.flushing = 1; 101756bec294SChris Mason 1018c3e69d58SChris Mason ret = btrfs_run_delayed_refs(trans, root, 0); 101956bec294SChris Mason BUG_ON(ret); 102056bec294SChris Mason 102179154b1bSChris Mason mutex_lock(&root->fs_info->trans_mutex); 1022b7ec40d7SChris Mason if (cur_trans->in_commit) { 1023b7ec40d7SChris Mason cur_trans->use_count++; 1024ccd467d6SChris Mason mutex_unlock(&root->fs_info->trans_mutex); 102579154b1bSChris Mason btrfs_end_transaction(trans, root); 1026ccd467d6SChris Mason 102779154b1bSChris Mason ret = wait_for_commit(root, cur_trans); 102879154b1bSChris Mason BUG_ON(ret); 102915ee9bc7SJosef Bacik 103015ee9bc7SJosef Bacik mutex_lock(&root->fs_info->trans_mutex); 103179154b1bSChris Mason put_transaction(cur_trans); 103215ee9bc7SJosef Bacik mutex_unlock(&root->fs_info->trans_mutex); 103315ee9bc7SJosef Bacik 103479154b1bSChris Mason return 0; 103579154b1bSChris Mason } 10364313b399SChris Mason 10372c90e5d6SChris Mason trans->transaction->in_commit = 1; 1038f9295749SChris Mason trans->transaction->blocked = 1; 1039ccd467d6SChris Mason if (cur_trans->list.prev != &root->fs_info->trans_list) { 1040ccd467d6SChris Mason prev_trans = list_entry(cur_trans->list.prev, 1041ccd467d6SChris Mason struct btrfs_transaction, list); 1042ccd467d6SChris Mason if (!prev_trans->commit_done) { 1043ccd467d6SChris Mason prev_trans->use_count++; 1044ccd467d6SChris Mason mutex_unlock(&root->fs_info->trans_mutex); 1045ccd467d6SChris Mason 1046ccd467d6SChris Mason wait_for_commit(root, prev_trans); 1047ccd467d6SChris Mason 1048ccd467d6SChris Mason mutex_lock(&root->fs_info->trans_mutex); 104915ee9bc7SJosef Bacik put_transaction(prev_trans); 1050ccd467d6SChris Mason } 1051ccd467d6SChris Mason } 105215ee9bc7SJosef Bacik 105389573b9cSChris Mason if (now < cur_trans->start_time || now - cur_trans->start_time < 1) 105489573b9cSChris Mason should_grow = 1; 105589573b9cSChris Mason 105615ee9bc7SJosef Bacik do { 10577ea394f1SYan Zheng int snap_pending = 0; 105815ee9bc7SJosef Bacik joined = cur_trans->num_joined; 10597ea394f1SYan Zheng if (!list_empty(&trans->transaction->pending_snapshots)) 10607ea394f1SYan Zheng snap_pending = 1; 10617ea394f1SYan Zheng 10622c90e5d6SChris Mason WARN_ON(cur_trans != trans->transaction); 106315ee9bc7SJosef Bacik if (cur_trans->num_writers > 1) 106415ee9bc7SJosef Bacik timeout = MAX_SCHEDULE_TIMEOUT; 106589573b9cSChris Mason else if (should_grow) 106615ee9bc7SJosef Bacik timeout = 1; 106715ee9bc7SJosef Bacik 106879154b1bSChris Mason mutex_unlock(&root->fs_info->trans_mutex); 106915ee9bc7SJosef Bacik 10700bdb1db2SSage Weil if (flush_on_commit || snap_pending) { 107124bbcf04SYan, Zheng btrfs_start_delalloc_inodes(root, 1); 107224bbcf04SYan, Zheng ret = btrfs_wait_ordered_extents(root, 0, 1); 1073ebecd3d9SSage Weil BUG_ON(ret); 10747ea394f1SYan Zheng } 10757ea394f1SYan Zheng 10765a3f23d5SChris Mason /* 10775a3f23d5SChris Mason * rename don't use btrfs_join_transaction, so, once we 10785a3f23d5SChris Mason * set the transaction to blocked above, we aren't going 10795a3f23d5SChris Mason * to get any new ordered operations. We can safely run 10805a3f23d5SChris Mason * it here and no for sure that nothing new will be added 10815a3f23d5SChris Mason * to the list 10825a3f23d5SChris Mason */ 10835a3f23d5SChris Mason btrfs_run_ordered_operations(root, 1); 10845a3f23d5SChris Mason 1085ed3b3d31SChris Mason prepare_to_wait(&cur_trans->writer_wait, &wait, 1086ed3b3d31SChris Mason TASK_UNINTERRUPTIBLE); 1087ed3b3d31SChris Mason 108889573b9cSChris Mason smp_mb(); 108989573b9cSChris Mason if (cur_trans->num_writers > 1 || should_grow) 109015ee9bc7SJosef Bacik schedule_timeout(timeout); 109115ee9bc7SJosef Bacik 109279154b1bSChris Mason mutex_lock(&root->fs_info->trans_mutex); 109315ee9bc7SJosef Bacik finish_wait(&cur_trans->writer_wait, &wait); 109415ee9bc7SJosef Bacik } while (cur_trans->num_writers > 1 || 109589573b9cSChris Mason (should_grow && cur_trans->num_joined != joined)); 109615ee9bc7SJosef Bacik 10973063d29fSChris Mason ret = create_pending_snapshots(trans, root->fs_info); 10983063d29fSChris Mason BUG_ON(ret); 10993063d29fSChris Mason 110056bec294SChris Mason ret = btrfs_run_delayed_refs(trans, root, (unsigned long)-1); 110156bec294SChris Mason BUG_ON(ret); 110256bec294SChris Mason 11032c90e5d6SChris Mason WARN_ON(cur_trans != trans->transaction); 1104dc17ff8fSChris Mason 1105e02119d5SChris Mason /* btrfs_commit_tree_roots is responsible for getting the 1106e02119d5SChris Mason * various roots consistent with each other. Every pointer 1107e02119d5SChris Mason * in the tree of tree roots has to point to the most up to date 1108e02119d5SChris Mason * root for every subvolume and other tree. So, we have to keep 1109e02119d5SChris Mason * the tree logging code from jumping in and changing any 1110e02119d5SChris Mason * of the trees. 1111e02119d5SChris Mason * 1112e02119d5SChris Mason * At this point in the commit, there can't be any tree-log 1113e02119d5SChris Mason * writers, but a little lower down we drop the trans mutex 1114e02119d5SChris Mason * and let new people in. By holding the tree_log_mutex 1115e02119d5SChris Mason * from now until after the super is written, we avoid races 1116e02119d5SChris Mason * with the tree-log code. 1117e02119d5SChris Mason */ 1118e02119d5SChris Mason mutex_lock(&root->fs_info->tree_log_mutex); 11191a40e23bSZheng Yan 11205d4f98a2SYan Zheng ret = commit_fs_roots(trans, root); 112154aa1f4dSChris Mason BUG_ON(ret); 112254aa1f4dSChris Mason 11235d4f98a2SYan Zheng /* commit_fs_roots gets rid of all the tree log roots, it is now 1124e02119d5SChris Mason * safe to free the root of tree log roots 1125e02119d5SChris Mason */ 1126e02119d5SChris Mason btrfs_free_log_root_tree(trans, root->fs_info); 1127e02119d5SChris Mason 11285d4f98a2SYan Zheng ret = commit_cowonly_roots(trans, root); 112979154b1bSChris Mason BUG_ON(ret); 113054aa1f4dSChris Mason 113111833d66SYan Zheng btrfs_prepare_extent_commit(trans, root); 113211833d66SYan Zheng 113378fae27eSChris Mason cur_trans = root->fs_info->running_transaction; 1134cee36a03SChris Mason spin_lock(&root->fs_info->new_trans_lock); 113578fae27eSChris Mason root->fs_info->running_transaction = NULL; 1136cee36a03SChris Mason spin_unlock(&root->fs_info->new_trans_lock); 11375f39d397SChris Mason 11385d4f98a2SYan Zheng btrfs_set_root_node(&root->fs_info->tree_root->root_item, 11395d4f98a2SYan Zheng root->fs_info->tree_root->node); 1140817d52f8SJosef Bacik switch_commit_root(root->fs_info->tree_root); 11415d4f98a2SYan Zheng 11425d4f98a2SYan Zheng btrfs_set_root_node(&root->fs_info->chunk_root->root_item, 11435d4f98a2SYan Zheng root->fs_info->chunk_root->node); 1144817d52f8SJosef Bacik switch_commit_root(root->fs_info->chunk_root); 11455d4f98a2SYan Zheng 11465d4f98a2SYan Zheng update_super_roots(root); 1147e02119d5SChris Mason 1148e02119d5SChris Mason if (!root->fs_info->log_root_recovering) { 1149e02119d5SChris Mason btrfs_set_super_log_root(&root->fs_info->super_copy, 0); 1150e02119d5SChris Mason btrfs_set_super_log_root_level(&root->fs_info->super_copy, 0); 1151e02119d5SChris Mason } 1152e02119d5SChris Mason 1153a061fc8dSChris Mason memcpy(&root->fs_info->super_for_commit, &root->fs_info->super_copy, 11544b52dff6SChris Mason sizeof(root->fs_info->super_copy)); 1155ccd467d6SChris Mason 1156f9295749SChris Mason trans->transaction->blocked = 0; 1157b7ec40d7SChris Mason 1158f9295749SChris Mason wake_up(&root->fs_info->transaction_wait); 1159e6dcd2dcSChris Mason 116078fae27eSChris Mason mutex_unlock(&root->fs_info->trans_mutex); 116179154b1bSChris Mason ret = btrfs_write_and_wait_transaction(trans, root); 116279154b1bSChris Mason BUG_ON(ret); 1163a512bbf8SYan Zheng write_ctree_super(trans, root, 0); 11644313b399SChris Mason 1165e02119d5SChris Mason /* 1166e02119d5SChris Mason * the super is written, we can safely allow the tree-loggers 1167e02119d5SChris Mason * to go about their business 1168e02119d5SChris Mason */ 1169e02119d5SChris Mason mutex_unlock(&root->fs_info->tree_log_mutex); 1170e02119d5SChris Mason 117111833d66SYan Zheng btrfs_finish_extent_commit(trans, root); 11724313b399SChris Mason 11731a40e23bSZheng Yan mutex_lock(&root->fs_info->trans_mutex); 11741a40e23bSZheng Yan 11752c90e5d6SChris Mason cur_trans->commit_done = 1; 1176b7ec40d7SChris Mason 117715ee9bc7SJosef Bacik root->fs_info->last_trans_committed = cur_trans->transid; 1178817d52f8SJosef Bacik 11792c90e5d6SChris Mason wake_up(&cur_trans->commit_wait); 11803de4586cSChris Mason 118179154b1bSChris Mason put_transaction(cur_trans); 118278fae27eSChris Mason put_transaction(cur_trans); 118358176a96SJosef Bacik 118478fae27eSChris Mason mutex_unlock(&root->fs_info->trans_mutex); 11853de4586cSChris Mason 11869ed74f2dSJosef Bacik if (current->journal_info == trans) 11879ed74f2dSJosef Bacik current->journal_info = NULL; 11889ed74f2dSJosef Bacik 11892c90e5d6SChris Mason kmem_cache_free(btrfs_trans_handle_cachep, trans); 119024bbcf04SYan, Zheng 119124bbcf04SYan, Zheng if (current != root->fs_info->transaction_kthread) 119224bbcf04SYan, Zheng btrfs_run_delayed_iputs(root); 119324bbcf04SYan, Zheng 119479154b1bSChris Mason return ret; 119579154b1bSChris Mason } 119679154b1bSChris Mason 1197d352ac68SChris Mason /* 1198d352ac68SChris Mason * interface function to delete all the snapshots we have scheduled for deletion 1199d352ac68SChris Mason */ 1200e9d0b13bSChris Mason int btrfs_clean_old_snapshots(struct btrfs_root *root) 1201e9d0b13bSChris Mason { 12025d4f98a2SYan Zheng LIST_HEAD(list); 12035d4f98a2SYan Zheng struct btrfs_fs_info *fs_info = root->fs_info; 1204e9d0b13bSChris Mason 12055d4f98a2SYan Zheng mutex_lock(&fs_info->trans_mutex); 12065d4f98a2SYan Zheng list_splice_init(&fs_info->dead_roots, &list); 12075d4f98a2SYan Zheng mutex_unlock(&fs_info->trans_mutex); 12085d4f98a2SYan Zheng 12095d4f98a2SYan Zheng while (!list_empty(&list)) { 12105d4f98a2SYan Zheng root = list_entry(list.next, struct btrfs_root, root_list); 121176dda93cSYan, Zheng list_del(&root->root_list); 121276dda93cSYan, Zheng 121376dda93cSYan, Zheng if (btrfs_header_backref_rev(root->node) < 121476dda93cSYan, Zheng BTRFS_MIXED_BACKREF_REV) 12153fd0a558SYan, Zheng btrfs_drop_snapshot(root, NULL, 0); 121676dda93cSYan, Zheng else 12173fd0a558SYan, Zheng btrfs_drop_snapshot(root, NULL, 1); 1218e9d0b13bSChris Mason } 1219e9d0b13bSChris Mason return 0; 1220e9d0b13bSChris Mason } 1221