super.c 18.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
#include <linux/fs.h>
#include <linux/pagemap.h>
#include <linux/highmem.h>
#include <linux/time.h>
#include <linux/init.h>
E
Eric Paris 已提交
27
#include <linux/seq_file.h>
28 29 30
#include <linux/string.h>
#include <linux/smp_lock.h>
#include <linux/backing-dev.h>
Y
Yan 已提交
31
#include <linux/mount.h>
C
Chris Mason 已提交
32
#include <linux/mpage.h>
C
Chris Mason 已提交
33 34
#include <linux/swap.h>
#include <linux/writeback.h>
C
Chris Mason 已提交
35
#include <linux/statfs.h>
C
Chris Mason 已提交
36
#include <linux/compat.h>
37
#include <linux/parser.h>
38
#include <linux/ctype.h>
39
#include <linux/namei.h>
40
#include <linux/miscdevice.h>
41
#include <linux/magic.h>
C
Chris Mason 已提交
42
#include "compat.h"
43
#include "ctree.h"
C
Chris Mason 已提交
44
#include "disk-io.h"
45
#include "transaction.h"
C
Chris Mason 已提交
46
#include "btrfs_inode.h"
C
Chris Mason 已提交
47
#include "ioctl.h"
C
Chris Mason 已提交
48
#include "print-tree.h"
J
Josef Bacik 已提交
49
#include "xattr.h"
50
#include "volumes.h"
51
#include "version.h"
B
Balaji Rao 已提交
52
#include "export.h"
C
Chris Mason 已提交
53
#include "compression.h"
54

C
Chris Mason 已提交
55

C
Chris Mason 已提交
56
static struct super_operations btrfs_super_ops;
C
Chris Mason 已提交
57

C
Chris Mason 已提交
58
static void btrfs_put_super(struct super_block *sb)
C
Chris Mason 已提交
59
{
C
Chris Mason 已提交
60
	struct btrfs_root *root = btrfs_sb(sb);
C
Chris Mason 已提交
61 62
	int ret;

C
Chris Mason 已提交
63 64
	ret = close_ctree(root);
	sb->s_fs_info = NULL;
C
Chris Mason 已提交
65 66
}

67
enum {
68
	Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
69
	Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
S
Sage Weil 已提交
70
	Opt_ssd, Opt_thread_pool, Opt_noacl,  Opt_compress, Opt_notreelog,
71
	Opt_flushoncommit, Opt_err,
72 73 74
};

static match_table_t tokens = {
75
	{Opt_degraded, "degraded"},
76
	{Opt_subvol, "subvol=%s"},
77
	{Opt_device, "device=%s"},
78
	{Opt_nodatasum, "nodatasum"},
79
	{Opt_nodatacow, "nodatacow"},
80
	{Opt_nobarrier, "nobarrier"},
81
	{Opt_max_extent, "max_extent=%s"},
82
	{Opt_max_inline, "max_inline=%s"},
83
	{Opt_alloc_start, "alloc_start=%s"},
84
	{Opt_thread_pool, "thread_pool=%d"},
C
Chris Mason 已提交
85
	{Opt_compress, "compress"},
86
	{Opt_ssd, "ssd"},
J
Josef Bacik 已提交
87
	{Opt_noacl, "noacl"},
S
Sage Weil 已提交
88
	{Opt_notreelog, "notreelog"},
89
	{Opt_flushoncommit, "flushoncommit"},
J
Josef Bacik 已提交
90
	{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;
S
Sage Weil 已提交
229 230 231 232
		case Opt_notreelog:
			printk(KERN_INFO "btrfs: disabling tree log\n");
			btrfs_set_opt(info->mount_opt, NOTREELOG);
			break;
233 234 235 236
		case Opt_flushoncommit:
			printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
			btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
			break;
237
		default:
238
			break;
239 240
		}
	}
241
	kfree(options);
242 243 244 245 246 247 248 249 250
	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.
 */
251
static int btrfs_parse_early_options(const char *options, fmode_t flags,
252 253
		void *holder, char **subvol_name,
		struct btrfs_fs_devices **fs_devices)
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
{
	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;
280 281 282 283 284 285
		case Opt_device:
			error = btrfs_scan_one_device(match_strdup(&args[0]),
					flags, holder, fs_devices);
			if (error)
				goto out_free_opts;
			break;
286 287 288 289 290
		default:
			break;
		}
	}

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

