transaction.c 22.0 KB
Newer Older
C
Chris Mason 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * Copyright (C) 2007 Oracle.  All rights reserved.
 *
 * 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.
 */

C
Chris Mason 已提交
19
#include <linux/fs.h>
C
Chris Mason 已提交
20
#include <linux/sched.h>
21
#include <linux/writeback.h>
22
#include <linux/pagemap.h>
C
Chris Mason 已提交
23 24 25
#include "ctree.h"
#include "disk-io.h"
#include "transaction.h"
26
#include "locking.h"
Y
Yan Zheng 已提交
27
#include "ref-cache.h"
C
Chris Mason 已提交
28

C
Chris Mason 已提交
29
static int total_trans = 0;
C
Chris Mason 已提交
30 31 32
extern struct kmem_cache *btrfs_trans_handle_cachep;
extern struct kmem_cache *btrfs_transaction_cachep;

33 34
#define BTRFS_ROOT_TRANS_TAG 0

35
static noinline void put_transaction(struct btrfs_transaction *transaction)
C
Chris Mason 已提交
36
{
C
Chris Mason 已提交
37
	WARN_ON(transaction->use_count == 0);
C
Chris Mason 已提交
38
	transaction->use_count--;
C
Chris Mason 已提交
39 40 41
	if (transaction->use_count == 0) {
		WARN_ON(total_trans == 0);
		total_trans--;
C
Chris Mason 已提交
42
		list_del_init(&transaction->list);
C
Chris Mason 已提交
43 44
		memset(transaction, 0, sizeof(*transaction));
		kmem_cache_free(btrfs_transaction_cachep, transaction);
C
Chris Mason 已提交
45
	}
C
Chris Mason 已提交
46 47
}

48
static noinline int join_transaction(struct btrfs_root *root)
C
Chris Mason 已提交
49 50 51 52
{
	struct btrfs_transaction *cur_trans;
	cur_trans = root->fs_info->running_transaction;
	if (!cur_trans) {
C
Chris Mason 已提交
53 54
		cur_trans = kmem_cache_alloc(btrfs_transaction_cachep,
					     GFP_NOFS);
C
Chris Mason 已提交
55
		total_trans++;
C
Chris Mason 已提交
56
		BUG_ON(!cur_trans);
57
		root->fs_info->generation++;
58
		root->fs_info->last_alloc = 0;
59
		root->fs_info->last_data_alloc = 0;
60 61
		cur_trans->num_writers = 1;
		cur_trans->num_joined = 0;
62
		cur_trans->transid = root->fs_info->generation;
C
Chris Mason 已提交
63 64 65
		init_waitqueue_head(&cur_trans->writer_wait);
		init_waitqueue_head(&cur_trans->commit_wait);
		cur_trans->in_commit = 0;
66
		cur_trans->blocked = 0;
67
		cur_trans->use_count = 1;
C
Chris Mason 已提交
68
		cur_trans->commit_done = 0;
C
Chris Mason 已提交
69
		cur_trans->start_time = get_seconds();
70
		INIT_LIST_HEAD(&cur_trans->pending_snapshots);
C
Chris Mason 已提交
71
		list_add_tail(&cur_trans->list, &root->fs_info->trans_list);
72
		extent_io_tree_init(&cur_trans->dirty_pages,
73 74
				     root->fs_info->btree_inode->i_mapping,
				     GFP_NOFS);
75 76 77
		spin_lock(&root->fs_info->new_trans_lock);
		root->fs_info->running_transaction = cur_trans;
		spin_unlock(&root->fs_info->new_trans_lock);
78 79 80
	} else {
		cur_trans->num_writers++;
		cur_trans->num_joined++;
C
Chris Mason 已提交
81
	}
82

C
Chris Mason 已提交
83 84 85
	return 0;
}

