disk-io.c 23.5 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>
20
#include <linux/blkdev.h>
21
#include <linux/crc32c.h>
C
Chris Mason 已提交
22
#include <linux/scatterlist.h>
C
Chris Mason 已提交
23
#include <linux/swap.h>
24
#include <linux/radix-tree.h>
C
Chris Mason 已提交
25
#include <linux/writeback.h>
26
#include <linux/buffer_head.h> // for block_sync_page
27 28
#include "ctree.h"
#include "disk-io.h"
29
#include "transaction.h"
30
#include "btrfs_inode.h"
31
#include "print-tree.h"
32

33 34
#if 0
static int check_tree_block(struct btrfs_root *root, struct extent_buffer *buf)
35
{
36 37 38 39
	if (extent_buffer_blocknr(buf) != btrfs_header_blocknr(buf)) {
		printk(KERN_CRIT "buf blocknr(buf) is %llu, header is %llu\n",
		       (unsigned long long)extent_buffer_blocknr(buf),
		       (unsigned long long)btrfs_header_blocknr(buf));
C
Chris Mason 已提交
40
		return 1;
41
	}
42
	return 0;
43
}
44
#endif
45

46 47
static struct extent_map_ops btree_extent_map_ops;

48
struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root,
49
					    u64 bytenr, u32 blocksize)
50
{
51
	struct inode *btree_inode = root->fs_info->btree_inode;
52 53
	struct extent_buffer *eb;
	eb = find_extent_buffer(&BTRFS_I(btree_inode)->extent_tree,
54
				bytenr, blocksize, GFP_NOFS);
55
	return eb;
56
}
57

58
struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
59
						 u64 bytenr, u32 blocksize)
60 61
{
	struct inode *btree_inode = root->fs_info->btree_inode;
62
	struct extent_buffer *eb;
63

64
	eb = alloc_extent_buffer(&BTRFS_I(btree_inode)->extent_tree,
65
				 bytenr, blocksize, NULL, GFP_NOFS);
66
	return eb;
67 68
}

69 70 71
struct extent_map *btree_get_extent(struct inode *inode, struct page *page,
				    size_t page_offset, u64 start, u64 end,
				    int create)
72
{
73 74 75 76 77 78 79 80
	struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
	struct extent_map *em;
	int ret;

again:
	em = lookup_extent_mapping(em_tree, start, end);
	if (em) {
		goto out;
81
	}
82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
	em = alloc_extent_map(GFP_NOFS);
	if (!em) {
		em = ERR_PTR(-ENOMEM);
		goto out;
	}
	em->start = 0;
	em->end = (i_size_read(inode) & ~((u64)PAGE_CACHE_SIZE -1)) - 1;
	em->block_start = 0;
	em->block_end = em->end;
	em->bdev = inode->i_sb->s_bdev;
	ret = add_extent_mapping(em_tree, em);
	if (ret == -EEXIST) {
		free_extent_map(em);
		em = NULL;
		goto again;
	} else if (ret) {
		em = ERR_PTR(ret);
	}
out:
	return em;
102 103
}

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
u32 btrfs_csum_data(struct btrfs_root *root, char *data, u32 seed, size_t len)
{
	return crc32c(seed, data, len);
}

void btrfs_csum_final(u32 crc, char *result)
{
	*(__le32 *)result = ~cpu_to_le32(crc);
}

static int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf,
			   int verify)
{
	char result[BTRFS_CRC32_SIZE];
	unsigned long len;
	unsigned long cur_len;
	unsigned long offset = BTRFS_CSUM_SIZE;
	char *map_token = NULL;
	char *kaddr;
	unsigned long map_start;
	unsigned long map_len;
	int err;
	u32 crc = ~(u32)0;

	len = buf->len - offset;
	while(len > 0) {
		err = map_private_extent_buffer(buf, offset, 32,
					&map_token, &kaddr,
					&map_start, &map_len, KM_USER0);
		if (err) {
			printk("failed to map extent buffer! %lu\n",
			       offset);
			return 1;
		}
		cur_len = min(len, map_len - (offset - map_start));
		crc = btrfs_csum_data(root, kaddr + offset - map_start,
				      crc, cur_len);
		len -= cur_len;
		offset += cur_len;
		unmap_extent_buffer(buf, map_token, KM_USER0);
	}
	btrfs_csum_final(crc, result);

	if (verify) {
		if (memcmp_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE)) {
			printk("btrfs: %s checksum verify failed on %llu\n",
			       root->fs_info->sb->s_id,
			       buf->start);
			return 1;
		}
	} else {
		write_extent_buffer(buf, result, 0, BTRFS_CRC32_SIZE);
	}
	return 0;
}


