transaction.c 21.4 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 104

			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);

105
			root->commit_root = btrfs_root_node(root);
C
Chris Mason 已提交
106
			root->dirty_root = dirty;
Y
Yan Zheng 已提交
107 108

			memcpy(dirty->root, root, sizeof(*root));
C
Chris Mason 已提交
109 110
			dirty->root->ref_tree = &root->ref_tree_struct;

Y
Yan Zheng 已提交
111 112 113 114
			spin_lock_init(&dirty->root->node_lock);
			mutex_init(&dirty->root->objectid_mutex);
			dirty->root->node = root->commit_root;
			dirty->root->commit_root = NULL;
115 116 117 118 119 120 121 122
		} else {
			WARN_ON(1);
		}
		root->last_trans = running_trans_id;
	}
	return 0;
}

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

	mutex_lock(&root->fs_info->trans_mutex);
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152
	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 已提交
153 154
	ret = join_transaction(root);
	BUG_ON(ret);
155

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

169 170 171 172 173 174 175 176 177 178 179
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);
}

180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
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;
}

199 200 201 202 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
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;
		}
	}
}

235 236
static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
			  struct btrfs_root *root, int throttle)
C
Chris Mason 已提交
237 238
{
	struct btrfs_transaction *cur_trans;
239
	struct btrfs_fs_info *info = root->fs_info;
240

241 242
	mutex_lock(&info->trans_mutex);
	cur_trans = info->running_transaction;
C
Chris Mason 已提交
243
	WARN_ON(cur_trans != trans->transaction);
244
	WARN_ON(cur_trans->num_writers < 1);
C
Chris Mason 已提交
245
	cur_trans->num_writers--;
246

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

	if (throttle)
		btrfs_throttle(root);

C
Chris Mason 已提交
257 258 259
	return 0;
}

260 261 262 263 264 265 266 267 268 269 270 271
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 已提交
272 273 274 275

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

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

323 324
static int update_cowonly_root(struct btrfs_trans_handle *trans,
			       struct btrfs_root *root)
C
Chris Mason 已提交
325 326
{
	int ret;
327 328
	u64 old_root_bytenr;
	struct btrfs_root *tree_root = root->fs_info->tree_root;
C
Chris Mason 已提交
329

330
	btrfs_write_dirty_block_groups(trans, root);
C
Chris Mason 已提交
331
	while(1) {
332 333
		old_root_bytenr = btrfs_root_bytenr(&root->root_item);
		if (old_root_bytenr == root->node->start)
C
Chris Mason 已提交
334
			break;
335 336 337 338
		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 已提交
339
		ret = btrfs_update_root(trans, tree_root,
340 341
					&root->root_key,
					&root->root_item);
C
Chris Mason 已提交
342
		BUG_ON(ret);
343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358
		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 已提交
359 360
		if (root->fs_info->closing)
			btrfs_remove_leaf_refs(root);
C
Chris Mason 已提交
361 362 363 364
	}
	return 0;
}

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

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

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

392 393 394 395 396 397 398 399
	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 已提交
400 401 402
			radix_tree_tag_clear(radix,
				     (unsigned long)root->root_key.objectid,
				     BTRFS_ROOT_TRANS_TAG);
Y
Yan Zheng 已提交
403 404

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

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

411
				free_extent_buffer(root->commit_root);
412
				root->commit_root = NULL;
Y
Yan Zheng 已提交
413 414 415
				
				kfree(dirty->root);
				kfree(dirty);