86
static noinline int record_root_in_trans(struct btrfs_root *root)
87
{
88
	struct btrfs_dirty_root *dirty;
89 90 91 92 93 94 95
	u64 running_trans_id = root->fs_info->running_transaction->transid;
	if (root->ref_cows && root->last_trans < running_trans_id) {
		WARN_ON(root == root->fs_info->extent_root);
		if (root->root_item.refs != 0) {
			radix_tree_tag_set(&root->fs_info->fs_roots_radix,
				   (unsigned long)root->root_key.objectid,
				   BTRFS_ROOT_TRANS_TAG);
Y
Yan Zheng 已提交
96 97 98 99 100 101 102 103

			dirty = kmalloc(sizeof(*dirty), GFP_NOFS);
			BUG_ON(!dirty);
			dirty->root = kmalloc(sizeof(*dirty->root), GFP_NOFS);
			BUG_ON(!dirty->root);
			dirty->latest_root = root;
			INIT_LIST_HEAD(&dirty->list);

104
			root->commit_root = btrfs_root_node(root);
Y
Yan Zheng 已提交
105 106 107

			memcpy(dirty->root, root, sizeof(*root));
			spin_lock_init(&dirty->root->node_lock);
108
			spin_lock_init(&dirty->root->list_lock);
Y
Yan Zheng 已提交
109
			mutex_init(&dirty->root->objectid_mutex);
110
			INIT_LIST_HEAD(&dirty->root->dead_list);
Y
Yan Zheng 已提交
111 112
			dirty->root->node = root->commit_root;
			dirty->root->commit_root = NULL;
113 114 115 116 117 118

			spin_lock(&root->list_lock);
			list_add(&dirty->root->dead_list, &root->dead_list);
			spin_unlock(&root->list_lock);

			root->dirty_root = dirty;
119 120 121 122 123 124 125 126
		} else {
			WARN_ON(1);
		}
		root->last_trans = running_trans_id;
	}
	return 0;
}

127 128
struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
					     int num_blocks, int join)
C
Chris Mason 已提交
129
{
C
Chris Mason 已提交
130 131
	struct btrfs_trans_handle *h =
		kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
132
	struct btrfs_transaction *cur_trans;
C
Chris Mason 已提交
133 134 135
	int ret;

	mutex_lock(&root->fs_info->trans_mutex);
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
	cur_trans = root->fs_info->running_transaction;
	if (cur_trans && cur_trans->blocked && !join) {
		DEFINE_WAIT(wait);
		cur_trans->use_count++;
		while(1) {
			prepare_to_wait(&root->fs_info->transaction_wait, &wait,
					TASK_UNINTERRUPTIBLE);
			if (cur_trans->blocked) {
				mutex_unlock(&root->fs_info->trans_mutex);
				schedule();
				mutex_lock(&root->fs_info->trans_mutex);
				finish_wait(&root->fs_info->transaction_wait,
					    &wait);
			} else {
				finish_wait(&root->fs_info->transaction_wait,
					    &wait);
				break;
			}
		}
		put_transaction(cur_trans);
	}
C
Chris Mason 已提交
157 158
	ret = join_transaction(root);
	BUG_ON(ret);
159

160 161
	record_root_in_trans(root);
	h->transid = root->fs_info->running_transaction->transid;
C
Chris Mason 已提交
162 163 164
	h->transaction = root->fs_info->running_transaction;
	h->blocks_reserved = num_blocks;
	h->blocks_used = 0;
165
	h->block_group = NULL;
166 167
	h->alloc_exclude_nr = 0;
	h->alloc_exclude_start = 0;
C
Chris Mason 已提交
168 169 170 171 172
	root->fs_info->running_transaction->use_count++;
	mutex_unlock(&root->fs_info->trans_mutex);
	return h;
}

173 174 175 176 177 178 179 180 181 182 183
struct btrfs_trans_handle *btrfs_start_transaction(struct btrfs_root *root,
						   int num_blocks)
{
	return start_transaction(root, num_blocks, 0);
}
struct btrfs_trans_handle *btrfs_join_transaction(struct btrfs_root *root,
						   int num_blocks)
{
	return start_transaction(root, num_blocks, 1);
}

184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202
static noinline int wait_for_commit(struct btrfs_root *root,
				    struct btrfs_transaction *commit)
{
	DEFINE_WAIT(wait);
	mutex_lock(&root->fs_info->trans_mutex);
	while(!commit->commit_done) {
		prepare_to_wait(&commit->commit_wait, &wait,
				TASK_UNINTERRUPTIBLE);
		if (commit->commit_done)
			break;
		mutex_unlock(&root->fs_info->trans_mutex);
		schedule();
		mutex_lock(&root->fs_info->trans_mutex);
	}
	mutex_unlock(&root->fs_info->trans_mutex);
	finish_wait(&commit->commit_wait, &wait);
	return 0;
}