int csum_dirty_buffer(struct btrfs_root *root, struct page *page)
{
	struct extent_map_tree *tree;
164
	u64 start = (u64)page->index << PAGE_CACHE_SHIFT;
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192
	u64 found_start;
	int found_level;
	unsigned long len;
	struct extent_buffer *eb;
	tree = &BTRFS_I(page->mapping->host)->extent_tree;

	if (page->private == EXTENT_PAGE_PRIVATE)
		goto out;
	if (!page->private)
		goto out;
	len = page->private >> 2;
	if (len == 0) {
		WARN_ON(1);
	}
	eb = alloc_extent_buffer(tree, start, len, page, GFP_NOFS);
	read_extent_buffer_pages(tree, eb, start + PAGE_CACHE_SIZE, 1);
	found_start = btrfs_header_bytenr(eb);
	if (found_start != start) {
		printk("warning: eb start incorrect %Lu buffer %Lu len %lu\n",
		       start, found_start, len);
	}
	found_level = btrfs_header_level(eb);
	csum_tree_block(root, eb, 0);
	free_extent_buffer(eb);
out:
	return 0;
}

193
static int btree_writepage_io_hook(struct page *page, u64 start, u64 end)
194
{
195 196 197
	struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;

	csum_dirty_buffer(root, page);
198 199 200 201 202 203 204
	return 0;
}

static int btree_writepage(struct page *page, struct writeback_control *wbc)
{
	struct extent_map_tree *tree;
	tree = &BTRFS_I(page->mapping->host)->extent_tree;
205 206
	return extent_write_full_page(tree, page, btree_get_extent, wbc);
}
207 208 209 210 211 212 213 214 215

static int btree_writepages(struct address_space *mapping,
			    struct writeback_control *wbc)
{
	struct extent_map_tree *tree;
	tree = &BTRFS_I(mapping->host)->extent_tree;
	return extent_writepages(tree, mapping, btree_get_extent, wbc);
}

216 217 218 219 220 221
int btree_readpage(struct file *file, struct page *page)
{
	struct extent_map_tree *tree;
	tree = &BTRFS_I(page->mapping->host)->extent_tree;
	return extent_read_full_page(tree, page, btree_get_extent);
}
C
Chris Mason 已提交
222

223 224 225 226
static int btree_releasepage(struct page *page, gfp_t unused_gfp_flags)
{
	struct extent_map_tree *tree;
	int ret;
227

228 229 230 231 232 233 234
	tree = &BTRFS_I(page->mapping->host)->extent_tree;
	ret = try_release_extent_mapping(tree, page);
	if (ret == 1) {
		ClearPagePrivate(page);
		set_page_private(page, 0);
		page_cache_release(page);
	}
235 236 237
	return ret;
}

238
static void btree_invalidatepage(struct page *page, unsigned long offset)
239
{
240 241 242 243
	struct extent_map_tree *tree;
	tree = &BTRFS_I(page->mapping->host)->extent_tree;
	extent_invalidatepage(tree, page, offset);
	btree_releasepage(page, GFP_NOFS);
244 245
}

246
#if 0
247
static int btree_writepage(struct page *page, struct writeback_control *wbc)
248
{
C
Chris Mason 已提交
249
	struct buffer_head *bh;
250
	struct btrfs_root *root = BTRFS_I(page->mapping->host)->root;
C
Chris Mason 已提交
251 252 253 254 255 256 257 258 259 260 261 262
	struct buffer_head *head;
	if (!page_has_buffers(page)) {
		create_empty_buffers(page, root->fs_info->sb->s_blocksize,
					(1 << BH_Dirty)|(1 << BH_Uptodate));
	}
	head = page_buffers(page);
	bh = head;
	do {
		if (buffer_dirty(bh))
			csum_tree_block(root, bh, 0);
		bh = bh->b_this_page;
	} while (bh != head);
263
	return block_write_full_page(page, btree_get_block, wbc);
264
}
265
#endif
266

