super.c 16.1 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.
 */

Y
Yan 已提交
19
#include <linux/blkdev.h>
20
#include <linux/module.h>
C
Chris Mason 已提交
21
#include <linux/buffer_head.h>
22 23 24 25 26 27 28 29
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
Y
Yan 已提交
30
#include <linux/mount.h>
C
Chris Mason 已提交
31
#include <linux/mpage.h>
C
Chris Mason 已提交
32 33
#include <linux/swap.h>
#include <linux/writeback.h>
C
Chris Mason 已提交
34
#include <linux/statfs.h>
C
Chris Mason 已提交
35
#include <linux/compat.h>
36
#include <linux/parser.h>
37
#include <linux/ctype.h>
38
#include <linux/namei.h>
39
#include <linux/miscdevice.h>
40
#include "ctree.h"
C
Chris Mason 已提交
41
#include "disk-io.h"
42
#include "transaction.h"
C
Chris Mason 已提交
43
#include "btrfs_inode.h"
C
Chris Mason 已提交
44
#include "ioctl.h"
C
Chris Mason 已提交
45
#include "print-tree.h"
J
Josef Bacik 已提交
46
#include "xattr.h"
47
#include "volumes.h"
48
#include "version.h"
B
Balaji Rao 已提交
49
#include "export.h"
C
Chris Mason 已提交
50
#include "compression.h"
51

52
#define BTRFS_SUPER_MAGIC 0x9123683E
C
Chris Mason 已提交
53

C
Chris Mason 已提交
54
static struct super_operations btrfs_super_ops;
C
Chris Mason 已提交
55

C
Chris Mason 已提交
56
static void btrfs_put_super (struct super_block * sb)
C
Chris Mason 已提交
57
{
C
Chris Mason 已提交
58
	struct btrfs_root *root = btrfs_sb(sb);
59
	struct btrfs_fs_info *fs = root->fs_info;
C
Chris Mason 已提交
60 61
	int ret;

C
Chris Mason 已提交
62 63 64
	ret = close_ctree(root);
	if (ret) {
		printk("close ctree returns %d\n", ret);
C
Chris Mason 已提交
65
	}
66
	btrfs_sysfs_del_super(fs);
C
Chris Mason 已提交
67
	sb->s_fs_info = NULL;
C
Chris Mason 已提交
68 69
}

70
enum {
71
	Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
72
	Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
C
Chris Mason 已提交
73
	Opt_ssd, Opt_thread_pool, Opt_noacl,  Opt_compress, Opt_err,
74 75 76
};

static match_table_t tokens = {
77
	{Opt_degraded, "degraded"},
78
	{Opt_subvol, "subvol=%s"},
79
	{Opt_device, "device=%s"},
80
	{Opt_nodatasum, "nodatasum"},
81
	{Opt_nodatacow, "nodatacow"},
82
	{Opt_nobarrier, "nobarrier"},
83
	{Opt_max_extent, "max_extent=%s"},
84
	{Opt_max_inline, "max_inline=%s"},
85
	{Opt_alloc_start, "alloc_start=%s"},
86
	{Opt_thread_pool, "thread_pool=%d"},
C
Chris Mason 已提交
87
	{Opt_compress, "compress"},
88
	{Opt_ssd, "ssd"},
J
Josef Bacik 已提交
89 90
	{Opt_noacl, "noacl"},
	{Opt_err, NULL},
91 92
};

93
u64 btrfs_parse_size(char *str)
94
{
95
	u64 res;
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
	int mult = 1;
	char *end;
	char last;

	res = simple_strtoul(str, &end, 10);

	last = end[0];
	if (isalpha(last)) {
		last = tolower(last);
		switch (last) {
		case 'g':
			mult *= 1024;
		case 'm':
			mult *= 1024;
		case 'k':
			mult *= 1024;
		}
		res = res * mult;
	}
	return res;
}

118 119 120 121 122
/*
 * Regular mount options parser.  Everything that is needed only when
 * reading in a new superblock is parsed here.
 */