203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238
void btrfs_throttle(struct btrfs_root *root)
{
	struct btrfs_fs_info *info = root->fs_info;

harder:
	if (atomic_read(&info->throttles)) {
		DEFINE_WAIT(wait);
		int thr;
		int harder_count = 0;
		thr = atomic_read(&info->throttle_gen);

		do {
			prepare_to_wait(&info->transaction_throttle,
					&wait, TASK_UNINTERRUPTIBLE);
			if (!atomic_read(&info->throttles)) {
				finish_wait(&info->transaction_throttle, &wait);
				break;
			}
			schedule();
			finish_wait(&info->transaction_throttle, &wait);
		} while (thr == atomic_read(&info->throttle_gen));

		if (harder_count < 5 &&
		    info->total_ref_cache_size > 5 * 1024 * 1024) {
			harder_count++;
			goto harder;
		}

		if (harder_count < 10 &&
		    info->total_ref_cache_size > 10 * 1024 * 1024) {
			harder_count++;
			goto harder;
		}
	}
}

239 240
static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
			  struct btrfs_root *root, int throttle)
C
Chris Mason 已提交
241 242
{
	struct btrfs_transaction *cur_trans;
243
	struct btrfs_fs_info *info = root->fs_info;
244

245 246
	mutex_lock(&info->trans_mutex);
	cur_trans = info->running_transaction;
C
Chris Mason 已提交
247
	WARN_ON(cur_trans != trans->transaction);
248
	WARN_ON(cur_trans->num_writers < 1);
C
Chris Mason 已提交
249
	cur_trans->num_writers--;
250

C
Chris Mason 已提交
251 252 253
	if (waitqueue_active(&cur_trans->writer_wait))
		wake_up(&cur_trans->writer_wait);
	put_transaction(cur_trans);
254
	mutex_unlock(&info->trans_mutex);
C
Chris Mason 已提交
255
	memset(trans, 0, sizeof(*trans));
C
Chris Mason 已提交
256
	kmem_cache_free(btrfs_trans_handle_cachep, trans);
257 258 259 260

	if (throttle)
		btrfs_throttle(root);

C
Chris Mason 已提交
261 262 263
	return 0;
}

264 265 266 267 268 269 270 271 272 273 274 275
int btrfs_end_transaction(struct btrfs_trans_handle *trans,
			  struct btrfs_root *root)
{
	return __btrfs_end_transaction(trans, root, 0);
}

int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans,
				   struct btrfs_root *root)
{
	return __btrfs_end_transaction(trans, root, 1);
}

C
Chris Mason 已提交
276 277 278 279

int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans,
				     struct btrfs_root *root)
{
280 281 282
	int ret;
	int err;
	int werr = 0;
283
	struct extent_io_tree *dirty_pages;
284 285
	struct page *page;
	struct inode *btree_inode = root->fs_info->btree_inode;
286 287 288
	u64 start;
	u64 end;
	unsigned long index;
289 290 291 292 293 294

	if (!trans || !trans->transaction) {
		return filemap_write_and_wait(btree_inode->i_mapping);
	}
	dirty_pages = &trans->transaction->dirty_pages;
	while(1) {
295 296 297
		ret = find_first_extent_bit(dirty_pages, 0, &start, &end,
					    EXTENT_DIRTY);
		if (ret)
298
			break;
299 300 301
		clear_extent_dirty(dirty_pages, start, end, GFP_NOFS);
		while(start <= end) {
			index = start >> PAGE_CACHE_SHIFT;
302
			start = (u64)(index + 1) << PAGE_CACHE_SHIFT;
303
			page = find_lock_page(btree_inode->i_mapping, index);
304 305
			if (!page)
				continue;
306 307 308 309 310 311 312 313 314
			if (PageWriteback(page)) {
				if (PageDirty(page))
					wait_on_page_writeback(page);
				else {
					unlock_page(page);
					page_cache_release(page);
					continue;
				}
			}
315 316 317 318 319 320 321 322 323 324
			err = write_one_page(page, 0);
			if (err)
				werr = err;
			page_cache_release(page);
		}
	}
	err = filemap_fdatawait(btree_inode->i_mapping);
	if (err)
		werr = err;
	return werr;
C
Chris Mason 已提交
325 326
}

