Commit f23c8af8ca2789eeb0ab9ea90c214f9694d96cc5
1 parent
a90e8b6fb8
Exists in
master
and in
6 other branches
Btrfs: fix subvol_name leak on error in btrfs_mount()
btrfs_parse_early_options() can fail due to error while scanning devices (-o device= option), but still strdup() subvol_name string: mount -o subvol=SUBV,device=BAD_DEVICE <dev> <mnt> So free subvol_name string on error. Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Showing 1 changed file with 3 additions and 1 deletions Inline Diff
fs/btrfs/super.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2007 Oracle. All rights reserved. | 2 | * Copyright (C) 2007 Oracle. All rights reserved. |
3 | * | 3 | * |
4 | * This program is free software; you can redistribute it and/or | 4 | * This program is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU General Public | 5 | * modify it under the terms of the GNU General Public |
6 | * License v2 as published by the Free Software Foundation. | 6 | * License v2 as published by the Free Software Foundation. |
7 | * | 7 | * |
8 | * This program is distributed in the hope that it will be useful, | 8 | * This program is distributed in the hope that it will be useful, |
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
11 | * General Public License for more details. | 11 | * General Public License for more details. |
12 | * | 12 | * |
13 | * You should have received a copy of the GNU General Public | 13 | * You should have received a copy of the GNU General Public |
14 | * License along with this program; if not, write to the | 14 | * License along with this program; if not, write to the |
15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 15 | * Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/blkdev.h> | 19 | #include <linux/blkdev.h> |
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/buffer_head.h> | 21 | #include <linux/buffer_head.h> |
22 | #include <linux/fs.h> | 22 | #include <linux/fs.h> |
23 | #include <linux/pagemap.h> | 23 | #include <linux/pagemap.h> |
24 | #include <linux/highmem.h> | 24 | #include <linux/highmem.h> |
25 | #include <linux/time.h> | 25 | #include <linux/time.h> |
26 | #include <linux/init.h> | 26 | #include <linux/init.h> |
27 | #include <linux/seq_file.h> | 27 | #include <linux/seq_file.h> |
28 | #include <linux/string.h> | 28 | #include <linux/string.h> |
29 | #include <linux/backing-dev.h> | 29 | #include <linux/backing-dev.h> |
30 | #include <linux/mount.h> | 30 | #include <linux/mount.h> |
31 | #include <linux/mpage.h> | 31 | #include <linux/mpage.h> |
32 | #include <linux/swap.h> | 32 | #include <linux/swap.h> |
33 | #include <linux/writeback.h> | 33 | #include <linux/writeback.h> |
34 | #include <linux/statfs.h> | 34 | #include <linux/statfs.h> |
35 | #include <linux/compat.h> | 35 | #include <linux/compat.h> |
36 | #include <linux/parser.h> | 36 | #include <linux/parser.h> |
37 | #include <linux/ctype.h> | 37 | #include <linux/ctype.h> |
38 | #include <linux/namei.h> | 38 | #include <linux/namei.h> |
39 | #include <linux/miscdevice.h> | 39 | #include <linux/miscdevice.h> |
40 | #include <linux/magic.h> | 40 | #include <linux/magic.h> |
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/cleancache.h> | 42 | #include <linux/cleancache.h> |
43 | #include <linux/mnt_namespace.h> | 43 | #include <linux/mnt_namespace.h> |
44 | #include "compat.h" | 44 | #include "compat.h" |
45 | #include "delayed-inode.h" | 45 | #include "delayed-inode.h" |
46 | #include "ctree.h" | 46 | #include "ctree.h" |
47 | #include "disk-io.h" | 47 | #include "disk-io.h" |
48 | #include "transaction.h" | 48 | #include "transaction.h" |
49 | #include "btrfs_inode.h" | 49 | #include "btrfs_inode.h" |
50 | #include "ioctl.h" | 50 | #include "ioctl.h" |
51 | #include "print-tree.h" | 51 | #include "print-tree.h" |
52 | #include "xattr.h" | 52 | #include "xattr.h" |
53 | #include "volumes.h" | 53 | #include "volumes.h" |
54 | #include "version.h" | 54 | #include "version.h" |
55 | #include "export.h" | 55 | #include "export.h" |
56 | #include "compression.h" | 56 | #include "compression.h" |
57 | 57 | ||
58 | #define CREATE_TRACE_POINTS | 58 | #define CREATE_TRACE_POINTS |
59 | #include <trace/events/btrfs.h> | 59 | #include <trace/events/btrfs.h> |
60 | 60 | ||
61 | static const struct super_operations btrfs_super_ops; | 61 | static const struct super_operations btrfs_super_ops; |
62 | static struct file_system_type btrfs_fs_type; | 62 | static struct file_system_type btrfs_fs_type; |
63 | 63 | ||
64 | static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno, | 64 | static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno, |
65 | char nbuf[16]) | 65 | char nbuf[16]) |
66 | { | 66 | { |
67 | char *errstr = NULL; | 67 | char *errstr = NULL; |
68 | 68 | ||
69 | switch (errno) { | 69 | switch (errno) { |
70 | case -EIO: | 70 | case -EIO: |
71 | errstr = "IO failure"; | 71 | errstr = "IO failure"; |
72 | break; | 72 | break; |
73 | case -ENOMEM: | 73 | case -ENOMEM: |
74 | errstr = "Out of memory"; | 74 | errstr = "Out of memory"; |
75 | break; | 75 | break; |
76 | case -EROFS: | 76 | case -EROFS: |
77 | errstr = "Readonly filesystem"; | 77 | errstr = "Readonly filesystem"; |
78 | break; | 78 | break; |
79 | default: | 79 | default: |
80 | if (nbuf) { | 80 | if (nbuf) { |
81 | if (snprintf(nbuf, 16, "error %d", -errno) >= 0) | 81 | if (snprintf(nbuf, 16, "error %d", -errno) >= 0) |
82 | errstr = nbuf; | 82 | errstr = nbuf; |
83 | } | 83 | } |
84 | break; | 84 | break; |
85 | } | 85 | } |
86 | 86 | ||
87 | return errstr; | 87 | return errstr; |
88 | } | 88 | } |
89 | 89 | ||
90 | static void __save_error_info(struct btrfs_fs_info *fs_info) | 90 | static void __save_error_info(struct btrfs_fs_info *fs_info) |
91 | { | 91 | { |
92 | /* | 92 | /* |
93 | * today we only save the error info into ram. Long term we'll | 93 | * today we only save the error info into ram. Long term we'll |
94 | * also send it down to the disk | 94 | * also send it down to the disk |
95 | */ | 95 | */ |
96 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; | 96 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; |
97 | } | 97 | } |
98 | 98 | ||
99 | /* NOTE: | 99 | /* NOTE: |
100 | * We move write_super stuff at umount in order to avoid deadlock | 100 | * We move write_super stuff at umount in order to avoid deadlock |
101 | * for umount hold all lock. | 101 | * for umount hold all lock. |
102 | */ | 102 | */ |
103 | static void save_error_info(struct btrfs_fs_info *fs_info) | 103 | static void save_error_info(struct btrfs_fs_info *fs_info) |
104 | { | 104 | { |
105 | __save_error_info(fs_info); | 105 | __save_error_info(fs_info); |
106 | } | 106 | } |
107 | 107 | ||
108 | /* btrfs handle error by forcing the filesystem readonly */ | 108 | /* btrfs handle error by forcing the filesystem readonly */ |
109 | static void btrfs_handle_error(struct btrfs_fs_info *fs_info) | 109 | static void btrfs_handle_error(struct btrfs_fs_info *fs_info) |
110 | { | 110 | { |
111 | struct super_block *sb = fs_info->sb; | 111 | struct super_block *sb = fs_info->sb; |
112 | 112 | ||
113 | if (sb->s_flags & MS_RDONLY) | 113 | if (sb->s_flags & MS_RDONLY) |
114 | return; | 114 | return; |
115 | 115 | ||
116 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | 116 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { |
117 | sb->s_flags |= MS_RDONLY; | 117 | sb->s_flags |= MS_RDONLY; |
118 | printk(KERN_INFO "btrfs is forced readonly\n"); | 118 | printk(KERN_INFO "btrfs is forced readonly\n"); |
119 | } | 119 | } |
120 | } | 120 | } |
121 | 121 | ||
122 | /* | 122 | /* |
123 | * __btrfs_std_error decodes expected errors from the caller and | 123 | * __btrfs_std_error decodes expected errors from the caller and |
124 | * invokes the approciate error response. | 124 | * invokes the approciate error response. |
125 | */ | 125 | */ |
126 | void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | 126 | void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, |
127 | unsigned int line, int errno) | 127 | unsigned int line, int errno) |
128 | { | 128 | { |
129 | struct super_block *sb = fs_info->sb; | 129 | struct super_block *sb = fs_info->sb; |
130 | char nbuf[16]; | 130 | char nbuf[16]; |
131 | const char *errstr; | 131 | const char *errstr; |
132 | 132 | ||
133 | /* | 133 | /* |
134 | * Special case: if the error is EROFS, and we're already | 134 | * Special case: if the error is EROFS, and we're already |
135 | * under MS_RDONLY, then it is safe here. | 135 | * under MS_RDONLY, then it is safe here. |
136 | */ | 136 | */ |
137 | if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) | 137 | if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) |
138 | return; | 138 | return; |
139 | 139 | ||
140 | errstr = btrfs_decode_error(fs_info, errno, nbuf); | 140 | errstr = btrfs_decode_error(fs_info, errno, nbuf); |
141 | printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n", | 141 | printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n", |
142 | sb->s_id, function, line, errstr); | 142 | sb->s_id, function, line, errstr); |
143 | save_error_info(fs_info); | 143 | save_error_info(fs_info); |
144 | 144 | ||
145 | btrfs_handle_error(fs_info); | 145 | btrfs_handle_error(fs_info); |
146 | } | 146 | } |
147 | 147 | ||
148 | static void btrfs_put_super(struct super_block *sb) | 148 | static void btrfs_put_super(struct super_block *sb) |
149 | { | 149 | { |
150 | struct btrfs_root *root = btrfs_sb(sb); | 150 | struct btrfs_root *root = btrfs_sb(sb); |
151 | int ret; | 151 | int ret; |
152 | 152 | ||
153 | ret = close_ctree(root); | 153 | ret = close_ctree(root); |
154 | sb->s_fs_info = NULL; | 154 | sb->s_fs_info = NULL; |
155 | 155 | ||
156 | (void)ret; /* FIXME: need to fix VFS to return error? */ | 156 | (void)ret; /* FIXME: need to fix VFS to return error? */ |
157 | } | 157 | } |
158 | 158 | ||
159 | enum { | 159 | enum { |
160 | Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum, | 160 | Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum, |
161 | Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd, | 161 | Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd, |
162 | Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, | 162 | Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, |
163 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, | 163 | Opt_compress_type, Opt_compress_force, Opt_compress_force_type, |
164 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, | 164 | Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, |
165 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, | 165 | Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, |
166 | Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, | 166 | Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, |
167 | Opt_inode_cache, Opt_no_space_cache, Opt_recovery, Opt_err, | 167 | Opt_inode_cache, Opt_no_space_cache, Opt_recovery, Opt_err, |
168 | }; | 168 | }; |
169 | 169 | ||
170 | static match_table_t tokens = { | 170 | static match_table_t tokens = { |
171 | {Opt_degraded, "degraded"}, | 171 | {Opt_degraded, "degraded"}, |
172 | {Opt_subvol, "subvol=%s"}, | 172 | {Opt_subvol, "subvol=%s"}, |
173 | {Opt_subvolid, "subvolid=%d"}, | 173 | {Opt_subvolid, "subvolid=%d"}, |
174 | {Opt_device, "device=%s"}, | 174 | {Opt_device, "device=%s"}, |
175 | {Opt_nodatasum, "nodatasum"}, | 175 | {Opt_nodatasum, "nodatasum"}, |
176 | {Opt_nodatacow, "nodatacow"}, | 176 | {Opt_nodatacow, "nodatacow"}, |
177 | {Opt_nobarrier, "nobarrier"}, | 177 | {Opt_nobarrier, "nobarrier"}, |
178 | {Opt_max_inline, "max_inline=%s"}, | 178 | {Opt_max_inline, "max_inline=%s"}, |
179 | {Opt_alloc_start, "alloc_start=%s"}, | 179 | {Opt_alloc_start, "alloc_start=%s"}, |
180 | {Opt_thread_pool, "thread_pool=%d"}, | 180 | {Opt_thread_pool, "thread_pool=%d"}, |
181 | {Opt_compress, "compress"}, | 181 | {Opt_compress, "compress"}, |
182 | {Opt_compress_type, "compress=%s"}, | 182 | {Opt_compress_type, "compress=%s"}, |
183 | {Opt_compress_force, "compress-force"}, | 183 | {Opt_compress_force, "compress-force"}, |
184 | {Opt_compress_force_type, "compress-force=%s"}, | 184 | {Opt_compress_force_type, "compress-force=%s"}, |
185 | {Opt_ssd, "ssd"}, | 185 | {Opt_ssd, "ssd"}, |
186 | {Opt_ssd_spread, "ssd_spread"}, | 186 | {Opt_ssd_spread, "ssd_spread"}, |
187 | {Opt_nossd, "nossd"}, | 187 | {Opt_nossd, "nossd"}, |
188 | {Opt_noacl, "noacl"}, | 188 | {Opt_noacl, "noacl"}, |
189 | {Opt_notreelog, "notreelog"}, | 189 | {Opt_notreelog, "notreelog"}, |
190 | {Opt_flushoncommit, "flushoncommit"}, | 190 | {Opt_flushoncommit, "flushoncommit"}, |
191 | {Opt_ratio, "metadata_ratio=%d"}, | 191 | {Opt_ratio, "metadata_ratio=%d"}, |
192 | {Opt_discard, "discard"}, | 192 | {Opt_discard, "discard"}, |
193 | {Opt_space_cache, "space_cache"}, | 193 | {Opt_space_cache, "space_cache"}, |
194 | {Opt_clear_cache, "clear_cache"}, | 194 | {Opt_clear_cache, "clear_cache"}, |
195 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, | 195 | {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, |
196 | {Opt_enospc_debug, "enospc_debug"}, | 196 | {Opt_enospc_debug, "enospc_debug"}, |
197 | {Opt_subvolrootid, "subvolrootid=%d"}, | 197 | {Opt_subvolrootid, "subvolrootid=%d"}, |
198 | {Opt_defrag, "autodefrag"}, | 198 | {Opt_defrag, "autodefrag"}, |
199 | {Opt_inode_cache, "inode_cache"}, | 199 | {Opt_inode_cache, "inode_cache"}, |
200 | {Opt_no_space_cache, "no_space_cache"}, | 200 | {Opt_no_space_cache, "no_space_cache"}, |
201 | {Opt_recovery, "recovery"}, | 201 | {Opt_recovery, "recovery"}, |
202 | {Opt_err, NULL}, | 202 | {Opt_err, NULL}, |
203 | }; | 203 | }; |
204 | 204 | ||
205 | /* | 205 | /* |
206 | * Regular mount options parser. Everything that is needed only when | 206 | * Regular mount options parser. Everything that is needed only when |
207 | * reading in a new superblock is parsed here. | 207 | * reading in a new superblock is parsed here. |
208 | */ | 208 | */ |
209 | int btrfs_parse_options(struct btrfs_root *root, char *options) | 209 | int btrfs_parse_options(struct btrfs_root *root, char *options) |
210 | { | 210 | { |
211 | struct btrfs_fs_info *info = root->fs_info; | 211 | struct btrfs_fs_info *info = root->fs_info; |
212 | substring_t args[MAX_OPT_ARGS]; | 212 | substring_t args[MAX_OPT_ARGS]; |
213 | char *p, *num, *orig = NULL; | 213 | char *p, *num, *orig = NULL; |
214 | u64 cache_gen; | 214 | u64 cache_gen; |
215 | int intarg; | 215 | int intarg; |
216 | int ret = 0; | 216 | int ret = 0; |
217 | char *compress_type; | 217 | char *compress_type; |
218 | bool compress_force = false; | 218 | bool compress_force = false; |
219 | 219 | ||
220 | cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy); | 220 | cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy); |
221 | if (cache_gen) | 221 | if (cache_gen) |
222 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); | 222 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); |
223 | 223 | ||
224 | if (!options) | 224 | if (!options) |
225 | goto out; | 225 | goto out; |
226 | 226 | ||
227 | /* | 227 | /* |
228 | * strsep changes the string, duplicate it because parse_options | 228 | * strsep changes the string, duplicate it because parse_options |
229 | * gets called twice | 229 | * gets called twice |
230 | */ | 230 | */ |
231 | options = kstrdup(options, GFP_NOFS); | 231 | options = kstrdup(options, GFP_NOFS); |
232 | if (!options) | 232 | if (!options) |
233 | return -ENOMEM; | 233 | return -ENOMEM; |
234 | 234 | ||
235 | orig = options; | 235 | orig = options; |
236 | 236 | ||
237 | while ((p = strsep(&options, ",")) != NULL) { | 237 | while ((p = strsep(&options, ",")) != NULL) { |
238 | int token; | 238 | int token; |
239 | if (!*p) | 239 | if (!*p) |
240 | continue; | 240 | continue; |
241 | 241 | ||
242 | token = match_token(p, tokens, args); | 242 | token = match_token(p, tokens, args); |
243 | switch (token) { | 243 | switch (token) { |
244 | case Opt_degraded: | 244 | case Opt_degraded: |
245 | printk(KERN_INFO "btrfs: allowing degraded mounts\n"); | 245 | printk(KERN_INFO "btrfs: allowing degraded mounts\n"); |
246 | btrfs_set_opt(info->mount_opt, DEGRADED); | 246 | btrfs_set_opt(info->mount_opt, DEGRADED); |
247 | break; | 247 | break; |
248 | case Opt_subvol: | 248 | case Opt_subvol: |
249 | case Opt_subvolid: | 249 | case Opt_subvolid: |
250 | case Opt_subvolrootid: | 250 | case Opt_subvolrootid: |
251 | case Opt_device: | 251 | case Opt_device: |
252 | /* | 252 | /* |
253 | * These are parsed by btrfs_parse_early_options | 253 | * These are parsed by btrfs_parse_early_options |
254 | * and can be happily ignored here. | 254 | * and can be happily ignored here. |
255 | */ | 255 | */ |
256 | break; | 256 | break; |
257 | case Opt_nodatasum: | 257 | case Opt_nodatasum: |
258 | printk(KERN_INFO "btrfs: setting nodatasum\n"); | 258 | printk(KERN_INFO "btrfs: setting nodatasum\n"); |
259 | btrfs_set_opt(info->mount_opt, NODATASUM); | 259 | btrfs_set_opt(info->mount_opt, NODATASUM); |
260 | break; | 260 | break; |
261 | case Opt_nodatacow: | 261 | case Opt_nodatacow: |
262 | printk(KERN_INFO "btrfs: setting nodatacow\n"); | 262 | printk(KERN_INFO "btrfs: setting nodatacow\n"); |
263 | btrfs_set_opt(info->mount_opt, NODATACOW); | 263 | btrfs_set_opt(info->mount_opt, NODATACOW); |
264 | btrfs_set_opt(info->mount_opt, NODATASUM); | 264 | btrfs_set_opt(info->mount_opt, NODATASUM); |
265 | break; | 265 | break; |
266 | case Opt_compress_force: | 266 | case Opt_compress_force: |
267 | case Opt_compress_force_type: | 267 | case Opt_compress_force_type: |
268 | compress_force = true; | 268 | compress_force = true; |
269 | case Opt_compress: | 269 | case Opt_compress: |
270 | case Opt_compress_type: | 270 | case Opt_compress_type: |
271 | if (token == Opt_compress || | 271 | if (token == Opt_compress || |
272 | token == Opt_compress_force || | 272 | token == Opt_compress_force || |
273 | strcmp(args[0].from, "zlib") == 0) { | 273 | strcmp(args[0].from, "zlib") == 0) { |
274 | compress_type = "zlib"; | 274 | compress_type = "zlib"; |
275 | info->compress_type = BTRFS_COMPRESS_ZLIB; | 275 | info->compress_type = BTRFS_COMPRESS_ZLIB; |
276 | } else if (strcmp(args[0].from, "lzo") == 0) { | 276 | } else if (strcmp(args[0].from, "lzo") == 0) { |
277 | compress_type = "lzo"; | 277 | compress_type = "lzo"; |
278 | info->compress_type = BTRFS_COMPRESS_LZO; | 278 | info->compress_type = BTRFS_COMPRESS_LZO; |
279 | } else { | 279 | } else { |
280 | ret = -EINVAL; | 280 | ret = -EINVAL; |
281 | goto out; | 281 | goto out; |
282 | } | 282 | } |
283 | 283 | ||
284 | btrfs_set_opt(info->mount_opt, COMPRESS); | 284 | btrfs_set_opt(info->mount_opt, COMPRESS); |
285 | if (compress_force) { | 285 | if (compress_force) { |
286 | btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); | 286 | btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); |
287 | pr_info("btrfs: force %s compression\n", | 287 | pr_info("btrfs: force %s compression\n", |
288 | compress_type); | 288 | compress_type); |
289 | } else | 289 | } else |
290 | pr_info("btrfs: use %s compression\n", | 290 | pr_info("btrfs: use %s compression\n", |
291 | compress_type); | 291 | compress_type); |
292 | break; | 292 | break; |
293 | case Opt_ssd: | 293 | case Opt_ssd: |
294 | printk(KERN_INFO "btrfs: use ssd allocation scheme\n"); | 294 | printk(KERN_INFO "btrfs: use ssd allocation scheme\n"); |
295 | btrfs_set_opt(info->mount_opt, SSD); | 295 | btrfs_set_opt(info->mount_opt, SSD); |
296 | break; | 296 | break; |
297 | case Opt_ssd_spread: | 297 | case Opt_ssd_spread: |
298 | printk(KERN_INFO "btrfs: use spread ssd " | 298 | printk(KERN_INFO "btrfs: use spread ssd " |
299 | "allocation scheme\n"); | 299 | "allocation scheme\n"); |
300 | btrfs_set_opt(info->mount_opt, SSD); | 300 | btrfs_set_opt(info->mount_opt, SSD); |
301 | btrfs_set_opt(info->mount_opt, SSD_SPREAD); | 301 | btrfs_set_opt(info->mount_opt, SSD_SPREAD); |
302 | break; | 302 | break; |
303 | case Opt_nossd: | 303 | case Opt_nossd: |
304 | printk(KERN_INFO "btrfs: not using ssd allocation " | 304 | printk(KERN_INFO "btrfs: not using ssd allocation " |
305 | "scheme\n"); | 305 | "scheme\n"); |
306 | btrfs_set_opt(info->mount_opt, NOSSD); | 306 | btrfs_set_opt(info->mount_opt, NOSSD); |
307 | btrfs_clear_opt(info->mount_opt, SSD); | 307 | btrfs_clear_opt(info->mount_opt, SSD); |
308 | btrfs_clear_opt(info->mount_opt, SSD_SPREAD); | 308 | btrfs_clear_opt(info->mount_opt, SSD_SPREAD); |
309 | break; | 309 | break; |
310 | case Opt_nobarrier: | 310 | case Opt_nobarrier: |
311 | printk(KERN_INFO "btrfs: turning off barriers\n"); | 311 | printk(KERN_INFO "btrfs: turning off barriers\n"); |
312 | btrfs_set_opt(info->mount_opt, NOBARRIER); | 312 | btrfs_set_opt(info->mount_opt, NOBARRIER); |
313 | break; | 313 | break; |
314 | case Opt_thread_pool: | 314 | case Opt_thread_pool: |
315 | intarg = 0; | 315 | intarg = 0; |
316 | match_int(&args[0], &intarg); | 316 | match_int(&args[0], &intarg); |
317 | if (intarg) { | 317 | if (intarg) { |
318 | info->thread_pool_size = intarg; | 318 | info->thread_pool_size = intarg; |
319 | printk(KERN_INFO "btrfs: thread pool %d\n", | 319 | printk(KERN_INFO "btrfs: thread pool %d\n", |
320 | info->thread_pool_size); | 320 | info->thread_pool_size); |
321 | } | 321 | } |
322 | break; | 322 | break; |
323 | case Opt_max_inline: | 323 | case Opt_max_inline: |
324 | num = match_strdup(&args[0]); | 324 | num = match_strdup(&args[0]); |
325 | if (num) { | 325 | if (num) { |
326 | info->max_inline = memparse(num, NULL); | 326 | info->max_inline = memparse(num, NULL); |
327 | kfree(num); | 327 | kfree(num); |
328 | 328 | ||
329 | if (info->max_inline) { | 329 | if (info->max_inline) { |
330 | info->max_inline = max_t(u64, | 330 | info->max_inline = max_t(u64, |
331 | info->max_inline, | 331 | info->max_inline, |
332 | root->sectorsize); | 332 | root->sectorsize); |
333 | } | 333 | } |
334 | printk(KERN_INFO "btrfs: max_inline at %llu\n", | 334 | printk(KERN_INFO "btrfs: max_inline at %llu\n", |
335 | (unsigned long long)info->max_inline); | 335 | (unsigned long long)info->max_inline); |
336 | } | 336 | } |
337 | break; | 337 | break; |
338 | case Opt_alloc_start: | 338 | case Opt_alloc_start: |
339 | num = match_strdup(&args[0]); | 339 | num = match_strdup(&args[0]); |
340 | if (num) { | 340 | if (num) { |
341 | info->alloc_start = memparse(num, NULL); | 341 | info->alloc_start = memparse(num, NULL); |
342 | kfree(num); | 342 | kfree(num); |
343 | printk(KERN_INFO | 343 | printk(KERN_INFO |
344 | "btrfs: allocations start at %llu\n", | 344 | "btrfs: allocations start at %llu\n", |
345 | (unsigned long long)info->alloc_start); | 345 | (unsigned long long)info->alloc_start); |
346 | } | 346 | } |
347 | break; | 347 | break; |
348 | case Opt_noacl: | 348 | case Opt_noacl: |
349 | root->fs_info->sb->s_flags &= ~MS_POSIXACL; | 349 | root->fs_info->sb->s_flags &= ~MS_POSIXACL; |
350 | break; | 350 | break; |
351 | case Opt_notreelog: | 351 | case Opt_notreelog: |
352 | printk(KERN_INFO "btrfs: disabling tree log\n"); | 352 | printk(KERN_INFO "btrfs: disabling tree log\n"); |
353 | btrfs_set_opt(info->mount_opt, NOTREELOG); | 353 | btrfs_set_opt(info->mount_opt, NOTREELOG); |
354 | break; | 354 | break; |
355 | case Opt_flushoncommit: | 355 | case Opt_flushoncommit: |
356 | printk(KERN_INFO "btrfs: turning on flush-on-commit\n"); | 356 | printk(KERN_INFO "btrfs: turning on flush-on-commit\n"); |
357 | btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT); | 357 | btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT); |
358 | break; | 358 | break; |
359 | case Opt_ratio: | 359 | case Opt_ratio: |
360 | intarg = 0; | 360 | intarg = 0; |
361 | match_int(&args[0], &intarg); | 361 | match_int(&args[0], &intarg); |
362 | if (intarg) { | 362 | if (intarg) { |
363 | info->metadata_ratio = intarg; | 363 | info->metadata_ratio = intarg; |
364 | printk(KERN_INFO "btrfs: metadata ratio %d\n", | 364 | printk(KERN_INFO "btrfs: metadata ratio %d\n", |
365 | info->metadata_ratio); | 365 | info->metadata_ratio); |
366 | } | 366 | } |
367 | break; | 367 | break; |
368 | case Opt_discard: | 368 | case Opt_discard: |
369 | btrfs_set_opt(info->mount_opt, DISCARD); | 369 | btrfs_set_opt(info->mount_opt, DISCARD); |
370 | break; | 370 | break; |
371 | case Opt_space_cache: | 371 | case Opt_space_cache: |
372 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); | 372 | btrfs_set_opt(info->mount_opt, SPACE_CACHE); |
373 | break; | 373 | break; |
374 | case Opt_no_space_cache: | 374 | case Opt_no_space_cache: |
375 | printk(KERN_INFO "btrfs: disabling disk space caching\n"); | 375 | printk(KERN_INFO "btrfs: disabling disk space caching\n"); |
376 | btrfs_clear_opt(info->mount_opt, SPACE_CACHE); | 376 | btrfs_clear_opt(info->mount_opt, SPACE_CACHE); |
377 | break; | 377 | break; |
378 | case Opt_inode_cache: | 378 | case Opt_inode_cache: |
379 | printk(KERN_INFO "btrfs: enabling inode map caching\n"); | 379 | printk(KERN_INFO "btrfs: enabling inode map caching\n"); |
380 | btrfs_set_opt(info->mount_opt, INODE_MAP_CACHE); | 380 | btrfs_set_opt(info->mount_opt, INODE_MAP_CACHE); |
381 | break; | 381 | break; |
382 | case Opt_clear_cache: | 382 | case Opt_clear_cache: |
383 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); | 383 | printk(KERN_INFO "btrfs: force clearing of disk cache\n"); |
384 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); | 384 | btrfs_set_opt(info->mount_opt, CLEAR_CACHE); |
385 | break; | 385 | break; |
386 | case Opt_user_subvol_rm_allowed: | 386 | case Opt_user_subvol_rm_allowed: |
387 | btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); | 387 | btrfs_set_opt(info->mount_opt, USER_SUBVOL_RM_ALLOWED); |
388 | break; | 388 | break; |
389 | case Opt_enospc_debug: | 389 | case Opt_enospc_debug: |
390 | btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG); | 390 | btrfs_set_opt(info->mount_opt, ENOSPC_DEBUG); |
391 | break; | 391 | break; |
392 | case Opt_defrag: | 392 | case Opt_defrag: |
393 | printk(KERN_INFO "btrfs: enabling auto defrag"); | 393 | printk(KERN_INFO "btrfs: enabling auto defrag"); |
394 | btrfs_set_opt(info->mount_opt, AUTO_DEFRAG); | 394 | btrfs_set_opt(info->mount_opt, AUTO_DEFRAG); |
395 | break; | 395 | break; |
396 | case Opt_recovery: | 396 | case Opt_recovery: |
397 | printk(KERN_INFO "btrfs: enabling auto recovery"); | 397 | printk(KERN_INFO "btrfs: enabling auto recovery"); |
398 | btrfs_set_opt(info->mount_opt, RECOVERY); | 398 | btrfs_set_opt(info->mount_opt, RECOVERY); |
399 | break; | 399 | break; |
400 | case Opt_err: | 400 | case Opt_err: |
401 | printk(KERN_INFO "btrfs: unrecognized mount option " | 401 | printk(KERN_INFO "btrfs: unrecognized mount option " |
402 | "'%s'\n", p); | 402 | "'%s'\n", p); |
403 | ret = -EINVAL; | 403 | ret = -EINVAL; |
404 | goto out; | 404 | goto out; |
405 | default: | 405 | default: |
406 | break; | 406 | break; |
407 | } | 407 | } |
408 | } | 408 | } |
409 | out: | 409 | out: |
410 | if (!ret && btrfs_test_opt(root, SPACE_CACHE)) | 410 | if (!ret && btrfs_test_opt(root, SPACE_CACHE)) |
411 | printk(KERN_INFO "btrfs: disk space caching is enabled\n"); | 411 | printk(KERN_INFO "btrfs: disk space caching is enabled\n"); |
412 | kfree(orig); | 412 | kfree(orig); |
413 | return ret; | 413 | return ret; |
414 | } | 414 | } |
415 | 415 | ||
416 | /* | 416 | /* |
417 | * Parse mount options that are required early in the mount process. | 417 | * Parse mount options that are required early in the mount process. |
418 | * | 418 | * |
419 | * All other options will be parsed on much later in the mount process and | 419 | * All other options will be parsed on much later in the mount process and |
420 | * only when we need to allocate a new super block. | 420 | * only when we need to allocate a new super block. |
421 | */ | 421 | */ |
422 | static int btrfs_parse_early_options(const char *options, fmode_t flags, | 422 | static int btrfs_parse_early_options(const char *options, fmode_t flags, |
423 | void *holder, char **subvol_name, u64 *subvol_objectid, | 423 | void *holder, char **subvol_name, u64 *subvol_objectid, |
424 | u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices) | 424 | u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices) |
425 | { | 425 | { |
426 | substring_t args[MAX_OPT_ARGS]; | 426 | substring_t args[MAX_OPT_ARGS]; |
427 | char *device_name, *opts, *orig, *p; | 427 | char *device_name, *opts, *orig, *p; |
428 | int error = 0; | 428 | int error = 0; |
429 | int intarg; | 429 | int intarg; |
430 | 430 | ||
431 | if (!options) | 431 | if (!options) |
432 | return 0; | 432 | return 0; |
433 | 433 | ||
434 | /* | 434 | /* |
435 | * strsep changes the string, duplicate it because parse_options | 435 | * strsep changes the string, duplicate it because parse_options |
436 | * gets called twice | 436 | * gets called twice |
437 | */ | 437 | */ |
438 | opts = kstrdup(options, GFP_KERNEL); | 438 | opts = kstrdup(options, GFP_KERNEL); |
439 | if (!opts) | 439 | if (!opts) |
440 | return -ENOMEM; | 440 | return -ENOMEM; |
441 | orig = opts; | 441 | orig = opts; |
442 | 442 | ||
443 | while ((p = strsep(&opts, ",")) != NULL) { | 443 | while ((p = strsep(&opts, ",")) != NULL) { |
444 | int token; | 444 | int token; |
445 | if (!*p) | 445 | if (!*p) |
446 | continue; | 446 | continue; |
447 | 447 | ||
448 | token = match_token(p, tokens, args); | 448 | token = match_token(p, tokens, args); |
449 | switch (token) { | 449 | switch (token) { |
450 | case Opt_subvol: | 450 | case Opt_subvol: |
451 | kfree(*subvol_name); | 451 | kfree(*subvol_name); |
452 | *subvol_name = match_strdup(&args[0]); | 452 | *subvol_name = match_strdup(&args[0]); |
453 | break; | 453 | break; |
454 | case Opt_subvolid: | 454 | case Opt_subvolid: |
455 | intarg = 0; | 455 | intarg = 0; |
456 | error = match_int(&args[0], &intarg); | 456 | error = match_int(&args[0], &intarg); |
457 | if (!error) { | 457 | if (!error) { |
458 | /* we want the original fs_tree */ | 458 | /* we want the original fs_tree */ |
459 | if (!intarg) | 459 | if (!intarg) |
460 | *subvol_objectid = | 460 | *subvol_objectid = |
461 | BTRFS_FS_TREE_OBJECTID; | 461 | BTRFS_FS_TREE_OBJECTID; |
462 | else | 462 | else |
463 | *subvol_objectid = intarg; | 463 | *subvol_objectid = intarg; |
464 | } | 464 | } |
465 | break; | 465 | break; |
466 | case Opt_subvolrootid: | 466 | case Opt_subvolrootid: |
467 | intarg = 0; | 467 | intarg = 0; |
468 | error = match_int(&args[0], &intarg); | 468 | error = match_int(&args[0], &intarg); |
469 | if (!error) { | 469 | if (!error) { |
470 | /* we want the original fs_tree */ | 470 | /* we want the original fs_tree */ |
471 | if (!intarg) | 471 | if (!intarg) |
472 | *subvol_rootid = | 472 | *subvol_rootid = |
473 | BTRFS_FS_TREE_OBJECTID; | 473 | BTRFS_FS_TREE_OBJECTID; |
474 | else | 474 | else |
475 | *subvol_rootid = intarg; | 475 | *subvol_rootid = intarg; |
476 | } | 476 | } |
477 | break; | 477 | break; |
478 | case Opt_device: | 478 | case Opt_device: |
479 | device_name = match_strdup(&args[0]); | 479 | device_name = match_strdup(&args[0]); |
480 | if (!device_name) { | 480 | if (!device_name) { |
481 | error = -ENOMEM; | 481 | error = -ENOMEM; |
482 | goto out; | 482 | goto out; |
483 | } | 483 | } |
484 | error = btrfs_scan_one_device(device_name, | 484 | error = btrfs_scan_one_device(device_name, |
485 | flags, holder, fs_devices); | 485 | flags, holder, fs_devices); |
486 | kfree(device_name); | 486 | kfree(device_name); |
487 | if (error) | 487 | if (error) |
488 | goto out; | 488 | goto out; |
489 | break; | 489 | break; |
490 | default: | 490 | default: |
491 | break; | 491 | break; |
492 | } | 492 | } |
493 | } | 493 | } |
494 | 494 | ||
495 | out: | 495 | out: |
496 | kfree(orig); | 496 | kfree(orig); |
497 | return error; | 497 | return error; |
498 | } | 498 | } |
499 | 499 | ||
500 | static struct dentry *get_default_root(struct super_block *sb, | 500 | static struct dentry *get_default_root(struct super_block *sb, |
501 | u64 subvol_objectid) | 501 | u64 subvol_objectid) |
502 | { | 502 | { |
503 | struct btrfs_root *root = sb->s_fs_info; | 503 | struct btrfs_root *root = sb->s_fs_info; |
504 | struct btrfs_root *new_root; | 504 | struct btrfs_root *new_root; |
505 | struct btrfs_dir_item *di; | 505 | struct btrfs_dir_item *di; |
506 | struct btrfs_path *path; | 506 | struct btrfs_path *path; |
507 | struct btrfs_key location; | 507 | struct btrfs_key location; |
508 | struct inode *inode; | 508 | struct inode *inode; |
509 | u64 dir_id; | 509 | u64 dir_id; |
510 | int new = 0; | 510 | int new = 0; |
511 | 511 | ||
512 | /* | 512 | /* |
513 | * We have a specific subvol we want to mount, just setup location and | 513 | * We have a specific subvol we want to mount, just setup location and |
514 | * go look up the root. | 514 | * go look up the root. |
515 | */ | 515 | */ |
516 | if (subvol_objectid) { | 516 | if (subvol_objectid) { |
517 | location.objectid = subvol_objectid; | 517 | location.objectid = subvol_objectid; |
518 | location.type = BTRFS_ROOT_ITEM_KEY; | 518 | location.type = BTRFS_ROOT_ITEM_KEY; |
519 | location.offset = (u64)-1; | 519 | location.offset = (u64)-1; |
520 | goto find_root; | 520 | goto find_root; |
521 | } | 521 | } |
522 | 522 | ||
523 | path = btrfs_alloc_path(); | 523 | path = btrfs_alloc_path(); |
524 | if (!path) | 524 | if (!path) |
525 | return ERR_PTR(-ENOMEM); | 525 | return ERR_PTR(-ENOMEM); |
526 | path->leave_spinning = 1; | 526 | path->leave_spinning = 1; |
527 | 527 | ||
528 | /* | 528 | /* |
529 | * Find the "default" dir item which points to the root item that we | 529 | * Find the "default" dir item which points to the root item that we |
530 | * will mount by default if we haven't been given a specific subvolume | 530 | * will mount by default if we haven't been given a specific subvolume |
531 | * to mount. | 531 | * to mount. |
532 | */ | 532 | */ |
533 | dir_id = btrfs_super_root_dir(root->fs_info->super_copy); | 533 | dir_id = btrfs_super_root_dir(root->fs_info->super_copy); |
534 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); | 534 | di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0); |
535 | if (IS_ERR(di)) { | 535 | if (IS_ERR(di)) { |
536 | btrfs_free_path(path); | 536 | btrfs_free_path(path); |
537 | return ERR_CAST(di); | 537 | return ERR_CAST(di); |
538 | } | 538 | } |
539 | if (!di) { | 539 | if (!di) { |
540 | /* | 540 | /* |
541 | * Ok the default dir item isn't there. This is weird since | 541 | * Ok the default dir item isn't there. This is weird since |
542 | * it's always been there, but don't freak out, just try and | 542 | * it's always been there, but don't freak out, just try and |
543 | * mount to root most subvolume. | 543 | * mount to root most subvolume. |
544 | */ | 544 | */ |
545 | btrfs_free_path(path); | 545 | btrfs_free_path(path); |
546 | dir_id = BTRFS_FIRST_FREE_OBJECTID; | 546 | dir_id = BTRFS_FIRST_FREE_OBJECTID; |
547 | new_root = root->fs_info->fs_root; | 547 | new_root = root->fs_info->fs_root; |
548 | goto setup_root; | 548 | goto setup_root; |
549 | } | 549 | } |
550 | 550 | ||
551 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); | 551 | btrfs_dir_item_key_to_cpu(path->nodes[0], di, &location); |
552 | btrfs_free_path(path); | 552 | btrfs_free_path(path); |
553 | 553 | ||
554 | find_root: | 554 | find_root: |
555 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); | 555 | new_root = btrfs_read_fs_root_no_name(root->fs_info, &location); |
556 | if (IS_ERR(new_root)) | 556 | if (IS_ERR(new_root)) |
557 | return ERR_CAST(new_root); | 557 | return ERR_CAST(new_root); |
558 | 558 | ||
559 | if (btrfs_root_refs(&new_root->root_item) == 0) | 559 | if (btrfs_root_refs(&new_root->root_item) == 0) |
560 | return ERR_PTR(-ENOENT); | 560 | return ERR_PTR(-ENOENT); |
561 | 561 | ||
562 | dir_id = btrfs_root_dirid(&new_root->root_item); | 562 | dir_id = btrfs_root_dirid(&new_root->root_item); |
563 | setup_root: | 563 | setup_root: |
564 | location.objectid = dir_id; | 564 | location.objectid = dir_id; |
565 | location.type = BTRFS_INODE_ITEM_KEY; | 565 | location.type = BTRFS_INODE_ITEM_KEY; |
566 | location.offset = 0; | 566 | location.offset = 0; |
567 | 567 | ||
568 | inode = btrfs_iget(sb, &location, new_root, &new); | 568 | inode = btrfs_iget(sb, &location, new_root, &new); |
569 | if (IS_ERR(inode)) | 569 | if (IS_ERR(inode)) |
570 | return ERR_CAST(inode); | 570 | return ERR_CAST(inode); |
571 | 571 | ||
572 | /* | 572 | /* |
573 | * If we're just mounting the root most subvol put the inode and return | 573 | * If we're just mounting the root most subvol put the inode and return |
574 | * a reference to the dentry. We will have already gotten a reference | 574 | * a reference to the dentry. We will have already gotten a reference |
575 | * to the inode in btrfs_fill_super so we're good to go. | 575 | * to the inode in btrfs_fill_super so we're good to go. |
576 | */ | 576 | */ |
577 | if (!new && sb->s_root->d_inode == inode) { | 577 | if (!new && sb->s_root->d_inode == inode) { |
578 | iput(inode); | 578 | iput(inode); |
579 | return dget(sb->s_root); | 579 | return dget(sb->s_root); |
580 | } | 580 | } |
581 | 581 | ||
582 | return d_obtain_alias(inode); | 582 | return d_obtain_alias(inode); |
583 | } | 583 | } |
584 | 584 | ||
585 | static int btrfs_fill_super(struct super_block *sb, | 585 | static int btrfs_fill_super(struct super_block *sb, |
586 | struct btrfs_fs_devices *fs_devices, | 586 | struct btrfs_fs_devices *fs_devices, |
587 | void *data, int silent) | 587 | void *data, int silent) |
588 | { | 588 | { |
589 | struct inode *inode; | 589 | struct inode *inode; |
590 | struct dentry *root_dentry; | 590 | struct dentry *root_dentry; |
591 | struct btrfs_root *tree_root; | 591 | struct btrfs_root *tree_root; |
592 | struct btrfs_key key; | 592 | struct btrfs_key key; |
593 | int err; | 593 | int err; |
594 | 594 | ||
595 | sb->s_maxbytes = MAX_LFS_FILESIZE; | 595 | sb->s_maxbytes = MAX_LFS_FILESIZE; |
596 | sb->s_magic = BTRFS_SUPER_MAGIC; | 596 | sb->s_magic = BTRFS_SUPER_MAGIC; |
597 | sb->s_op = &btrfs_super_ops; | 597 | sb->s_op = &btrfs_super_ops; |
598 | sb->s_d_op = &btrfs_dentry_operations; | 598 | sb->s_d_op = &btrfs_dentry_operations; |
599 | sb->s_export_op = &btrfs_export_ops; | 599 | sb->s_export_op = &btrfs_export_ops; |
600 | sb->s_xattr = btrfs_xattr_handlers; | 600 | sb->s_xattr = btrfs_xattr_handlers; |
601 | sb->s_time_gran = 1; | 601 | sb->s_time_gran = 1; |
602 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL | 602 | #ifdef CONFIG_BTRFS_FS_POSIX_ACL |
603 | sb->s_flags |= MS_POSIXACL; | 603 | sb->s_flags |= MS_POSIXACL; |
604 | #endif | 604 | #endif |
605 | 605 | ||
606 | tree_root = open_ctree(sb, fs_devices, (char *)data); | 606 | tree_root = open_ctree(sb, fs_devices, (char *)data); |
607 | 607 | ||
608 | if (IS_ERR(tree_root)) { | 608 | if (IS_ERR(tree_root)) { |
609 | printk("btrfs: open_ctree failed\n"); | 609 | printk("btrfs: open_ctree failed\n"); |
610 | return PTR_ERR(tree_root); | 610 | return PTR_ERR(tree_root); |
611 | } | 611 | } |
612 | sb->s_fs_info = tree_root; | 612 | sb->s_fs_info = tree_root; |
613 | 613 | ||
614 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; | 614 | key.objectid = BTRFS_FIRST_FREE_OBJECTID; |
615 | key.type = BTRFS_INODE_ITEM_KEY; | 615 | key.type = BTRFS_INODE_ITEM_KEY; |
616 | key.offset = 0; | 616 | key.offset = 0; |
617 | inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL); | 617 | inode = btrfs_iget(sb, &key, tree_root->fs_info->fs_root, NULL); |
618 | if (IS_ERR(inode)) { | 618 | if (IS_ERR(inode)) { |
619 | err = PTR_ERR(inode); | 619 | err = PTR_ERR(inode); |
620 | goto fail_close; | 620 | goto fail_close; |
621 | } | 621 | } |
622 | 622 | ||
623 | root_dentry = d_alloc_root(inode); | 623 | root_dentry = d_alloc_root(inode); |
624 | if (!root_dentry) { | 624 | if (!root_dentry) { |
625 | iput(inode); | 625 | iput(inode); |
626 | err = -ENOMEM; | 626 | err = -ENOMEM; |
627 | goto fail_close; | 627 | goto fail_close; |
628 | } | 628 | } |
629 | 629 | ||
630 | sb->s_root = root_dentry; | 630 | sb->s_root = root_dentry; |
631 | 631 | ||
632 | save_mount_options(sb, data); | 632 | save_mount_options(sb, data); |
633 | cleancache_init_fs(sb); | 633 | cleancache_init_fs(sb); |
634 | return 0; | 634 | return 0; |
635 | 635 | ||
636 | fail_close: | 636 | fail_close: |
637 | close_ctree(tree_root); | 637 | close_ctree(tree_root); |
638 | return err; | 638 | return err; |
639 | } | 639 | } |
640 | 640 | ||
641 | int btrfs_sync_fs(struct super_block *sb, int wait) | 641 | int btrfs_sync_fs(struct super_block *sb, int wait) |
642 | { | 642 | { |
643 | struct btrfs_trans_handle *trans; | 643 | struct btrfs_trans_handle *trans; |
644 | struct btrfs_root *root = btrfs_sb(sb); | 644 | struct btrfs_root *root = btrfs_sb(sb); |
645 | int ret; | 645 | int ret; |
646 | 646 | ||
647 | trace_btrfs_sync_fs(wait); | 647 | trace_btrfs_sync_fs(wait); |
648 | 648 | ||
649 | if (!wait) { | 649 | if (!wait) { |
650 | filemap_flush(root->fs_info->btree_inode->i_mapping); | 650 | filemap_flush(root->fs_info->btree_inode->i_mapping); |
651 | return 0; | 651 | return 0; |
652 | } | 652 | } |
653 | 653 | ||
654 | btrfs_start_delalloc_inodes(root, 0); | 654 | btrfs_start_delalloc_inodes(root, 0); |
655 | btrfs_wait_ordered_extents(root, 0, 0); | 655 | btrfs_wait_ordered_extents(root, 0, 0); |
656 | 656 | ||
657 | trans = btrfs_start_transaction(root, 0); | 657 | trans = btrfs_start_transaction(root, 0); |
658 | if (IS_ERR(trans)) | 658 | if (IS_ERR(trans)) |
659 | return PTR_ERR(trans); | 659 | return PTR_ERR(trans); |
660 | ret = btrfs_commit_transaction(trans, root); | 660 | ret = btrfs_commit_transaction(trans, root); |
661 | return ret; | 661 | return ret; |
662 | } | 662 | } |
663 | 663 | ||
664 | static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) | 664 | static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs) |
665 | { | 665 | { |
666 | struct btrfs_root *root = btrfs_sb(vfs->mnt_sb); | 666 | struct btrfs_root *root = btrfs_sb(vfs->mnt_sb); |
667 | struct btrfs_fs_info *info = root->fs_info; | 667 | struct btrfs_fs_info *info = root->fs_info; |
668 | char *compress_type; | 668 | char *compress_type; |
669 | 669 | ||
670 | if (btrfs_test_opt(root, DEGRADED)) | 670 | if (btrfs_test_opt(root, DEGRADED)) |
671 | seq_puts(seq, ",degraded"); | 671 | seq_puts(seq, ",degraded"); |
672 | if (btrfs_test_opt(root, NODATASUM)) | 672 | if (btrfs_test_opt(root, NODATASUM)) |
673 | seq_puts(seq, ",nodatasum"); | 673 | seq_puts(seq, ",nodatasum"); |
674 | if (btrfs_test_opt(root, NODATACOW)) | 674 | if (btrfs_test_opt(root, NODATACOW)) |
675 | seq_puts(seq, ",nodatacow"); | 675 | seq_puts(seq, ",nodatacow"); |
676 | if (btrfs_test_opt(root, NOBARRIER)) | 676 | if (btrfs_test_opt(root, NOBARRIER)) |
677 | seq_puts(seq, ",nobarrier"); | 677 | seq_puts(seq, ",nobarrier"); |
678 | if (info->max_inline != 8192 * 1024) | 678 | if (info->max_inline != 8192 * 1024) |
679 | seq_printf(seq, ",max_inline=%llu", | 679 | seq_printf(seq, ",max_inline=%llu", |
680 | (unsigned long long)info->max_inline); | 680 | (unsigned long long)info->max_inline); |
681 | if (info->alloc_start != 0) | 681 | if (info->alloc_start != 0) |
682 | seq_printf(seq, ",alloc_start=%llu", | 682 | seq_printf(seq, ",alloc_start=%llu", |
683 | (unsigned long long)info->alloc_start); | 683 | (unsigned long long)info->alloc_start); |
684 | if (info->thread_pool_size != min_t(unsigned long, | 684 | if (info->thread_pool_size != min_t(unsigned long, |
685 | num_online_cpus() + 2, 8)) | 685 | num_online_cpus() + 2, 8)) |
686 | seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); | 686 | seq_printf(seq, ",thread_pool=%d", info->thread_pool_size); |
687 | if (btrfs_test_opt(root, COMPRESS)) { | 687 | if (btrfs_test_opt(root, COMPRESS)) { |
688 | if (info->compress_type == BTRFS_COMPRESS_ZLIB) | 688 | if (info->compress_type == BTRFS_COMPRESS_ZLIB) |
689 | compress_type = "zlib"; | 689 | compress_type = "zlib"; |
690 | else | 690 | else |
691 | compress_type = "lzo"; | 691 | compress_type = "lzo"; |
692 | if (btrfs_test_opt(root, FORCE_COMPRESS)) | 692 | if (btrfs_test_opt(root, FORCE_COMPRESS)) |
693 | seq_printf(seq, ",compress-force=%s", compress_type); | 693 | seq_printf(seq, ",compress-force=%s", compress_type); |
694 | else | 694 | else |
695 | seq_printf(seq, ",compress=%s", compress_type); | 695 | seq_printf(seq, ",compress=%s", compress_type); |
696 | } | 696 | } |
697 | if (btrfs_test_opt(root, NOSSD)) | 697 | if (btrfs_test_opt(root, NOSSD)) |
698 | seq_puts(seq, ",nossd"); | 698 | seq_puts(seq, ",nossd"); |
699 | if (btrfs_test_opt(root, SSD_SPREAD)) | 699 | if (btrfs_test_opt(root, SSD_SPREAD)) |
700 | seq_puts(seq, ",ssd_spread"); | 700 | seq_puts(seq, ",ssd_spread"); |
701 | else if (btrfs_test_opt(root, SSD)) | 701 | else if (btrfs_test_opt(root, SSD)) |
702 | seq_puts(seq, ",ssd"); | 702 | seq_puts(seq, ",ssd"); |
703 | if (btrfs_test_opt(root, NOTREELOG)) | 703 | if (btrfs_test_opt(root, NOTREELOG)) |
704 | seq_puts(seq, ",notreelog"); | 704 | seq_puts(seq, ",notreelog"); |
705 | if (btrfs_test_opt(root, FLUSHONCOMMIT)) | 705 | if (btrfs_test_opt(root, FLUSHONCOMMIT)) |
706 | seq_puts(seq, ",flushoncommit"); | 706 | seq_puts(seq, ",flushoncommit"); |
707 | if (btrfs_test_opt(root, DISCARD)) | 707 | if (btrfs_test_opt(root, DISCARD)) |
708 | seq_puts(seq, ",discard"); | 708 | seq_puts(seq, ",discard"); |
709 | if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) | 709 | if (!(root->fs_info->sb->s_flags & MS_POSIXACL)) |
710 | seq_puts(seq, ",noacl"); | 710 | seq_puts(seq, ",noacl"); |
711 | if (btrfs_test_opt(root, SPACE_CACHE)) | 711 | if (btrfs_test_opt(root, SPACE_CACHE)) |
712 | seq_puts(seq, ",space_cache"); | 712 | seq_puts(seq, ",space_cache"); |
713 | else | 713 | else |
714 | seq_puts(seq, ",no_space_cache"); | 714 | seq_puts(seq, ",no_space_cache"); |
715 | if (btrfs_test_opt(root, CLEAR_CACHE)) | 715 | if (btrfs_test_opt(root, CLEAR_CACHE)) |
716 | seq_puts(seq, ",clear_cache"); | 716 | seq_puts(seq, ",clear_cache"); |
717 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) | 717 | if (btrfs_test_opt(root, USER_SUBVOL_RM_ALLOWED)) |
718 | seq_puts(seq, ",user_subvol_rm_allowed"); | 718 | seq_puts(seq, ",user_subvol_rm_allowed"); |
719 | if (btrfs_test_opt(root, ENOSPC_DEBUG)) | 719 | if (btrfs_test_opt(root, ENOSPC_DEBUG)) |
720 | seq_puts(seq, ",enospc_debug"); | 720 | seq_puts(seq, ",enospc_debug"); |
721 | if (btrfs_test_opt(root, AUTO_DEFRAG)) | 721 | if (btrfs_test_opt(root, AUTO_DEFRAG)) |
722 | seq_puts(seq, ",autodefrag"); | 722 | seq_puts(seq, ",autodefrag"); |
723 | if (btrfs_test_opt(root, INODE_MAP_CACHE)) | 723 | if (btrfs_test_opt(root, INODE_MAP_CACHE)) |
724 | seq_puts(seq, ",inode_cache"); | 724 | seq_puts(seq, ",inode_cache"); |
725 | return 0; | 725 | return 0; |
726 | } | 726 | } |
727 | 727 | ||
728 | static int btrfs_test_super(struct super_block *s, void *data) | 728 | static int btrfs_test_super(struct super_block *s, void *data) |
729 | { | 729 | { |
730 | struct btrfs_root *test_root = data; | 730 | struct btrfs_root *test_root = data; |
731 | struct btrfs_root *root = btrfs_sb(s); | 731 | struct btrfs_root *root = btrfs_sb(s); |
732 | 732 | ||
733 | /* | 733 | /* |
734 | * If this super block is going away, return false as it | 734 | * If this super block is going away, return false as it |
735 | * can't match as an existing super block. | 735 | * can't match as an existing super block. |
736 | */ | 736 | */ |
737 | if (!atomic_read(&s->s_active)) | 737 | if (!atomic_read(&s->s_active)) |
738 | return 0; | 738 | return 0; |
739 | return root->fs_info->fs_devices == test_root->fs_info->fs_devices; | 739 | return root->fs_info->fs_devices == test_root->fs_info->fs_devices; |
740 | } | 740 | } |
741 | 741 | ||
742 | static int btrfs_set_super(struct super_block *s, void *data) | 742 | static int btrfs_set_super(struct super_block *s, void *data) |
743 | { | 743 | { |
744 | s->s_fs_info = data; | 744 | s->s_fs_info = data; |
745 | 745 | ||
746 | return set_anon_super(s, data); | 746 | return set_anon_super(s, data); |
747 | } | 747 | } |
748 | 748 | ||
749 | /* | 749 | /* |
750 | * subvolumes are identified by ino 256 | 750 | * subvolumes are identified by ino 256 |
751 | */ | 751 | */ |
752 | static inline int is_subvolume_inode(struct inode *inode) | 752 | static inline int is_subvolume_inode(struct inode *inode) |
753 | { | 753 | { |
754 | if (inode && inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | 754 | if (inode && inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) |
755 | return 1; | 755 | return 1; |
756 | return 0; | 756 | return 0; |
757 | } | 757 | } |
758 | 758 | ||
759 | /* | 759 | /* |
760 | * This will strip out the subvol=%s argument for an argument string and add | 760 | * This will strip out the subvol=%s argument for an argument string and add |
761 | * subvolid=0 to make sure we get the actual tree root for path walking to the | 761 | * subvolid=0 to make sure we get the actual tree root for path walking to the |
762 | * subvol we want. | 762 | * subvol we want. |
763 | */ | 763 | */ |
764 | static char *setup_root_args(char *args) | 764 | static char *setup_root_args(char *args) |
765 | { | 765 | { |
766 | unsigned copied = 0; | 766 | unsigned copied = 0; |
767 | unsigned len = strlen(args) + 2; | 767 | unsigned len = strlen(args) + 2; |
768 | char *pos; | 768 | char *pos; |
769 | char *ret; | 769 | char *ret; |
770 | 770 | ||
771 | /* | 771 | /* |
772 | * We need the same args as before, but minus | 772 | * We need the same args as before, but minus |
773 | * | 773 | * |
774 | * subvol=a | 774 | * subvol=a |
775 | * | 775 | * |
776 | * and add | 776 | * and add |
777 | * | 777 | * |
778 | * subvolid=0 | 778 | * subvolid=0 |
779 | * | 779 | * |
780 | * which is a difference of 2 characters, so we allocate strlen(args) + | 780 | * which is a difference of 2 characters, so we allocate strlen(args) + |
781 | * 2 characters. | 781 | * 2 characters. |
782 | */ | 782 | */ |
783 | ret = kzalloc(len * sizeof(char), GFP_NOFS); | 783 | ret = kzalloc(len * sizeof(char), GFP_NOFS); |
784 | if (!ret) | 784 | if (!ret) |
785 | return NULL; | 785 | return NULL; |
786 | pos = strstr(args, "subvol="); | 786 | pos = strstr(args, "subvol="); |
787 | 787 | ||
788 | /* This shouldn't happen, but just in case.. */ | 788 | /* This shouldn't happen, but just in case.. */ |
789 | if (!pos) { | 789 | if (!pos) { |
790 | kfree(ret); | 790 | kfree(ret); |
791 | return NULL; | 791 | return NULL; |
792 | } | 792 | } |
793 | 793 | ||
794 | /* | 794 | /* |
795 | * The subvol=<> arg is not at the front of the string, copy everybody | 795 | * The subvol=<> arg is not at the front of the string, copy everybody |
796 | * up to that into ret. | 796 | * up to that into ret. |
797 | */ | 797 | */ |
798 | if (pos != args) { | 798 | if (pos != args) { |
799 | *pos = '\0'; | 799 | *pos = '\0'; |
800 | strcpy(ret, args); | 800 | strcpy(ret, args); |
801 | copied += strlen(args); | 801 | copied += strlen(args); |
802 | pos++; | 802 | pos++; |
803 | } | 803 | } |
804 | 804 | ||
805 | strncpy(ret + copied, "subvolid=0", len - copied); | 805 | strncpy(ret + copied, "subvolid=0", len - copied); |
806 | 806 | ||
807 | /* Length of subvolid=0 */ | 807 | /* Length of subvolid=0 */ |
808 | copied += 10; | 808 | copied += 10; |
809 | 809 | ||
810 | /* | 810 | /* |
811 | * If there is no , after the subvol= option then we know there's no | 811 | * If there is no , after the subvol= option then we know there's no |
812 | * other options and we can just return. | 812 | * other options and we can just return. |
813 | */ | 813 | */ |
814 | pos = strchr(pos, ','); | 814 | pos = strchr(pos, ','); |
815 | if (!pos) | 815 | if (!pos) |
816 | return ret; | 816 | return ret; |
817 | 817 | ||
818 | /* Copy the rest of the arguments into our buffer */ | 818 | /* Copy the rest of the arguments into our buffer */ |
819 | strncpy(ret + copied, pos, len - copied); | 819 | strncpy(ret + copied, pos, len - copied); |
820 | copied += strlen(pos); | 820 | copied += strlen(pos); |
821 | 821 | ||
822 | return ret; | 822 | return ret; |
823 | } | 823 | } |
824 | 824 | ||
825 | static struct dentry *mount_subvol(const char *subvol_name, int flags, | 825 | static struct dentry *mount_subvol(const char *subvol_name, int flags, |
826 | const char *device_name, char *data) | 826 | const char *device_name, char *data) |
827 | { | 827 | { |
828 | struct super_block *s; | 828 | struct super_block *s; |
829 | struct dentry *root; | 829 | struct dentry *root; |
830 | struct vfsmount *mnt; | 830 | struct vfsmount *mnt; |
831 | struct mnt_namespace *ns_private; | 831 | struct mnt_namespace *ns_private; |
832 | char *newargs; | 832 | char *newargs; |
833 | struct path path; | 833 | struct path path; |
834 | int error; | 834 | int error; |
835 | 835 | ||
836 | newargs = setup_root_args(data); | 836 | newargs = setup_root_args(data); |
837 | if (!newargs) | 837 | if (!newargs) |
838 | return ERR_PTR(-ENOMEM); | 838 | return ERR_PTR(-ENOMEM); |
839 | mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name, | 839 | mnt = vfs_kern_mount(&btrfs_fs_type, flags, device_name, |
840 | newargs); | 840 | newargs); |
841 | kfree(newargs); | 841 | kfree(newargs); |
842 | if (IS_ERR(mnt)) | 842 | if (IS_ERR(mnt)) |
843 | return ERR_CAST(mnt); | 843 | return ERR_CAST(mnt); |
844 | 844 | ||
845 | ns_private = create_mnt_ns(mnt); | 845 | ns_private = create_mnt_ns(mnt); |
846 | if (IS_ERR(ns_private)) { | 846 | if (IS_ERR(ns_private)) { |
847 | mntput(mnt); | 847 | mntput(mnt); |
848 | return ERR_CAST(ns_private); | 848 | return ERR_CAST(ns_private); |
849 | } | 849 | } |
850 | 850 | ||
851 | /* | 851 | /* |
852 | * This will trigger the automount of the subvol so we can just | 852 | * This will trigger the automount of the subvol so we can just |
853 | * drop the mnt we have here and return the dentry that we | 853 | * drop the mnt we have here and return the dentry that we |
854 | * found. | 854 | * found. |
855 | */ | 855 | */ |
856 | error = vfs_path_lookup(mnt->mnt_root, mnt, subvol_name, | 856 | error = vfs_path_lookup(mnt->mnt_root, mnt, subvol_name, |
857 | LOOKUP_FOLLOW, &path); | 857 | LOOKUP_FOLLOW, &path); |
858 | put_mnt_ns(ns_private); | 858 | put_mnt_ns(ns_private); |
859 | if (error) | 859 | if (error) |
860 | return ERR_PTR(error); | 860 | return ERR_PTR(error); |
861 | 861 | ||
862 | if (!is_subvolume_inode(path.dentry->d_inode)) { | 862 | if (!is_subvolume_inode(path.dentry->d_inode)) { |
863 | path_put(&path); | 863 | path_put(&path); |
864 | mntput(mnt); | 864 | mntput(mnt); |
865 | error = -EINVAL; | 865 | error = -EINVAL; |
866 | printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n", | 866 | printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n", |
867 | subvol_name); | 867 | subvol_name); |
868 | return ERR_PTR(-EINVAL); | 868 | return ERR_PTR(-EINVAL); |
869 | } | 869 | } |
870 | 870 | ||
871 | /* Get a ref to the sb and the dentry we found and return it */ | 871 | /* Get a ref to the sb and the dentry we found and return it */ |
872 | s = path.mnt->mnt_sb; | 872 | s = path.mnt->mnt_sb; |
873 | atomic_inc(&s->s_active); | 873 | atomic_inc(&s->s_active); |
874 | root = dget(path.dentry); | 874 | root = dget(path.dentry); |
875 | path_put(&path); | 875 | path_put(&path); |
876 | down_write(&s->s_umount); | 876 | down_write(&s->s_umount); |
877 | 877 | ||
878 | return root; | 878 | return root; |
879 | } | 879 | } |
880 | 880 | ||
881 | /* | 881 | /* |
882 | * Find a superblock for the given device / mount point. | 882 | * Find a superblock for the given device / mount point. |
883 | * | 883 | * |
884 | * Note: This is based on get_sb_bdev from fs/super.c with a few additions | 884 | * Note: This is based on get_sb_bdev from fs/super.c with a few additions |
885 | * for multiple device setup. Make sure to keep it in sync. | 885 | * for multiple device setup. Make sure to keep it in sync. |
886 | */ | 886 | */ |
887 | static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | 887 | static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, |
888 | const char *device_name, void *data) | 888 | const char *device_name, void *data) |
889 | { | 889 | { |
890 | struct block_device *bdev = NULL; | 890 | struct block_device *bdev = NULL; |
891 | struct super_block *s; | 891 | struct super_block *s; |
892 | struct dentry *root; | 892 | struct dentry *root; |
893 | struct btrfs_fs_devices *fs_devices = NULL; | 893 | struct btrfs_fs_devices *fs_devices = NULL; |
894 | struct btrfs_root *tree_root = NULL; | 894 | struct btrfs_root *tree_root = NULL; |
895 | struct btrfs_fs_info *fs_info = NULL; | 895 | struct btrfs_fs_info *fs_info = NULL; |
896 | fmode_t mode = FMODE_READ; | 896 | fmode_t mode = FMODE_READ; |
897 | char *subvol_name = NULL; | 897 | char *subvol_name = NULL; |
898 | u64 subvol_objectid = 0; | 898 | u64 subvol_objectid = 0; |
899 | u64 subvol_rootid = 0; | 899 | u64 subvol_rootid = 0; |
900 | int error = 0; | 900 | int error = 0; |
901 | 901 | ||
902 | if (!(flags & MS_RDONLY)) | 902 | if (!(flags & MS_RDONLY)) |
903 | mode |= FMODE_WRITE; | 903 | mode |= FMODE_WRITE; |
904 | 904 | ||
905 | error = btrfs_parse_early_options(data, mode, fs_type, | 905 | error = btrfs_parse_early_options(data, mode, fs_type, |
906 | &subvol_name, &subvol_objectid, | 906 | &subvol_name, &subvol_objectid, |
907 | &subvol_rootid, &fs_devices); | 907 | &subvol_rootid, &fs_devices); |
908 | if (error) | 908 | if (error) { |
909 | kfree(subvol_name); | ||
909 | return ERR_PTR(error); | 910 | return ERR_PTR(error); |
911 | } | ||
910 | 912 | ||
911 | if (subvol_name) { | 913 | if (subvol_name) { |
912 | root = mount_subvol(subvol_name, flags, device_name, data); | 914 | root = mount_subvol(subvol_name, flags, device_name, data); |
913 | kfree(subvol_name); | 915 | kfree(subvol_name); |
914 | return root; | 916 | return root; |
915 | } | 917 | } |
916 | 918 | ||
917 | error = btrfs_scan_one_device(device_name, mode, fs_type, &fs_devices); | 919 | error = btrfs_scan_one_device(device_name, mode, fs_type, &fs_devices); |
918 | if (error) | 920 | if (error) |
919 | return ERR_PTR(error); | 921 | return ERR_PTR(error); |
920 | 922 | ||
921 | error = btrfs_open_devices(fs_devices, mode, fs_type); | 923 | error = btrfs_open_devices(fs_devices, mode, fs_type); |
922 | if (error) | 924 | if (error) |
923 | return ERR_PTR(error); | 925 | return ERR_PTR(error); |
924 | 926 | ||
925 | if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) { | 927 | if (!(flags & MS_RDONLY) && fs_devices->rw_devices == 0) { |
926 | error = -EACCES; | 928 | error = -EACCES; |
927 | goto error_close_devices; | 929 | goto error_close_devices; |
928 | } | 930 | } |
929 | 931 | ||
930 | /* | 932 | /* |
931 | * Setup a dummy root and fs_info for test/set super. This is because | 933 | * Setup a dummy root and fs_info for test/set super. This is because |
932 | * we don't actually fill this stuff out until open_ctree, but we need | 934 | * we don't actually fill this stuff out until open_ctree, but we need |
933 | * it for searching for existing supers, so this lets us do that and | 935 | * it for searching for existing supers, so this lets us do that and |
934 | * then open_ctree will properly initialize everything later. | 936 | * then open_ctree will properly initialize everything later. |
935 | */ | 937 | */ |
936 | fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); | 938 | fs_info = kzalloc(sizeof(struct btrfs_fs_info), GFP_NOFS); |
937 | if (!fs_info) { | 939 | if (!fs_info) { |
938 | error = -ENOMEM; | 940 | error = -ENOMEM; |
939 | goto error_close_devices; | 941 | goto error_close_devices; |
940 | } | 942 | } |
941 | tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); | 943 | tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS); |
942 | if (!tree_root) { | 944 | if (!tree_root) { |
943 | error = -ENOMEM; | 945 | error = -ENOMEM; |
944 | goto error_close_devices; | 946 | goto error_close_devices; |
945 | } | 947 | } |
946 | fs_info->tree_root = tree_root; | 948 | fs_info->tree_root = tree_root; |
947 | fs_info->fs_devices = fs_devices; | 949 | fs_info->fs_devices = fs_devices; |
948 | tree_root->fs_info = fs_info; | 950 | tree_root->fs_info = fs_info; |
949 | 951 | ||
950 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | 952 | fs_info->super_copy = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); |
951 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); | 953 | fs_info->super_for_commit = kzalloc(BTRFS_SUPER_INFO_SIZE, GFP_NOFS); |
952 | if (!fs_info->super_copy || !fs_info->super_for_commit) { | 954 | if (!fs_info->super_copy || !fs_info->super_for_commit) { |
953 | error = -ENOMEM; | 955 | error = -ENOMEM; |
954 | goto error_close_devices; | 956 | goto error_close_devices; |
955 | } | 957 | } |
956 | 958 | ||
957 | bdev = fs_devices->latest_bdev; | 959 | bdev = fs_devices->latest_bdev; |
958 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); | 960 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, tree_root); |
959 | if (IS_ERR(s)) { | 961 | if (IS_ERR(s)) { |
960 | error = PTR_ERR(s); | 962 | error = PTR_ERR(s); |
961 | goto error_close_devices; | 963 | goto error_close_devices; |
962 | } | 964 | } |
963 | 965 | ||
964 | if (s->s_root) { | 966 | if (s->s_root) { |
965 | if ((flags ^ s->s_flags) & MS_RDONLY) { | 967 | if ((flags ^ s->s_flags) & MS_RDONLY) { |
966 | deactivate_locked_super(s); | 968 | deactivate_locked_super(s); |
967 | return ERR_PTR(-EBUSY); | 969 | return ERR_PTR(-EBUSY); |
968 | } | 970 | } |
969 | 971 | ||
970 | btrfs_close_devices(fs_devices); | 972 | btrfs_close_devices(fs_devices); |
971 | free_fs_info(fs_info); | 973 | free_fs_info(fs_info); |
972 | } else { | 974 | } else { |
973 | char b[BDEVNAME_SIZE]; | 975 | char b[BDEVNAME_SIZE]; |
974 | 976 | ||
975 | s->s_flags = flags | MS_NOSEC; | 977 | s->s_flags = flags | MS_NOSEC; |
976 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 978 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); |
977 | btrfs_sb(s)->fs_info->bdev_holder = fs_type; | 979 | btrfs_sb(s)->fs_info->bdev_holder = fs_type; |
978 | error = btrfs_fill_super(s, fs_devices, data, | 980 | error = btrfs_fill_super(s, fs_devices, data, |
979 | flags & MS_SILENT ? 1 : 0); | 981 | flags & MS_SILENT ? 1 : 0); |
980 | if (error) { | 982 | if (error) { |
981 | deactivate_locked_super(s); | 983 | deactivate_locked_super(s); |
982 | return ERR_PTR(error); | 984 | return ERR_PTR(error); |
983 | } | 985 | } |
984 | 986 | ||
985 | s->s_flags |= MS_ACTIVE; | 987 | s->s_flags |= MS_ACTIVE; |
986 | } | 988 | } |
987 | 989 | ||
988 | root = get_default_root(s, subvol_objectid); | 990 | root = get_default_root(s, subvol_objectid); |
989 | if (IS_ERR(root)) { | 991 | if (IS_ERR(root)) { |
990 | deactivate_locked_super(s); | 992 | deactivate_locked_super(s); |
991 | return root; | 993 | return root; |
992 | } | 994 | } |
993 | 995 | ||
994 | return root; | 996 | return root; |
995 | 997 | ||
996 | error_close_devices: | 998 | error_close_devices: |
997 | btrfs_close_devices(fs_devices); | 999 | btrfs_close_devices(fs_devices); |
998 | free_fs_info(fs_info); | 1000 | free_fs_info(fs_info); |
999 | return ERR_PTR(error); | 1001 | return ERR_PTR(error); |
1000 | } | 1002 | } |
1001 | 1003 | ||
1002 | static int btrfs_remount(struct super_block *sb, int *flags, char *data) | 1004 | static int btrfs_remount(struct super_block *sb, int *flags, char *data) |
1003 | { | 1005 | { |
1004 | struct btrfs_root *root = btrfs_sb(sb); | 1006 | struct btrfs_root *root = btrfs_sb(sb); |
1005 | int ret; | 1007 | int ret; |
1006 | 1008 | ||
1007 | ret = btrfs_parse_options(root, data); | 1009 | ret = btrfs_parse_options(root, data); |
1008 | if (ret) | 1010 | if (ret) |
1009 | return -EINVAL; | 1011 | return -EINVAL; |
1010 | 1012 | ||
1011 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) | 1013 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) |
1012 | return 0; | 1014 | return 0; |
1013 | 1015 | ||
1014 | if (*flags & MS_RDONLY) { | 1016 | if (*flags & MS_RDONLY) { |
1015 | sb->s_flags |= MS_RDONLY; | 1017 | sb->s_flags |= MS_RDONLY; |
1016 | 1018 | ||
1017 | ret = btrfs_commit_super(root); | 1019 | ret = btrfs_commit_super(root); |
1018 | WARN_ON(ret); | 1020 | WARN_ON(ret); |
1019 | } else { | 1021 | } else { |
1020 | if (root->fs_info->fs_devices->rw_devices == 0) | 1022 | if (root->fs_info->fs_devices->rw_devices == 0) |
1021 | return -EACCES; | 1023 | return -EACCES; |
1022 | 1024 | ||
1023 | if (btrfs_super_log_root(root->fs_info->super_copy) != 0) | 1025 | if (btrfs_super_log_root(root->fs_info->super_copy) != 0) |
1024 | return -EINVAL; | 1026 | return -EINVAL; |
1025 | 1027 | ||
1026 | ret = btrfs_cleanup_fs_roots(root->fs_info); | 1028 | ret = btrfs_cleanup_fs_roots(root->fs_info); |
1027 | WARN_ON(ret); | 1029 | WARN_ON(ret); |
1028 | 1030 | ||
1029 | /* recover relocation */ | 1031 | /* recover relocation */ |
1030 | ret = btrfs_recover_relocation(root); | 1032 | ret = btrfs_recover_relocation(root); |
1031 | WARN_ON(ret); | 1033 | WARN_ON(ret); |
1032 | 1034 | ||
1033 | sb->s_flags &= ~MS_RDONLY; | 1035 | sb->s_flags &= ~MS_RDONLY; |
1034 | } | 1036 | } |
1035 | 1037 | ||
1036 | return 0; | 1038 | return 0; |
1037 | } | 1039 | } |
1038 | 1040 | ||
1039 | /* Used to sort the devices by max_avail(descending sort) */ | 1041 | /* Used to sort the devices by max_avail(descending sort) */ |
1040 | static int btrfs_cmp_device_free_bytes(const void *dev_info1, | 1042 | static int btrfs_cmp_device_free_bytes(const void *dev_info1, |
1041 | const void *dev_info2) | 1043 | const void *dev_info2) |
1042 | { | 1044 | { |
1043 | if (((struct btrfs_device_info *)dev_info1)->max_avail > | 1045 | if (((struct btrfs_device_info *)dev_info1)->max_avail > |
1044 | ((struct btrfs_device_info *)dev_info2)->max_avail) | 1046 | ((struct btrfs_device_info *)dev_info2)->max_avail) |
1045 | return -1; | 1047 | return -1; |
1046 | else if (((struct btrfs_device_info *)dev_info1)->max_avail < | 1048 | else if (((struct btrfs_device_info *)dev_info1)->max_avail < |
1047 | ((struct btrfs_device_info *)dev_info2)->max_avail) | 1049 | ((struct btrfs_device_info *)dev_info2)->max_avail) |
1048 | return 1; | 1050 | return 1; |
1049 | else | 1051 | else |
1050 | return 0; | 1052 | return 0; |
1051 | } | 1053 | } |
1052 | 1054 | ||
1053 | /* | 1055 | /* |
1054 | * sort the devices by max_avail, in which max free extent size of each device | 1056 | * sort the devices by max_avail, in which max free extent size of each device |
1055 | * is stored.(Descending Sort) | 1057 | * is stored.(Descending Sort) |
1056 | */ | 1058 | */ |
1057 | static inline void btrfs_descending_sort_devices( | 1059 | static inline void btrfs_descending_sort_devices( |
1058 | struct btrfs_device_info *devices, | 1060 | struct btrfs_device_info *devices, |
1059 | size_t nr_devices) | 1061 | size_t nr_devices) |
1060 | { | 1062 | { |
1061 | sort(devices, nr_devices, sizeof(struct btrfs_device_info), | 1063 | sort(devices, nr_devices, sizeof(struct btrfs_device_info), |
1062 | btrfs_cmp_device_free_bytes, NULL); | 1064 | btrfs_cmp_device_free_bytes, NULL); |
1063 | } | 1065 | } |
1064 | 1066 | ||
1065 | /* | 1067 | /* |
1066 | * The helper to calc the free space on the devices that can be used to store | 1068 | * The helper to calc the free space on the devices that can be used to store |
1067 | * file data. | 1069 | * file data. |
1068 | */ | 1070 | */ |
1069 | static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) | 1071 | static int btrfs_calc_avail_data_space(struct btrfs_root *root, u64 *free_bytes) |
1070 | { | 1072 | { |
1071 | struct btrfs_fs_info *fs_info = root->fs_info; | 1073 | struct btrfs_fs_info *fs_info = root->fs_info; |
1072 | struct btrfs_device_info *devices_info; | 1074 | struct btrfs_device_info *devices_info; |
1073 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; | 1075 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; |
1074 | struct btrfs_device *device; | 1076 | struct btrfs_device *device; |
1075 | u64 skip_space; | 1077 | u64 skip_space; |
1076 | u64 type; | 1078 | u64 type; |
1077 | u64 avail_space; | 1079 | u64 avail_space; |
1078 | u64 used_space; | 1080 | u64 used_space; |
1079 | u64 min_stripe_size; | 1081 | u64 min_stripe_size; |
1080 | int min_stripes = 1; | 1082 | int min_stripes = 1; |
1081 | int i = 0, nr_devices; | 1083 | int i = 0, nr_devices; |
1082 | int ret; | 1084 | int ret; |
1083 | 1085 | ||
1084 | nr_devices = fs_info->fs_devices->rw_devices; | 1086 | nr_devices = fs_info->fs_devices->rw_devices; |
1085 | BUG_ON(!nr_devices); | 1087 | BUG_ON(!nr_devices); |
1086 | 1088 | ||
1087 | devices_info = kmalloc(sizeof(*devices_info) * nr_devices, | 1089 | devices_info = kmalloc(sizeof(*devices_info) * nr_devices, |
1088 | GFP_NOFS); | 1090 | GFP_NOFS); |
1089 | if (!devices_info) | 1091 | if (!devices_info) |
1090 | return -ENOMEM; | 1092 | return -ENOMEM; |
1091 | 1093 | ||
1092 | /* calc min stripe number for data space alloction */ | 1094 | /* calc min stripe number for data space alloction */ |
1093 | type = btrfs_get_alloc_profile(root, 1); | 1095 | type = btrfs_get_alloc_profile(root, 1); |
1094 | if (type & BTRFS_BLOCK_GROUP_RAID0) | 1096 | if (type & BTRFS_BLOCK_GROUP_RAID0) |
1095 | min_stripes = 2; | 1097 | min_stripes = 2; |
1096 | else if (type & BTRFS_BLOCK_GROUP_RAID1) | 1098 | else if (type & BTRFS_BLOCK_GROUP_RAID1) |
1097 | min_stripes = 2; | 1099 | min_stripes = 2; |
1098 | else if (type & BTRFS_BLOCK_GROUP_RAID10) | 1100 | else if (type & BTRFS_BLOCK_GROUP_RAID10) |
1099 | min_stripes = 4; | 1101 | min_stripes = 4; |
1100 | 1102 | ||
1101 | if (type & BTRFS_BLOCK_GROUP_DUP) | 1103 | if (type & BTRFS_BLOCK_GROUP_DUP) |
1102 | min_stripe_size = 2 * BTRFS_STRIPE_LEN; | 1104 | min_stripe_size = 2 * BTRFS_STRIPE_LEN; |
1103 | else | 1105 | else |
1104 | min_stripe_size = BTRFS_STRIPE_LEN; | 1106 | min_stripe_size = BTRFS_STRIPE_LEN; |
1105 | 1107 | ||
1106 | list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { | 1108 | list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { |
1107 | if (!device->in_fs_metadata) | 1109 | if (!device->in_fs_metadata) |
1108 | continue; | 1110 | continue; |
1109 | 1111 | ||
1110 | avail_space = device->total_bytes - device->bytes_used; | 1112 | avail_space = device->total_bytes - device->bytes_used; |
1111 | 1113 | ||
1112 | /* align with stripe_len */ | 1114 | /* align with stripe_len */ |
1113 | do_div(avail_space, BTRFS_STRIPE_LEN); | 1115 | do_div(avail_space, BTRFS_STRIPE_LEN); |
1114 | avail_space *= BTRFS_STRIPE_LEN; | 1116 | avail_space *= BTRFS_STRIPE_LEN; |
1115 | 1117 | ||
1116 | /* | 1118 | /* |
1117 | * In order to avoid overwritting the superblock on the drive, | 1119 | * In order to avoid overwritting the superblock on the drive, |
1118 | * btrfs starts at an offset of at least 1MB when doing chunk | 1120 | * btrfs starts at an offset of at least 1MB when doing chunk |
1119 | * allocation. | 1121 | * allocation. |
1120 | */ | 1122 | */ |
1121 | skip_space = 1024 * 1024; | 1123 | skip_space = 1024 * 1024; |
1122 | 1124 | ||
1123 | /* user can set the offset in fs_info->alloc_start. */ | 1125 | /* user can set the offset in fs_info->alloc_start. */ |
1124 | if (fs_info->alloc_start + BTRFS_STRIPE_LEN <= | 1126 | if (fs_info->alloc_start + BTRFS_STRIPE_LEN <= |
1125 | device->total_bytes) | 1127 | device->total_bytes) |
1126 | skip_space = max(fs_info->alloc_start, skip_space); | 1128 | skip_space = max(fs_info->alloc_start, skip_space); |
1127 | 1129 | ||
1128 | /* | 1130 | /* |
1129 | * btrfs can not use the free space in [0, skip_space - 1], | 1131 | * btrfs can not use the free space in [0, skip_space - 1], |
1130 | * we must subtract it from the total. In order to implement | 1132 | * we must subtract it from the total. In order to implement |
1131 | * it, we account the used space in this range first. | 1133 | * it, we account the used space in this range first. |
1132 | */ | 1134 | */ |
1133 | ret = btrfs_account_dev_extents_size(device, 0, skip_space - 1, | 1135 | ret = btrfs_account_dev_extents_size(device, 0, skip_space - 1, |
1134 | &used_space); | 1136 | &used_space); |
1135 | if (ret) { | 1137 | if (ret) { |
1136 | kfree(devices_info); | 1138 | kfree(devices_info); |
1137 | return ret; | 1139 | return ret; |
1138 | } | 1140 | } |
1139 | 1141 | ||
1140 | /* calc the free space in [0, skip_space - 1] */ | 1142 | /* calc the free space in [0, skip_space - 1] */ |
1141 | skip_space -= used_space; | 1143 | skip_space -= used_space; |
1142 | 1144 | ||
1143 | /* | 1145 | /* |
1144 | * we can use the free space in [0, skip_space - 1], subtract | 1146 | * we can use the free space in [0, skip_space - 1], subtract |
1145 | * it from the total. | 1147 | * it from the total. |
1146 | */ | 1148 | */ |
1147 | if (avail_space && avail_space >= skip_space) | 1149 | if (avail_space && avail_space >= skip_space) |
1148 | avail_space -= skip_space; | 1150 | avail_space -= skip_space; |
1149 | else | 1151 | else |
1150 | avail_space = 0; | 1152 | avail_space = 0; |
1151 | 1153 | ||
1152 | if (avail_space < min_stripe_size) | 1154 | if (avail_space < min_stripe_size) |
1153 | continue; | 1155 | continue; |
1154 | 1156 | ||
1155 | devices_info[i].dev = device; | 1157 | devices_info[i].dev = device; |
1156 | devices_info[i].max_avail = avail_space; | 1158 | devices_info[i].max_avail = avail_space; |
1157 | 1159 | ||
1158 | i++; | 1160 | i++; |
1159 | } | 1161 | } |
1160 | 1162 | ||
1161 | nr_devices = i; | 1163 | nr_devices = i; |
1162 | 1164 | ||
1163 | btrfs_descending_sort_devices(devices_info, nr_devices); | 1165 | btrfs_descending_sort_devices(devices_info, nr_devices); |
1164 | 1166 | ||
1165 | i = nr_devices - 1; | 1167 | i = nr_devices - 1; |
1166 | avail_space = 0; | 1168 | avail_space = 0; |
1167 | while (nr_devices >= min_stripes) { | 1169 | while (nr_devices >= min_stripes) { |
1168 | if (devices_info[i].max_avail >= min_stripe_size) { | 1170 | if (devices_info[i].max_avail >= min_stripe_size) { |
1169 | int j; | 1171 | int j; |
1170 | u64 alloc_size; | 1172 | u64 alloc_size; |
1171 | 1173 | ||
1172 | avail_space += devices_info[i].max_avail * min_stripes; | 1174 | avail_space += devices_info[i].max_avail * min_stripes; |
1173 | alloc_size = devices_info[i].max_avail; | 1175 | alloc_size = devices_info[i].max_avail; |
1174 | for (j = i + 1 - min_stripes; j <= i; j++) | 1176 | for (j = i + 1 - min_stripes; j <= i; j++) |
1175 | devices_info[j].max_avail -= alloc_size; | 1177 | devices_info[j].max_avail -= alloc_size; |
1176 | } | 1178 | } |
1177 | i--; | 1179 | i--; |
1178 | nr_devices--; | 1180 | nr_devices--; |
1179 | } | 1181 | } |
1180 | 1182 | ||
1181 | kfree(devices_info); | 1183 | kfree(devices_info); |
1182 | *free_bytes = avail_space; | 1184 | *free_bytes = avail_space; |
1183 | return 0; | 1185 | return 0; |
1184 | } | 1186 | } |
1185 | 1187 | ||
1186 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 1188 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
1187 | { | 1189 | { |
1188 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); | 1190 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); |
1189 | struct btrfs_super_block *disk_super = root->fs_info->super_copy; | 1191 | struct btrfs_super_block *disk_super = root->fs_info->super_copy; |
1190 | struct list_head *head = &root->fs_info->space_info; | 1192 | struct list_head *head = &root->fs_info->space_info; |
1191 | struct btrfs_space_info *found; | 1193 | struct btrfs_space_info *found; |
1192 | u64 total_used = 0; | 1194 | u64 total_used = 0; |
1193 | u64 total_free_data = 0; | 1195 | u64 total_free_data = 0; |
1194 | int bits = dentry->d_sb->s_blocksize_bits; | 1196 | int bits = dentry->d_sb->s_blocksize_bits; |
1195 | __be32 *fsid = (__be32 *)root->fs_info->fsid; | 1197 | __be32 *fsid = (__be32 *)root->fs_info->fsid; |
1196 | int ret; | 1198 | int ret; |
1197 | 1199 | ||
1198 | /* holding chunk_muext to avoid allocating new chunks */ | 1200 | /* holding chunk_muext to avoid allocating new chunks */ |
1199 | mutex_lock(&root->fs_info->chunk_mutex); | 1201 | mutex_lock(&root->fs_info->chunk_mutex); |
1200 | rcu_read_lock(); | 1202 | rcu_read_lock(); |
1201 | list_for_each_entry_rcu(found, head, list) { | 1203 | list_for_each_entry_rcu(found, head, list) { |
1202 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { | 1204 | if (found->flags & BTRFS_BLOCK_GROUP_DATA) { |
1203 | total_free_data += found->disk_total - found->disk_used; | 1205 | total_free_data += found->disk_total - found->disk_used; |
1204 | total_free_data -= | 1206 | total_free_data -= |
1205 | btrfs_account_ro_block_groups_free_space(found); | 1207 | btrfs_account_ro_block_groups_free_space(found); |
1206 | } | 1208 | } |
1207 | 1209 | ||
1208 | total_used += found->disk_used; | 1210 | total_used += found->disk_used; |
1209 | } | 1211 | } |
1210 | rcu_read_unlock(); | 1212 | rcu_read_unlock(); |
1211 | 1213 | ||
1212 | buf->f_namelen = BTRFS_NAME_LEN; | 1214 | buf->f_namelen = BTRFS_NAME_LEN; |
1213 | buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; | 1215 | buf->f_blocks = btrfs_super_total_bytes(disk_super) >> bits; |
1214 | buf->f_bfree = buf->f_blocks - (total_used >> bits); | 1216 | buf->f_bfree = buf->f_blocks - (total_used >> bits); |
1215 | buf->f_bsize = dentry->d_sb->s_blocksize; | 1217 | buf->f_bsize = dentry->d_sb->s_blocksize; |
1216 | buf->f_type = BTRFS_SUPER_MAGIC; | 1218 | buf->f_type = BTRFS_SUPER_MAGIC; |
1217 | buf->f_bavail = total_free_data; | 1219 | buf->f_bavail = total_free_data; |
1218 | ret = btrfs_calc_avail_data_space(root, &total_free_data); | 1220 | ret = btrfs_calc_avail_data_space(root, &total_free_data); |
1219 | if (ret) { | 1221 | if (ret) { |
1220 | mutex_unlock(&root->fs_info->chunk_mutex); | 1222 | mutex_unlock(&root->fs_info->chunk_mutex); |
1221 | return ret; | 1223 | return ret; |
1222 | } | 1224 | } |
1223 | buf->f_bavail += total_free_data; | 1225 | buf->f_bavail += total_free_data; |
1224 | buf->f_bavail = buf->f_bavail >> bits; | 1226 | buf->f_bavail = buf->f_bavail >> bits; |
1225 | mutex_unlock(&root->fs_info->chunk_mutex); | 1227 | mutex_unlock(&root->fs_info->chunk_mutex); |
1226 | 1228 | ||
1227 | /* We treat it as constant endianness (it doesn't matter _which_) | 1229 | /* We treat it as constant endianness (it doesn't matter _which_) |
1228 | because we want the fsid to come out the same whether mounted | 1230 | because we want the fsid to come out the same whether mounted |
1229 | on a big-endian or little-endian host */ | 1231 | on a big-endian or little-endian host */ |
1230 | buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]); | 1232 | buf->f_fsid.val[0] = be32_to_cpu(fsid[0]) ^ be32_to_cpu(fsid[2]); |
1231 | buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]); | 1233 | buf->f_fsid.val[1] = be32_to_cpu(fsid[1]) ^ be32_to_cpu(fsid[3]); |
1232 | /* Mask in the root object ID too, to disambiguate subvols */ | 1234 | /* Mask in the root object ID too, to disambiguate subvols */ |
1233 | buf->f_fsid.val[0] ^= BTRFS_I(dentry->d_inode)->root->objectid >> 32; | 1235 | buf->f_fsid.val[0] ^= BTRFS_I(dentry->d_inode)->root->objectid >> 32; |
1234 | buf->f_fsid.val[1] ^= BTRFS_I(dentry->d_inode)->root->objectid; | 1236 | buf->f_fsid.val[1] ^= BTRFS_I(dentry->d_inode)->root->objectid; |
1235 | 1237 | ||
1236 | return 0; | 1238 | return 0; |
1237 | } | 1239 | } |
1238 | 1240 | ||
1239 | static struct file_system_type btrfs_fs_type = { | 1241 | static struct file_system_type btrfs_fs_type = { |
1240 | .owner = THIS_MODULE, | 1242 | .owner = THIS_MODULE, |
1241 | .name = "btrfs", | 1243 | .name = "btrfs", |
1242 | .mount = btrfs_mount, | 1244 | .mount = btrfs_mount, |
1243 | .kill_sb = kill_anon_super, | 1245 | .kill_sb = kill_anon_super, |
1244 | .fs_flags = FS_REQUIRES_DEV, | 1246 | .fs_flags = FS_REQUIRES_DEV, |
1245 | }; | 1247 | }; |
1246 | 1248 | ||
1247 | /* | 1249 | /* |
1248 | * used by btrfsctl to scan devices when no FS is mounted | 1250 | * used by btrfsctl to scan devices when no FS is mounted |
1249 | */ | 1251 | */ |
1250 | static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | 1252 | static long btrfs_control_ioctl(struct file *file, unsigned int cmd, |
1251 | unsigned long arg) | 1253 | unsigned long arg) |
1252 | { | 1254 | { |
1253 | struct btrfs_ioctl_vol_args *vol; | 1255 | struct btrfs_ioctl_vol_args *vol; |
1254 | struct btrfs_fs_devices *fs_devices; | 1256 | struct btrfs_fs_devices *fs_devices; |
1255 | int ret = -ENOTTY; | 1257 | int ret = -ENOTTY; |
1256 | 1258 | ||
1257 | if (!capable(CAP_SYS_ADMIN)) | 1259 | if (!capable(CAP_SYS_ADMIN)) |
1258 | return -EPERM; | 1260 | return -EPERM; |
1259 | 1261 | ||
1260 | vol = memdup_user((void __user *)arg, sizeof(*vol)); | 1262 | vol = memdup_user((void __user *)arg, sizeof(*vol)); |
1261 | if (IS_ERR(vol)) | 1263 | if (IS_ERR(vol)) |
1262 | return PTR_ERR(vol); | 1264 | return PTR_ERR(vol); |
1263 | 1265 | ||
1264 | switch (cmd) { | 1266 | switch (cmd) { |
1265 | case BTRFS_IOC_SCAN_DEV: | 1267 | case BTRFS_IOC_SCAN_DEV: |
1266 | ret = btrfs_scan_one_device(vol->name, FMODE_READ, | 1268 | ret = btrfs_scan_one_device(vol->name, FMODE_READ, |
1267 | &btrfs_fs_type, &fs_devices); | 1269 | &btrfs_fs_type, &fs_devices); |
1268 | break; | 1270 | break; |
1269 | } | 1271 | } |
1270 | 1272 | ||
1271 | kfree(vol); | 1273 | kfree(vol); |
1272 | return ret; | 1274 | return ret; |
1273 | } | 1275 | } |
1274 | 1276 | ||
1275 | static int btrfs_freeze(struct super_block *sb) | 1277 | static int btrfs_freeze(struct super_block *sb) |
1276 | { | 1278 | { |
1277 | struct btrfs_root *root = btrfs_sb(sb); | 1279 | struct btrfs_root *root = btrfs_sb(sb); |
1278 | mutex_lock(&root->fs_info->transaction_kthread_mutex); | 1280 | mutex_lock(&root->fs_info->transaction_kthread_mutex); |
1279 | mutex_lock(&root->fs_info->cleaner_mutex); | 1281 | mutex_lock(&root->fs_info->cleaner_mutex); |
1280 | return 0; | 1282 | return 0; |
1281 | } | 1283 | } |
1282 | 1284 | ||
1283 | static int btrfs_unfreeze(struct super_block *sb) | 1285 | static int btrfs_unfreeze(struct super_block *sb) |
1284 | { | 1286 | { |
1285 | struct btrfs_root *root = btrfs_sb(sb); | 1287 | struct btrfs_root *root = btrfs_sb(sb); |
1286 | mutex_unlock(&root->fs_info->cleaner_mutex); | 1288 | mutex_unlock(&root->fs_info->cleaner_mutex); |
1287 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); | 1289 | mutex_unlock(&root->fs_info->transaction_kthread_mutex); |
1288 | return 0; | 1290 | return 0; |
1289 | } | 1291 | } |
1290 | 1292 | ||
1291 | static const struct super_operations btrfs_super_ops = { | 1293 | static const struct super_operations btrfs_super_ops = { |
1292 | .drop_inode = btrfs_drop_inode, | 1294 | .drop_inode = btrfs_drop_inode, |
1293 | .evict_inode = btrfs_evict_inode, | 1295 | .evict_inode = btrfs_evict_inode, |
1294 | .put_super = btrfs_put_super, | 1296 | .put_super = btrfs_put_super, |
1295 | .sync_fs = btrfs_sync_fs, | 1297 | .sync_fs = btrfs_sync_fs, |
1296 | .show_options = btrfs_show_options, | 1298 | .show_options = btrfs_show_options, |
1297 | .write_inode = btrfs_write_inode, | 1299 | .write_inode = btrfs_write_inode, |
1298 | .dirty_inode = btrfs_dirty_inode, | 1300 | .dirty_inode = btrfs_dirty_inode, |
1299 | .alloc_inode = btrfs_alloc_inode, | 1301 | .alloc_inode = btrfs_alloc_inode, |
1300 | .destroy_inode = btrfs_destroy_inode, | 1302 | .destroy_inode = btrfs_destroy_inode, |
1301 | .statfs = btrfs_statfs, | 1303 | .statfs = btrfs_statfs, |
1302 | .remount_fs = btrfs_remount, | 1304 | .remount_fs = btrfs_remount, |
1303 | .freeze_fs = btrfs_freeze, | 1305 | .freeze_fs = btrfs_freeze, |
1304 | .unfreeze_fs = btrfs_unfreeze, | 1306 | .unfreeze_fs = btrfs_unfreeze, |
1305 | }; | 1307 | }; |
1306 | 1308 | ||
1307 | static const struct file_operations btrfs_ctl_fops = { | 1309 | static const struct file_operations btrfs_ctl_fops = { |
1308 | .unlocked_ioctl = btrfs_control_ioctl, | 1310 | .unlocked_ioctl = btrfs_control_ioctl, |
1309 | .compat_ioctl = btrfs_control_ioctl, | 1311 | .compat_ioctl = btrfs_control_ioctl, |
1310 | .owner = THIS_MODULE, | 1312 | .owner = THIS_MODULE, |
1311 | .llseek = noop_llseek, | 1313 | .llseek = noop_llseek, |
1312 | }; | 1314 | }; |
1313 | 1315 | ||
1314 | static struct miscdevice btrfs_misc = { | 1316 | static struct miscdevice btrfs_misc = { |
1315 | .minor = BTRFS_MINOR, | 1317 | .minor = BTRFS_MINOR, |
1316 | .name = "btrfs-control", | 1318 | .name = "btrfs-control", |
1317 | .fops = &btrfs_ctl_fops | 1319 | .fops = &btrfs_ctl_fops |
1318 | }; | 1320 | }; |
1319 | 1321 | ||
1320 | MODULE_ALIAS_MISCDEV(BTRFS_MINOR); | 1322 | MODULE_ALIAS_MISCDEV(BTRFS_MINOR); |
1321 | MODULE_ALIAS("devname:btrfs-control"); | 1323 | MODULE_ALIAS("devname:btrfs-control"); |
1322 | 1324 | ||
1323 | static int btrfs_interface_init(void) | 1325 | static int btrfs_interface_init(void) |
1324 | { | 1326 | { |
1325 | return misc_register(&btrfs_misc); | 1327 | return misc_register(&btrfs_misc); |
1326 | } | 1328 | } |
1327 | 1329 | ||
1328 | static void btrfs_interface_exit(void) | 1330 | static void btrfs_interface_exit(void) |
1329 | { | 1331 | { |
1330 | if (misc_deregister(&btrfs_misc) < 0) | 1332 | if (misc_deregister(&btrfs_misc) < 0) |
1331 | printk(KERN_INFO "misc_deregister failed for control device"); | 1333 | printk(KERN_INFO "misc_deregister failed for control device"); |
1332 | } | 1334 | } |
1333 | 1335 | ||
1334 | static int __init init_btrfs_fs(void) | 1336 | static int __init init_btrfs_fs(void) |
1335 | { | 1337 | { |
1336 | int err; | 1338 | int err; |
1337 | 1339 | ||
1338 | err = btrfs_init_sysfs(); | 1340 | err = btrfs_init_sysfs(); |
1339 | if (err) | 1341 | if (err) |
1340 | return err; | 1342 | return err; |
1341 | 1343 | ||
1342 | err = btrfs_init_compress(); | 1344 | err = btrfs_init_compress(); |
1343 | if (err) | 1345 | if (err) |
1344 | goto free_sysfs; | 1346 | goto free_sysfs; |
1345 | 1347 | ||
1346 | err = btrfs_init_cachep(); | 1348 | err = btrfs_init_cachep(); |
1347 | if (err) | 1349 | if (err) |
1348 | goto free_compress; | 1350 | goto free_compress; |
1349 | 1351 | ||
1350 | err = extent_io_init(); | 1352 | err = extent_io_init(); |
1351 | if (err) | 1353 | if (err) |
1352 | goto free_cachep; | 1354 | goto free_cachep; |
1353 | 1355 | ||
1354 | err = extent_map_init(); | 1356 | err = extent_map_init(); |
1355 | if (err) | 1357 | if (err) |
1356 | goto free_extent_io; | 1358 | goto free_extent_io; |
1357 | 1359 | ||
1358 | err = btrfs_delayed_inode_init(); | 1360 | err = btrfs_delayed_inode_init(); |
1359 | if (err) | 1361 | if (err) |
1360 | goto free_extent_map; | 1362 | goto free_extent_map; |
1361 | 1363 | ||
1362 | err = btrfs_interface_init(); | 1364 | err = btrfs_interface_init(); |
1363 | if (err) | 1365 | if (err) |
1364 | goto free_delayed_inode; | 1366 | goto free_delayed_inode; |
1365 | 1367 | ||
1366 | err = register_filesystem(&btrfs_fs_type); | 1368 | err = register_filesystem(&btrfs_fs_type); |
1367 | if (err) | 1369 | if (err) |
1368 | goto unregister_ioctl; | 1370 | goto unregister_ioctl; |
1369 | 1371 | ||
1370 | printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION); | 1372 | printk(KERN_INFO "%s loaded\n", BTRFS_BUILD_VERSION); |
1371 | return 0; | 1373 | return 0; |
1372 | 1374 | ||
1373 | unregister_ioctl: | 1375 | unregister_ioctl: |
1374 | btrfs_interface_exit(); | 1376 | btrfs_interface_exit(); |
1375 | free_delayed_inode: | 1377 | free_delayed_inode: |
1376 | btrfs_delayed_inode_exit(); | 1378 | btrfs_delayed_inode_exit(); |
1377 | free_extent_map: | 1379 | free_extent_map: |
1378 | extent_map_exit(); | 1380 | extent_map_exit(); |
1379 | free_extent_io: | 1381 | free_extent_io: |
1380 | extent_io_exit(); | 1382 | extent_io_exit(); |
1381 | free_cachep: | 1383 | free_cachep: |
1382 | btrfs_destroy_cachep(); | 1384 | btrfs_destroy_cachep(); |
1383 | free_compress: | 1385 | free_compress: |
1384 | btrfs_exit_compress(); | 1386 | btrfs_exit_compress(); |
1385 | free_sysfs: | 1387 | free_sysfs: |
1386 | btrfs_exit_sysfs(); | 1388 | btrfs_exit_sysfs(); |
1387 | return err; | 1389 | return err; |
1388 | } | 1390 | } |
1389 | 1391 | ||
1390 | static void __exit exit_btrfs_fs(void) | 1392 | static void __exit exit_btrfs_fs(void) |
1391 | { | 1393 | { |
1392 | btrfs_destroy_cachep(); | 1394 | btrfs_destroy_cachep(); |
1393 | btrfs_delayed_inode_exit(); | 1395 | btrfs_delayed_inode_exit(); |
1394 | extent_map_exit(); | 1396 | extent_map_exit(); |
1395 | extent_io_exit(); | 1397 | extent_io_exit(); |
1396 | btrfs_interface_exit(); | 1398 | btrfs_interface_exit(); |
1397 | unregister_filesystem(&btrfs_fs_type); | 1399 | unregister_filesystem(&btrfs_fs_type); |
1398 | btrfs_exit_sysfs(); | 1400 | btrfs_exit_sysfs(); |
1399 | btrfs_cleanup_fs_uuids(); | 1401 | btrfs_cleanup_fs_uuids(); |
1400 | btrfs_exit_compress(); | 1402 | btrfs_exit_compress(); |
1401 | } | 1403 | } |
1402 | 1404 | ||
1403 | module_init(init_btrfs_fs) | 1405 | module_init(init_btrfs_fs) |
1404 | module_exit(exit_btrfs_fs) | 1406 | module_exit(exit_btrfs_fs) |
1405 | 1407 | ||
1406 | MODULE_LICENSE("GPL"); | 1408 | MODULE_LICENSE("GPL"); |
1407 | 1409 |