int btrfs_parse_options(struct btrfs_root *root, char *options)
123
{
124
	struct btrfs_fs_info *info = root->fs_info;
125
	substring_t args[MAX_OPT_ARGS];
126
	char *p, *num;
127
	int intarg;
128

129
	if (!options)
130
		return 0;
131

132 133 134 135 136 137 138 139 140
	/*
	 * strsep changes the string, duplicate it because parse_options
	 * gets called twice
	 */
	options = kstrdup(options, GFP_NOFS);
	if (!options)
		return -ENOMEM;


141
	while ((p = strsep(&options, ",")) != NULL) {
142 143 144 145 146 147
		int token;
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
148
		case Opt_degraded:
149 150
			printk(KERN_INFO "btrfs: allowing degraded mounts\n");
			btrfs_set_opt(info->mount_opt, DEGRADED);
151
			break;
152
		case Opt_subvol:
153
		case Opt_device:
154
			/*
155
			 * These are parsed by btrfs_parse_early_options
156 157
			 * and can be happily ignored here.
			 */
158 159
			break;
		case Opt_nodatasum:
160 161
			printk(KERN_INFO "btrfs: setting nodatacsum\n");
			btrfs_set_opt(info->mount_opt, NODATASUM);
162 163
			break;
		case Opt_nodatacow:
164 165 166
			printk(KERN_INFO "btrfs: setting nodatacow\n");
			btrfs_set_opt(info->mount_opt, NODATACOW);
			btrfs_set_opt(info->mount_opt, NODATASUM);
167
			break;
C
Chris Mason 已提交
168 169 170 171
		case Opt_compress:
			printk(KERN_INFO "btrfs: use compression\n");
			btrfs_set_opt(info->mount_opt, COMPRESS);
			break;
172
		case Opt_ssd:
173 174
			printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
			btrfs_set_opt(info->mount_opt, SSD);
175
			break;
176
		case Opt_nobarrier:
177 178
			printk(KERN_INFO "btrfs: turning off barriers\n");
			btrfs_set_opt(info->mount_opt, NOBARRIER);
179
			break;
180 181 182 183 184 185 186 187 188
		case Opt_thread_pool:
			intarg = 0;
			match_int(&args[0], &intarg);
			if (intarg) {
				info->thread_pool_size = intarg;
				printk(KERN_INFO "btrfs: thread pool %d\n",
				       info->thread_pool_size);
			}
			break;
189
		case Opt_max_extent:
190 191 192 193 194 195 196 197 198
			num = match_strdup(&args[0]);
			if (num) {
				info->max_extent = btrfs_parse_size(num);
				kfree(num);

				info->max_extent = max_t(u64,
					info->max_extent, root->sectorsize);
				printk(KERN_INFO "btrfs: max_extent at %llu\n",
				       info->max_extent);
199 200
			}
			break;
201
		case Opt_max_inline:
202 203 204 205 206
			num = match_strdup(&args[0]);
			if (num) {
				info->max_inline = btrfs_parse_size(num);
				kfree(num);

C
Chris Mason 已提交
207 208 209 210 211
				if (info->max_inline) {
					info->max_inline = max_t(u64,
						info->max_inline,
						root->sectorsize);
				}
212 213
				printk(KERN_INFO "btrfs: max_inline at %llu\n",
					info->max_inline);
214 215
			}
			break;
216
		case Opt_alloc_start:
217 218 219 220 221 222 223
			num = match_strdup(&args[0]);
			if (num) {
				info->alloc_start = btrfs_parse_size(num);
				kfree(num);
				printk(KERN_INFO
					"btrfs: allocations start at %llu\n",
					info->alloc_start);
224 225
			}
			break;
J
Josef Bacik 已提交
226 227 228
		case Opt_noacl:
			root->fs_info->sb->s_flags &= ~MS_POSIXACL;
			break;
229
		default:
230
			break;
231 232
		}
	}
233
	kfree(options);
234 235 236 237 238 239 240 241 242
	return 0;
}

/*
 * Parse mount options that are required early in the mount process.
 *
 * All other options will be parsed on much later in the mount process and
 * only when we need to allocate a new super block.
 */
243 244 245
static int btrfs_parse_early_options(const char *options, int flags,
		void *holder, char **subvol_name,
		struct btrfs_fs_devices **fs_devices)