327 328
static int update_cowonly_root(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root)
C
Chris Mason 已提交
329 330
{
	int ret;
331 332
	u64 old_root_bytenr;
	struct btrfs_root *tree_root = root->fs_info->tree_root;
C
Chris Mason 已提交
333

334
	btrfs_write_dirty_block_groups(trans, root);
C
Chris Mason 已提交
335
	while(1) {
336 337
		old_root_bytenr = btrfs_root_bytenr(&root->root_item);
		if (old_root_bytenr == root->node->start)
C
Chris Mason 已提交
338
			break;
339 340 341 342
		btrfs_set_root_bytenr(&root->root_item,
				       root->node->start);
		btrfs_set_root_level(&root->root_item,
				     btrfs_header_level(root->node));
C
Chris Mason 已提交
343
		ret = btrfs_update_root(trans, tree_root,
344 345
					&root->root_key,
					&root->root_item);
C
Chris Mason 已提交
346
		BUG_ON(ret);
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362
		btrfs_write_dirty_block_groups(trans, root);
	}
	return 0;
}

int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans,
			    struct btrfs_root *root)
{
	struct btrfs_fs_info *fs_info = root->fs_info;
	struct list_head *next;

	while(!list_empty(&fs_info->dirty_cowonly_roots)) {
		next = fs_info->dirty_cowonly_roots.next;
		list_del_init(next);
		root = list_entry(next, struct btrfs_root, dirty_list);
		update_cowonly_root(trans, root);
C
Chris Mason 已提交
363 364 365 366
	}
	return 0;
}

367 368 369
int btrfs_add_dead_root(struct btrfs_root *root,
			struct btrfs_root *latest,
			struct list_head *dead_list)
370
{
371
	struct btrfs_dirty_root *dirty;
372 373 374 375 376

	dirty = kmalloc(sizeof(*dirty), GFP_NOFS);
	if (!dirty)
		return -ENOMEM;
	dirty->root = root;
377
	dirty->latest_root = latest;
378 379 380 381
	list_add(&dirty->list, dead_list);
	return 0;
}

382 383 384
static noinline int add_dirty_roots(struct btrfs_trans_handle *trans,
				    struct radix_tree_root *radix,
				    struct list_head *list)
385
{
386
	struct btrfs_dirty_root *dirty;
387 388 389 390
	struct btrfs_root *gang[8];
	struct btrfs_root *root;
	int i;
	int ret;
391
	int err = 0;
392
	u32 refs;
393

394 395 396 397 398 399 400 401
	while(1) {
		ret = radix_tree_gang_lookup_tag(radix, (void **)gang, 0,
						 ARRAY_SIZE(gang),
						 BTRFS_ROOT_TRANS_TAG);
		if (ret == 0)
			break;
		for (i = 0; i < ret; i++) {
			root = gang[i];
C
Chris Mason 已提交
402 403 404
			radix_tree_tag_clear(radix,
				     (unsigned long)root->root_key.objectid,
				     BTRFS_ROOT_TRANS_TAG);
Y
Yan Zheng 已提交
405 406

			BUG_ON(!root->ref_tree);
C
Chris Mason 已提交
407
			dirty = root->dirty_root;
Y
Yan Zheng 已提交
408

409
			if (root->commit_root == root->node) {
410 411
				WARN_ON(root->node->start !=
					btrfs_root_bytenr(&root->root_item));
Y
Yan Zheng 已提交
412

413
				free_extent_buffer(root->commit_root);
414
				root->commit_root = NULL;
415 416 417 418 419

				spin_lock(&root->list_lock);
				list_del_init(&dirty->root->dead_list);
				spin_unlock(&root->list_lock);

Y
Yan Zheng 已提交
420 421
				kfree(dirty->root);
				kfree(dirty);
422 423 424 425 426 427 428 429 430

				/* make sure to update the root on disk
				 * so we get any updates to the block used
				 * counts
				 */
				err = btrfs_update_root(trans,
						root->fs_info->tree_root,
						&root->root_key,
						&root->root_item);
431 432
				continue;
			}
433 434 435 436

			memset(&root->root_item.drop_progress, 0,
			       sizeof(struct btrfs_disk_key));
			root->root_item.drop_level = 0;
437 438
			root->commit_root = NULL;
			root->root_key.offset = root->fs_info->generation;
439 440 441 442
			btrfs_set_root_bytenr(&root->root_item,
					      root->node->start);
			btrfs_set_root_level(&root->root_item,
					     btrfs_header_level(root->node));
443 444 445
			err = btrfs_insert_root(trans, root->fs_info->tree_root,
						&root->root_key,
						&root->root_item);
446 447
			if (err)
				break;
448 449 450

			refs = btrfs_root_refs(&dirty->root->root_item);
			btrfs_set_root_refs(&dirty->root->root_item, refs - 1);
451
			err = btrfs_update_root(trans, root->fs_info->tree_root,
452 453
						&dirty->root->root_key,
						&dirty->root->root_item);
454 455

			BUG_ON(err);
456
			if (refs == 1) {
457
				list_add(&dirty->list, list);
458 459
			} else {
				WARN_ON(1);
Y
Yan Zheng 已提交
460
				free_extent_buffer(dirty->root->node);
461
				kfree(dirty->root);
462
				kfree(dirty);
463
			}
464 465
		}
	}
466
	return err;
467 468
}