C
Chris Mason 已提交
307
static int btrfs_fill_super(struct super_block *sb,
308
			    struct btrfs_fs_devices *fs_devices,
C
Chris Mason 已提交
309
			    void *data, int silent)
C
Chris Mason 已提交
310
{
C
Chris Mason 已提交
311 312
	struct inode *inode;
	struct dentry *root_dentry;
C
Chris Mason 已提交
313 314 315 316
	struct btrfs_super_block *disk_super;
	struct btrfs_root *tree_root;
	struct btrfs_inode *bi;
	int err;
317

C
Chris Mason 已提交
318 319 320
	sb->s_maxbytes = MAX_LFS_FILESIZE;
	sb->s_magic = BTRFS_SUPER_MAGIC;
	sb->s_op = &btrfs_super_ops;
B
Balaji Rao 已提交
321
	sb->s_export_op = &btrfs_export_ops;
J
Josef Bacik 已提交
322
	sb->s_xattr = btrfs_xattr_handlers;
C
Chris Mason 已提交
323
	sb->s_time_gran = 1;
J
Josef Bacik 已提交
324
	sb->s_flags |= MS_POSIXACL;
325

326
	tree_root = open_ctree(sb, fs_devices, (char *)data);
327

328
	if (IS_ERR(tree_root)) {
C
Chris Mason 已提交
329
		printk("btrfs: open_ctree failed\n");
330
		return PTR_ERR(tree_root);
331
	}
C
Chris Mason 已提交
332
	sb->s_fs_info = tree_root;
333
	disk_super = &tree_root->fs_info->super_copy;
334 335
	inode = btrfs_iget_locked(sb, BTRFS_FIRST_FREE_OBJECTID,
				  tree_root->fs_info->fs_root);
C
Chris Mason 已提交
336 337 338
	bi = BTRFS_I(inode);
	bi->location.objectid = inode->i_ino;
	bi->location.offset = 0;
339
	bi->root = tree_root->fs_info->fs_root;
340

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

C
Chris Mason 已提交
343
	if (!inode) {
344
		err = -ENOMEM;
C
Chris Mason 已提交
345
		goto fail_close;
C
Chris Mason 已提交
346
	}
C
Chris Mason 已提交
347 348 349
	if (inode->i_state & I_NEW) {
		btrfs_read_locked_inode(inode);
		unlock_new_inode(inode);
C
Chris Mason 已提交
350 351
	}

C
Chris Mason 已提交
352 353 354 355 356
	root_dentry = d_alloc_root(inode);
	if (!root_dentry) {
		iput(inode);
		err = -ENOMEM;
		goto fail_close;
C
Chris Mason 已提交
357
	}
Y
Yan Zheng 已提交
358
#if 0
359 360 361 362
	/* this does the super kobj at the same time */
	err = btrfs_sysfs_add_super(tree_root->fs_info);
	if (err)
		goto fail_close;
Y
Yan Zheng 已提交
363
#endif
364

C
Chris Mason 已提交
365
	sb->s_root = root_dentry;
C
Chris Mason 已提交
366 367

	save_mount_options(sb, data);
C
Chris Mason 已提交
368
	return 0;
C
Chris Mason 已提交
369 370 371 372

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

S
Sage Weil 已提交
375
int btrfs_sync_fs(struct super_block *sb, int wait)
C
Chris Mason 已提交
376 377
{
	struct btrfs_trans_handle *trans;
378
	struct btrfs_root *root = btrfs_sb(sb);
C
Chris Mason 已提交
379
	int ret;
C
Chris Mason 已提交
380

Y
Yan Zheng 已提交
381 382 383
	if (sb->s_flags & MS_RDONLY)
		return 0;

C
Chris Mason 已提交
384 385 386 387 388
	sb->s_dirt = 0;
	if (!wait) {
		filemap_flush(root->fs_info->btree_inode->i_mapping);
		return 0;
	}
389 390 391 392

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

C
Chris Mason 已提交
393 394
	trans = btrfs_start_transaction(root, 1);
	ret = btrfs_commit_transaction(trans, root);
C
Chris Mason 已提交
395
	sb->s_dirt = 0;
396
	return ret;
C
Chris Mason 已提交
397 398
}

E
Eric Paris 已提交
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424
static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
	struct btrfs_root *root = btrfs_sb(vfs->mnt_sb);
	struct btrfs_fs_info *info = root->fs_info;

	if (btrfs_test_opt(root, DEGRADED))
		seq_puts(seq, ",degraded");
	if (btrfs_test_opt(root, NODATASUM))
		seq_puts(seq, ",nodatasum");
	if (btrfs_test_opt(root, NODATACOW))
		seq_puts(seq, ",nodatacow");
	if (btrfs_test_opt(root, NOBARRIER))
		seq_puts(seq, ",nobarrier");
	if (info->max_extent != (u64)-1)
		seq_printf(seq, ",max_extent=%llu", info->max_extent);
	if (info->max_inline != 8192 * 1024)
		seq_printf(seq, ",max_inline=%llu", info->max_inline);
	if (info->alloc_start != 0)
		seq_printf(seq, ",alloc_start=%llu", info->alloc_start);
	if (info->thread_pool_size !=  min_t(unsigned long,
					     num_online_cpus() + 2, 8))
		seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
	if (btrfs_test_opt(root, COMPRESS))
		seq_puts(seq, ",compress");
	if (btrfs_test_opt(root, SSD))
		seq_puts(seq, ",ssd");
S
Sage Weil 已提交
425
	if (btrfs_test_opt(root, NOTREELOG))
426 427 428
		seq_puts(seq, ",no-treelog");
	if (btrfs_test_opt(root, FLUSHONCOMMIT))
		seq_puts(seq, ",flush-on-commit");
E
Eric Paris 已提交
429 430 431 432 433
	if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
		seq_puts(seq, ",noacl");
	return 0;
}