267 268 269
static struct address_space_operations btree_aops = {
	.readpage	= btree_readpage,
	.writepage	= btree_writepage,
270
	.writepages	= btree_writepages,
271 272
	.releasepage	= btree_releasepage,
	.invalidatepage = btree_invalidatepage,
273 274 275
	.sync_page	= block_sync_page,
};

276
int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize)
C
Chris Mason 已提交
277
{
278 279
	struct extent_buffer *buf = NULL;
	struct inode *btree_inode = root->fs_info->btree_inode;
280
	int ret = 0;
C
Chris Mason 已提交
281

282
	buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
283
	if (!buf)
C
Chris Mason 已提交
284
		return 0;
285
	read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree,
286
				 buf, 0, 0);
287
	free_extent_buffer(buf);
288
	return ret;
C
Chris Mason 已提交
289 290
}

291 292
struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
				      u32 blocksize)
293
{
294 295
	struct extent_buffer *buf = NULL;
	struct inode *btree_inode = root->fs_info->btree_inode;
296 297 298 299
	struct extent_map_tree *extent_tree;
	int ret;

	extent_tree = &BTRFS_I(btree_inode)->extent_tree;
300

301
	buf = btrfs_find_create_tree_block(root, bytenr, blocksize);
302 303 304
	if (!buf)
		return NULL;
	read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree,
305 306 307 308 309 310 311 312 313 314 315 316 317 318
				 buf, 0, 1);
	if (buf->flags & EXTENT_CSUM) {
		return buf;
	}
	if (test_range_bit(extent_tree, buf->start, buf->start + buf->len - 1,
			   EXTENT_CSUM, 1)) {
		buf->flags |= EXTENT_CSUM;
		return buf;
	}
	ret = csum_tree_block(root, buf, 1);
	set_extent_bits(extent_tree, buf->start,
			buf->start + buf->len - 1,
			EXTENT_CSUM, GFP_NOFS);
	buf->flags |= EXTENT_CSUM;
319
	return buf;
320 321
}

322
int clean_tree_block(struct btrfs_trans_handle *trans, struct btrfs_root *root,
323
		     struct extent_buffer *buf)
324
{
325 326 327 328 329 330 331 332 333 334 335 336 337 338
	struct inode *btree_inode = root->fs_info->btree_inode;
	clear_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf);
	return 0;
}

int wait_on_tree_block_writeback(struct btrfs_root *root,
				 struct extent_buffer *buf)
{
	struct inode *btree_inode = root->fs_info->btree_inode;
	wait_on_extent_buffer_writeback(&BTRFS_I(btree_inode)->extent_tree,
					buf);
	return 0;
}

339
static int __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,
340 341
			struct btrfs_root *root,
			struct btrfs_fs_info *fs_info,
C
Chris Mason 已提交
342
			u64 objectid)
343
{
C
Chris Mason 已提交
344
	root->node = NULL;
345
	root->inode = NULL;
346
	root->commit_root = NULL;
347 348 349
	root->sectorsize = sectorsize;
	root->nodesize = nodesize;
	root->leafsize = leafsize;
C
Chris Mason 已提交
350
	root->ref_cows = 0;
351
	root->fs_info = fs_info;
352 353
	root->objectid = objectid;
	root->last_trans = 0;
C
Chris Mason 已提交
354 355
	root->highest_inode = 0;
	root->last_inode_alloc = 0;
356
	root->name = NULL;
357 358
	memset(&root->root_key, 0, sizeof(root->root_key));
	memset(&root->root_item, 0, sizeof(root->root_item));
359
	memset(&root->defrag_progress, 0, sizeof(root->defrag_progress));
360 361
	memset(&root->root_kobj, 0, sizeof(root->root_kobj));
	init_completion(&root->kobj_unregister);
362
	init_rwsem(&root->snap_sem);
363 364
	root->defrag_running = 0;
	root->defrag_level = 0;
365
	root->root_key.objectid = objectid;
366 367 368
	return 0;
}

369
static int find_and_setup_root(struct btrfs_root *tree_root,
370 371
			       struct btrfs_fs_info *fs_info,
			       u64 objectid,
C
Chris Mason 已提交
372
			       struct btrfs_root *root)