469 470 471 472 473
int btrfs_defrag_root(struct btrfs_root *root, int cacheonly)
{
	struct btrfs_fs_info *info = root->fs_info;
	int ret;
	struct btrfs_trans_handle *trans;
474
	unsigned long nr;
475

476
	smp_mb();
477 478 479
	if (root->defrag_running)
		return 0;
	trans = btrfs_start_transaction(root, 1);
480
	while (1) {
481 482
		root->defrag_running = 1;
		ret = btrfs_defrag_leaves(trans, root, cacheonly);
483
		nr = trans->blocks_used;
484
		btrfs_end_transaction(trans, root);
485
		btrfs_btree_balance_dirty(info->tree_root, nr);
486 487 488
		cond_resched();

		trans = btrfs_start_transaction(root, 1);
489
		if (root->fs_info->closing || ret != -EAGAIN)
490 491 492
			break;
	}
	root->defrag_running = 0;
493
	smp_mb();
494 495 496 497
	btrfs_end_transaction(trans, root);
	return 0;
}

498 499
static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
				     struct list_head *list)
500
{
501
	struct btrfs_dirty_root *dirty;
502
	struct btrfs_trans_handle *trans;
503
	unsigned long nr;
504 505
	u64 num_bytes;
	u64 bytes_used;
506
	u64 max_useless;
507
	int ret = 0;
508 509
	int err;

510
	while(!list_empty(list)) {
511 512
		struct btrfs_root *root;

513
		dirty = list_entry(list->prev, struct btrfs_dirty_root, list);
514
		list_del_init(&dirty->list);
515

516
		num_bytes = btrfs_root_used(&dirty->root->root_item);
517
		root = dirty->latest_root;
518
		atomic_inc(&root->fs_info->throttles);
519

520
		mutex_lock(&root->fs_info->drop_mutex);
521 522 523 524 525 526
		while(1) {
			trans = btrfs_start_transaction(tree_root, 1);
			ret = btrfs_drop_snapshot(trans, dirty->root);
			if (ret != -EAGAIN) {
				break;
			}
527

528 529 530 531 532 533
			err = btrfs_update_root(trans,
					tree_root,
					&dirty->root->root_key,
					&dirty->root->root_item);
			if (err)
				ret = err;
534
			nr = trans->blocks_used;
C
Chris Mason 已提交
535
			ret = btrfs_end_transaction(trans, tree_root);
536
			BUG_ON(ret);
537 538

			mutex_unlock(&root->fs_info->drop_mutex);
539
			btrfs_btree_balance_dirty(tree_root, nr);
540
			cond_resched();
541
			mutex_lock(&root->fs_info->drop_mutex);
542
		}
543
		BUG_ON(ret);
544
		atomic_dec(&root->fs_info->throttles);
C
Chris Mason 已提交
545
		wake_up(&root->fs_info->transaction_throttle);
546

547
		mutex_lock(&root->fs_info->alloc_mutex);
548 549 550
		num_bytes -= btrfs_root_used(&dirty->root->root_item);
		bytes_used = btrfs_root_used(&root->root_item);
		if (num_bytes) {
551
			record_root_in_trans(root);
552
			btrfs_set_root_used(&root->root_item,
553
					    bytes_used - num_bytes);
554
		}
555 556
		mutex_unlock(&root->fs_info->alloc_mutex);

557
		ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key);
558 559
		if (ret) {
			BUG();
560
			break;
561
		}
562 563
		mutex_unlock(&root->fs_info->drop_mutex);

564 565 566 567 568 569 570 571 572 573 574 575
		spin_lock(&root->list_lock);
		list_del_init(&dirty->root->dead_list);
		if (!list_empty(&root->dead_list)) {
			struct btrfs_root *oldest;
			oldest = list_entry(root->dead_list.prev,
					    struct btrfs_root, dead_list);
			max_useless = oldest->root_key.offset - 1;
		} else {
			max_useless = root->root_key.offset - 1;
		}
		spin_unlock(&root->list_lock);

576
		nr = trans->blocks_used;
577 578
		ret = btrfs_end_transaction(trans, tree_root);
		BUG_ON(ret);
579

580 581 582
		ret = btrfs_remove_leaf_refs(root, max_useless);
		BUG_ON(ret);

583
		free_extent_buffer(dirty->root->node);
584
		kfree(dirty->root);
585
		kfree(dirty);
586 587

		btrfs_btree_balance_dirty(tree_root, nr);
588
		cond_resched();
589
	}
