diff options
Diffstat (limited to 'fs/btrfs/super.c')
| -rw-r--r-- | fs/btrfs/super.c | 77 | 
1 files changed, 53 insertions, 24 deletions
| diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index e23991574fdf..f2eb24c477a3 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
| @@ -100,10 +100,6 @@ static void __save_error_info(struct btrfs_fs_info *fs_info) | |||
| 100 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; | 100 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; | 
| 101 | } | 101 | } | 
| 102 | 102 | ||
| 103 | /* NOTE: | ||
| 104 | * We move write_super stuff at umount in order to avoid deadlock | ||
| 105 | * for umount hold all lock. | ||
| 106 | */ | ||
| 107 | static void save_error_info(struct btrfs_fs_info *fs_info) | 103 | static void save_error_info(struct btrfs_fs_info *fs_info) | 
| 108 | { | 104 | { | 
| 109 | __save_error_info(fs_info); | 105 | __save_error_info(fs_info); | 
| @@ -125,6 +121,7 @@ static void btrfs_handle_error(struct btrfs_fs_info *fs_info) | |||
| 125 | } | 121 | } | 
| 126 | } | 122 | } | 
| 127 | 123 | ||
| 124 | #ifdef CONFIG_PRINTK | ||
| 128 | /* | 125 | /* | 
| 129 | * __btrfs_std_error decodes expected errors from the caller and | 126 | * __btrfs_std_error decodes expected errors from the caller and | 
| 130 | * invokes the approciate error response. | 127 | * invokes the approciate error response. | 
| @@ -167,7 +164,7 @@ void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | |||
| 167 | va_end(args); | 164 | va_end(args); | 
| 168 | } | 165 | } | 
| 169 | 166 | ||
| 170 | const char *logtypes[] = { | 167 | static const char * const logtypes[] = { | 
| 171 | "emergency", | 168 | "emergency", | 
| 172 | "alert", | 169 | "alert", | 
| 173 | "critical", | 170 | "critical", | 
| @@ -185,21 +182,49 @@ void btrfs_printk(struct btrfs_fs_info *fs_info, const char *fmt, ...) | |||
| 185 | struct va_format vaf; | 182 | struct va_format vaf; | 
| 186 | va_list args; | 183 | va_list args; | 
| 187 | const char *type = logtypes[4]; | 184 | const char *type = logtypes[4]; | 
| 185 | int kern_level; | ||
| 188 | 186 | ||
| 189 | va_start(args, fmt); | 187 | va_start(args, fmt); | 
| 190 | 188 | ||
| 191 | if (fmt[0] == '<' && isdigit(fmt[1]) && fmt[2] == '>') { | 189 | kern_level = printk_get_level(fmt); | 
| 192 | memcpy(lvl, fmt, 3); | 190 | if (kern_level) { | 
| 193 | lvl[3] = '\0'; | 191 | size_t size = printk_skip_level(fmt) - fmt; | 
| 194 | fmt += 3; | 192 | memcpy(lvl, fmt, size); | 
| 195 | type = logtypes[fmt[1] - '0']; | 193 | lvl[size] = '\0'; | 
| 194 | fmt += size; | ||
| 195 | type = logtypes[kern_level - '0']; | ||
| 196 | } else | 196 | } else | 
| 197 | *lvl = '\0'; | 197 | *lvl = '\0'; | 
| 198 | 198 | ||
| 199 | vaf.fmt = fmt; | 199 | vaf.fmt = fmt; | 
| 200 | vaf.va = &args; | 200 | vaf.va = &args; | 
| 201 | |||
| 201 | printk("%sBTRFS %s (device %s): %pV", lvl, type, sb->s_id, &vaf); | 202 | printk("%sBTRFS %s (device %s): %pV", lvl, type, sb->s_id, &vaf); | 
| 203 | |||
| 204 | va_end(args); | ||
| 205 | } | ||
| 206 | |||
| 207 | #else | ||
| 208 | |||
| 209 | void __btrfs_std_error(struct btrfs_fs_info *fs_info, const char *function, | ||
| 210 | unsigned int line, int errno, const char *fmt, ...) | ||
| 211 | { | ||
| 212 | struct super_block *sb = fs_info->sb; | ||
| 213 | |||
| 214 | /* | ||
| 215 | * Special case: if the error is EROFS, and we're already | ||
| 216 | * under MS_RDONLY, then it is safe here. | ||
| 217 | */ | ||
| 218 | if (errno == -EROFS && (sb->s_flags & MS_RDONLY)) | ||
| 219 | return; | ||
| 220 | |||
| 221 | /* Don't go through full error handling during mount */ | ||
| 222 | if (sb->s_flags & MS_BORN) { | ||
| 223 | save_error_info(fs_info); | ||
| 224 | btrfs_handle_error(fs_info); | ||
| 225 | } | ||
| 202 | } | 226 | } | 
| 227 | #endif | ||
| 203 | 228 | ||
| 204 | /* | 229 | /* | 
| 205 | * We only mark the transaction aborted and then set the file system read-only. | 230 | * We only mark the transaction aborted and then set the file system read-only. | 
| @@ -396,15 +421,23 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) | |||
| 396 | strcmp(args[0].from, "zlib") == 0) { | 421 | strcmp(args[0].from, "zlib") == 0) { | 
| 397 | compress_type = "zlib"; | 422 | compress_type = "zlib"; | 
| 398 | info->compress_type = BTRFS_COMPRESS_ZLIB; | 423 | info->compress_type = BTRFS_COMPRESS_ZLIB; | 
| 424 | btrfs_set_opt(info->mount_opt, COMPRESS); | ||
| 399 | } else if (strcmp(args[0].from, "lzo") == 0) { | 425 | } else if (strcmp(args[0].from, "lzo") == 0) { | 
| 400 | compress_type = "lzo"; | 426 | compress_type = "lzo"; | 
| 401 | info->compress_type = BTRFS_COMPRESS_LZO; | 427 | info->compress_type = BTRFS_COMPRESS_LZO; | 
| 428 | btrfs_set_opt(info->mount_opt, COMPRESS); | ||
| 429 | btrfs_set_fs_incompat(info, COMPRESS_LZO); | ||
| 430 | } else if (strncmp(args[0].from, "no", 2) == 0) { | ||
| 431 | compress_type = "no"; | ||
| 432 | info->compress_type = BTRFS_COMPRESS_NONE; | ||
| 433 | btrfs_clear_opt(info->mount_opt, COMPRESS); | ||
| 434 | btrfs_clear_opt(info->mount_opt, FORCE_COMPRESS); | ||
| 435 | compress_force = false; | ||
| 402 | } else { | 436 | } else { | 
| 403 | ret = -EINVAL; | 437 | ret = -EINVAL; | 
| 404 | goto out; | 438 | goto out; | 
| 405 | } | 439 | } | 
| 406 | 440 | ||
| 407 | btrfs_set_opt(info->mount_opt, COMPRESS); | ||
| 408 | if (compress_force) { | 441 | if (compress_force) { | 
| 409 | btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); | 442 | btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); | 
| 410 | pr_info("btrfs: force %s compression\n", | 443 | pr_info("btrfs: force %s compression\n", | 
| @@ -1068,7 +1101,8 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 1068 | } | 1101 | } | 
| 1069 | 1102 | ||
| 1070 | bdev = fs_devices->latest_bdev; | 1103 | bdev = fs_devices->latest_bdev; | 
| 1071 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, fs_info); | 1104 | s = sget(fs_type, btrfs_test_super, btrfs_set_super, flags | MS_NOSEC, | 
| 1105 | fs_info); | ||
| 1072 | if (IS_ERR(s)) { | 1106 | if (IS_ERR(s)) { | 
| 1073 | error = PTR_ERR(s); | 1107 | error = PTR_ERR(s); | 
| 1074 | goto error_close_devices; | 1108 | goto error_close_devices; | 
| @@ -1082,7 +1116,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags, | |||
| 1082 | } else { | 1116 | } else { | 
| 1083 | char b[BDEVNAME_SIZE]; | 1117 | char b[BDEVNAME_SIZE]; | 
| 1084 | 1118 | ||
| 1085 | s->s_flags = flags | MS_NOSEC; | ||
| 1086 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 1119 | strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id)); | 
| 1087 | btrfs_sb(s)->bdev_holder = fs_type; | 1120 | btrfs_sb(s)->bdev_holder = fs_type; | 
| 1088 | error = btrfs_fill_super(s, fs_devices, data, | 1121 | error = btrfs_fill_super(s, fs_devices, data, | 
| @@ -1455,6 +1488,13 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, | |||
| 1455 | ret = btrfs_scan_one_device(vol->name, FMODE_READ, | 1488 | ret = btrfs_scan_one_device(vol->name, FMODE_READ, | 
| 1456 | &btrfs_fs_type, &fs_devices); | 1489 | &btrfs_fs_type, &fs_devices); | 
| 1457 | break; | 1490 | break; | 
| 1491 | case BTRFS_IOC_DEVICES_READY: | ||
| 1492 | ret = btrfs_scan_one_device(vol->name, FMODE_READ, | ||
| 1493 | &btrfs_fs_type, &fs_devices); | ||
| 1494 | if (ret) | ||
| 1495 | break; | ||
| 1496 | ret = !(fs_devices->num_devices == fs_devices->total_devices); | ||
| 1497 | break; | ||
| 1458 | } | 1498 | } | 
| 1459 | 1499 | ||
| 1460 | kfree(vol); | 1500 | kfree(vol); | 
| @@ -1477,16 +1517,6 @@ static int btrfs_unfreeze(struct super_block *sb) | |||
| 1477 | return 0; | 1517 | return 0; | 
| 1478 | } | 1518 | } | 
| 1479 | 1519 | ||
| 1480 | static void btrfs_fs_dirty_inode(struct inode *inode, int flags) | ||
| 1481 | { | ||
| 1482 | int ret; | ||
| 1483 | |||
| 1484 | ret = btrfs_dirty_inode(inode); | ||
| 1485 | if (ret) | ||
| 1486 | printk_ratelimited(KERN_ERR "btrfs: fail to dirty inode %Lu " | ||
| 1487 | "error %d\n", btrfs_ino(inode), ret); | ||
| 1488 | } | ||
| 1489 | |||
| 1490 | static int btrfs_show_devname(struct seq_file *m, struct dentry *root) | 1520 | static int btrfs_show_devname(struct seq_file *m, struct dentry *root) | 
| 1491 | { | 1521 | { | 
| 1492 | struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb); | 1522 | struct btrfs_fs_info *fs_info = btrfs_sb(root->d_sb); | 
| @@ -1526,7 +1556,6 @@ static const struct super_operations btrfs_super_ops = { | |||
| 1526 | .show_options = btrfs_show_options, | 1556 | .show_options = btrfs_show_options, | 
| 1527 | .show_devname = btrfs_show_devname, | 1557 | .show_devname = btrfs_show_devname, | 
| 1528 | .write_inode = btrfs_write_inode, | 1558 | .write_inode = btrfs_write_inode, | 
| 1529 | .dirty_inode = btrfs_fs_dirty_inode, | ||
| 1530 | .alloc_inode = btrfs_alloc_inode, | 1559 | .alloc_inode = btrfs_alloc_inode, | 
| 1531 | .destroy_inode = btrfs_destroy_inode, | 1560 | .destroy_inode = btrfs_destroy_inode, | 
| 1532 | .statfs = btrfs_statfs, | 1561 | .statfs = btrfs_statfs, | 