416 417 418 419 420 421 422 423 424

				/* 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);
425 426
				continue;
			}
427 428 429 430

			memset(&root->root_item.drop_progress, 0,
			       sizeof(struct btrfs_disk_key));
			root->root_item.drop_level = 0;
431 432
			root->commit_root = NULL;
			root->root_key.offset = root->fs_info->generation;
433 434 435 436
			btrfs_set_root_bytenr(&root->root_item,
					      root->node->start);
			btrfs_set_root_level(&root->root_item,
					     btrfs_header_level(root->node));
437 438 439
			err = btrfs_insert_root(trans, root->fs_info->tree_root,
						&root->root_key,
						&root->root_item);
440 441
			if (err)
				break;
442 443 444

			refs = btrfs_root_refs(&dirty->root->root_item);
			btrfs_set_root_refs(&dirty->root->root_item, refs - 1);
445
			err = btrfs_update_root(trans, root->fs_info->tree_root,
446 447
						&dirty->root->root_key,
						&dirty->root->root_item);
448 449

			BUG_ON(err);
450
			if (refs == 1) {
451
				list_add(&dirty->list, list);
452 453
			} else {
				WARN_ON(1);
Y
Yan Zheng 已提交
454
				free_extent_buffer(dirty->root->node);
455
				kfree(dirty->root);
456
				kfree(dirty);
457
			}
458 459
		}
	}
460
	return err;
461 462
}

463 464 465 466 467
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;
468
	unsigned long nr;
469

470
	smp_mb();
471 472 473
	if (root->defrag_running)
		return 0;
	trans = btrfs_start_transaction(root, 1);
474
	while (1) {
475 476
		root->defrag_running = 1;
		ret = btrfs_defrag_leaves(trans, root, cacheonly);
477
		nr = trans->blocks_used;
478
		btrfs_end_transaction(trans, root);
479
		btrfs_btree_balance_dirty(info->tree_root, nr);
480 481 482
		cond_resched();

		trans = btrfs_start_transaction(root, 1);
483
		if (root->fs_info->closing || ret != -EAGAIN)
484 485 486
			break;
	}
	root->defrag_running = 0;
487
	smp_mb();
488 489 490 491
	btrfs_end_transaction(trans, root);
	return 0;
}

492 493
static noinline int drop_dirty_roots(struct btrfs_root *tree_root,
				     struct list_head *list)
494
{
495
	struct btrfs_dirty_root *dirty;
496
	struct btrfs_trans_handle *trans;
497
	unsigned long nr;
498 499
	u64 num_bytes;
	u64 bytes_used;
500
	int ret = 0;
501 502
	int err;

503
	while(!list_empty(list)) {
504 505
		struct btrfs_root *root;

506
		dirty = list_entry(list->prev, struct btrfs_dirty_root, list);
507
		list_del_init(&dirty->list);
508

509
		num_bytes = btrfs_root_used(&dirty->root->root_item);
510
		root = dirty->latest_root;
511
		atomic_inc(&root->fs_info->throttles);
512

513
		mutex_lock(&root->fs_info->drop_mutex);
514 515 516 517 518 519
		while(1) {
			trans = btrfs_start_transaction(tree_root, 1);
			ret = btrfs_drop_snapshot(trans, dirty->root);
			if (ret != -EAGAIN) {
				break;
			}
520

521 522 523 524 525 526
			err = btrfs_update_root(trans,
					tree_root,
					&dirty->root->root_key,
					&dirty->root->root_item);
			if (err)
				ret = err;
527
			nr = trans->blocks_used;
C
Chris Mason 已提交
528
			ret = btrfs_end_transaction(trans, tree_root);
529
			BUG_ON(ret);
530 531

			mutex_unlock(&root->fs_info->drop_mutex);
532
			btrfs_btree_balance_dirty(tree_root, nr);
533
			cond_resched();
534
			mutex_lock(&root->fs_info->drop_mutex);
535
		}
536
		BUG_ON(ret);
537
		atomic_dec(&root->fs_info->throttles);
C
Chris Mason 已提交
538
		wake_up(&root->fs_info->transaction_throttle);
539

540
		mutex_lock(&root->fs_info->alloc_mutex);
541 542 543
		num_bytes -= btrfs_root_used(&dirty->root->root_item);
		bytes_used = btrfs_root_used(&root->root_item);
		if (num_bytes) {
544
			record_root_in_trans(root);
545
			btrfs_set_root_used(&root->root_item,
546
					    bytes_used - num_bytes);
547
		}
548 549
		mutex_unlock(&root->fs_info->alloc_mutex);

550
		ret = btrfs_del_root(trans, tree_root, &dirty->root->root_key);
551 552
		if (ret) {
			BUG();
553
			break;
554
		}
555 556
		mutex_unlock(&root->fs_info->drop_mutex);

557
		nr = trans->blocks_used;
558 559
		ret = btrfs_end_transaction(trans, tree_root);
		BUG_ON(ret);
560

561
		free_extent_buffer(dirty->root->node);
562
		kfree(dirty->root);
563
		kfree(dirty);
564 565

		btrfs_btree_balance_dirty(tree_root, nr);
566
		cond_resched();
567
	}
568
	return ret;
569 570
}

571
static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
572 573 574 575
				   struct btrfs_fs_info *fs_info,
				   struct btrfs_pending_snapshot *pending)
{
	struct btrfs_key key;
576
	struct btrfs_root_item *new_root_item;
577 578 579
	struct btrfs_root *tree_root = fs_info->tree_root;
	struct btrfs_root *root = pending->root;
	struct extent_buffer *tmp;
580
	struct extent_buffer *old;
581
	int ret;
582
	int namelen;
583 584
	u64 objectid;

585 586 587 588 589
	new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
	if (!new_root_item) {
		ret = -ENOMEM;
		goto fail;
	}
590 591 592 593
	ret = btrfs_find_free_objectid(trans, tree_root, 0, &objectid);
	if (ret)
		goto fail;

594
	memcpy(new_root_item, &root->root_item, sizeof(*new_root_item));
595 596 597 598 599

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

600 601
	old = btrfs_lock_root_node(root);
	btrfs_cow_block(trans, root, old, NULL, 0, &old);
602

603 604 605
	btrfs_copy_root(trans, root, old, &tmp, objectid);
	btrfs_tree_unlock(old);
	free_extent_buffer(old);
606

607 608
	btrfs_set_root_bytenr(new_root_item, tmp->start);
	btrfs_set_root_level(new_root_item, btrfs_header_level(tmp));
609
	ret = btrfs_insert_root(trans, root->fs_info->tree_root, &key,
610
				new_root_item);
611
	btrfs_tree_unlock(tmp);
612 613 614 615 616 617 618 619
	free_extent_buffer(tmp);
	if (ret)
		goto fail;

	/*
	 * insert the directory item
	 */
	key.offset = (u64)-1;