373 374
{
	int ret;
375
	u32 blocksize;
376

377 378
	__setup_root(tree_root->nodesize, tree_root->leafsize,
		     tree_root->sectorsize, root, fs_info, objectid);
379 380 381 382
	ret = btrfs_find_last_root(tree_root, objectid,
				   &root->root_item, &root->root_key);
	BUG_ON(ret);

383 384 385
	blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
	root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
				     blocksize);
386
	BUG_ON(!root->node);
387 388 389
	return 0;
}

390 391
struct btrfs_root *btrfs_read_fs_root_no_radix(struct btrfs_fs_info *fs_info,
					       struct btrfs_key *location)
392 393 394 395
{
	struct btrfs_root *root;
	struct btrfs_root *tree_root = fs_info->tree_root;
	struct btrfs_path *path;
396
	struct extent_buffer *l;
C
Chris Mason 已提交
397
	u64 highest_inode;
398
	u32 blocksize;
399 400
	int ret = 0;

401
	root = kzalloc(sizeof(*root), GFP_NOFS);
C
Chris Mason 已提交
402
	if (!root)
403 404
		return ERR_PTR(-ENOMEM);
	if (location->offset == (u64)-1) {
405
		ret = find_and_setup_root(tree_root, fs_info,
406 407 408 409 410 411 412 413
					  location->objectid, root);
		if (ret) {
			kfree(root);
			return ERR_PTR(ret);
		}
		goto insert;
	}

414 415
	__setup_root(tree_root->nodesize, tree_root->leafsize,
		     tree_root->sectorsize, root, fs_info,
416 417 418 419 420 421 422 423 424 425
		     location->objectid);

	path = btrfs_alloc_path();
	BUG_ON(!path);
	ret = btrfs_search_slot(NULL, tree_root, location, path, 0, 0);
	if (ret != 0) {
		if (ret > 0)
			ret = -ENOENT;
		goto out;
	}
426 427 428
	l = path->nodes[0];
	read_extent_buffer(l, &root->root_item,
	       btrfs_item_ptr_offset(l, path->slots[0]),
429
	       sizeof(root->root_item));
430
	memcpy(&root->root_key, location, sizeof(*location));
431 432 433 434 435 436 437 438
	ret = 0;
out:
	btrfs_release_path(root, path);
	btrfs_free_path(path);
	if (ret) {
		kfree(root);
		return ERR_PTR(ret);
	}
439 440 441
	blocksize = btrfs_level_size(root, btrfs_root_level(&root->root_item));
	root->node = read_tree_block(root, btrfs_root_bytenr(&root->root_item),
				     blocksize);
442 443 444
	BUG_ON(!root->node);
insert:
	root->ref_cows = 1;
445 446 447 448 449 450 451 452 453
	ret = btrfs_find_highest_inode(root, &highest_inode);
	if (ret == 0) {
		root->highest_inode = highest_inode;
		root->last_inode_alloc = highest_inode;
	}
	return root;
}

struct btrfs_root *btrfs_read_fs_root(struct btrfs_fs_info *fs_info,
454 455
				      struct btrfs_key *location,
				      const char *name, int namelen)
