diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2008-11-12 14:34:12 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-11-12 14:34:12 -0500 |
commit | c146afad2c7fea6a366d4945c1bab9b03880f526 (patch) | |
tree | dd217139525a521895125843ca31f61cfbb49dca /fs/btrfs/disk-io.c | |
parent | f3465ca44e2a51fd647c167045768a8ab5a96603 (diff) |
Btrfs: mount ro and remount support
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.
Signed-off-by: Yan Zheng <zheng.yan@oracle.com>
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 83 |
1 files changed, 63 insertions, 20 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 3b0e974a9e9c..c599f0ee997a 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1075,10 +1075,12 @@ struct btrfs_root *btrfs_read_fs_root_no_name(struct btrfs_fs_info *fs_info, | |||
1075 | kfree(root); | 1075 | kfree(root); |
1076 | return ERR_PTR(ret); | 1076 | return ERR_PTR(ret); |
1077 | } | 1077 | } |
1078 | ret = btrfs_find_dead_roots(fs_info->tree_root, | 1078 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { |
1079 | root->root_key.objectid, root); | 1079 | ret = btrfs_find_dead_roots(fs_info->tree_root, |
1080 | BUG_ON(ret); | 1080 | root->root_key.objectid, root); |
1081 | 1081 | BUG_ON(ret); | |
1082 | btrfs_orphan_cleanup(root); | ||
1083 | } | ||
1082 | return root; | 1084 | return root; |
1083 | } | 1085 | } |
1084 | 1086 | ||
@@ -1700,7 +1702,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1700 | 1702 | ||
1701 | btrfs_read_block_groups(extent_root); | 1703 | btrfs_read_block_groups(extent_root); |
1702 | 1704 | ||
1703 | fs_info->generation = btrfs_super_generation(disk_super) + 1; | 1705 | fs_info->generation = generation + 1; |
1706 | fs_info->last_trans_committed = generation; | ||
1704 | fs_info->data_alloc_profile = (u64)-1; | 1707 | fs_info->data_alloc_profile = (u64)-1; |
1705 | fs_info->metadata_alloc_profile = (u64)-1; | 1708 | fs_info->metadata_alloc_profile = (u64)-1; |
1706 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; | 1709 | fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; |
@@ -1715,6 +1718,9 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1715 | if (!fs_info->transaction_kthread) | 1718 | if (!fs_info->transaction_kthread) |
1716 | goto fail_cleaner; | 1719 | goto fail_cleaner; |
1717 | 1720 | ||
1721 | if (sb->s_flags & MS_RDONLY) | ||
1722 | return tree_root; | ||
1723 | |||
1718 | if (btrfs_super_log_root(disk_super) != 0) { | 1724 | if (btrfs_super_log_root(disk_super) != 0) { |
1719 | u32 blocksize; | 1725 | u32 blocksize; |
1720 | u64 bytenr = btrfs_super_log_root(disk_super); | 1726 | u64 bytenr = btrfs_super_log_root(disk_super); |
@@ -1735,7 +1741,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1735 | ret = btrfs_recover_log_trees(log_tree_root); | 1741 | ret = btrfs_recover_log_trees(log_tree_root); |
1736 | BUG_ON(ret); | 1742 | BUG_ON(ret); |
1737 | } | 1743 | } |
1738 | fs_info->last_trans_committed = btrfs_super_generation(disk_super); | ||
1739 | 1744 | ||
1740 | ret = btrfs_cleanup_reloc_trees(tree_root); | 1745 | ret = btrfs_cleanup_reloc_trees(tree_root); |
1741 | BUG_ON(ret); | 1746 | BUG_ON(ret); |
@@ -1955,28 +1960,69 @@ static int del_fs_roots(struct btrfs_fs_info *fs_info) | |||
1955 | return 0; | 1960 | return 0; |
1956 | } | 1961 | } |
1957 | 1962 | ||
1958 | int close_ctree(struct btrfs_root *root) | 1963 | int btrfs_cleanup_fs_roots(struct btrfs_fs_info *fs_info) |
1959 | { | 1964 | { |
1965 | u64 root_objectid = 0; | ||
1966 | struct btrfs_root *gang[8]; | ||
1967 | int i; | ||
1960 | int ret; | 1968 | int ret; |
1961 | struct btrfs_trans_handle *trans; | ||
1962 | struct btrfs_fs_info *fs_info = root->fs_info; | ||
1963 | 1969 | ||
1964 | fs_info->closing = 1; | 1970 | while (1) { |
1965 | smp_mb(); | 1971 | ret = radix_tree_gang_lookup(&fs_info->fs_roots_radix, |
1972 | (void **)gang, root_objectid, | ||
1973 | ARRAY_SIZE(gang)); | ||
1974 | if (!ret) | ||
1975 | break; | ||
1976 | for (i = 0; i < ret; i++) { | ||
1977 | root_objectid = gang[i]->root_key.objectid; | ||
1978 | ret = btrfs_find_dead_roots(fs_info->tree_root, | ||
1979 | root_objectid, gang[i]); | ||
1980 | BUG_ON(ret); | ||
1981 | btrfs_orphan_cleanup(gang[i]); | ||
1982 | } | ||
1983 | root_objectid++; | ||
1984 | } | ||
1985 | return 0; | ||
1986 | } | ||
1966 | 1987 | ||
1967 | kthread_stop(root->fs_info->transaction_kthread); | 1988 | int btrfs_commit_super(struct btrfs_root *root) |
1968 | kthread_stop(root->fs_info->cleaner_kthread); | 1989 | { |
1990 | struct btrfs_trans_handle *trans; | ||
1991 | int ret; | ||
1969 | 1992 | ||
1993 | mutex_lock(&root->fs_info->cleaner_mutex); | ||
1970 | btrfs_clean_old_snapshots(root); | 1994 | btrfs_clean_old_snapshots(root); |
1995 | mutex_unlock(&root->fs_info->cleaner_mutex); | ||
1971 | trans = btrfs_start_transaction(root, 1); | 1996 | trans = btrfs_start_transaction(root, 1); |
1972 | ret = btrfs_commit_transaction(trans, root); | 1997 | ret = btrfs_commit_transaction(trans, root); |
1973 | /* run commit again to drop the original snapshot */ | 1998 | BUG_ON(ret); |
1999 | /* run commit again to drop the original snapshot */ | ||
1974 | trans = btrfs_start_transaction(root, 1); | 2000 | trans = btrfs_start_transaction(root, 1); |
1975 | btrfs_commit_transaction(trans, root); | 2001 | btrfs_commit_transaction(trans, root); |
1976 | ret = btrfs_write_and_wait_transaction(NULL, root); | 2002 | ret = btrfs_write_and_wait_transaction(NULL, root); |
1977 | BUG_ON(ret); | 2003 | BUG_ON(ret); |
1978 | 2004 | ||
1979 | write_ctree_super(NULL, root); | 2005 | ret = write_ctree_super(NULL, root); |
2006 | return ret; | ||
2007 | } | ||
2008 | |||
2009 | int close_ctree(struct btrfs_root *root) | ||
2010 | { | ||
2011 | struct btrfs_fs_info *fs_info = root->fs_info; | ||
2012 | int ret; | ||
2013 | |||
2014 | fs_info->closing = 1; | ||
2015 | smp_mb(); | ||
2016 | |||
2017 | kthread_stop(root->fs_info->transaction_kthread); | ||
2018 | kthread_stop(root->fs_info->cleaner_kthread); | ||
2019 | |||
2020 | if (!(fs_info->sb->s_flags & MS_RDONLY)) { | ||
2021 | ret = btrfs_commit_super(root); | ||
2022 | if (ret) { | ||
2023 | printk("btrfs: commit super returns %d\n", ret); | ||
2024 | } | ||
2025 | } | ||
1980 | 2026 | ||
1981 | if (fs_info->delalloc_bytes) { | 2027 | if (fs_info->delalloc_bytes) { |
1982 | printk("btrfs: at unmount delalloc count %Lu\n", | 2028 | printk("btrfs: at unmount delalloc count %Lu\n", |
@@ -2000,12 +2046,10 @@ int close_ctree(struct btrfs_root *root) | |||
2000 | free_extent_buffer(root->fs_info->dev_root->node); | 2046 | free_extent_buffer(root->fs_info->dev_root->node); |
2001 | 2047 | ||
2002 | btrfs_free_block_groups(root->fs_info); | 2048 | btrfs_free_block_groups(root->fs_info); |
2003 | fs_info->closing = 2; | ||
2004 | del_fs_roots(fs_info); | ||
2005 | 2049 | ||
2006 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); | 2050 | del_fs_roots(fs_info); |
2007 | 2051 | ||
2008 | truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); | 2052 | iput(fs_info->btree_inode); |
2009 | 2053 | ||
2010 | btrfs_stop_workers(&fs_info->fixup_workers); | 2054 | btrfs_stop_workers(&fs_info->fixup_workers); |
2011 | btrfs_stop_workers(&fs_info->delalloc_workers); | 2055 | btrfs_stop_workers(&fs_info->delalloc_workers); |
@@ -2014,7 +2058,6 @@ int close_ctree(struct btrfs_root *root) | |||
2014 | btrfs_stop_workers(&fs_info->endio_write_workers); | 2058 | btrfs_stop_workers(&fs_info->endio_write_workers); |
2015 | btrfs_stop_workers(&fs_info->submit_workers); | 2059 | btrfs_stop_workers(&fs_info->submit_workers); |
2016 | 2060 | ||
2017 | iput(fs_info->btree_inode); | ||
2018 | #if 0 | 2061 | #if 0 |
2019 | while(!list_empty(&fs_info->hashers)) { | 2062 | while(!list_empty(&fs_info->hashers)) { |
2020 | struct btrfs_hasher *hasher; | 2063 | struct btrfs_hasher *hasher; |