C
Chris Mason 已提交
434
static void btrfs_write_super(struct super_block *sb)
C
Chris Mason 已提交
435
{
C
Chris Mason 已提交
436
	sb->s_dirt = 0;
C
Chris Mason 已提交
437 438
}

439
static int btrfs_test_super(struct super_block *s, void *data)
Y
Yan 已提交
440
{
441 442
	struct btrfs_fs_devices *test_fs_devices = data;
	struct btrfs_root *root = btrfs_sb(s);
Y
Yan 已提交
443

444
	return root->fs_info->fs_devices == test_fs_devices;
Y
Yan 已提交
445 446
}

447 448 449 450 451 452 453 454
/*
 * 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 已提交
455
{
456
	char *subvol_name = NULL;
Y
Yan 已提交
457 458 459
	struct block_device *bdev = NULL;
	struct super_block *s;
	struct dentry *root;
460
	struct btrfs_fs_devices *fs_devices = NULL;
461
	fmode_t mode = FMODE_READ;
Y
Yan 已提交
462 463
	int error = 0;

464 465 466 467
	if (!(flags & MS_RDONLY))
		mode |= FMODE_WRITE;

	error = btrfs_parse_early_options(data, mode, fs_type,
468
					  &subvol_name, &fs_devices);
469
	if (error)
470
		return error;
471

472
	error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
473
	if (error)
474
		goto error_free_subvol_name;
Y
Yan 已提交
475

476
	error = btrfs_open_devices(fs_devices, mode, fs_type);
477
	if (error)
478
		goto error_free_subvol_name;
479

Y
Yan Zheng 已提交
480 481 482 483 484
	if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
		error = -EACCES;
		goto error_close_devices;
	}

485
	bdev = fs_devices->latest_bdev;
486
	s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
Y
Yan 已提交
487 488 489 490 491 492 493 494
	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 已提交
495
			goto error_close_devices;
Y
Yan 已提交
496 497
		}

Y
Yan Zheng 已提交
498
		btrfs_close_devices(fs_devices);
Y
Yan 已提交
499 500 501 502 503
	} else {
		char b[BDEVNAME_SIZE];

		s->s_flags = flags;
		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
504 505
		error = btrfs_fill_super(s, fs_devices, data,
					 flags & MS_SILENT ? 1 : 0);
Y
Yan 已提交
506 507 508
		if (error) {
			up_write(&s->s_umount);
			deactivate_super(s);
509
			goto error_free_subvol_name;
Y
Yan 已提交
510 511
		}

512
		btrfs_sb(s)->fs_info->bdev_holder = fs_type;
Y
Yan 已提交
513 514 515
		s->s_flags |= MS_ACTIVE;
	}

516 517 518 519
	if (!strcmp(subvol_name, "."))
		root = dget(s->s_root);
	else {
		mutex_lock(&s->s_root->d_inode->i_mutex);
C
Chris Mason 已提交
520 521
		root = lookup_one_len(subvol_name, s->s_root,
				      strlen(subvol_name));
522
		mutex_unlock(&s->s_root->d_inode->i_mutex);
C
Chris Mason 已提交
523

524 525 526 527
		if (IS_ERR(root)) {
			up_write(&s->s_umount);
			deactivate_super(s);
			error = PTR_ERR(root);
528
			goto error_free_subvol_name;
529 530 531 532 533 534
		}
		if (!root->d_inode) {
			dput(root);
			up_write(&s->s_umount);
			deactivate_super(s);
			error = -ENXIO;
535
			goto error_free_subvol_name;
536
		}
Y
Yan 已提交
537 538 539 540
	}

	mnt->mnt_sb = s;
	mnt->mnt_root = root;
541 542

	kfree(subvol_name);
Y
Yan 已提交
543 544 545 546
	return 0;

error_s:
	error = PTR_ERR(s);
Y
Yan Zheng 已提交
547
error_close_devices:
548
	btrfs_close_devices(fs_devices);
549 550
error_free_subvol_name:
	kfree(subvol_name);
Y
Yan 已提交
551 552
	return error;
}
553

Y
Yan Zheng 已提交
554 555 556 557 558
static int btrfs_remount(struct super_block *sb, int *flags, char *data)
{
	struct btrfs_root *root = btrfs_sb(sb);
	int ret;

559 560 561 562
	ret = btrfs_parse_options(root, data);
	if (ret)
		return -EINVAL;

Y
Yan Zheng 已提交
563 564 565 566 567 568 569 570 571
	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 {
Y
Yan Zheng 已提交
572 573 574
		if (root->fs_info->fs_devices->rw_devices == 0)
			return -EACCES;

Y
Yan Zheng 已提交
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589
		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 已提交
590 591 592
static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
{
	struct btrfs_root *root = btrfs_sb(dentry->d_sb);
593
	struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
594
	int bits = dentry->d_sb->s_blocksize_bits;
595
	__be32 *fsid = (__be32 *)root->fs_info->fsid;
C
Chris Mason 已提交
596 597

	buf->f_namelen = BTRFS_NAME_LEN;
598 599 600
	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 已提交
601 602 603
	buf->f_bavail = buf->f_bfree;
	buf->f_bsize = dentry->d_sb->s_blocksize;
	buf->f_type = BTRFS_SUPER_MAGIC;
C
Chris Mason 已提交
604

605
	/* We treat it as constant endianness (it doesn't matter _which_)
C
Chris Mason 已提交
606
	   because we want the fsid to come out the same whether mounted
607 608 609
	   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]);
610 611 612 613
	/* 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 已提交
614 615
	return 0;
}
C
Chris Mason 已提交
616

617 618 619 620
static struct file_system_type btrfs_fs_type = {
	.owner		= THIS_MODULE,
	.name		= "btrfs",
	.get_sb		= btrfs_get_sb,
621
	.kill_sb	= kill_anon_super,
622 623
	.fs_flags	= FS_REQUIRES_DEV,
};
624

C
Chris Mason 已提交
625 626 627
/*
 * used by btrfsctl to scan devices when no FS is mounted
 */
