xref: /openbmc/linux/fs/btrfs/super.c (revision bd4d1088)
16cbd5570SChris Mason /*
26cbd5570SChris Mason  * Copyright (C) 2007 Oracle.  All rights reserved.
36cbd5570SChris Mason  *
46cbd5570SChris Mason  * This program is free software; you can redistribute it and/or
56cbd5570SChris Mason  * modify it under the terms of the GNU General Public
66cbd5570SChris Mason  * License v2 as published by the Free Software Foundation.
76cbd5570SChris Mason  *
86cbd5570SChris Mason  * This program is distributed in the hope that it will be useful,
96cbd5570SChris Mason  * but WITHOUT ANY WARRANTY; without even the implied warranty of
106cbd5570SChris Mason  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
116cbd5570SChris Mason  * General Public License for more details.
126cbd5570SChris Mason  *
136cbd5570SChris Mason  * You should have received a copy of the GNU General Public
146cbd5570SChris Mason  * License along with this program; if not, write to the
156cbd5570SChris Mason  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
166cbd5570SChris Mason  * Boston, MA 021110-1307, USA.
176cbd5570SChris Mason  */
186cbd5570SChris Mason 
194b82d6e4SYan #include <linux/blkdev.h>
202e635a27SChris Mason #include <linux/module.h>
21e20d96d6SChris Mason #include <linux/buffer_head.h>
222e635a27SChris Mason #include <linux/fs.h>
232e635a27SChris Mason #include <linux/pagemap.h>
242e635a27SChris Mason #include <linux/highmem.h>
252e635a27SChris Mason #include <linux/time.h>
262e635a27SChris Mason #include <linux/init.h>
27a9572a15SEric Paris #include <linux/seq_file.h>
282e635a27SChris Mason #include <linux/string.h>
292e635a27SChris Mason #include <linux/backing-dev.h>
304b82d6e4SYan #include <linux/mount.h>
31dee26a9fSChris Mason #include <linux/mpage.h>
3275dfe396SChris Mason #include <linux/swap.h>
3375dfe396SChris Mason #include <linux/writeback.h>
348fd17795SChris Mason #include <linux/statfs.h>
3508607c1bSChris Mason #include <linux/compat.h>
3695e05289SChris Mason #include <linux/parser.h>
37c59f8951SChris Mason #include <linux/ctype.h>
386da6abaeSChris Mason #include <linux/namei.h>
39a9218f6bSChris Mason #include <linux/miscdevice.h>
401bcbf313SQinghuang Feng #include <linux/magic.h>
414b4e25f2SChris Mason #include "compat.h"
422e635a27SChris Mason #include "ctree.h"
43e20d96d6SChris Mason #include "disk-io.h"
44d5719762SChris Mason #include "transaction.h"
452c90e5d6SChris Mason #include "btrfs_inode.h"
46c5739bbaSChris Mason #include "ioctl.h"
473a686375SChris Mason #include "print-tree.h"
485103e947SJosef Bacik #include "xattr.h"
498a4b83ccSChris Mason #include "volumes.h"
50b3c3da71SChris Mason #include "version.h"
51be6e8dc0SBalaji Rao #include "export.h"
52c8b97818SChris Mason #include "compression.h"
532e635a27SChris Mason 
54b87221deSAlexey Dobriyan static const struct super_operations btrfs_super_ops;
55e20d96d6SChris Mason 
56e20d96d6SChris Mason static void btrfs_put_super(struct super_block *sb)
57e20d96d6SChris Mason {
58e20d96d6SChris Mason 	struct btrfs_root *root = btrfs_sb(sb);
59e20d96d6SChris Mason 	int ret;
60e20d96d6SChris Mason 
61e20d96d6SChris Mason 	ret = close_ctree(root);
62e20d96d6SChris Mason 	sb->s_fs_info = NULL;
63e20d96d6SChris Mason }
642e635a27SChris Mason 
6595e05289SChris Mason enum {
6673f73415SJosef Bacik 	Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum,
6773f73415SJosef Bacik 	Opt_nodatacow, Opt_max_extent, Opt_max_inline, Opt_alloc_start,
6873f73415SJosef Bacik 	Opt_nobarrier, Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool,
6973f73415SJosef Bacik 	Opt_noacl, Opt_compress, Opt_compress_force, Opt_notreelog, Opt_ratio,
70a555f810SChris Mason 	Opt_flushoncommit,
71e244a0aeSChristoph Hellwig 	Opt_discard, Opt_err,
7295e05289SChris Mason };
7395e05289SChris Mason 
7495e05289SChris Mason static match_table_t tokens = {
75dfe25020SChris Mason 	{Opt_degraded, "degraded"},
7695e05289SChris Mason 	{Opt_subvol, "subvol=%s"},
7773f73415SJosef Bacik 	{Opt_subvolid, "subvolid=%d"},
7843e570b0SChristoph Hellwig 	{Opt_device, "device=%s"},
79b6cda9bcSChris Mason 	{Opt_nodatasum, "nodatasum"},
80be20aa9dSChris Mason 	{Opt_nodatacow, "nodatacow"},
8121ad10cfSChris Mason 	{Opt_nobarrier, "nobarrier"},
82c59f8951SChris Mason 	{Opt_max_extent, "max_extent=%s"},
836f568d35SChris Mason 	{Opt_max_inline, "max_inline=%s"},
848f662a76SChris Mason 	{Opt_alloc_start, "alloc_start=%s"},
854543df7eSChris Mason 	{Opt_thread_pool, "thread_pool=%d"},
86c8b97818SChris Mason 	{Opt_compress, "compress"},
87a555f810SChris Mason 	{Opt_compress_force, "compress-force"},
88e18e4809SChris Mason 	{Opt_ssd, "ssd"},
89451d7585SChris Mason 	{Opt_ssd_spread, "ssd_spread"},
903b30c22fSChris Mason 	{Opt_nossd, "nossd"},
9133268eafSJosef Bacik 	{Opt_noacl, "noacl"},
923a5e1404SSage Weil 	{Opt_notreelog, "notreelog"},
93dccae999SSage Weil 	{Opt_flushoncommit, "flushoncommit"},
9497e728d4SJosef Bacik 	{Opt_ratio, "metadata_ratio=%d"},
95e244a0aeSChristoph Hellwig 	{Opt_discard, "discard"},
9633268eafSJosef Bacik 	{Opt_err, NULL},
9795e05289SChris Mason };
9895e05289SChris Mason 
99edbd8d4eSChris Mason u64 btrfs_parse_size(char *str)
100c59f8951SChris Mason {
101edbd8d4eSChris Mason 	u64 res;
102c59f8951SChris Mason 	int mult = 1;
103c59f8951SChris Mason 	char *end;
104c59f8951SChris Mason 	char last;
105c59f8951SChris Mason 
106c59f8951SChris Mason 	res = simple_strtoul(str, &end, 10);
107c59f8951SChris Mason 
108c59f8951SChris Mason 	last = end[0];
109c59f8951SChris Mason 	if (isalpha(last)) {
110c59f8951SChris Mason 		last = tolower(last);
111c59f8951SChris Mason 		switch (last) {
112c59f8951SChris Mason 		case 'g':
113c59f8951SChris Mason 			mult *= 1024;
114c59f8951SChris Mason 		case 'm':
115c59f8951SChris Mason 			mult *= 1024;
116c59f8951SChris Mason 		case 'k':
117c59f8951SChris Mason 			mult *= 1024;
118c59f8951SChris Mason 		}
119c59f8951SChris Mason 		res = res * mult;
120c59f8951SChris Mason 	}
121c59f8951SChris Mason 	return res;
122c59f8951SChris Mason }
123c59f8951SChris Mason 
124edf24abeSChristoph Hellwig /*
125edf24abeSChristoph Hellwig  * Regular mount options parser.  Everything that is needed only when
126edf24abeSChristoph Hellwig  * reading in a new superblock is parsed here.
127edf24abeSChristoph Hellwig  */
128edf24abeSChristoph Hellwig int btrfs_parse_options(struct btrfs_root *root, char *options)
12995e05289SChris Mason {
130edf24abeSChristoph Hellwig 	struct btrfs_fs_info *info = root->fs_info;
13195e05289SChris Mason 	substring_t args[MAX_OPT_ARGS];
132da495eccSJosef Bacik 	char *p, *num, *orig;
1334543df7eSChris Mason 	int intarg;
134a7a3f7caSSage Weil 	int ret = 0;
135b6cda9bcSChris Mason 
13695e05289SChris Mason 	if (!options)
137edf24abeSChristoph Hellwig 		return 0;
13895e05289SChris Mason 
139be20aa9dSChris Mason 	/*
140be20aa9dSChris Mason 	 * strsep changes the string, duplicate it because parse_options
141be20aa9dSChris Mason 	 * gets called twice
142be20aa9dSChris Mason 	 */
143be20aa9dSChris Mason 	options = kstrdup(options, GFP_NOFS);
144be20aa9dSChris Mason 	if (!options)
145be20aa9dSChris Mason 		return -ENOMEM;
146be20aa9dSChris Mason 
147da495eccSJosef Bacik 	orig = options;
148be20aa9dSChris Mason 
14995e05289SChris Mason 	while ((p = strsep(&options, ",")) != NULL) {
15095e05289SChris Mason 		int token;
15195e05289SChris Mason 		if (!*p)
15295e05289SChris Mason 			continue;
15395e05289SChris Mason 
15495e05289SChris Mason 		token = match_token(p, tokens, args);
15595e05289SChris Mason 		switch (token) {
156dfe25020SChris Mason 		case Opt_degraded:
157edf24abeSChristoph Hellwig 			printk(KERN_INFO "btrfs: allowing degraded mounts\n");
158dfe25020SChris Mason 			btrfs_set_opt(info->mount_opt, DEGRADED);
159dfe25020SChris Mason 			break;
16095e05289SChris Mason 		case Opt_subvol:
16173f73415SJosef Bacik 		case Opt_subvolid:
16243e570b0SChristoph Hellwig 		case Opt_device:
163edf24abeSChristoph Hellwig 			/*
16443e570b0SChristoph Hellwig 			 * These are parsed by btrfs_parse_early_options
165edf24abeSChristoph Hellwig 			 * and can be happily ignored here.
166edf24abeSChristoph Hellwig 			 */
16795e05289SChris Mason 			break;
168b6cda9bcSChris Mason 		case Opt_nodatasum:
169067c28adSChris Mason 			printk(KERN_INFO "btrfs: setting nodatasum\n");
170b6cda9bcSChris Mason 			btrfs_set_opt(info->mount_opt, NODATASUM);
171be20aa9dSChris Mason 			break;
172be20aa9dSChris Mason 		case Opt_nodatacow:
173edf24abeSChristoph Hellwig 			printk(KERN_INFO "btrfs: setting nodatacow\n");
174be20aa9dSChris Mason 			btrfs_set_opt(info->mount_opt, NODATACOW);
175be20aa9dSChris Mason 			btrfs_set_opt(info->mount_opt, NODATASUM);
176b6cda9bcSChris Mason 			break;
177c8b97818SChris Mason 		case Opt_compress:
178c8b97818SChris Mason 			printk(KERN_INFO "btrfs: use compression\n");
179c8b97818SChris Mason 			btrfs_set_opt(info->mount_opt, COMPRESS);
180c8b97818SChris Mason 			break;
181a555f810SChris Mason 		case Opt_compress_force:
182a555f810SChris Mason 			printk(KERN_INFO "btrfs: forcing compression\n");
183a555f810SChris Mason 			btrfs_set_opt(info->mount_opt, FORCE_COMPRESS);
184a555f810SChris Mason 			btrfs_set_opt(info->mount_opt, COMPRESS);
185a555f810SChris Mason 			break;
186e18e4809SChris Mason 		case Opt_ssd:
187edf24abeSChristoph Hellwig 			printk(KERN_INFO "btrfs: use ssd allocation scheme\n");
188e18e4809SChris Mason 			btrfs_set_opt(info->mount_opt, SSD);
189e18e4809SChris Mason 			break;
190451d7585SChris Mason 		case Opt_ssd_spread:
191451d7585SChris Mason 			printk(KERN_INFO "btrfs: use spread ssd "
192451d7585SChris Mason 			       "allocation scheme\n");
193451d7585SChris Mason 			btrfs_set_opt(info->mount_opt, SSD);
194451d7585SChris Mason 			btrfs_set_opt(info->mount_opt, SSD_SPREAD);
195451d7585SChris Mason 			break;
1963b30c22fSChris Mason 		case Opt_nossd:
197451d7585SChris Mason 			printk(KERN_INFO "btrfs: not using ssd allocation "
198451d7585SChris Mason 			       "scheme\n");
199c289811cSChris Mason 			btrfs_set_opt(info->mount_opt, NOSSD);
2003b30c22fSChris Mason 			btrfs_clear_opt(info->mount_opt, SSD);
201451d7585SChris Mason 			btrfs_clear_opt(info->mount_opt, SSD_SPREAD);
2023b30c22fSChris Mason 			break;
20321ad10cfSChris Mason 		case Opt_nobarrier:
204edf24abeSChristoph Hellwig 			printk(KERN_INFO "btrfs: turning off barriers\n");
20521ad10cfSChris Mason 			btrfs_set_opt(info->mount_opt, NOBARRIER);
20621ad10cfSChris Mason 			break;
2074543df7eSChris Mason 		case Opt_thread_pool:
2084543df7eSChris Mason 			intarg = 0;
2094543df7eSChris Mason 			match_int(&args[0], &intarg);
2104543df7eSChris Mason 			if (intarg) {
2114543df7eSChris Mason 				info->thread_pool_size = intarg;
2124543df7eSChris Mason 				printk(KERN_INFO "btrfs: thread pool %d\n",
2134543df7eSChris Mason 				       info->thread_pool_size);
2144543df7eSChris Mason 			}
2154543df7eSChris Mason 			break;
216c59f8951SChris Mason 		case Opt_max_extent:
217edf24abeSChristoph Hellwig 			num = match_strdup(&args[0]);
218c59f8951SChris Mason 			if (num) {
219edf24abeSChristoph Hellwig 				info->max_extent = btrfs_parse_size(num);
220c59f8951SChris Mason 				kfree(num);
221c59f8951SChris Mason 
222c59f8951SChris Mason 				info->max_extent = max_t(u64,
223edf24abeSChristoph Hellwig 					info->max_extent, root->sectorsize);
224edf24abeSChristoph Hellwig 				printk(KERN_INFO "btrfs: max_extent at %llu\n",
22521380931SJoel Becker 				       (unsigned long long)info->max_extent);
226c59f8951SChris Mason 			}
227c59f8951SChris Mason 			break;
2286f568d35SChris Mason 		case Opt_max_inline:
229edf24abeSChristoph Hellwig 			num = match_strdup(&args[0]);
2306f568d35SChris Mason 			if (num) {
231edf24abeSChristoph Hellwig 				info->max_inline = btrfs_parse_size(num);
2326f568d35SChris Mason 				kfree(num);
2336f568d35SChris Mason 
23415ada040SChris Mason 				if (info->max_inline) {
2356f568d35SChris Mason 					info->max_inline = max_t(u64,
23615ada040SChris Mason 						info->max_inline,
23715ada040SChris Mason 						root->sectorsize);
23815ada040SChris Mason 				}
239edf24abeSChristoph Hellwig 				printk(KERN_INFO "btrfs: max_inline at %llu\n",
24021380931SJoel Becker 					(unsigned long long)info->max_inline);
2416f568d35SChris Mason 			}
2426f568d35SChris Mason 			break;
2438f662a76SChris Mason 		case Opt_alloc_start:
244edf24abeSChristoph Hellwig 			num = match_strdup(&args[0]);
2458f662a76SChris Mason 			if (num) {
246edf24abeSChristoph Hellwig 				info->alloc_start = btrfs_parse_size(num);
2478f662a76SChris Mason 				kfree(num);
248edf24abeSChristoph Hellwig 				printk(KERN_INFO
249edf24abeSChristoph Hellwig 					"btrfs: allocations start at %llu\n",
25021380931SJoel Becker 					(unsigned long long)info->alloc_start);
2518f662a76SChris Mason 			}
2528f662a76SChris Mason 			break;
25333268eafSJosef Bacik 		case Opt_noacl:
25433268eafSJosef Bacik 			root->fs_info->sb->s_flags &= ~MS_POSIXACL;
25533268eafSJosef Bacik 			break;
2563a5e1404SSage Weil 		case Opt_notreelog:
2573a5e1404SSage Weil 			printk(KERN_INFO "btrfs: disabling tree log\n");
2583a5e1404SSage Weil 			btrfs_set_opt(info->mount_opt, NOTREELOG);
2593a5e1404SSage Weil 			break;
260dccae999SSage Weil 		case Opt_flushoncommit:
261dccae999SSage Weil 			printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
262dccae999SSage Weil 			btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
263dccae999SSage Weil 			break;
26497e728d4SJosef Bacik 		case Opt_ratio:
26597e728d4SJosef Bacik 			intarg = 0;
26697e728d4SJosef Bacik 			match_int(&args[0], &intarg);
26797e728d4SJosef Bacik 			if (intarg) {
26897e728d4SJosef Bacik 				info->metadata_ratio = intarg;
26997e728d4SJosef Bacik 				printk(KERN_INFO "btrfs: metadata ratio %d\n",
27097e728d4SJosef Bacik 				       info->metadata_ratio);
27197e728d4SJosef Bacik 			}
27297e728d4SJosef Bacik 			break;
273e244a0aeSChristoph Hellwig 		case Opt_discard:
274e244a0aeSChristoph Hellwig 			btrfs_set_opt(info->mount_opt, DISCARD);
275e244a0aeSChristoph Hellwig 			break;
276a7a3f7caSSage Weil 		case Opt_err:
277a7a3f7caSSage Weil 			printk(KERN_INFO "btrfs: unrecognized mount option "
278a7a3f7caSSage Weil 			       "'%s'\n", p);
279a7a3f7caSSage Weil 			ret = -EINVAL;
280a7a3f7caSSage Weil 			goto out;
28195e05289SChris Mason 		default:
282be20aa9dSChris Mason 			break;
28395e05289SChris Mason 		}
28495e05289SChris Mason 	}
285a7a3f7caSSage Weil out:
286da495eccSJosef Bacik 	kfree(orig);
287a7a3f7caSSage Weil 	return ret;
288edf24abeSChristoph Hellwig }
289edf24abeSChristoph Hellwig 
290edf24abeSChristoph Hellwig /*
291edf24abeSChristoph Hellwig  * Parse mount options that are required early in the mount process.
292edf24abeSChristoph Hellwig  *
293edf24abeSChristoph Hellwig  * All other options will be parsed on much later in the mount process and
294edf24abeSChristoph Hellwig  * only when we need to allocate a new super block.
295edf24abeSChristoph Hellwig  */
29697288f2cSChristoph Hellwig static int btrfs_parse_early_options(const char *options, fmode_t flags,
29773f73415SJosef Bacik 		void *holder, char **subvol_name, u64 *subvol_objectid,
29843e570b0SChristoph Hellwig 		struct btrfs_fs_devices **fs_devices)
299edf24abeSChristoph Hellwig {
300edf24abeSChristoph Hellwig 	substring_t args[MAX_OPT_ARGS];
301edf24abeSChristoph Hellwig 	char *opts, *p;
302edf24abeSChristoph Hellwig 	int error = 0;
30373f73415SJosef Bacik 	int intarg;
304edf24abeSChristoph Hellwig 
305edf24abeSChristoph Hellwig 	if (!options)
306edf24abeSChristoph Hellwig 		goto out;
307edf24abeSChristoph Hellwig 
308edf24abeSChristoph Hellwig 	/*
309edf24abeSChristoph Hellwig 	 * strsep changes the string, duplicate it because parse_options
310edf24abeSChristoph Hellwig 	 * gets called twice
311edf24abeSChristoph Hellwig 	 */
312edf24abeSChristoph Hellwig 	opts = kstrdup(options, GFP_KERNEL);
313edf24abeSChristoph Hellwig 	if (!opts)
314edf24abeSChristoph Hellwig 		return -ENOMEM;
315edf24abeSChristoph Hellwig 
316edf24abeSChristoph Hellwig 	while ((p = strsep(&opts, ",")) != NULL) {
317edf24abeSChristoph Hellwig 		int token;
318edf24abeSChristoph Hellwig 		if (!*p)
319edf24abeSChristoph Hellwig 			continue;
320edf24abeSChristoph Hellwig 
321edf24abeSChristoph Hellwig 		token = match_token(p, tokens, args);
322edf24abeSChristoph Hellwig 		switch (token) {
323edf24abeSChristoph Hellwig 		case Opt_subvol:
324edf24abeSChristoph Hellwig 			*subvol_name = match_strdup(&args[0]);
325edf24abeSChristoph Hellwig 			break;
32673f73415SJosef Bacik 		case Opt_subvolid:
32773f73415SJosef Bacik 			intarg = 0;
3284849f01dSJosef Bacik 			error = match_int(&args[0], &intarg);
3294849f01dSJosef Bacik 			if (!error) {
3304849f01dSJosef Bacik 				/* we want the original fs_tree */
3314849f01dSJosef Bacik 				if (!intarg)
3324849f01dSJosef Bacik 					*subvol_objectid =
3334849f01dSJosef Bacik 						BTRFS_FS_TREE_OBJECTID;
3344849f01dSJosef Bacik 				else
33573f73415SJosef Bacik 					*subvol_objectid = intarg;
3364849f01dSJosef Bacik 			}
33773f73415SJosef Bacik 			break;
33843e570b0SChristoph Hellwig 		case Opt_device:
33943e570b0SChristoph Hellwig 			error = btrfs_scan_one_device(match_strdup(&args[0]),
34043e570b0SChristoph Hellwig 					flags, holder, fs_devices);
34143e570b0SChristoph Hellwig 			if (error)
34243e570b0SChristoph Hellwig 				goto out_free_opts;
34343e570b0SChristoph Hellwig 			break;
344edf24abeSChristoph Hellwig 		default:
345edf24abeSChristoph Hellwig 			break;
346edf24abeSChristoph Hellwig 		}
347edf24abeSChristoph Hellwig 	}
348edf24abeSChristoph Hellwig 
34943e570b0SChristoph Hellwig  out_free_opts:
350edf24abeSChristoph Hellwig 	kfree(opts);
351edf24abeSChristoph Hellwig  out:
352edf24abeSChristoph Hellwig 	/*
353edf24abeSChristoph Hellwig 	 * If no subvolume name is specified we use the default one.  Allocate
3543de4586cSChris Mason 	 * a copy of the string "." here so that code later in the
355edf24abeSChristoph Hellwig 	 * mount path doesn't care if it's the default volume or another one.
356edf24abeSChristoph Hellwig 	 */
357edf24abeSChristoph Hellwig 	if (!*subvol_name) {
3583de4586cSChris Mason 		*subvol_name = kstrdup(".", GFP_KERNEL);
359edf24abeSChristoph Hellwig 		if (!*subvol_name)
360edf24abeSChristoph Hellwig 			return -ENOMEM;
361edf24abeSChristoph Hellwig 	}
362edf24abeSChristoph Hellwig 	return error;
36395e05289SChris Mason }
36495e05289SChris Mason 
36573f73415SJosef Bacik static struct dentry *get_default_root(struct super_block *sb,
36673f73415SJosef Bacik 				       u64 subvol_objectid)
36773f73415SJosef Bacik {
36873f73415SJosef Bacik 	struct btrfs_root *root = sb->s_fs_info;
36973f73415SJosef Bacik 	struct btrfs_root *new_root;
37073f73415SJosef Bacik 	struct btrfs_dir_item *di;
37173f73415SJosef Bacik 	struct btrfs_path *path;
37273f73415SJosef Bacik 	struct btrfs_key location;
37373f73415SJosef Bacik 	struct inode *inode;
37473f73415SJosef Bacik 	struct dentry *dentry;
37573f73415SJosef Bacik 	u64 dir_id;
37673f73415SJosef Bacik 	int new = 0;
37773f73415SJosef Bacik 
37873f73415SJosef Bacik 	/*
37973f73415SJosef Bacik 	 * We have a specific subvol we want to mount, just setup location and
38073f73415SJosef Bacik 	 * go look up the root.
38173f73415SJosef Bacik 	 */
38273f73415SJosef Bacik 	if (subvol_objectid) {
38373f73415SJosef Bacik 		location.objectid = subvol_objectid;
38473f73415SJosef Bacik 		location.type = BTRFS_ROOT_ITEM_KEY;
38573f73415SJosef Bacik 		location.offset = (u64)-1;
38673f73415SJosef Bacik 		goto find_root;
38773f73415SJosef Bacik 	}
38873f73415SJosef Bacik 
38973f73415SJosef Bacik 	path = btrfs_alloc_path();
39073f73415SJosef Bacik 	if (!path)
39173f73415SJosef Bacik 		return ERR_PTR(-ENOMEM);
39273f73415SJosef Bacik 	path->leave_spinning = 1;
39373f73415SJosef Bacik 
39473f73415SJosef Bacik 	/*
39573f73415SJosef Bacik 	 * Find the "default" dir item which points to the root item that we
39673f73415SJosef Bacik 	 * will mount by default if we haven't been given a specific subvolume
39773f73415SJosef Bacik 	 * to mount.
39873f73415SJosef Bacik 	 */
39973f73415SJosef Bacik 	dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
40073f73415SJosef Bacik 	di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
40173f73415SJosef Bacik 	if (!di) {
40273f73415SJosef Bacik 		/*
40373f73415SJosef Bacik 		 * Ok the default dir item isn't there.  This is weird since
40473f73415SJosef Bacik 		 * it's always been there, but don't freak out, just try and
40573f73415SJosef Bacik 		 * mount to root most subvolume.
40673f73415SJosef Bacik 		 */
40773f73415SJosef Bacik 		btrfs_free_path(path);
40873f73415SJosef Bacik 		dir_id = BTRFS_FIRST_FREE_OBJECTID;
40973f73415SJosef Bacik 		new_root = root->fs_info->fs_root;
41073f73415SJosef Bacik 		goto setup_root;
41173f73415SJosef Bacik 	}
41273f73415SJosef Bacik 
41373f73415SJosef Bacik 	btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location);
41473f73415SJosef Bacik 	btrfs_free_path(path);
41573f73415SJosef Bacik 
41673f73415SJosef Bacik find_root:
41773f73415SJosef Bacik 	new_root = btrfs_read_fs_root_no_name(root->fs_info, &location);
41873f73415SJosef Bacik 	if (IS_ERR(new_root))
41973f73415SJosef Bacik 		return ERR_PTR(PTR_ERR(new_root));
42073f73415SJosef Bacik 
42173f73415SJosef Bacik 	if (btrfs_root_refs(&new_root->root_item) == 0)
42273f73415SJosef Bacik 		return ERR_PTR(-ENOENT);
42373f73415SJosef Bacik 
42473f73415SJosef Bacik 	dir_id = btrfs_root_dirid(&new_root->root_item);
42573f73415SJosef Bacik setup_root:
42673f73415SJosef Bacik 	location.objectid = dir_id;
42773f73415SJosef Bacik 	location.type = BTRFS_INODE_ITEM_KEY;
42873f73415SJosef Bacik 	location.offset = 0;
42973f73415SJosef Bacik 
43073f73415SJosef Bacik 	inode = btrfs_iget(sb, &location, new_root, &new);
43173f73415SJosef Bacik 	if (!inode)
43273f73415SJosef Bacik 		return ERR_PTR(-ENOMEM);
43373f73415SJosef Bacik 
43473f73415SJosef Bacik 	/*
43573f73415SJosef Bacik 	 * If we're just mounting the root most subvol put the inode and return
43673f73415SJosef Bacik 	 * a reference to the dentry.  We will have already gotten a reference
43773f73415SJosef Bacik 	 * to the inode in btrfs_fill_super so we're good to go.
43873f73415SJosef Bacik 	 */
43973f73415SJosef Bacik 	if (!new && sb->s_root->d_inode == inode) {
44073f73415SJosef Bacik 		iput(inode);
44173f73415SJosef Bacik 		return dget(sb->s_root);
44273f73415SJosef Bacik 	}
44373f73415SJosef Bacik 
44473f73415SJosef Bacik 	if (new) {
44573f73415SJosef Bacik 		const struct qstr name = { .name = "/", .len = 1 };
44673f73415SJosef Bacik 
44773f73415SJosef Bacik 		/*
44873f73415SJosef Bacik 		 * New inode, we need to make the dentry a sibling of s_root so
44973f73415SJosef Bacik 		 * everything gets cleaned up properly on unmount.
45073f73415SJosef Bacik 		 */
45173f73415SJosef Bacik 		dentry = d_alloc(sb->s_root, &name);
45273f73415SJosef Bacik 		if (!dentry) {
45373f73415SJosef Bacik 			iput(inode);
45473f73415SJosef Bacik 			return ERR_PTR(-ENOMEM);
45573f73415SJosef Bacik 		}
45673f73415SJosef Bacik 		d_splice_alias(inode, dentry);
45773f73415SJosef Bacik 	} else {
45873f73415SJosef Bacik 		/*
45973f73415SJosef Bacik 		 * We found the inode in cache, just find a dentry for it and
46073f73415SJosef Bacik 		 * put the reference to the inode we just got.
46173f73415SJosef Bacik 		 */
46273f73415SJosef Bacik 		dentry = d_find_alias(inode);
46373f73415SJosef Bacik 		iput(inode);
46473f73415SJosef Bacik 	}
46573f73415SJosef Bacik 
46673f73415SJosef Bacik 	return dentry;
46773f73415SJosef Bacik }
46873f73415SJosef Bacik 
4698a4b83ccSChris Mason static int btrfs_fill_super(struct super_block *sb,
4708a4b83ccSChris Mason 			    struct btrfs_fs_devices *fs_devices,
4718a4b83ccSChris Mason 			    void *data, int silent)
4722e635a27SChris Mason {
4732e635a27SChris Mason 	struct inode *inode;
474e20d96d6SChris Mason 	struct dentry *root_dentry;
475e20d96d6SChris Mason 	struct btrfs_super_block *disk_super;
4760f7d52f4SChris Mason 	struct btrfs_root *tree_root;
4775d4f98a2SYan Zheng 	struct btrfs_key key;
47839279cc3SChris Mason 	int err;
4792e635a27SChris Mason 
4802e635a27SChris Mason 	sb->s_maxbytes = MAX_LFS_FILESIZE;
4812e635a27SChris Mason 	sb->s_magic = BTRFS_SUPER_MAGIC;
482e20d96d6SChris Mason 	sb->s_op = &btrfs_super_ops;
483be6e8dc0SBalaji Rao 	sb->s_export_op = &btrfs_export_ops;
4845103e947SJosef Bacik 	sb->s_xattr = btrfs_xattr_handlers;
4852e635a27SChris Mason 	sb->s_time_gran = 1;
4860eda294dSChris Mason #ifdef CONFIG_BTRFS_FS_POSIX_ACL
48733268eafSJosef Bacik 	sb->s_flags |= MS_POSIXACL;
48849cf6f45SChris Ball #endif
489e20d96d6SChris Mason 
490dfe25020SChris Mason 	tree_root = open_ctree(sb, fs_devices, (char *)data);
491d98237b3SChris Mason 
492e58ca020SYan 	if (IS_ERR(tree_root)) {
493e20d96d6SChris Mason 		printk("btrfs: open_ctree failed\n");
494e58ca020SYan 		return PTR_ERR(tree_root);
495e20d96d6SChris Mason 	}
4960f7d52f4SChris Mason 	sb->s_fs_info = tree_root;
4975f39d397SChris Mason 	disk_super = &tree_root->fs_info->super_copy;
498b888db2bSChris Mason 
4995d4f98a2SYan Zheng 	key.objectid = BTRFS_FIRST_FREE_OBJECTID;
5005d4f98a2SYan Zheng 	key.type = BTRFS_INODE_ITEM_KEY;
5015d4f98a2SYan Zheng 	key.offset = 0;
50273f73415SJosef Bacik 	inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL);
5035d4f98a2SYan Zheng 	if (IS_ERR(inode)) {
5045d4f98a2SYan Zheng 		err = PTR_ERR(inode);
50539279cc3SChris Mason 		goto fail_close;
50639279cc3SChris Mason 	}
5072e635a27SChris Mason 
508e20d96d6SChris Mason 	root_dentry = d_alloc_root(inode);
509e20d96d6SChris Mason 	if (!root_dentry) {
5102e635a27SChris Mason 		iput(inode);
51139279cc3SChris Mason 		err = -ENOMEM;
51239279cc3SChris Mason 		goto fail_close;
5132e635a27SChris Mason 	}
51458176a96SJosef Bacik 
515e20d96d6SChris Mason 	sb->s_root = root_dentry;
5166885f308SChris Mason 
5176885f308SChris Mason 	save_mount_options(sb, data);
5182e635a27SChris Mason 	return 0;
5192e635a27SChris Mason 
52039279cc3SChris Mason fail_close:
52139279cc3SChris Mason 	close_ctree(tree_root);
522d5719762SChris Mason 	return err;
523d5719762SChris Mason }
524d5719762SChris Mason 
5256bf13c0cSSage Weil int btrfs_sync_fs(struct super_block *sb, int wait)
526d5719762SChris Mason {
527d5719762SChris Mason 	struct btrfs_trans_handle *trans;
528dccae999SSage Weil 	struct btrfs_root *root = btrfs_sb(sb);
529d5719762SChris Mason 	int ret;
530df2ce34cSChris Mason 
531d561c025SChris Mason 	if (!wait) {
5327cfcc17eSChris Mason 		filemap_flush(root->fs_info->btree_inode->i_mapping);
533df2ce34cSChris Mason 		return 0;
534d561c025SChris Mason 	}
535771ed689SChris Mason 
53624bbcf04SYan, Zheng 	btrfs_start_delalloc_inodes(root, 0);
53724bbcf04SYan, Zheng 	btrfs_wait_ordered_extents(root, 0, 0);
538771ed689SChris Mason 
539d5719762SChris Mason 	trans = btrfs_start_transaction(root, 1);
540d5719762SChris Mason 	ret = btrfs_commit_transaction(trans, root);
54154aa1f4dSChris Mason 	return ret;
542d5719762SChris Mason }
543d5719762SChris Mason 
544a9572a15SEric Paris static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
545a9572a15SEric Paris {
546a9572a15SEric Paris 	struct btrfs_root *root = btrfs_sb(vfs->mnt_sb);
547a9572a15SEric Paris 	struct btrfs_fs_info *info = root->fs_info;
548a9572a15SEric Paris 
549a9572a15SEric Paris 	if (btrfs_test_opt(root, DEGRADED))
550a9572a15SEric Paris 		seq_puts(seq, ",degraded");
551a9572a15SEric Paris 	if (btrfs_test_opt(root, NODATASUM))
552a9572a15SEric Paris 		seq_puts(seq, ",nodatasum");
553a9572a15SEric Paris 	if (btrfs_test_opt(root, NODATACOW))
554a9572a15SEric Paris 		seq_puts(seq, ",nodatacow");
555a9572a15SEric Paris 	if (btrfs_test_opt(root, NOBARRIER))
556a9572a15SEric Paris 		seq_puts(seq, ",nobarrier");
557a9572a15SEric Paris 	if (info->max_extent != (u64)-1)
55821380931SJoel Becker 		seq_printf(seq, ",max_extent=%llu",
55921380931SJoel Becker 			   (unsigned long long)info->max_extent);
560a9572a15SEric Paris 	if (info->max_inline != 8192 * 1024)
56121380931SJoel Becker 		seq_printf(seq, ",max_inline=%llu",
56221380931SJoel Becker 			   (unsigned long long)info->max_inline);
563a9572a15SEric Paris 	if (info->alloc_start != 0)
56421380931SJoel Becker 		seq_printf(seq, ",alloc_start=%llu",
56521380931SJoel Becker 			   (unsigned long long)info->alloc_start);
566a9572a15SEric Paris 	if (info->thread_pool_size !=  min_t(unsigned long,
567a9572a15SEric Paris 					     num_online_cpus() + 2, 8))
568a9572a15SEric Paris 		seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
569a9572a15SEric Paris 	if (btrfs_test_opt(root, COMPRESS))
570a9572a15SEric Paris 		seq_puts(seq, ",compress");
571c289811cSChris Mason 	if (btrfs_test_opt(root, NOSSD))
572c289811cSChris Mason 		seq_puts(seq, ",nossd");
573451d7585SChris Mason 	if (btrfs_test_opt(root, SSD_SPREAD))
574451d7585SChris Mason 		seq_puts(seq, ",ssd_spread");
575451d7585SChris Mason 	else if (btrfs_test_opt(root, SSD))
576a9572a15SEric Paris 		seq_puts(seq, ",ssd");
5773a5e1404SSage Weil 	if (btrfs_test_opt(root, NOTREELOG))
5786b65c5c6SSage Weil 		seq_puts(seq, ",notreelog");
579dccae999SSage Weil 	if (btrfs_test_opt(root, FLUSHONCOMMIT))
5806b65c5c6SSage Weil 		seq_puts(seq, ",flushoncommit");
58120a5239aSMatthew Wilcox 	if (btrfs_test_opt(root, DISCARD))
58220a5239aSMatthew Wilcox 		seq_puts(seq, ",discard");
583a9572a15SEric Paris 	if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
584a9572a15SEric Paris 		seq_puts(seq, ",noacl");
585a9572a15SEric Paris 	return 0;
586a9572a15SEric Paris }
587a9572a15SEric Paris 
588a061fc8dSChris Mason static int btrfs_test_super(struct super_block *s, void *data)
5892e635a27SChris Mason {
590a061fc8dSChris Mason 	struct btrfs_fs_devices *test_fs_devices = data;
591a061fc8dSChris Mason 	struct btrfs_root *root = btrfs_sb(s);
5924b82d6e4SYan 
593a061fc8dSChris Mason 	return root->fs_info->fs_devices == test_fs_devices;
5944b82d6e4SYan }
5954b82d6e4SYan 
596edf24abeSChristoph Hellwig /*
597edf24abeSChristoph Hellwig  * Find a superblock for the given device / mount point.
598edf24abeSChristoph Hellwig  *
599edf24abeSChristoph Hellwig  * Note:  This is based on get_sb_bdev from fs/super.c with a few additions
600edf24abeSChristoph Hellwig  *	  for multiple device setup.  Make sure to keep it in sync.
601edf24abeSChristoph Hellwig  */
602edf24abeSChristoph Hellwig static int btrfs_get_sb(struct file_system_type *fs_type, int flags,
603edf24abeSChristoph Hellwig 		const char *dev_name, void *data, struct vfsmount *mnt)
6044b82d6e4SYan {
6054b82d6e4SYan 	struct block_device *bdev = NULL;
6064b82d6e4SYan 	struct super_block *s;
6074b82d6e4SYan 	struct dentry *root;
6088a4b83ccSChris Mason 	struct btrfs_fs_devices *fs_devices = NULL;
60997288f2cSChristoph Hellwig 	fmode_t mode = FMODE_READ;
61073f73415SJosef Bacik 	char *subvol_name = NULL;
61173f73415SJosef Bacik 	u64 subvol_objectid = 0;
6124b82d6e4SYan 	int error = 0;
61373f73415SJosef Bacik 	int found = 0;
6144b82d6e4SYan 
61597288f2cSChristoph Hellwig 	if (!(flags & MS_RDONLY))
61697288f2cSChristoph Hellwig 		mode |= FMODE_WRITE;
61797288f2cSChristoph Hellwig 
61897288f2cSChristoph Hellwig 	error = btrfs_parse_early_options(data, mode, fs_type,
61973f73415SJosef Bacik 					  &subvol_name, &subvol_objectid,
62073f73415SJosef Bacik 					  &fs_devices);
621edf24abeSChristoph Hellwig 	if (error)
6221f483660SShen Feng 		return error;
623edf24abeSChristoph Hellwig 
62497288f2cSChristoph Hellwig 	error = btrfs_scan_one_device(dev_name, mode, fs_type, &fs_devices);
6258a4b83ccSChris Mason 	if (error)
626edf24abeSChristoph Hellwig 		goto error_free_subvol_name;
6274b82d6e4SYan 
62897288f2cSChristoph Hellwig 	error = btrfs_open_devices(fs_devices, mode, fs_type);
6298a4b83ccSChris Mason 	if (error)
630edf24abeSChristoph Hellwig 		goto error_free_subvol_name;
6318a4b83ccSChris Mason 
6322b82032cSYan Zheng 	if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) {
6332b82032cSYan Zheng 		error = -EACCES;
6342b82032cSYan Zheng 		goto error_close_devices;
6352b82032cSYan Zheng 	}
6362b82032cSYan Zheng 
637dfe25020SChris Mason 	bdev = fs_devices->latest_bdev;
638a061fc8dSChris Mason 	s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices);
6394b82d6e4SYan 	if (IS_ERR(s))
6404b82d6e4SYan 		goto error_s;
6414b82d6e4SYan 
6424b82d6e4SYan 	if (s->s_root) {
6434b82d6e4SYan 		if ((flags ^ s->s_flags) & MS_RDONLY) {
6446f5bbff9SAl Viro 			deactivate_locked_super(s);
6454b82d6e4SYan 			error = -EBUSY;
646c146afadSYan Zheng 			goto error_close_devices;
6474b82d6e4SYan 		}
6484b82d6e4SYan 
64973f73415SJosef Bacik 		found = 1;
6502b82032cSYan Zheng 		btrfs_close_devices(fs_devices);
6514b82d6e4SYan 	} else {
6524b82d6e4SYan 		char b[BDEVNAME_SIZE];
6534b82d6e4SYan 
6544b82d6e4SYan 		s->s_flags = flags;
6554b82d6e4SYan 		strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
6568a4b83ccSChris Mason 		error = btrfs_fill_super(s, fs_devices, data,
6578a4b83ccSChris Mason 					 flags & MS_SILENT ? 1 : 0);
6584b82d6e4SYan 		if (error) {
6596f5bbff9SAl Viro 			deactivate_locked_super(s);
6601f483660SShen Feng 			goto error_free_subvol_name;
6614b82d6e4SYan 		}
6624b82d6e4SYan 
663788f20ebSChris Mason 		btrfs_sb(s)->fs_info->bdev_holder = fs_type;
6644b82d6e4SYan 		s->s_flags |= MS_ACTIVE;
6654b82d6e4SYan 	}
6664b82d6e4SYan 
66773f73415SJosef Bacik 	root = get_default_root(s, subvol_objectid);
6684b82d6e4SYan 	if (IS_ERR(root)) {
6694b82d6e4SYan 		error = PTR_ERR(root);
67073f73415SJosef Bacik 		deactivate_locked_super(s);
67173f73415SJosef Bacik 		goto error;
6724b82d6e4SYan 	}
67373f73415SJosef Bacik 	/* if they gave us a subvolume name bind mount into that */
67473f73415SJosef Bacik 	if (strcmp(subvol_name, ".")) {
67573f73415SJosef Bacik 		struct dentry *new_root;
67673f73415SJosef Bacik 		mutex_lock(&root->d_inode->i_mutex);
67773f73415SJosef Bacik 		new_root = lookup_one_len(subvol_name, root,
67873f73415SJosef Bacik 				      strlen(subvol_name));
67973f73415SJosef Bacik 		mutex_unlock(&root->d_inode->i_mutex);
68073f73415SJosef Bacik 
68173f73415SJosef Bacik 		if (IS_ERR(new_root)) {
68273f73415SJosef Bacik 			deactivate_locked_super(s);
68373f73415SJosef Bacik 			error = PTR_ERR(new_root);
6844b82d6e4SYan 			dput(root);
68573f73415SJosef Bacik 			goto error_close_devices;
68673f73415SJosef Bacik 		}
68773f73415SJosef Bacik 		if (!new_root->d_inode) {
68873f73415SJosef Bacik 			dput(root);
68973f73415SJosef Bacik 			dput(new_root);
6906f5bbff9SAl Viro 			deactivate_locked_super(s);
6914b82d6e4SYan 			error = -ENXIO;
69273f73415SJosef Bacik 			goto error_close_devices;
6934b82d6e4SYan 		}
69473f73415SJosef Bacik 		dput(root);
69573f73415SJosef Bacik 		root = new_root;
69676fcef19SDavid Woodhouse 	}
6974b82d6e4SYan 
6984b82d6e4SYan 	mnt->mnt_sb = s;
6994b82d6e4SYan 	mnt->mnt_root = root;
700edf24abeSChristoph Hellwig 
701edf24abeSChristoph Hellwig 	kfree(subvol_name);
7024b82d6e4SYan 	return 0;
7034b82d6e4SYan 
7044b82d6e4SYan error_s:
7054b82d6e4SYan 	error = PTR_ERR(s);
706c146afadSYan Zheng error_close_devices:
7078a4b83ccSChris Mason 	btrfs_close_devices(fs_devices);
708edf24abeSChristoph Hellwig error_free_subvol_name:
709edf24abeSChristoph Hellwig 	kfree(subvol_name);
71073f73415SJosef Bacik error:
7114b82d6e4SYan 	return error;
7124b82d6e4SYan }
7132e635a27SChris Mason 
714c146afadSYan Zheng static int btrfs_remount(struct super_block *sb, int *flags, char *data)
715c146afadSYan Zheng {
716c146afadSYan Zheng 	struct btrfs_root *root = btrfs_sb(sb);
717c146afadSYan Zheng 	int ret;
718c146afadSYan Zheng 
719b288052eSChris Mason 	ret = btrfs_parse_options(root, data);
720b288052eSChris Mason 	if (ret)
721b288052eSChris Mason 		return -EINVAL;
722b288052eSChris Mason 
723c146afadSYan Zheng 	if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
724c146afadSYan Zheng 		return 0;
725c146afadSYan Zheng 
726c146afadSYan Zheng 	if (*flags & MS_RDONLY) {
727c146afadSYan Zheng 		sb->s_flags |= MS_RDONLY;
728c146afadSYan Zheng 
729c146afadSYan Zheng 		ret =  btrfs_commit_super(root);
730c146afadSYan Zheng 		WARN_ON(ret);
731c146afadSYan Zheng 	} else {
7322b82032cSYan Zheng 		if (root->fs_info->fs_devices->rw_devices == 0)
7332b82032cSYan Zheng 			return -EACCES;
7342b82032cSYan Zheng 
735c146afadSYan Zheng 		if (btrfs_super_log_root(&root->fs_info->super_copy) != 0)
736c146afadSYan Zheng 			return -EINVAL;
737c146afadSYan Zheng 
7385d4f98a2SYan Zheng 		/* recover relocation */
7395d4f98a2SYan Zheng 		ret = btrfs_recover_relocation(root);
740c146afadSYan Zheng 		WARN_ON(ret);
741c146afadSYan Zheng 
742c146afadSYan Zheng 		ret = btrfs_cleanup_fs_roots(root->fs_info);
743c146afadSYan Zheng 		WARN_ON(ret);
744c146afadSYan Zheng 
745c146afadSYan Zheng 		sb->s_flags &= ~MS_RDONLY;
746c146afadSYan Zheng 	}
747c146afadSYan Zheng 
748c146afadSYan Zheng 	return 0;
749c146afadSYan Zheng }
750c146afadSYan Zheng 
7518fd17795SChris Mason static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
7528fd17795SChris Mason {
7538fd17795SChris Mason 	struct btrfs_root *root = btrfs_sb(dentry->d_sb);
7544b52dff6SChris Mason 	struct btrfs_super_block *disk_super = &root->fs_info->super_copy;
755*bd4d1088SJosef Bacik 	struct list_head *head = &root->fs_info->space_info;
756*bd4d1088SJosef Bacik 	struct btrfs_space_info *found;
757*bd4d1088SJosef Bacik 	u64 total_used = 0;
758*bd4d1088SJosef Bacik 	u64 data_used = 0;
759db94535dSChris Mason 	int bits = dentry->d_sb->s_blocksize_bits;
7609d03632eSDavid Woodhouse 	__be32 *fsid = (__be32 *)root->fs_info->fsid;
7618fd17795SChris Mason 
762*bd4d1088SJosef Bacik 	rcu_read_lock();
763*bd4d1088SJosef Bacik 	list_for_each_entry_rcu(found, head, list) {
764*bd4d1088SJosef Bacik 		if (found->flags & (BTRFS_BLOCK_GROUP_DUP|
765*bd4d1088SJosef Bacik 				    BTRFS_BLOCK_GROUP_RAID10|
766*bd4d1088SJosef Bacik 				    BTRFS_BLOCK_GROUP_RAID1)) {
767*bd4d1088SJosef Bacik 			total_used += found->bytes_used;
768*bd4d1088SJosef Bacik 			if (found->flags & BTRFS_BLOCK_GROUP_DATA)
769*bd4d1088SJosef Bacik 				data_used += found->bytes_used;
770*bd4d1088SJosef Bacik 			else
771*bd4d1088SJosef Bacik 				data_used += found->total_bytes;
772*bd4d1088SJosef Bacik 		}
773*bd4d1088SJosef Bacik 
774*bd4d1088SJosef Bacik 		total_used += found->bytes_used;
775*bd4d1088SJosef Bacik 		if (found->flags & BTRFS_BLOCK_GROUP_DATA)
776*bd4d1088SJosef Bacik 			data_used += found->bytes_used;
777*bd4d1088SJosef Bacik 		else
778*bd4d1088SJosef Bacik 			data_used += found->total_bytes;
779*bd4d1088SJosef Bacik 	}
780*bd4d1088SJosef Bacik 	rcu_read_unlock();
781*bd4d1088SJosef Bacik 
7828fd17795SChris Mason 	buf->f_namelen = BTRFS_NAME_LEN;
783db94535dSChris Mason 	buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits;
784*bd4d1088SJosef Bacik 	buf->f_bfree = buf->f_blocks - (total_used >> bits);
785*bd4d1088SJosef Bacik 	buf->f_bavail = buf->f_blocks - (data_used >> bits);
7868fd17795SChris Mason 	buf->f_bsize = dentry->d_sb->s_blocksize;
7878fd17795SChris Mason 	buf->f_type = BTRFS_SUPER_MAGIC;
788d397712bSChris Mason 
7899d03632eSDavid Woodhouse 	/* We treat it as constant endianness (it doesn't matter _which_)
7909d03632eSDavid Woodhouse 	   because we want the fsid to come out the same whether mounted
7919d03632eSDavid Woodhouse 	   on a big-endian or little-endian host */
7929d03632eSDavid Woodhouse 	buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]);
7939d03632eSDavid Woodhouse 	buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]);
79432d48fa1SDavid Woodhouse 	/* Mask in the root object ID too, to disambiguate subvols */
79532d48fa1SDavid Woodhouse 	buf->f_fsid.val[0] ^= BTRFS_I(dentry->d_inode)->root->objectid >> 32;
79632d48fa1SDavid Woodhouse 	buf->f_fsid.val[1] ^= BTRFS_I(dentry->d_inode)->root->objectid;
79732d48fa1SDavid Woodhouse 
7988fd17795SChris Mason 	return 0;
7998fd17795SChris Mason }
800b5133862SChris Mason 
8012e635a27SChris Mason static struct file_system_type btrfs_fs_type = {
8022e635a27SChris Mason 	.owner		= THIS_MODULE,
8032e635a27SChris Mason 	.name		= "btrfs",
8042e635a27SChris Mason 	.get_sb		= btrfs_get_sb,
805a061fc8dSChris Mason 	.kill_sb	= kill_anon_super,
8062e635a27SChris Mason 	.fs_flags	= FS_REQUIRES_DEV,
8072e635a27SChris Mason };
808a9218f6bSChris Mason 
809d352ac68SChris Mason /*
810d352ac68SChris Mason  * used by btrfsctl to scan devices when no FS is mounted
811d352ac68SChris Mason  */
8128a4b83ccSChris Mason static long btrfs_control_ioctl(struct file *file, unsigned int cmd,
8138a4b83ccSChris Mason 				unsigned long arg)
8148a4b83ccSChris Mason {
8158a4b83ccSChris Mason 	struct btrfs_ioctl_vol_args *vol;
8168a4b83ccSChris Mason 	struct btrfs_fs_devices *fs_devices;
817c071fcfdSChris Mason 	int ret = -ENOTTY;
8188a4b83ccSChris Mason 
819e441d54dSChris Mason 	if (!capable(CAP_SYS_ADMIN))
820e441d54dSChris Mason 		return -EPERM;
821e441d54dSChris Mason 
822dae7b665SLi Zefan 	vol = memdup_user((void __user *)arg, sizeof(*vol));
823dae7b665SLi Zefan 	if (IS_ERR(vol))
824dae7b665SLi Zefan 		return PTR_ERR(vol);
825c071fcfdSChris Mason 
8268a4b83ccSChris Mason 	switch (cmd) {
8278a4b83ccSChris Mason 	case BTRFS_IOC_SCAN_DEV:
82897288f2cSChristoph Hellwig 		ret = btrfs_scan_one_device(vol->name, FMODE_READ,
8298a4b83ccSChris Mason 					    &btrfs_fs_type, &fs_devices);
8308a4b83ccSChris Mason 		break;
8318a4b83ccSChris Mason 	}
832dae7b665SLi Zefan 
8338a4b83ccSChris Mason 	kfree(vol);
834f819d837SLinda Knippers 	return ret;
8358a4b83ccSChris Mason }
8368a4b83ccSChris Mason 
8370176260fSLinus Torvalds static int btrfs_freeze(struct super_block *sb)
838ed0dab6bSYan {
839ed0dab6bSYan 	struct btrfs_root *root = btrfs_sb(sb);
840a74a4b97SChris Mason 	mutex_lock(&root->fs_info->transaction_kthread_mutex);
841a74a4b97SChris Mason 	mutex_lock(&root->fs_info->cleaner_mutex);
8420176260fSLinus Torvalds 	return 0;
843ed0dab6bSYan }
844ed0dab6bSYan 
8450176260fSLinus Torvalds static int btrfs_unfreeze(struct super_block *sb)
846ed0dab6bSYan {
847ed0dab6bSYan 	struct btrfs_root *root = btrfs_sb(sb);
848a74a4b97SChris Mason 	mutex_unlock(&root->fs_info->cleaner_mutex);
849a74a4b97SChris Mason 	mutex_unlock(&root->fs_info->transaction_kthread_mutex);
8500176260fSLinus Torvalds 	return 0;
851ed0dab6bSYan }
8522e635a27SChris Mason 
853b87221deSAlexey Dobriyan static const struct super_operations btrfs_super_ops = {
85476dda93cSYan, Zheng 	.drop_inode	= btrfs_drop_inode,
855134e9731SChris Mason 	.delete_inode	= btrfs_delete_inode,
856e20d96d6SChris Mason 	.put_super	= btrfs_put_super,
857d5719762SChris Mason 	.sync_fs	= btrfs_sync_fs,
858a9572a15SEric Paris 	.show_options	= btrfs_show_options,
8594730a4bcSChris Mason 	.write_inode	= btrfs_write_inode,
860b5133862SChris Mason 	.dirty_inode	= btrfs_dirty_inode,
8612c90e5d6SChris Mason 	.alloc_inode	= btrfs_alloc_inode,
8622c90e5d6SChris Mason 	.destroy_inode	= btrfs_destroy_inode,
8638fd17795SChris Mason 	.statfs		= btrfs_statfs,
864c146afadSYan Zheng 	.remount_fs	= btrfs_remount,
8650176260fSLinus Torvalds 	.freeze_fs	= btrfs_freeze,
8660176260fSLinus Torvalds 	.unfreeze_fs	= btrfs_unfreeze,
867e20d96d6SChris Mason };
868a9218f6bSChris Mason 
869a9218f6bSChris Mason static const struct file_operations btrfs_ctl_fops = {
870a9218f6bSChris Mason 	.unlocked_ioctl	 = btrfs_control_ioctl,
871a9218f6bSChris Mason 	.compat_ioctl = btrfs_control_ioctl,
872a9218f6bSChris Mason 	.owner	 = THIS_MODULE,
873a9218f6bSChris Mason };
874a9218f6bSChris Mason 
875a9218f6bSChris Mason static struct miscdevice btrfs_misc = {
876a9218f6bSChris Mason 	.minor		= MISC_DYNAMIC_MINOR,
877a9218f6bSChris Mason 	.name		= "btrfs-control",
878a9218f6bSChris Mason 	.fops		= &btrfs_ctl_fops
879a9218f6bSChris Mason };
880a9218f6bSChris Mason 
881a9218f6bSChris Mason static int btrfs_interface_init(void)
882a9218f6bSChris Mason {
883a9218f6bSChris Mason 	return misc_register(&btrfs_misc);
884a9218f6bSChris Mason }
885a9218f6bSChris Mason 
886b2950863SChristoph Hellwig static void btrfs_interface_exit(void)
887a9218f6bSChris Mason {
888a9218f6bSChris Mason 	if (misc_deregister(&btrfs_misc) < 0)
889d397712bSChris Mason 		printk(KERN_INFO "misc_deregister failed for control device");
890a9218f6bSChris Mason }
891a9218f6bSChris Mason 
8922e635a27SChris Mason static int __init init_btrfs_fs(void)
8932e635a27SChris Mason {
8942c90e5d6SChris Mason 	int err;
89558176a96SJosef Bacik 
89658176a96SJosef Bacik 	err = btrfs_init_sysfs();
89758176a96SJosef Bacik 	if (err)
89858176a96SJosef Bacik 		return err;
89958176a96SJosef Bacik 
90039279cc3SChris Mason 	err = btrfs_init_cachep();
9012c90e5d6SChris Mason 	if (err)
902a74a4b97SChris Mason 		goto free_sysfs;
903d1310b2eSChris Mason 
904d1310b2eSChris Mason 	err = extent_io_init();
9052f4cbe64SWyatt Banks 	if (err)
9062f4cbe64SWyatt Banks 		goto free_cachep;
9072f4cbe64SWyatt Banks 
908d1310b2eSChris Mason 	err = extent_map_init();
909d1310b2eSChris Mason 	if (err)
910d1310b2eSChris Mason 		goto free_extent_io;
911d1310b2eSChris Mason 
912a9218f6bSChris Mason 	err = btrfs_interface_init();
9132f4cbe64SWyatt Banks 	if (err)
9142f4cbe64SWyatt Banks 		goto free_extent_map;
915c8b97818SChris Mason 
916a9218f6bSChris Mason 	err = register_filesystem(&btrfs_fs_type);
917a9218f6bSChris Mason 	if (err)
918a9218f6bSChris Mason 		goto unregister_ioctl;
919b3c3da71SChris Mason 
920b3c3da71SChris Mason 	printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION);
9212f4cbe64SWyatt Banks 	return 0;
9222f4cbe64SWyatt Banks 
923a9218f6bSChris Mason unregister_ioctl:
924a9218f6bSChris Mason 	btrfs_interface_exit();
9252f4cbe64SWyatt Banks free_extent_map:
9262f4cbe64SWyatt Banks 	extent_map_exit();
927d1310b2eSChris Mason free_extent_io:
928d1310b2eSChris Mason 	extent_io_exit();
9292f4cbe64SWyatt Banks free_cachep:
9302f4cbe64SWyatt Banks 	btrfs_destroy_cachep();
931a74a4b97SChris Mason free_sysfs:
9322f4cbe64SWyatt Banks 	btrfs_exit_sysfs();
9332c90e5d6SChris Mason 	return err;
9342e635a27SChris Mason }
9352e635a27SChris Mason 
9362e635a27SChris Mason static void __exit exit_btrfs_fs(void)
9372e635a27SChris Mason {
93839279cc3SChris Mason 	btrfs_destroy_cachep();
939a52d9a80SChris Mason 	extent_map_exit();
940d1310b2eSChris Mason 	extent_io_exit();
941a9218f6bSChris Mason 	btrfs_interface_exit();
9422e635a27SChris Mason 	unregister_filesystem(&btrfs_fs_type);
94358176a96SJosef Bacik 	btrfs_exit_sysfs();
9448a4b83ccSChris Mason 	btrfs_cleanup_fs_uuids();
945c8b97818SChris Mason 	btrfs_zlib_exit();
9462e635a27SChris Mason }
9472e635a27SChris Mason 
9482e635a27SChris Mason module_init(init_btrfs_fs)
9492e635a27SChris Mason module_exit(exit_btrfs_fs)
9502e635a27SChris Mason 
9512e635a27SChris Mason MODULE_LICENSE("GPL");
952