diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 89 |
1 files changed, 68 insertions, 21 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index d8982e9601d3..68a29a1ea068 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -41,13 +41,13 @@ | |||
41 | #include <linux/slab.h> | 41 | #include <linux/slab.h> |
42 | #include <linux/cleancache.h> | 42 | #include <linux/cleancache.h> |
43 | #include <linux/ratelimit.h> | 43 | #include <linux/ratelimit.h> |
44 | #include <linux/btrfs.h> | ||
44 | #include "compat.h" | 45 | #include "compat.h" |
45 | #include "delayed-inode.h" | 46 | #include "delayed-inode.h" |
46 | #include "ctree.h" | 47 | #include "ctree.h" |
47 | #include "disk-io.h" | 48 | #include "disk-io.h" |
48 | #include "transaction.h" | 49 | #include "transaction.h" |
49 | #include "btrfs_inode.h" | 50 | #include "btrfs_inode.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" |
@@ -63,8 +63,7 @@ | |||
63 | static const struct super_operations btrfs_super_ops; | 63 | static const struct super_operations btrfs_super_ops; |
64 | static struct file_system_type btrfs_fs_type; | 64 | static struct file_system_type btrfs_fs_type; |
65 | 65 | ||
66 | static const char *btrfs_decode_error(struct btrfs_fs_info *fs_info, int errno, | 66 | static const char *btrfs_decode_error(int errno, char nbuf[16]) |
67 | char nbuf[16]) | ||
68 | { | 67 | { |
69 | char *errstr = NULL; | 68 | char *errstr = NULL; |
70 | 69 | ||
@@ -98,7 +97,7 @@ static void __save_error_info(struct btrfs_fs_info *fs_info) | |||
98 | * today we only save the error info into ram. Long term we'll | 97 | * today we only save the error info into ram. Long term we'll |
99 | * also send it down to the disk | 98 | * also send it down to the disk |
100 | */ | 99 | */ |
101 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; | 100 | set_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state); |
102 | } | 101 | } |
103 | 102 | ||
104 | static void save_error_info(struct btrfs_fs_info *fs_info) | 103 | static void save_error_info(struct btrfs_fs_info *fs_info) |
@@ -114,7 +113,7 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info) | |||
114 | if (sb->s_flags & MS_RDONLY) | 113 | if (sb->s_flags & MS_RDONLY) |
115 | return; | 114 | return; |
116 | 115 | ||
117 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | 116 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { |
118 | sb->s_flags |= MS_RDONLY; | 117 | sb->s_flags |= MS_RDONLY; |
119 | printk(KERN_INFO "btrfs is forced readonly\n"); | 118 | printk(KERN_INFO "btrfs is forced readonly\n"); |
120 | /* | 119 | /* |
@@ -142,8 +141,6 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | |||
142 | struct super_block *sb = fs_info->sb; | 141 | struct super_block *sb = fs_info->sb; |
143 | char nbuf[16]; | 142 | char nbuf[16]; |
144 | const char *errstr; | 143 | const char *errstr; |
145 | va_list args; | ||
146 | va_start(args, fmt); | ||
147 | 144 | ||
148 | /* | 145 | /* |
149 | * Special case: if the error is EROFS, and we're already | 146 | * Special case: if the error is EROFS, and we're already |
@@ -152,15 +149,18 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | |||
152 | if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) | 149 | if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) |
153 | return; | 150 | return; |
154 | 151 | ||
155 | errstr = btrfs_decode_error(fs_info, errno, nbuf); | 152 | errstr = btrfs_decode_error(errno, nbuf); |
156 | if (fmt) { | 153 | if (fmt) { |
157 | struct va_format vaf = { | 154 | struct va_format vaf; |
158 | .fmt = fmt, | 155 | va_list args; |
159 | .va = &args, | 156 | |
160 | }; | 157 | va_start(args, fmt); |
158 | vaf.fmt = fmt; | ||
159 | vaf.va = &args; | ||
161 | 160 | ||
162 | printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s (%pV)\n", | 161 | printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s (%pV)\n", |
163 | sb->s_id, function, line, errstr, &vaf); | 162 | sb->s_id, function, line, errstr, &vaf); |
163 | va_end(args); | ||
164 | } else { | 164 | } else { |
165 | printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n", | 165 | printk(KERN_CRIT "BTRFS error (device %s) in %s:%d: %s\n", |
166 | sb->s_id, function, line, errstr); | 166 | sb->s_id, function, line, errstr); |
@@ -171,7 +171,6 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | |||
171 | save_error_info(fs_info); | 171 | save_error_info(fs_info); |
172 | btrfs_handle_error(fs_info); | 172 | btrfs_handle_error(fs_info); |
173 | } | 173 | } |
174 | va_end(args); | ||
175 | } | 174 | } |
176 | 175 | ||
177 | static const char * const logtypes[] = { | 176 | static const char * const logtypes[] = { |
@@ -261,7 +260,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, | |||
261 | char nbuf[16]; | 260 | char nbuf[16]; |
262 | const char *errstr; | 261 | const char *errstr; |
263 | 262 | ||
264 | errstr = btrfs_decode_error(root->fs_info, errno, nbuf); | 263 | errstr = btrfs_decode_error(errno, nbuf); |
265 | btrfs_printk(root->fs_info, | 264 | btrfs_printk(root->fs_info, |
266 | "%s:%d: Aborting unused transaction(%s).\n", | 265 | "%s:%d: Aborting unused transaction(%s).\n", |
267 | function, line, errstr); | 266 | function, line, errstr); |
@@ -289,8 +288,8 @@ void __btrfs_panic(struct btrfs_fs_info *fs_info, const char *function, | |||
289 | va_start(args, fmt); | 288 | va_start(args, fmt); |
290 | vaf.va = &args; | 289 | vaf.va = &args; |
291 | 290 | ||
292 | errstr = btrfs_decode_error(fs_info, errno, nbuf); | 291 | errstr = btrfs_decode_error(errno, nbuf); |
293 | if (fs_info->mount_opt & BTRFS_MOUNT_PANIC_ON_FATAL_ERROR) | 292 | if (fs_info && (fs_info->mount_opt & BTRFS_MOUNT_PANIC_ON_FATAL_ERROR)) |
294 | panic(KERN_CRIT "BTRFS panic (device %s) in %s:%d: %pV (%s)\n", | 293 | panic(KERN_CRIT "BTRFS panic (device %s) in %s:%d: %pV (%s)\n", |
295 | s_id, function, line, &vaf, errstr); | 294 | s_id, function, line, &vaf, errstr); |
296 | 295 | ||
@@ -438,6 +437,7 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
438 | case Opt_compress_force: | 437 | case Opt_compress_force: |
439 | case Opt_compress_force_type: | 438 | case Opt_compress_force_type: |
440 | compress_force = true; | 439 | compress_force = true; |
440 | /* Fallthrough */ | ||
441 | case Opt_compress: | 441 | case Opt_compress: |
442 | case Opt_compress_type: | 442 | case Opt_compress_type: |
443 | if (token == Opt_compress || | 443 | if (token == Opt_compress || |
@@ -519,7 +519,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
519 | case Opt_alloc_start: | 519 | case Opt_alloc_start: |
520 | num = match_strdup(&args[0]); | 520 | num = match_strdup(&args[0]); |
521 | if (num) { | 521 | if (num) { |
522 | mutex_lock(&info->chunk_mutex); | ||
522 | info->alloc_start = memparse(num, NULL); | 523 | info->alloc_start = memparse(num, NULL); |
524 | mutex_unlock(&info->chunk_mutex); | ||
523 | kfree(num); | 525 | kfree(num); |
524 | printk(KERN_INFO | 526 | printk(KERN_INFO |
525 | "btrfs: allocations start at %llu\n", | 527 | "btrfs: allocations start at %llu\n", |
@@ -876,7 +878,7 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
876 | 878 | ||
877 | btrfs_wait_ordered_extents(root, 0); | 879 | btrfs_wait_ordered_extents(root, 0); |
878 | 880 | ||
879 | trans = btrfs_attach_transaction(root); | 881 | trans = btrfs_attach_transaction_barrier(root); |
880 | if (IS_ERR(trans)) { | 882 | if (IS_ERR(trans)) { |
881 | /* no transaction, don't bother */ | 883 | /* no transaction, don't bother */ |
882 | if (PTR_ERR(trans) == -ENOENT) | 884 | if (PTR_ERR(trans) == -ENOENT) |
@@ -1200,6 +1202,38 @@ static void btrfs_resize_thread_pool(struct btrfs_fs_info *fs_info, | |||
1200 | new_pool_size); | 1202 | new_pool_size); |
1201 | } | 1203 | } |
1202 | 1204 | ||
1205 | static inline void btrfs_remount_prepare(struct btrfs_fs_info *fs_info, | ||
1206 | unsigned long old_opts, int flags) | ||
1207 | { | ||
1208 | set_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); | ||
1209 | |||
1210 | if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && | ||
1211 | (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || | ||
1212 | (flags & MS_RDONLY))) { | ||
1213 | /* wait for any defraggers to finish */ | ||
1214 | wait_event(fs_info->transaction_wait, | ||
1215 | (atomic_read(&fs_info->defrag_running) == 0)); | ||
1216 | if (flags & MS_RDONLY) | ||
1217 | sync_filesystem(fs_info->sb); | ||
1218 | } | ||
1219 | } | ||
1220 | |||
1221 | static inline void btrfs_remount_cleanup(struct btrfs_fs_info *fs_info, | ||
1222 | unsigned long old_opts) | ||
1223 | { | ||
1224 | /* | ||
1225 | * We need cleanup all defragable inodes if the autodefragment is | ||
1226 | * close or the fs is R/O. | ||
1227 | */ | ||
1228 | if (btrfs_raw_test_opt(old_opts, AUTO_DEFRAG) && | ||
1229 | (!btrfs_raw_test_opt(fs_info->mount_opt, AUTO_DEFRAG) || | ||
1230 | (fs_info->sb->s_flags & MS_RDONLY))) { | ||
1231 | btrfs_cleanup_defrag_inodes(fs_info); | ||
1232 | } | ||
1233 | |||
1234 | clear_bit(BTRFS_FS_STATE_REMOUNTING, &fs_info->fs_state); | ||
1235 | } | ||
1236 | |||
1203 | static int btrfs_remount(struct super_block *sb, int *flags, char *data) | 1237 | static int btrfs_remount(struct super_block *sb, int *flags, char *data) |
1204 | { | 1238 | { |
1205 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); | 1239 | struct btrfs_fs_info *fs_info = btrfs_sb(sb); |
@@ -1213,6 +1247,8 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1213 | unsigned int old_metadata_ratio = fs_info->metadata_ratio; | 1247 | unsigned int old_metadata_ratio = fs_info->metadata_ratio; |
1214 | int ret; | 1248 | int ret; |
1215 | 1249 | ||
1250 | btrfs_remount_prepare(fs_info, old_opts, *flags); | ||
1251 | |||
1216 | ret = btrfs_parse_options(root, data); | 1252 | ret = btrfs_parse_options(root, data); |
1217 | if (ret) { | 1253 | if (ret) { |
1218 | ret = -EINVAL; | 1254 | ret = -EINVAL; |
@@ -1223,7 +1259,7 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1223 | fs_info->thread_pool_size, old_thread_pool_size); | 1259 | fs_info->thread_pool_size, old_thread_pool_size); |
1224 | 1260 | ||
1225 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) | 1261 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) |
1226 | return 0; | 1262 | goto out; |
1227 | 1263 | ||
1228 | if (*flags & MS_RDONLY) { | 1264 | if (*flags & MS_RDONLY) { |
1229 | /* | 1265 | /* |
@@ -1278,7 +1314,8 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1278 | } | 1314 | } |
1279 | sb->s_flags &= ~MS_RDONLY; | 1315 | sb->s_flags &= ~MS_RDONLY; |
1280 | } | 1316 | } |
1281 | 1317 | out: | |
1318 | btrfs_remount_cleanup(fs_info, old_opts); | ||
1282 | return 0; | 1319 | return 0; |
1283 | 1320 | ||
1284 | restore: | 1321 | restore: |
@@ -1289,10 +1326,13 @@ restore: | |||
1289 | fs_info->mount_opt = old_opts; | 1326 | fs_info->mount_opt = old_opts; |
1290 | fs_info->compress_type = old_compress_type; | 1327 | fs_info->compress_type = old_compress_type; |
1291 | fs_info->max_inline = old_max_inline; | 1328 | fs_info->max_inline = old_max_inline; |
1329 | mutex_lock(&fs_info->chunk_mutex); | ||
1292 | fs_info->alloc_start = old_alloc_start; | 1330 | fs_info->alloc_start = old_alloc_start; |
1331 | mutex_unlock(&fs_info->chunk_mutex); | ||
1293 | btrfs_resize_thread_pool(fs_info, | 1332 | btrfs_resize_thread_pool(fs_info, |
1294 | old_thread_pool_size, fs_info->thread_pool_size); | 1333 | old_thread_pool_size, fs_info->thread_pool_size); |
1295 | fs_info->metadata_ratio = old_metadata_ratio; | 1334 | fs_info->metadata_ratio = old_metadata_ratio; |
1335 | btrfs_remount_cleanup(fs_info, old_opts); | ||
1296 | return ret; | 1336 | return ret; |
1297 | } | 1337 | } |
1298 | 1338 | ||
@@ -1559,7 +1599,7 @@ static int btrfs_freeze(struct super_block *sb) | |||
1559 | struct btrfs_trans_handle *trans; | 1599 | struct btrfs_trans_handle *trans; |
1560 | struct btrfs_root *root = btrfs_sb(sb)->tree_root; | 1600 | struct btrfs_root *root = btrfs_sb(sb)->tree_root; |
1561 | 1601 | ||
1562 | trans = btrfs_attach_transaction(root); | 1602 | trans = btrfs_attach_transaction_barrier(root); |
1563 | if (IS_ERR(trans)) { | 1603 | if (IS_ERR(trans)) { |
1564 | /* no transaction, don't bother */ | 1604 | /* no transaction, don't bother */ |
1565 | if (PTR_ERR(trans) == -ENOENT) | 1605 | if (PTR_ERR(trans) == -ENOENT) |
@@ -1684,10 +1724,14 @@ static int __init init_btrfs_fs(void) | |||
1684 | if (err) | 1724 | if (err) |
1685 | goto free_delayed_inode; | 1725 | goto free_delayed_inode; |
1686 | 1726 | ||
1687 | err = btrfs_interface_init(); | 1727 | err = btrfs_delayed_ref_init(); |
1688 | if (err) | 1728 | if (err) |
1689 | goto free_auto_defrag; | 1729 | goto free_auto_defrag; |
1690 | 1730 | ||
1731 | err = btrfs_interface_init(); | ||
1732 | if (err) | ||
1733 | goto free_delayed_ref; | ||
1734 | |||
1691 | err = register_filesystem(&btrfs_fs_type); | 1735 | err = register_filesystem(&btrfs_fs_type); |
1692 | if (err) | 1736 | if (err) |
1693 | goto unregister_ioctl; | 1737 | goto unregister_ioctl; |
@@ -1699,6 +1743,8 @@ static int __init init_btrfs_fs(void) | |||
1699 | 1743 | ||
1700 | unregister_ioctl: | 1744 | unregister_ioctl: |
1701 | btrfs_interface_exit(); | 1745 | btrfs_interface_exit(); |
1746 | free_delayed_ref: | ||
1747 | btrfs_delayed_ref_exit(); | ||
1702 | free_auto_defrag: | 1748 | free_auto_defrag: |
1703 | btrfs_auto_defrag_exit(); | 1749 | btrfs_auto_defrag_exit(); |
1704 | free_delayed_inode: | 1750 | free_delayed_inode: |
@@ -1720,6 +1766,7 @@ free_compress: | |||
1720 | static void __exit exit_btrfs_fs(void) | 1766 | static void __exit exit_btrfs_fs(void) |
1721 | { | 1767 | { |
1722 | btrfs_destroy_cachep(); | 1768 | btrfs_destroy_cachep(); |
1769 | btrfs_delayed_ref_exit(); | ||
1723 | btrfs_auto_defrag_exit(); | 1770 | btrfs_auto_defrag_exit(); |
1724 | btrfs_delayed_inode_exit(); | 1771 | btrfs_delayed_inode_exit(); |
1725 | ordered_data_exit(); | 1772 | ordered_data_exit(); |