mount ro and remount support
PATCH 1/2 mount ro and remount support
Hello,
This patch adds mount ro and remount support. The main changes in patch are: adding btrfs_remount and related helper function; splitting the transaction related code out of close_ctree into btrfs_commit_super; updating allocator to properly handle read only block group.
Regards
Signed-off-by Yan Zheng <[email protected]>
---
fs/btrfs/ctree.h +1 -0
@@ -541,6 +541,7 @@ struct btrfs_space_info {u64 bytes_used;u64 bytes_pinned;u64 bytes_reserved; +u64 bytes_readonly;int full;int force_alloc;struct list_head list;
fs/btrfs/disk-io.c +63 -20
140 lines not on this page · raw message
fs/btrfs/disk-io.h +2 -0
@@ -38,6 +38,7 @@ struct btrfs_root *open_ctree(struct supint close_ctree (struct btrfs_root *root);int write_ctree_super (struct btrfs_trans_handle *trans,struct btrfs_root *root); +int btrfs_commit_super (struct btrfs_root *root);struct extent_buffer *btrfs_find_tree_block (struct btrfs_root *root,u64 bytenr,u32 blocksize); struct btrfs_root *btrfs_lookup_fs_root(struct btrfs_fs_info *fs_info,
@@ -49,6 +50,7 @@ struct btrfs_root *btrfs_read_fs_root_no struct btrfs_key *location);struct btrfs_root *btrfs_read_fs_root_no_name (struct btrfs_fs_info *fs_info,struct btrfs_key *location); +int btrfs_cleanup_fs_roots (struct btrfs_fs_info *fs_info); int btrfs_insert_dev_radix(struct btrfs_root *root, struct block_device *bdev, u64 device_id,
fs/btrfs/extent-tree.c +35 -26
139 lines not on this page · raw message
fs/btrfs/inode.c +5 -10
@@ -1808,10 +1808,6 @@ void btrfs_orphan_cleanup(struct btrfs_rstruct inode *inode;int ret =0 , nr_unlink =0 , nr_truncate =0 ; -/* don't do orphan cleanup if the fs is readonly. */ -if (root->fs_info->sb->s_flags &MS_RDONLY ) -return ; - path =btrfs_alloc_path ();if (!path)return ;
@@ -3050,7 +3046,7 @@ static struct dentry *btrfs_lookup(strucstruct btrfs_root *root = bi->root;struct btrfs_root *sub_root = root;struct btrfs_key location; -int ret, new, do_orphan =0 ; +int ret, new;if (dentry->d_name.len >BTRFS_NAME_LEN )return ERR_PTR (-ENAMETOOLONG );
@@ -3076,13 +3072,9 @@ static struct dentry *btrfs_lookup(strucif (new && root != sub_root) {igrab (inode); sub_root->inode = inode; - do_orphan =1 ; } } -if (unlikely (do_orphan)) -btrfs_orphan_cleanup (sub_root); -return d_splice_alias (inode, dentry); }
@@ -3237,7 +3229,7 @@ int btrfs_write_inode(struct inode *inodstruct btrfs_trans_handle *trans;int ret =0 ; -if (root->fs_info->closing >1 ) +if (root->fs_info->btree_inode == inode)return 0 ;if (wait) {
@@ -4625,6 +4617,9 @@ int btrfs_start_delalloc_inodes(struct bstruct inode *inode;unsigned long flags; +if (root->fs_info->sb->s_flags &MS_RDONLY ) +return -EROFS ; +spin_lock_irqsave (&root->fs_info->delalloc_lock, flags);while (!list_empty (head)) { binode = list_entry(head->next, struct btrfs_inode,
fs/btrfs/ioctl.c +22 -0
@@ -378,6 +378,9 @@ static int btrfs_ioctl_resize(struct btrint namelen;int mod =0 ; +if (root->fs_info->sb->s_flags &MS_RDONLY ) +return -EROFS ; + vol_args =kmalloc (sizeof (*vol_args),GFP_NOFS );if (!vol_args)
@@ -478,6 +481,9 @@ static noinline int btrfs_ioctl_snap_creint namelen;int ret; +if (root->fs_info->sb->s_flags &MS_RDONLY ) +return -EROFS ; + vol_args =kmalloc (sizeof (*vol_args),GFP_NOFS );if (!vol_args)
@@ -534,6 +540,11 @@ static int btrfs_ioctl_defrag(struct fil {struct inode *inode =fdentry (file)->d_inode;struct btrfs_root *root =BTRFS_I (inode)->root; +int ret; + + ret =mnt_want_write (file->f_path.mnt); +if (ret) +return ret;switch (inode->i_mode &S_IFMT ) {case S_IFDIR :
@@ -575,6 +586,9 @@ long btrfs_ioctl_rm_dev(struct btrfs_roostruct btrfs_ioctl_vol_args *vol_args;int ret; +if (root->fs_info->sb->s_flags &MS_RDONLY ) +return -EROFS ; + vol_args =kmalloc (sizeof (*vol_args),GFP_NOFS );if (!vol_args)
@@ -607,6 +621,10 @@ long btrfs_ioctl_clone(struct file *fileint slot;int ret; + ret =mnt_want_write (file->f_path.mnt); +if (ret) +return ret; + src_file =fget (src_fd);if (!src_file)return -EBADF ;
@@ -789,6 +807,10 @@ long btrfs_ioctl_trans_start(struct file goto out; } + ret =mnt_want_write (file->f_path.mnt); +if (ret) + goto out; +mutex_lock (&root->fs_info->trans_mutex); root->fs_info->open_ioctl_trans++;mutex_unlock (&root->fs_info->trans_mutex);
fs/btrfs/super.c +35 -2
@@ -370,6 +370,9 @@ int btrfs_sync_fs(struct super_block *sbint ret; root =btrfs_sb (sb); +if (sb->s_flags &MS_RDONLY ) +return 0 ; + sb->s_dirt =0 ;if (!wait) {filemap_flush (root->fs_info->btree_inode->i_mapping);
@@ -438,7 +441,7 @@ static int btrfs_get_sb(struct file_systup_write (&s->s_umount);deactivate_super (s); error = -EBUSY ; - goto error_bdev; + goto error_close_devices; } }else {
@@ -487,7 +490,7 @@ static int btrfs_get_sb(struct file_syst error_s: error =PTR_ERR (s); -error_bdev: +error_close_devices:btrfs_close_devices (fs_devices); error_free_subvol_name:kfree (subvol_name);
@@ -495,6 +498,35 @@ error:return error; } +static int btrfs_remount (struct super_block *sb,int *flags,char *data) +{ +struct btrfs_root *root =btrfs_sb (sb); +int ret; + +if ((*flags &MS_RDONLY ) == (sb->s_flags &MS_RDONLY )) +return 0 ; + +if (*flags &MS_RDONLY ) { + sb->s_flags |=MS_RDONLY ; + + ret =btrfs_commit_super (root); +WARN_ON (ret); + }else { +if (btrfs_super_log_root (&root->fs_info->super_copy) !=0 ) +return -EINVAL ; + + ret =btrfs_cleanup_reloc_trees (root); +WARN_ON (ret); + + ret =btrfs_cleanup_fs_roots (root->fs_info); +WARN_ON (ret); + + sb->s_flags &= ~MS_RDONLY ; + } + +return 0 ; +} +static int btrfs_statfs (struct dentry *dentry,struct kstatfs *buf) {struct btrfs_root *root =btrfs_sb (dentry->d_sb);
@@ -582,6 +614,7 @@ static struct super_operations btrfs_sup .alloc_inode = btrfs_alloc_inode, .destroy_inode = btrfs_destroy_inode, .statfs = btrfs_statfs, + .remount_fs = btrfs_remount, .write_super_lockfs = btrfs_write_super_lockfs, .unlockfs = btrfs_unlockfs, };