246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
{
	substring_t args[MAX_OPT_ARGS];
	char *opts, *p;
	int error = 0;

	if (!options)
		goto out;

	/*
	 * strsep changes the string, duplicate it because parse_options
	 * gets called twice
	 */
	opts = kstrdup(options, GFP_KERNEL);
	if (!opts)
		return -ENOMEM;

	while ((p = strsep(&opts, ",")) != NULL) {
		int token;
		if (!*p)
			continue;

		token = match_token(p, tokens, args);
		switch (token) {
		case Opt_subvol:
			*subvol_name = match_strdup(&args[0]);
			break;
272 273 274 275 276 277
		case Opt_device:
			error = btrfs_scan_one_device(match_strdup(&args[0]),
					flags, holder, fs_devices);
			if (error)
				goto out_free_opts;
			break;
278 279 280 281 282
		default:
			break;
		}
	}

283
 out_free_opts:
284 285 286 287 288 289 290 291 292 293 294 295 296
	kfree(opts);
 out:
	/*
	 * If no subvolume name is specified we use the default one.  Allocate
	 * a copy of the string "default" here so that code later in the
	 * mount path doesn't care if it's the default volume or another one.
	 */
	if (!*subvol_name) {
		*subvol_name = kstrdup("default", GFP_KERNEL);
		if (!*subvol_name)
			return -ENOMEM;
	}
	return error;
297 298
}

299 300 301
static int btrfs_fill_super(struct super_block * sb,
			    struct btrfs_fs_devices *fs_devices,
			    void * data, int silent)
C
Chris Mason 已提交
302
{
C
Chris Mason 已提交
303 304 305 306 307 308
	struct inode * inode;
	struct dentry * root_dentry;
	struct btrfs_super_block *disk_super;
	struct btrfs_root *tree_root;
	struct btrfs_inode *bi;
	int err;
309

C
Chris Mason 已提交
310 311 312
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_magic = BTRFS_SUPER_MAGIC;
	sb->s_op = &btrfs_super_ops;
B
Balaji Rao 已提交
313
	sb->s_export_op = &btrfs_export_ops;
J
Josef Bacik 已提交
314
	sb->s_xattr = btrfs_xattr_handlers;
C
Chris Mason 已提交
315
	sb->s_time_gran = 1;
J
Josef Bacik 已提交
316
	sb->s_flags |= MS_POSIXACL;
317

318
	tree_root = open_ctree(sb, fs_devices, (char *)data);
319

320
	if (IS_ERR(tree_root)) {
C
Chris Mason 已提交
321
		printk("btrfs: open_ctree failed\n");
322
		return PTR_ERR(tree_root);
323
	}
C
Chris Mason 已提交
324
	sb->s_fs_info = tree_root;
325
	disk_super = &tree_root->fs_info->super_copy;
C
Chris Mason 已提交
326 327 328 329 330 331
	inode = btrfs_iget_locked(sb, btrfs_super_root_dir(disk_super),
				  tree_root);
	bi = BTRFS_I(inode);
	bi->location.objectid = inode->i_ino;
	bi->location.offset = 0;
	bi->root = tree_root;
332

C
Chris Mason 已提交
333
	btrfs_set_key_type(&bi->location, BTRFS_INODE_ITEM_KEY);
334

C
Chris Mason 已提交
335
	if (!inode) {
336
		err = -ENOMEM;
C
Chris Mason 已提交
337
		goto fail_close;
C
Chris Mason 已提交
338
	}
C
Chris Mason 已提交
339 340 341
	if (inode->i_state & I_NEW) {
		btrfs_read_locked_inode(inode);
		unlock_new_inode(inode);
C
Chris Mason 已提交
342 343
	}

C
Chris Mason 已提交
344 345 346 347 348
	root_dentry = d_alloc_root(inode);
	if (!root_dentry) {
		iput(inode);
		err = -ENOMEM;
		goto fail_close;
C
Chris Mason 已提交
349
	}
350 351 352 353 354 355

	/* this does the super kobj at the same time */
	err = btrfs_sysfs_add_super(tree_root->fs_info);
	if (err)
		goto fail_close;

C
Chris Mason 已提交
356
	sb->s_root = root_dentry;
C
Chris Mason 已提交
357 358

	save_mount_options(sb, data);
C
Chris Mason 已提交
359
	return 0;
C
Chris Mason 已提交
360 361 362 363

fail_close:
	close_ctree(tree_root);
	return err;
C
Chris Mason 已提交
364 365
}