456 457 458 459 460 461 462 463 464 465 466 467
{
	struct btrfs_root *root;
	int ret;

	root = radix_tree_lookup(&fs_info->fs_roots_radix,
				 (unsigned long)location->objectid);
	if (root)
		return root;

	root = btrfs_read_fs_root_no_radix(fs_info, location);
	if (IS_ERR(root))
		return root;
C
Chris Mason 已提交
468 469
	ret = radix_tree_insert(&fs_info->fs_roots_radix,
				(unsigned long)root->root_key.objectid,
470 471
				root);
	if (ret) {
472
		free_extent_buffer(root->node);
473 474 475
		kfree(root);
		return ERR_PTR(ret);
	}
476 477 478

	ret = btrfs_set_root_name(root, name, namelen);
	if (ret) {
479
		free_extent_buffer(root->node);
480 481 482 483 484 485
		kfree(root);
		return ERR_PTR(ret);
	}

	ret = btrfs_sysfs_add_root(root);
	if (ret) {
486
		free_extent_buffer(root->node);
487 488 489 490 491
		kfree(root->name);
		kfree(root);
		return ERR_PTR(ret);
	}

492 493 494 495
	ret = btrfs_find_dead_roots(fs_info->tree_root,
				    root->root_key.objectid, root);
	BUG_ON(ret);

496 497
	return root;
}
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515
#if 0
static int add_hasher(struct btrfs_fs_info *info, char *type) {
	struct btrfs_hasher *hasher;

	hasher = kmalloc(sizeof(*hasher), GFP_NOFS);
	if (!hasher)
		return -ENOMEM;
	hasher->hash_tfm = crypto_alloc_hash(type, 0, CRYPTO_ALG_ASYNC);
	if (!hasher->hash_tfm) {
		kfree(hasher);
		return -EINVAL;
	}
	spin_lock(&info->hash_lock);
	list_add(&hasher->list, &info->hashers);
	spin_unlock(&info->hash_lock);
	return 0;
}
#endif
C
Chris Mason 已提交
516
struct btrfs_root *open_ctree(struct super_block *sb)
517
{
518 519 520 521
	u32 sectorsize;
	u32 nodesize;
	u32 leafsize;
	u32 blocksize;
C
Chris Mason 已提交
522 523 524 525 526 527
	struct btrfs_root *extent_root = kmalloc(sizeof(struct btrfs_root),
						 GFP_NOFS);
	struct btrfs_root *tree_root = kmalloc(sizeof(struct btrfs_root),
					       GFP_NOFS);
	struct btrfs_fs_info *fs_info = kmalloc(sizeof(*fs_info),
						GFP_NOFS);
528
	int ret;
C
Chris Mason 已提交
529
	int err = -EIO;
C
Chris Mason 已提交
530
	struct btrfs_super_block *disk_super;
531

C
Chris Mason 已提交
532 533 534 535
	if (!extent_root || !tree_root || !fs_info) {
		err = -ENOMEM;
		goto fail;
	}
536
	INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_NOFS);
C
Chris Mason 已提交
537
	INIT_LIST_HEAD(&fs_info->trans_list);
538
	INIT_LIST_HEAD(&fs_info->dead_roots);
539 540 541
	INIT_LIST_HEAD(&fs_info->hashers);
	spin_lock_init(&fs_info->hash_lock);

542 543
	memset(&fs_info->super_kobj, 0, sizeof(fs_info->super_kobj));
	init_completion(&fs_info->kobj_unregister);
C
Chris Mason 已提交
544
	sb_set_blocksize(sb, 4096);
545
	fs_info->running_transaction = NULL;
546
	fs_info->last_trans_committed = 0;
547 548
	fs_info->tree_root = tree_root;
	fs_info->extent_root = extent_root;
C
Chris Mason 已提交
549
	fs_info->sb = sb;
550 551
	fs_info->btree_inode = new_inode(sb);
	fs_info->btree_inode->i_ino = 1;
C
Chris Mason 已提交
552
	fs_info->btree_inode->i_nlink = 1;
553 554
	fs_info->btree_inode->i_size = sb->s_bdev->bd_inode->i_size;
	fs_info->btree_inode->i_mapping->a_ops = &btree_aops;
555 556 557
	extent_map_tree_init(&BTRFS_I(fs_info->btree_inode)->extent_tree,
			     fs_info->btree_inode->i_mapping,
			     GFP_NOFS);
558 559
	BTRFS_I(fs_info->btree_inode)->extent_tree.ops = &btree_extent_map_ops;

560 561
	extent_map_tree_init(&fs_info->free_space_cache,
			     fs_info->btree_inode->i_mapping, GFP_NOFS);
562 563
	extent_map_tree_init(&fs_info->block_group_cache,
			     fs_info->btree_inode->i_mapping, GFP_NOFS);
564 565 566 567 568 569
	extent_map_tree_init(&fs_info->pinned_extents,
			     fs_info->btree_inode->i_mapping, GFP_NOFS);
	extent_map_tree_init(&fs_info->pending_del,
			     fs_info->btree_inode->i_mapping, GFP_NOFS);
	extent_map_tree_init(&fs_info->extent_ins,
			     fs_info->btree_inode->i_mapping, GFP_NOFS);
570
	fs_info->do_barriers = 1;
571 572
	fs_info->closing = 0;

C
Chris Mason 已提交
573
	INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner);