590
	return ret;
591 592
}

593
static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
594 595 596 597
				   struct btrfs_fs_info *fs_info,
				   struct btrfs_pending_snapshot *pending)
{
	struct btrfs_key key;
598
	struct btrfs_root_item *new_root_item;
599 600 601
	struct btrfs_root *tree_root = fs_info->tree_root;
	struct btrfs_root *root = pending->root;
	struct extent_buffer *tmp;
602
	struct extent_buffer *old;
603
	int ret;
604
	int namelen;
605 606
	u64 objectid;

607 608 609 610 611
	new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
	if (!new_root_item) {
		ret = -ENOMEM;
		goto fail;
	}
612 613 614 615
	ret = btrfs_find_free_objectid(trans, tree_root, 0, &objectid);
	if (ret)
		goto fail;

616
	memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
617 618 619 620 621

	key.objectid = objectid;
	key.offset = 1;
	btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY);

622 623
	old = btrfs_lock_root_node(root);
	btrfs_cow_block(trans, root, old, NULL, 0, &old);
624

625 626 627
	btrfs_copy_root(trans, root, old, &tmp, objectid);
	btrfs_tree_unlock(old);
	free_extent_buffer(old);
628

629 630
	btrfs_set_root_bytenr(new_root_item, tmp->start);
	btrfs_set_root_level(new_root_item, btrfs_header_level(tmp));
631
	ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
632
				new_root_item);
633
	btrfs_tree_unlock(tmp);
634 635 636 637 638 639 640 641
	free_extent_buffer(tmp);
	if (ret)
		goto fail;

	/*
	 * insert the directory item
	 */
	key.offset = (u64)-1;
642
	namelen = strlen(pending->name);
643
	ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root,
644
				    pending->name, namelen,
645
				    root->fs_info->sb->s_root->d_inode->i_ino,
646
				    &key, BTRFS_FT_DIR, 0);
647 648 649 650 651 652

	if (ret)
		goto fail;

	ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root,
			     pending->name, strlen(pending->name), objectid,
653
			     root->fs_info->sb->s_root->d_inode->i_ino, 0);
654 655 656 657

	/* Invalidate existing dcache entry for new snapshot. */
	btrfs_invalidate_dcache_root(root, pending->name, namelen);

658
fail:
659
	kfree(new_root_item);