S
Sage Weil 已提交
366
int btrfs_sync_fs(struct super_block *sb, int wait)
C
Chris Mason 已提交
367 368
{
	struct btrfs_trans_handle *trans;
C
Chris Mason 已提交
369
	struct btrfs_root *root;
C
Chris Mason 已提交
370
	int ret;
C
Chris Mason 已提交
371
	root = btrfs_sb(sb);
C
Chris Mason 已提交
372

Y
Yan Zheng 已提交
373 374 375
	if (sb->s_flags & MS_RDONLY)
		return 0;

C
Chris Mason 已提交
376 377 378 379 380
	sb->s_dirt = 0;
	if (!wait) {
		filemap_flush(root->fs_info->btree_inode->i_mapping);
		return 0;
	}
381 382 383 384

	btrfs_start_delalloc_inodes(root);
	btrfs_wait_ordered_extents(root, 0);

385
	btrfs_clean_old_snapshots(root);
C
Chris Mason 已提交
386 387
	trans = btrfs_start_transaction(root, 1);
	ret = btrfs_commit_transaction(trans, root);
C
Chris Mason 已提交
388
	sb->s_dirt = 0;
389
	return ret;
C
Chris Mason 已提交
390 391
}

C
Chris Mason 已提交
392
static void btrfs_write_super(struct super_block *sb)
C
Chris Mason 已提交
393
{
C
Chris Mason 已提交
394
	sb->s_dirt = 0;
C
Chris Mason 已提交
395 396
}

397
static int btrfs_test_super(struct super_block *s, void *data)
Y
Yan 已提交
398
{
399 400
	struct btrfs_fs_devices *test_fs_devices = data;
	struct btrfs_root *root = btrfs_sb(s);
Y
Yan 已提交
401

402
	return root->fs_info->fs_devices == test_fs_devices;
Y
Yan 已提交
403 404
}

405 406 407 408 409 410 411 412
/*
 * Find a superblock for the given device / mount point.
 *
 * Note:  This is based on get_sb_bdev from fs/super.c with a few additions
 *	  for multiple device setup.  Make sure to keep it in sync.
 */
static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
		const char *dev_name, void *data, struct vfsmount *mnt)
Y
Yan 已提交
413
{
414
	char *subvol_name = NULL;
Y
Yan 已提交
415 416 417
	struct block_device *bdev = NULL;
	struct super_block *s;
	struct dentry *root;
418
	struct btrfs_fs_devices *fs_devices = NULL;
Y
Yan 已提交
419 420
	int error = 0;

421 422
	error = btrfs_parse_early_options(data, flags, fs_type,
					  &subvol_name, &fs_devices);
423 424 425
	if (error)
		goto error;

426 427
	error = btrfs_scan_one_device(dev_name, flags, fs_type, &fs_devices);
	if (error)
428
		goto error_free_subvol_name;
Y
Yan 已提交
429

430 431
	error = btrfs_open_devices(fs_devices, flags, fs_type);
	if (error)
432
		goto error_free_subvol_name;
433

434
	bdev = fs_devices->latest_bdev;
435
	s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
Y
Yan 已提交
436 437 438 439 440 441 442 443
	if (IS_ERR(s))
		goto error_s;

	if (s->s_root) {
		if ((flags ^ s->s_flags) & MS_RDONLY) {
			up_write(&s->s_umount);
			deactivate_super(s);
			error = -EBUSY;
Y
Yan Zheng 已提交
444
			goto error_close_devices;
Y
Yan 已提交
445 446 447 448 449 450 451
		}

	} else {
		char b[BDEVNAME_SIZE];

		s->s_flags = flags;
		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
452 453
		error = btrfs_fill_super(s, fs_devices, data,
					 flags & MS_SILENT ? 1 : 0);
Y
Yan 已提交
454 455 456 457 458 459
		if (error) {
			up_write(&s->s_umount);
			deactivate_super(s);
			goto error;
		}

460
		btrfs_sb(s)->fs_info->bdev_holder = fs_type;
Y
Yan 已提交
461 462 463
		s->s_flags |= MS_ACTIVE;
	}

464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482
	if (!strcmp(subvol_name, "."))
		root = dget(s->s_root);
	else {
		mutex_lock(&s->s_root->d_inode->i_mutex);
		root = lookup_one_len(subvol_name, s->s_root, strlen(subvol_name));
		mutex_unlock(&s->s_root->d_inode->i_mutex);
		if (IS_ERR(root)) {
			up_write(&s->s_umount);
			deactivate_super(s);
			error = PTR_ERR(root);
			goto error;
		}
		if (!root->d_inode) {
			dput(root);
			up_write(&s->s_umount);
			deactivate_super(s);
			error = -ENXIO;
			goto error;
		}
Y
Yan 已提交
483 484 485 486
	}

	mnt->mnt_sb = s;
	mnt->mnt_root = root;
487 488

	kfree(subvol_name);
Y
Yan 已提交
489 490 491 492
	return 0;

error_s:
	error = PTR_ERR(s);
Y
Yan Zheng 已提交
493
error_close_devices:
494
	btrfs_close_devices(fs_devices);
495 496
error_free_subvol_name:
	kfree(subvol_name);
Y
Yan 已提交
497 498 499
error:
	return error;
}
500