574 575 576
	BTRFS_I(fs_info->btree_inode)->root = tree_root;
	memset(&BTRFS_I(fs_info->btree_inode)->location, 0,
	       sizeof(struct btrfs_key));
C
Chris Mason 已提交
577
	insert_inode_hash(fs_info->btree_inode);
578
	mapping_set_gfp_mask(fs_info->btree_inode->i_mapping, GFP_NOFS);
C
Chris Mason 已提交
579

C
Chris Mason 已提交
580
	mutex_init(&fs_info->trans_mutex);
C
Chris Mason 已提交
581
	mutex_init(&fs_info->fs_mutex);
582

583 584 585 586 587 588 589 590
#if 0
	ret = add_hasher(fs_info, "crc32c");
	if (ret) {
		printk("btrfs: failed hash setup, modprobe cryptomgr?\n");
		err = -ENOMEM;
		goto fail_iput;
	}
#endif
591
	__setup_root(512, 512, 512, tree_root,
C
Chris Mason 已提交
592
		     fs_info, BTRFS_ROOT_TREE_OBJECTID);
593

C
Chris Mason 已提交
594
	fs_info->sb_buffer = read_tree_block(tree_root,
595 596
					     BTRFS_SUPER_INFO_OFFSET,
					     512);
597

598
	if (!fs_info->sb_buffer)
C
Chris Mason 已提交
599 600
		goto fail_iput;

601 602 603 604 605 606 607
	read_extent_buffer(fs_info->sb_buffer, &fs_info->super_copy, 0,
			   sizeof(fs_info->super_copy));

	read_extent_buffer(fs_info->sb_buffer, fs_info->fsid,
			   (unsigned long)btrfs_super_fsid(fs_info->sb_buffer),
			   BTRFS_FSID_SIZE);
	disk_super = &fs_info->super_copy;
608
	if (!btrfs_super_root(disk_super))
C
Chris Mason 已提交
609
		goto fail_sb_buffer;
610

611 612 613 614 615 616
	nodesize = btrfs_super_nodesize(disk_super);
	leafsize = btrfs_super_leafsize(disk_super);
	sectorsize = btrfs_super_sectorsize(disk_super);
	tree_root->nodesize = nodesize;
	tree_root->leafsize = leafsize;
	tree_root->sectorsize = sectorsize;
617
	sb_set_blocksize(sb, sectorsize);
618

619
	i_size_write(fs_info->btree_inode,
620
		     btrfs_super_total_bytes(disk_super));
621

C
Chris Mason 已提交
622 623 624 625 626
	if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC,
		    sizeof(disk_super->magic))) {
		printk("btrfs: valid FS not found on %s\n", sb->s_id);
		goto fail_sb_buffer;
	}
627

628 629
	blocksize = btrfs_level_size(tree_root,
				     btrfs_super_root_level(disk_super));
630

C
Chris Mason 已提交
631
	tree_root->node = read_tree_block(tree_root,
632 633
					  btrfs_super_root(disk_super),
					  blocksize);
C
Chris Mason 已提交
634 635
	if (!tree_root->node)
		goto fail_sb_buffer;
636

C
Chris Mason 已提交
637
	mutex_lock(&fs_info->fs_mutex);
638 639

	ret = find_and_setup_root(tree_root, fs_info,
C
Chris Mason 已提交
640
				  BTRFS_EXTENT_TREE_OBJECTID, extent_root);
C
Chris Mason 已提交
641 642 643 644
	if (ret) {
		mutex_unlock(&fs_info->fs_mutex);
		goto fail_tree_root;
	}
645

C
Chris Mason 已提交
646 647
	btrfs_read_block_groups(extent_root);

648
	fs_info->generation = btrfs_super_generation(disk_super) + 1;
C
Chris Mason 已提交
649
	mutex_unlock(&fs_info->fs_mutex);
650
	return tree_root;
C
Chris Mason 已提交
651 652

fail_tree_root:
653
	free_extent_buffer(tree_root->node);
C
Chris Mason 已提交
654
fail_sb_buffer:
655
	free_extent_buffer(fs_info->sb_buffer);
C
Chris Mason 已提交
656 657 658 659 660 661 662
fail_iput:
	iput(fs_info->btree_inode);
fail:
	kfree(extent_root);
	kfree(tree_root);
	kfree(fs_info);
	return ERR_PTR(err);