660 661 662
	return ret;
}

663 664
static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
					     struct btrfs_fs_info *fs_info)
665 666 667 668 669 670 671 672 673 674 675 676 677 678
{
	struct btrfs_pending_snapshot *pending;
	struct list_head *head = &trans->transaction->pending_snapshots;
	int ret;

	while(!list_empty(head)) {
		pending = list_entry(head->next,
				     struct btrfs_pending_snapshot, list);
		ret = create_pending_snapshot(trans, fs_info, pending);
		BUG_ON(ret);
		list_del(&pending->list);
		kfree(pending->name);
		kfree(pending);
	}
C
Chris Mason 已提交
679 680 681
	return 0;
}

C
Chris Mason 已提交
682 683 684
int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
			     struct btrfs_root *root)
{
685 686
	unsigned long joined = 0;
	unsigned long timeout = 1;
C
Chris Mason 已提交
687
	struct btrfs_transaction *cur_trans;
C
Chris Mason 已提交
688
	struct btrfs_transaction *prev_trans = NULL;
689
	struct btrfs_root *chunk_root = root->fs_info->chunk_root;
690
	struct list_head dirty_fs_roots;
691
	struct extent_io_tree *pinned_copy;
C
Chris Mason 已提交
692
	DEFINE_WAIT(wait);
693
	int ret;
C
Chris Mason 已提交
694

695
	INIT_LIST_HEAD(&dirty_fs_roots);
696

C
Chris Mason 已提交
697 698 699 700
	mutex_lock(&root->fs_info->trans_mutex);
	if (trans->transaction->in_commit) {
		cur_trans = trans->transaction;
		trans->transaction->use_count++;
C
Chris Mason 已提交
701
		mutex_unlock(&root->fs_info->trans_mutex);
C
Chris Mason 已提交
702
		btrfs_end_transaction(trans, root);
C
Chris Mason 已提交
703

C
Chris Mason 已提交
704 705
		ret = wait_for_commit(root, cur_trans);
		BUG_ON(ret);
706 707

		mutex_lock(&root->fs_info->trans_mutex);
C
Chris Mason 已提交
708
		put_transaction(cur_trans);
709 710
		mutex_unlock(&root->fs_info->trans_mutex);

C
Chris Mason 已提交
711 712
		return 0;
	}
713 714 715 716 717

	pinned_copy = kmalloc(sizeof(*pinned_copy), GFP_NOFS);
	if (!pinned_copy)
		return -ENOMEM;

718
	extent_io_tree_init(pinned_copy,
719 720
			     root->fs_info->btree_inode->i_mapping, GFP_NOFS);

C
Chris Mason 已提交
721
	trans->transaction->in_commit = 1;
722
	trans->transaction->blocked = 1;
C
Chris Mason 已提交
723 724 725 726 727 728 729 730 731 732 733
	cur_trans = trans->transaction;
	if (cur_trans->list.prev != &root->fs_info->trans_list) {
		prev_trans = list_entry(cur_trans->list.prev,
					struct btrfs_transaction, list);
		if (!prev_trans->commit_done) {
			prev_trans->use_count++;
			mutex_unlock(&root->fs_info->trans_mutex);

			wait_for_commit(root, prev_trans);

			mutex_lock(&root->fs_info->trans_mutex);
734
			put_transaction(prev_trans);
C
Chris Mason 已提交
735 736
		}
	}
737 738 739

