diff options
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r-- | fs/btrfs/super.c | 37 |
1 files changed, 35 insertions, 2 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index ab9d5e89ed13..04a3bf816509 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -370,6 +370,9 @@ int btrfs_sync_fs(struct super_block *sb, int wait) | |||
370 | int ret; | 370 | int ret; |
371 | root = btrfs_sb(sb); | 371 | root = btrfs_sb(sb); |
372 | 372 | ||
373 | if (sb->s_flags & MS_RDONLY) | ||
374 | return 0; | ||
375 | |||
373 | sb->s_dirt = 0; | 376 | sb->s_dirt = 0; |
374 | if (!wait) { | 377 | if (!wait) { |
375 | filemap_flush(root->fs_info->btree_inode->i_mapping); | 378 | filemap_flush(root->fs_info->btree_inode->i_mapping); |
@@ -438,7 +441,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
438 | up_write(&s->s_umount); | 441 | up_write(&s->s_umount); |
439 | deactivate_super(s); | 442 | deactivate_super(s); |
440 | error = -EBUSY; | 443 | error = -EBUSY; |
441 | goto error_bdev; | 444 | goto error_close_devices; |
442 | } | 445 | } |
443 | 446 | ||
444 | } else { | 447 | } else { |
@@ -487,7 +490,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, | |||
487 | 490 | ||
488 | error_s: | 491 | error_s: |
489 | error = PTR_ERR(s); | 492 | error = PTR_ERR(s); |
490 | error_bdev: | 493 | error_close_devices: |
491 | btrfs_close_devices(fs_devices); | 494 | btrfs_close_devices(fs_devices); |
492 | error_free_subvol_name: | 495 | error_free_subvol_name: |
493 | kfree(subvol_name); | 496 | kfree(subvol_name); |
@@ -495,6 +498,35 @@ error: | |||
495 | return error; | 498 | return error; |
496 | } | 499 | } |
497 | 500 | ||
501 | static int btrfs_remount(struct super_block *sb, int *flags, char *data) | ||
502 | { | ||
503 | struct btrfs_root *root = btrfs_sb(sb); | ||
504 | int ret; | ||
505 | |||
506 | if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY)) | ||
507 | return 0; | ||
508 | |||
509 | if (*flags & MS_RDONLY) { | ||
510 | sb->s_flags |= MS_RDONLY; | ||
511 | |||
512 | ret = btrfs_commit_super(root); | ||
513 | WARN_ON(ret); | ||
514 | } else { | ||
515 | if (btrfs_super_log_root(&root->fs_info->super_copy) != 0) | ||
516 | return -EINVAL; | ||
517 | |||
518 | ret = btrfs_cleanup_reloc_trees(root); | ||
519 | WARN_ON(ret); | ||
520 | |||
521 | ret = btrfs_cleanup_fs_roots(root->fs_info); | ||
522 | WARN_ON(ret); | ||
523 | |||
524 | sb->s_flags &= ~MS_RDONLY; | ||
525 | } | ||
526 | |||
527 | return 0; | ||
528 | } | ||
529 | |||
498 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) | 530 | static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf) |
499 | { | 531 | { |
500 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); | 532 | struct btrfs_root *root = btrfs_sb(dentry->d_sb); |
@@ -582,6 +614,7 @@ static struct super_operations btrfs_super_ops = { | |||
582 | .alloc_inode = btrfs_alloc_inode, | 614 | .alloc_inode = btrfs_alloc_inode, |
583 | .destroy_inode = btrfs_destroy_inode, | 615 | .destroy_inode = btrfs_destroy_inode, |
584 | .statfs = btrfs_statfs, | 616 | .statfs = btrfs_statfs, |
617 | .remount_fs = btrfs_remount, | ||
585 | .write_super_lockfs = btrfs_write_super_lockfs, | 618 | .write_super_lockfs = btrfs_write_super_lockfs, |
586 | .unlockfs = btrfs_unlockfs, | 619 | .unlockfs = btrfs_unlockfs, |
587 | }; | 620 | }; |