Y
Yan Zheng 已提交
501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529
static int btrfs_remount(struct super_block *sb, int *flags, char *data)
{
	struct btrfs_root *root = btrfs_sb(sb);
	int ret;

	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
		return 0;

	if (*flags & MS_RDONLY) {
		sb->s_flags |= MS_RDONLY;

		ret =  btrfs_commit_super(root);
		WARN_ON(ret);
	} else {
		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
			return -EINVAL;

		ret = btrfs_cleanup_reloc_trees(root);
		WARN_ON(ret);

		ret = btrfs_cleanup_fs_roots(root->fs_info);
		WARN_ON(ret);

		sb->s_flags &= ~MS_RDONLY;
	}

	return 0;
}

C
Chris Mason 已提交
530 531 532
static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct btrfs_root *root = btrfs_sb(dentry->d_sb);
533
	struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
534
	int bits = dentry->d_sb->s_blocksize_bits;
535
	__be32 *fsid = (__be32 *)root->fs_info->fsid;
C
Chris Mason 已提交
536 537

	buf->f_namelen = BTRFS_NAME_LEN;
538 539 540
	buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
	buf->f_bfree = buf->f_blocks -
		(btrfs_super_bytes_used(disk_super) >> bits);
C
Chris Mason 已提交
541 542 543
	buf->f_bavail = buf->f_bfree;
	buf->f_bsize = dentry->d_sb->s_blocksize;
	buf->f_type = BTRFS_SUPER_MAGIC;
544 545 546 547 548
	/* We treat it as constant endianness (it doesn't matter _which_)
	   because we want the fsid to come out the same whether mounted 
	   on a big-endian or little-endian host */
	buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]);
	buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]);
549 550 551 552
	/* Mask in the root object ID too, to disambiguate subvols */
	buf->f_fsid.val[0] ^= BTRFS_I(dentry->d_inode)->root->objectid >> 32;
	buf->f_fsid.val[1] ^= BTRFS_I(dentry->d_inode)->root->objectid;

C
Chris Mason 已提交
553 554
	return 0;
}
C
Chris Mason 已提交
555

556 557 558 559
static struct file_system_type btrfs_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "btrfs",
	.get_sb		= btrfs_get_sb,
560
	.kill_sb	= kill_anon_super,
561 562
	.fs_flags	= FS_REQUIRES_DEV,
};
563

C
Chris Mason 已提交
564 565 566
/*
 * used by btrfsctl to scan devices when no FS is mounted
 */
567 568 569 570 571
static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
				unsigned long arg)
{
	struct btrfs_ioctl_vol_args *vol;
	struct btrfs_fs_devices *fs_devices;
L
Linda Knippers 已提交
572
	int ret = 0;
573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588
	int len;

	vol = kmalloc(sizeof(*vol), GFP_KERNEL);
	if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) {
		ret = -EFAULT;
		goto out;
	}
	len = strnlen(vol->name, BTRFS_PATH_NAME_MAX);
	switch (cmd) {
	case BTRFS_IOC_SCAN_DEV:
		ret = btrfs_scan_one_device(vol->name, MS_RDONLY,
					    &btrfs_fs_type, &fs_devices);
		break;
	}
out:
	kfree(vol);
L
Linda Knippers 已提交
589
	return ret;
590 591
}