	do {
		joined = cur_trans->num_joined;
C
Chris Mason 已提交
740
		WARN_ON(cur_trans != trans->transaction);
741
		prepare_to_wait(&cur_trans->writer_wait, &wait,
C
Chris Mason 已提交
742
				TASK_UNINTERRUPTIBLE);
743 744 745 746 747 748

		if (cur_trans->num_writers > 1)
			timeout = MAX_SCHEDULE_TIMEOUT;
		else
			timeout = 1;

C
Chris Mason 已提交
749
		mutex_unlock(&root->fs_info->trans_mutex);
750 751 752

		schedule_timeout(timeout);

C
Chris Mason 已提交
753
		mutex_lock(&root->fs_info->trans_mutex);
754 755 756 757
		finish_wait(&cur_trans->writer_wait, &wait);
	} while (cur_trans->num_writers > 1 ||
		 (cur_trans->num_joined != joined));

758 759 760
	ret = create_pending_snapshots(trans, root->fs_info);
	BUG_ON(ret);

C
Chris Mason 已提交
761
	WARN_ON(cur_trans != trans->transaction);
C
Chris Mason 已提交
762

763 764 765 766
	ret = add_dirty_roots(trans, &root->fs_info->fs_roots_radix,
			      &dirty_fs_roots);
	BUG_ON(ret);

C
Chris Mason 已提交
767 768
	ret = btrfs_commit_tree_roots(trans, root);
	BUG_ON(ret);
769

C
Chris Mason 已提交
770
	cur_trans = root->fs_info->running_transaction;
771
	spin_lock(&root->fs_info->new_trans_lock);
C
Chris Mason 已提交
772
	root->fs_info->running_transaction = NULL;
773
	spin_unlock(&root->fs_info->new_trans_lock);
774 775 776
	btrfs_set_super_generation(&root->fs_info->super_copy,
				   cur_trans->transid);
	btrfs_set_super_root(&root->fs_info->super_copy,
777 778 779
			     root->fs_info->tree_root->node->start);
	btrfs_set_super_root_level(&root->fs_info->super_copy,
			   btrfs_header_level(root->fs_info->tree_root->node));
780

781 782 783 784
	btrfs_set_super_chunk_root(&root->fs_info->super_copy,
				   chunk_root->node->start);
	btrfs_set_super_chunk_root_level(&root->fs_info->super_copy,
					 btrfs_header_level(chunk_root->node));
785 786
	memcpy(&root->fs_info->super_for_commit, &root->fs_info->super_copy,
	       sizeof(root->fs_info->super_copy));
C
Chris Mason 已提交
787

788
	btrfs_copy_pinned(root, pinned_copy);
C
Chris Mason 已提交
789

790
	trans->transaction->blocked = 0;
791
	wake_up(&root->fs_info->transaction_throttle);
792
	wake_up(&root->fs_info->transaction_wait);
793

C
Chris Mason 已提交
794
	mutex_unlock(&root->fs_info->trans_mutex);
C
Chris Mason 已提交
795 796 797
	ret = btrfs_write_and_wait_transaction(trans, root);
	BUG_ON(ret);
	write_ctree_super(trans, root);
798 799

	btrfs_finish_extent_commit(trans, root, pinned_copy);
C
Chris Mason 已提交
800
	mutex_lock(&root->fs_info->trans_mutex);
801 802 803

	kfree(pinned_copy);

C
Chris Mason 已提交
804
	cur_trans->commit_done = 1;
805
	root->fs_info->last_trans_committed = cur_trans->transid;
C
Chris Mason 已提交
806
	wake_up(&cur_trans->commit_wait);
C
Chris Mason 已提交
807
	put_transaction(cur_trans);
C
Chris Mason 已提交
808
	put_transaction(cur_trans);
809

810
	list_splice_init(&dirty_fs_roots, &root->fs_info->dead_roots);
811 812
	if (root->fs_info->closing)
		list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots);
813

C
Chris Mason 已提交
814
	mutex_unlock(&root->fs_info->trans_mutex);
C
Chris Mason 已提交
815
	kmem_cache_free(btrfs_trans_handle_cachep, trans);
C
Chris Mason 已提交
816

817 818 819
	if (root->fs_info->closing) {
		drop_dirty_roots(root->fs_info->tree_root, &dirty_fs_roots);
	}
C
Chris Mason 已提交
820 821 822
	return ret;
}

823 824 825 826
int btrfs_clean_old_snapshots(struct btrfs_root *root)
{
	struct list_head dirty_roots;
	INIT_LIST_HEAD(&dirty_roots);
827
again:
828 829 830 831 832 833
	mutex_lock(&root->fs_info->trans_mutex);
	list_splice_init(&root->fs_info->dead_roots, &dirty_roots);
	mutex_unlock(&root->fs_info->trans_mutex);

	if (!list_empty(&dirty_roots)) {
		drop_dirty_roots(root, &dirty_roots);
834
		goto again;
835 836 837
	}
	return 0;
}