620
	namelen = strlen(pending->name);
621
	ret = btrfs_insert_dir_item(trans, root->fs_info->tree_root,
622
				    pending->name, namelen,
623
				    root->fs_info->sb->s_root->d_inode->i_ino,
624
				    &key, BTRFS_FT_DIR, 0);
625 626 627 628 629 630

	if (ret)
		goto fail;

	ret = btrfs_insert_inode_ref(trans, root->fs_info->tree_root,
			     pending->name, strlen(pending->name), objectid,
631
			     root->fs_info->sb->s_root->d_inode->i_ino, 0);
632 633 634 635

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

636
fail:
637
	kfree(new_root_item);
638 639 640
	return ret;
}

641 642
static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans,
					     struct btrfs_fs_info *fs_info)
643 644 645 646 647 648 649 650 651 652 653 654 655 656
{
	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 已提交
657 658 659
	return 0;
}

C
Chris Mason 已提交
660 661 662
int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
			     struct btrfs_root *root)
{
663 664
	unsigned long joined = 0;
	unsigned long timeout = 1;
C
Chris Mason 已提交
665
	struct btrfs_transaction *cur_trans;
C
Chris Mason 已提交
666
	struct btrfs_transaction *prev_trans = NULL;
667
	struct btrfs_root *chunk_root = root->fs_info->chunk_root;
668
	struct list_head dirty_fs_roots;
669
	struct extent_io_tree *pinned_copy;
C
Chris Mason 已提交
670
	DEFINE_WAIT(wait);
671
	int ret;
C
Chris Mason 已提交
672

673
	INIT_LIST_HEAD(&dirty_fs_roots);
674

C
Chris Mason 已提交
675 676 677 678
	mutex_lock(&root->fs_info->trans_mutex);
	if (trans->transaction->in_commit) {
		cur_trans = trans->transaction;
		trans->transaction->use_count++;
C
Chris Mason 已提交
679
		mutex_unlock(&root->fs_info->trans_mutex);
C
Chris Mason 已提交
680
		btrfs_end_transaction(trans, root);
C
Chris Mason 已提交
681

C
Chris Mason 已提交
682 683
		ret = wait_for_commit(root, cur_trans);
		BUG_ON(ret);
684 685

		mutex_lock(&root->fs_info->trans_mutex);
C
Chris Mason 已提交
686
		put_transaction(cur_trans);
687 688
		mutex_unlock(&root->fs_info->trans_mutex);

C
Chris Mason 已提交
689 690
		return 0;
	}
691 692 693 694 695

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

696
	extent_io_tree_init(pinned_copy,
697 698
			     root->fs_info->btree_inode->i_mapping, GFP_NOFS);

C
Chris Mason 已提交
699
	trans->transaction->in_commit = 1;
700
	trans->transaction->blocked = 1;
C
Chris Mason 已提交
701 702 703 704 705 706 707 708 709 710 711
	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);