Y
Yan 已提交
592 593 594
static void btrfs_write_super_lockfs(struct super_block *sb)
{
	struct btrfs_root *root = btrfs_sb(sb);
595 596
	mutex_lock(&root->fs_info->transaction_kthread_mutex);
	mutex_lock(&root->fs_info->cleaner_mutex);
Y
Yan 已提交
597 598 599 600 601
}

static void btrfs_unlockfs(struct super_block *sb)
{
	struct btrfs_root *root = btrfs_sb(sb);
602 603
	mutex_unlock(&root->fs_info->cleaner_mutex);
	mutex_unlock(&root->fs_info->transaction_kthread_mutex);
Y
Yan 已提交
604
}
605

C
Chris Mason 已提交
606
static struct super_operations btrfs_super_ops = {
C
Chris Mason 已提交
607
	.delete_inode	= btrfs_delete_inode,
C
Chris Mason 已提交
608
	.put_super	= btrfs_put_super,
609 610
	.write_super	= btrfs_write_super,
	.sync_fs	= btrfs_sync_fs,
C
Chris Mason 已提交
611
	.show_options	= generic_show_options,
C
Chris Mason 已提交
612
	.write_inode	= btrfs_write_inode,
C
Chris Mason 已提交
613
	.dirty_inode	= btrfs_dirty_inode,
C
Chris Mason 已提交
614 615
	.alloc_inode	= btrfs_alloc_inode,
	.destroy_inode	= btrfs_destroy_inode,
C
Chris Mason 已提交
616
	.statfs		= btrfs_statfs,
Y
Yan Zheng 已提交
617
	.remount_fs	= btrfs_remount,
Y
Yan 已提交
618 619
	.write_super_lockfs = btrfs_write_super_lockfs,
	.unlockfs	= btrfs_unlockfs,
C
Chris Mason 已提交
620
};
621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644

static const struct file_operations btrfs_ctl_fops = {
	.unlocked_ioctl	 = btrfs_control_ioctl,
	.compat_ioctl = btrfs_control_ioctl,
	.owner	 = THIS_MODULE,
};

static struct miscdevice btrfs_misc = {
	.minor		= MISC_DYNAMIC_MINOR,
	.name		= "btrfs-control",
	.fops		= &btrfs_ctl_fops
};

static int btrfs_interface_init(void)
{
	return misc_register(&btrfs_misc);
}

void btrfs_interface_exit(void)
{
	if (misc_deregister(&btrfs_misc) < 0)
		printk("misc_deregister failed for control device");
}

645 646
static int __init init_btrfs_fs(void)
{
C
Chris Mason 已提交
647
	int err;
648 649 650 651 652

	err = btrfs_init_sysfs();
	if (err)
		return err;

C
Chris Mason 已提交
653
	err = btrfs_init_cachep();
C
Chris Mason 已提交
654
	if (err)
655
		goto free_sysfs;
656 657

	err = extent_io_init();
658 659 660
	if (err)
		goto free_cachep;

661 662 663 664
	err = extent_map_init();
	if (err)
		goto free_extent_io;

665
	err = btrfs_interface_init();
666 667
	if (err)
		goto free_extent_map;
C
Chris Mason 已提交
668

669 670 671
	err = register_filesystem(&btrfs_fs_type);
	if (err)
		goto unregister_ioctl;
672 673

	printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION);
674 675
	return 0;

676 677
unregister_ioctl:
	btrfs_interface_exit();
678 679
free_extent_map:
	extent_map_exit();
680 681
free_extent_io:
	extent_io_exit();
682 683
free_cachep:
	btrfs_destroy_cachep();
684
free_sysfs:
685 686
	btrfs_exit_sysfs();
	return err;
687 688 689 690
}

static void __exit exit_btrfs_fs(void)
{
C
Chris Mason 已提交
691
	btrfs_destroy_cachep();
692
	extent_map_exit();
693
	extent_io_exit();
694
	btrfs_interface_exit();
695
	unregister_filesystem(&btrfs_fs_type);
696
	btrfs_exit_sysfs();
697
	btrfs_cleanup_fs_uuids();
C
Chris Mason 已提交
698
	btrfs_zlib_exit();
699 700 701 702 703 704
}

module_init(init_btrfs_fs)
module_exit(exit_btrfs_fs)

MODULE_LICENSE("GPL");