663 664
}

665
int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root
C
Chris Mason 已提交
666
		      *root)
667
{
668
	int ret;
669 670 671 672 673 674 675
	struct extent_buffer *super = root->fs_info->sb_buffer;
	struct inode *btree_inode = root->fs_info->btree_inode;

	set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, super);
	ret = sync_page_range_nolock(btree_inode, btree_inode->i_mapping,
				     super->start, super->len);
	return ret;
C
Chris Mason 已提交
676 677
}

678
int btrfs_free_fs_root(struct btrfs_fs_info *fs_info, struct btrfs_root *root)
C
Chris Mason 已提交
679 680 681
{
	radix_tree_delete(&fs_info->fs_roots_radix,
			  (unsigned long)root->root_key.objectid);
682
	btrfs_sysfs_del_root(root);
C
Chris Mason 已提交
683 684 685
	if (root->inode)
		iput(root->inode);
	if (root->node)
686
		free_extent_buffer(root->node);
C
Chris Mason 已提交
687
	if (root->commit_root)
688
		free_extent_buffer(root->commit_root);
689 690
	if (root->name)
		kfree(root->name);
C
Chris Mason 已提交
691 692 693 694
	kfree(root);
	return 0;
}

C
Chris Mason 已提交
695
static int del_fs_roots(struct btrfs_fs_info *fs_info)
696 697 698 699 700 701 702 703 704 705 706
{
	int ret;
	struct btrfs_root *gang[8];
	int i;

	while(1) {
		ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix,
					     (void **)gang, 0,
					     ARRAY_SIZE(gang));
		if (!ret)
			break;
C
Chris Mason 已提交
707
		for (i = 0; i < ret; i++)
708
			btrfs_free_fs_root(fs_info, gang[i]);
709 710 711
	}
	return 0;
}
712

C
Chris Mason 已提交
713
int close_ctree(struct btrfs_root *root)
C
Chris Mason 已提交
714
{
715
	int ret;
716
	struct btrfs_trans_handle *trans;
717
	struct btrfs_fs_info *fs_info = root->fs_info;
718

719
	fs_info->closing = 1;
C
Chris Mason 已提交
720
	btrfs_transaction_flush_work(root);
721
	mutex_lock(&fs_info->fs_mutex);
722
	btrfs_defrag_dirty_roots(root->fs_info);
C
Chris Mason 已提交
723
	trans = btrfs_start_transaction(root, 1);
724
	ret = btrfs_commit_transaction(trans, root);
C
Chris Mason 已提交
725 726 727 728
	/* run commit again to  drop the original snapshot */
	trans = btrfs_start_transaction(root, 1);
	btrfs_commit_transaction(trans, root);
	ret = btrfs_write_and_wait_transaction(NULL, root);
729
	BUG_ON(ret);
C
Chris Mason 已提交
730
	write_ctree_super(NULL, root);
731 732 733
	mutex_unlock(&fs_info->fs_mutex);

	if (fs_info->extent_root->node)
734
		free_extent_buffer(fs_info->extent_root->node);
735

736
	if (fs_info->tree_root->node)
737
		free_extent_buffer(fs_info->tree_root->node);
738

739
	free_extent_buffer(fs_info->sb_buffer);
740

C
Chris Mason 已提交
741
	btrfs_free_block_groups(root->fs_info);
742
	del_fs_roots(fs_info);
743
	extent_map_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->extent_tree);
744 745
	truncate_inode_pages(fs_info->btree_inode->i_mapping, 0);
	iput(fs_info->btree_inode);
746 747 748 749 750 751 752 753 754 755
#if 0
	while(!list_empty(&fs_info->hashers)) {
		struct btrfs_hasher *hasher;
		hasher = list_entry(fs_info->hashers.next, struct btrfs_hasher,
				    hashers);
		list_del(&hasher->hashers);
		crypto_free_hash(&fs_info->hash_tfm);
		kfree(hasher);
	}
#endif
756 757
	kfree(fs_info->extent_root);
	kfree(fs_info->tree_root);
758 759 760
	return 0;
}

761 762
int btrfs_buffer_uptodate(struct extent_buffer *buf)
{
763
	struct inode *btree_inode = buf->first_page->mapping->host;
764 765 766 767
	return extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree, buf);
}