712
			put_transaction(prev_trans);
C
Chris Mason 已提交
713 714
		}
	}
715 716 717

	do {
		joined = cur_trans->num_joined;
C
Chris Mason 已提交
718
		WARN_ON(cur_trans != trans->transaction);
719
		prepare_to_wait(&cur_trans->writer_wait, &wait,
C
Chris Mason 已提交
720
				TASK_UNINTERRUPTIBLE);
721 722 723 724 725 726

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

C
Chris Mason 已提交
727
		mutex_unlock(&root->fs_info->trans_mutex);
728 729 730

		schedule_timeout(timeout);

C
Chris Mason 已提交
731
		mutex_lock(&root->fs_info->trans_mutex);
732 733 734 735
		finish_wait(&cur_trans->writer_wait, &wait);
	} while (cur_trans->num_writers > 1 ||
		 (cur_trans->num_joined != joined));

736 737 738
	ret = create_pending_snapshots(trans, root->fs_info);
	BUG_ON(ret);

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

741 742 743 744
	ret = add_dirty_roots(trans, &root->fs_info->fs_roots_radix,
			      &dirty_fs_roots);
	BUG_ON(ret);

C
Chris Mason 已提交
745 746
	ret = btrfs_commit_tree_roots(trans, root);
	BUG_ON(ret);
747

C
Chris Mason 已提交
748
	cur_trans = root->fs_info->running_transaction;
749
	spin_lock(&root->fs_info->new_trans_lock);
C
Chris Mason 已提交
750
	root->fs_info->running_transaction = NULL;
751
	spin_unlock(&root->fs_info->new_trans_lock);
752 753 754
	btrfs_set_super_generation(&root->fs_info->super_copy,
				   cur_trans->transid);
	btrfs_set_super_root(&root->fs_info->super_copy,
755 756 757
			     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));
758

759 760 761 762
	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));
763 764
	memcpy(&root->fs_info->super_for_commit, &root->fs_info->super_copy,
	       sizeof(root->fs_info->super_copy));
C
Chris Mason 已提交
765

766
	btrfs_copy_pinned(root, pinned_copy);
C
Chris Mason 已提交
767

768
	trans->transaction->blocked = 0;
769
	wake_up(&root->fs_info->transaction_throttle);
770
	wake_up(&root->fs_info->transaction_wait);
771

C
Chris Mason 已提交
772
	mutex_unlock(&root->fs_info->trans_mutex);
C
Chris Mason 已提交
773 774 775
	ret = btrfs_write_and_wait_transaction(trans, root);
	BUG_ON(ret);
	write_ctree_super(trans, root);
776 777

	btrfs_finish_extent_commit(trans, root, pinned_copy);
C
Chris Mason 已提交
778
	mutex_lock(&root->fs_info->trans_mutex);
779 780 781

	kfree(pinned_copy);

C
Chris Mason 已提交
782
	cur_trans->commit_done = 1;
783
	root->fs_info->last_trans_committed = cur_trans->transid;
C
Chris Mason 已提交
784
	wake_up(&cur_trans->commit_wait);
C
Chris Mason 已提交
785
	put_transaction(cur_trans);
C
Chris Mason 已提交
786
	put_transaction(cur_trans);
787

788 789 790 791
	if (root->fs_info->closing)
		list_splice_init(&root->fs_info->dead_roots, &dirty_fs_roots);
	else
		list_splice_init(&dirty_fs_roots, &root->fs_info->dead_roots);
792

C
Chris Mason 已提交
793
	mutex_unlock(&root->fs_info->trans_mutex);
C
Chris Mason 已提交
794
	kmem_cache_free(btrfs_trans_handle_cachep, trans);
C
Chris Mason 已提交
795

796 797 798
	if (root->fs_info->closing) {
		drop_dirty_roots(root->fs_info->tree_root, &dirty_fs_roots);
	}
C
Chris Mason 已提交
799 800 801
	return ret;
}

802 803 804 805
int btrfs_clean_old_snapshots(struct btrfs_root *root)
{
	struct list_head dirty_roots;
	INIT_LIST_HEAD(&dirty_roots);
806
again:
807 808 809 810 811 812
	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);
813
		goto again;
814 815 816
	}
	return 0;
}
C
Chris Mason 已提交
817