628 629 630 631 632
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;
633
	int ret = -ENOTTY;
634

635 636 637
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;

638
	vol = kmalloc(sizeof(*vol), GFP_KERNEL);
639 640 641
	if (!vol)
		return -ENOMEM;

642 643 644 645
	if (copy_from_user(vol, (void __user *)arg, sizeof(*vol))) {
		ret = -EFAULT;
		goto out;
	}
646

647 648
	switch (cmd) {
	case BTRFS_IOC_SCAN_DEV:
649
		ret = btrfs_scan_one_device(vol->name, FMODE_READ,
650 651 652 653 654
					    &btrfs_fs_type, &fs_devices);
		break;
	}
out:
	kfree(vol);
L
Linda Knippers 已提交
655
	return ret;
656 657
}

658
static int btrfs_freeze(struct super_block *sb)
Y
Yan 已提交
659 660
{
	struct btrfs_root *root = btrfs_sb(sb);
661 662
	mutex_lock(&root->fs_info->transaction_kthread_mutex);
	mutex_lock(&root->fs_info->cleaner_mutex);
663
	return 0;
Y
Yan 已提交
664 665
}

666
static int btrfs_unfreeze(struct super_block *sb)
Y
Yan 已提交
667 668
{
	struct btrfs_root *root = btrfs_sb(sb);
669 670
	mutex_unlock(&root->fs_info->cleaner_mutex);
	mutex_unlock(&root->fs_info->transaction_kthread_mutex);
671
	return 0;
Y
Yan 已提交
672
}
673