int btrfs_set_buffer_uptodate(struct extent_buffer *buf)
C
Chris Mason 已提交
768
{
769
	struct inode *btree_inode = buf->first_page->mapping->host;
770 771 772
	return set_extent_buffer_uptodate(&BTRFS_I(btree_inode)->extent_tree,
					  buf);
}
773

774 775
void btrfs_mark_buffer_dirty(struct extent_buffer *buf)
{
776
	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
777 778
	u64 transid = btrfs_header_generation(buf);
	struct inode *btree_inode = root->fs_info->btree_inode;
779

C
Chris Mason 已提交
780 781
	if (transid != root->fs_info->generation) {
		printk(KERN_CRIT "transid mismatch buffer %llu, found %Lu running %Lu\n",
782
			(unsigned long long)buf->start,
C
Chris Mason 已提交
783 784 785
			transid, root->fs_info->generation);
		WARN_ON(1);
	}
786
	set_extent_buffer_dirty(&BTRFS_I(btree_inode)->extent_tree, buf);
787 788
}

789
void btrfs_btree_balance_dirty(struct btrfs_root *root, unsigned long nr)
C
Chris Mason 已提交
790
{
791
	balance_dirty_pages_ratelimited_nr(
792
			root->fs_info->btree_inode->i_mapping, 1);
C
Chris Mason 已提交
793
}
794 795 796

void btrfs_set_buffer_defrag(struct extent_buffer *buf)
{
797
	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
798 799 800 801 802 803 804
	struct inode *btree_inode = root->fs_info->btree_inode;
	set_extent_bits(&BTRFS_I(btree_inode)->extent_tree, buf->start,
			buf->start + buf->len - 1, EXTENT_DEFRAG, GFP_NOFS);
}

void btrfs_set_buffer_defrag_done(struct extent_buffer *buf)
{
805
	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
806 807 808 809 810 811 812 813
	struct inode *btree_inode = root->fs_info->btree_inode;
	set_extent_bits(&BTRFS_I(btree_inode)->extent_tree, buf->start,
			buf->start + buf->len - 1, EXTENT_DEFRAG_DONE,
			GFP_NOFS);
}

int btrfs_buffer_defrag(struct extent_buffer *buf)
{
814
	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
815 816 817 818 819 820 821
	struct inode *btree_inode = root->fs_info->btree_inode;
	return test_range_bit(&BTRFS_I(btree_inode)->extent_tree,
		     buf->start, buf->start + buf->len - 1, EXTENT_DEFRAG, 0);
}

int btrfs_buffer_defrag_done(struct extent_buffer *buf)
{
822
	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
823 824 825 826 827 828 829 830
	struct inode *btree_inode = root->fs_info->btree_inode;
	return test_range_bit(&BTRFS_I(btree_inode)->extent_tree,
		     buf->start, buf->start + buf->len - 1,
		     EXTENT_DEFRAG_DONE, 0);
}

int btrfs_clear_buffer_defrag_done(struct extent_buffer *buf)
{
831
	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
832 833 834 835 836 837 838 839
	struct inode *btree_inode = root->fs_info->btree_inode;
	return clear_extent_bits(&BTRFS_I(btree_inode)->extent_tree,
		     buf->start, buf->start + buf->len - 1,
		     EXTENT_DEFRAG_DONE, GFP_NOFS);
}

int btrfs_clear_buffer_defrag(struct extent_buffer *buf)
{
840
	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
841 842 843 844 845 846 847 848
	struct inode *btree_inode = root->fs_info->btree_inode;
	return clear_extent_bits(&BTRFS_I(btree_inode)->extent_tree,
		     buf->start, buf->start + buf->len - 1,
		     EXTENT_DEFRAG, GFP_NOFS);
}

int btrfs_read_buffer(struct extent_buffer *buf)
{
849
	struct btrfs_root *root = BTRFS_I(buf->first_page->mapping->host)->root;
850 851
	struct inode *btree_inode = root->fs_info->btree_inode;
	return read_extent_buffer_pages(&BTRFS_I(btree_inode)->extent_tree,
852
					buf, 0, 1);
853
}
854 855 856 857

static struct extent_map_ops btree_extent_map_ops = {
	.writepage_io_hook = btree_writepage_io_hook,
};