C
Chris Mason 已提交
674
static struct super_operations btrfs_super_ops = {
C
Chris Mason 已提交
675
	.delete_inode	= btrfs_delete_inode,
C
Chris Mason 已提交
676
	.put_super	= btrfs_put_super,
677 678
	.write_super	= btrfs_write_super,
	.sync_fs	= btrfs_sync_fs,
E
Eric Paris 已提交
679
	.show_options	= btrfs_show_options,
C
Chris Mason 已提交
680
	.write_inode	= btrfs_write_inode,
C
Chris Mason 已提交
681
	.dirty_inode	= btrfs_dirty_inode,
C
Chris Mason 已提交
682 683
	.alloc_inode	= btrfs_alloc_inode,
	.destroy_inode	= btrfs_destroy_inode,
C
Chris Mason 已提交
684
	.statfs		= btrfs_statfs,
Y
Yan Zheng 已提交
685
	.remount_fs	= btrfs_remount,
686 687
	.freeze_fs	= btrfs_freeze,
	.unfreeze_fs	= btrfs_unfreeze,
C
Chris Mason 已提交
688
};
689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706

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

707
static void btrfs_interface_exit(void)
708 709
{
	if (misc_deregister(&btrfs_misc) < 0)
C
Chris Mason 已提交
710
		printk(KERN_INFO "misc_deregister failed for control device");
711 712
}

713 714
static int __init init_btrfs_fs(void)
{
C
Chris Mason 已提交
715
	int err;
716 717 718 719 720

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

C
Chris Mason 已提交
721
	err = btrfs_init_cachep();
C
Chris Mason 已提交
722
	if (err)
723
		goto free_sysfs;
724 725

	err = extent_io_init();
726 727 728
	if (err)
		goto free_cachep;

729 730 731 732
	err = extent_map_init();
	if (err)
		goto free_extent_io;

733
	err = btrfs_interface_init();
734 735
	if (err)
		goto free_extent_map;
C
Chris Mason 已提交
736

737 738 739
	err = register_filesystem(&btrfs_fs_type);
	if (err)
		goto unregister_ioctl;
740 741

	printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION);
742 743
	return 0;

744 745
unregister_ioctl:
	btrfs_interface_exit();
746 747
free_extent_map:
	extent_map_exit();
748 749
free_extent_io:
	extent_io_exit();
750 751
free_cachep:
	btrfs_destroy_cachep();
752
free_sysfs:
753 754
	btrfs_exit_sysfs();
	return err;
755 756 757 758
}

static void __exit exit_btrfs_fs(void)
{
C
Chris Mason 已提交
759
	btrfs_destroy_cachep();
760
	extent_map_exit();
761
	extent_io_exit();
762
	btrfs_interface_exit();
763
	unregister_filesystem(&btrfs_fs_type);
764
	btrfs_exit_sysfs();
765
	btrfs_cleanup_fs_uuids();
C
Chris Mason 已提交
766
	btrfs_zlib_exit();
767 768 769 770 771 772
}

module_init(init_btrfs_fs)
module_exit(exit_btrfs_fs)

MODULE_LICENSE("GPL");