aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorYan Zheng <zheng.yan@oracle.com>2008-11-12 14:34:12 -0500
committerChris Mason <chris.mason@oracle.com>2008-11-12 14:34:12 -0500
commitc146afad2c7fea6a366d4945c1bab9b03880f526 (patch)
treedd217139525a521895125843ca31f61cfbb49dca /fs/btrfs/extent-tree.c
parentf3465ca44e2a51fd647c167045768a8ab5a96603 (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/extent-tree.c')
-rw-r--r--fs/btrfs/extent-tree.c61
1 files changed, 35 insertions, 26 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index e785f0a0632b..af2de30dbeac 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -1794,7 +1794,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
1794 *space_info = found; 1794 *space_info = found;
1795 return 0; 1795 return 0;
1796 } 1796 }
1797 found = kmalloc(sizeof(*found), GFP_NOFS); 1797 found = kzalloc(sizeof(*found), GFP_NOFS);
1798 if (!found) 1798 if (!found)
1799 return -ENOMEM; 1799 return -ENOMEM;
1800 1800
@@ -1807,6 +1807,7 @@ static int update_space_info(struct btrfs_fs_info *info, u64 flags,
1807 found->bytes_used = bytes_used; 1807 found->bytes_used = bytes_used;
1808 found->bytes_pinned = 0; 1808 found->bytes_pinned = 0;
1809 found->bytes_reserved = 0; 1809 found->bytes_reserved = 0;
1810 found->bytes_readonly = 0;
1810 found->full = 0; 1811 found->full = 0;
1811 found->force_alloc = 0; 1812 found->force_alloc = 0;
1812 *space_info = found; 1813 *space_info = found;
@@ -1829,6 +1830,19 @@ static void set_avail_alloc_bits(struct btrfs_fs_info *fs_info, u64 flags)
1829 } 1830 }
1830} 1831}
1831 1832
1833static void set_block_group_readonly(struct btrfs_block_group_cache *cache)
1834{
1835 spin_lock(&cache->space_info->lock);
1836 spin_lock(&cache->lock);
1837 if (!cache->ro) {
1838 cache->space_info->bytes_readonly += cache->key.offset -
1839 btrfs_block_group_used(&cache->item);
1840 cache->ro = 1;
1841 }
1842 spin_unlock(&cache->lock);
1843 spin_unlock(&cache->space_info->lock);
1844}
1845
1832static u64 reduce_alloc_profile(struct btrfs_root *root, u64 flags) 1846static u64 reduce_alloc_profile(struct btrfs_root *root, u64 flags)
1833{ 1847{
1834 u64 num_devices = root->fs_info->fs_devices->num_devices; 1848 u64 num_devices = root->fs_info->fs_devices->num_devices;
@@ -1865,7 +1879,9 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1865 u64 thresh; 1879 u64 thresh;
1866 u64 start; 1880 u64 start;
1867 u64 num_bytes; 1881 u64 num_bytes;
1868 int ret = 0, waited = 0; 1882 int ret = 0;
1883
1884 mutex_lock(&extent_root->fs_info->chunk_mutex);
1869 1885
1870 flags = reduce_alloc_profile(extent_root, flags); 1886 flags = reduce_alloc_profile(extent_root, flags);
1871 1887
@@ -1887,46 +1903,28 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans,
1887 goto out; 1903 goto out;
1888 } 1904 }
1889 1905
1890 thresh = div_factor(space_info->total_bytes, 6); 1906 thresh = space_info->total_bytes - space_info->bytes_readonly;
1907 thresh = div_factor(thresh, 6);
1891 if (!force && 1908 if (!force &&
1892 (space_info->bytes_used + space_info->bytes_pinned + 1909 (space_info->bytes_used + space_info->bytes_pinned +
1893 space_info->bytes_reserved + alloc_bytes) < thresh) { 1910 space_info->bytes_reserved + alloc_bytes) < thresh) {
1894 spin_unlock(&space_info->lock); 1911 spin_unlock(&space_info->lock);
1895 goto out; 1912 goto out;
1896 } 1913 }
1897
1898 spin_unlock(&space_info->lock); 1914 spin_unlock(&space_info->lock);
1899 1915
1900 ret = mutex_trylock(&extent_root->fs_info->chunk_mutex);
1901 if (!ret && !force) {
1902 goto out;
1903 } else if (!ret) {
1904 mutex_lock(&extent_root->fs_info->chunk_mutex);
1905 waited = 1;
1906 }
1907
1908 if (waited) {
1909 spin_lock(&space_info->lock);
1910 if (space_info->full) {
1911 spin_unlock(&space_info->lock);
1912 goto out_unlock;
1913 }
1914 spin_unlock(&space_info->lock);
1915 }
1916
1917 ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags); 1916 ret = btrfs_alloc_chunk(trans, extent_root, &start, &num_bytes, flags);
1918 if (ret) { 1917 if (ret) {
1919printk("space info full %Lu\n", flags); 1918printk("space info full %Lu\n", flags);
1920 space_info->full = 1; 1919 space_info->full = 1;
1921 goto out_unlock; 1920 goto out;
1922 } 1921 }
1923 1922
1924 ret = btrfs_make_block_group(trans, extent_root, 0, flags, 1923 ret = btrfs_make_block_group(trans, extent_root, 0, flags,
1925 BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes); 1924 BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes);
1926 BUG_ON(ret); 1925 BUG_ON(ret);
1927out_unlock:
1928 mutex_unlock(&extent_root->fs_info->chunk_mutex);
1929out: 1926out:
1927 mutex_unlock(&extent_root->fs_info->chunk_mutex);
1930 return ret; 1928 return ret;
1931} 1929}
1932 1930
@@ -1956,12 +1954,18 @@ static int update_block_group(struct btrfs_trans_handle *trans,
1956 if (alloc) { 1954 if (alloc) {
1957 old_val += num_bytes; 1955 old_val += num_bytes;
1958 cache->space_info->bytes_used += num_bytes; 1956 cache->space_info->bytes_used += num_bytes;
1957 if (cache->ro) {
1958 cache->space_info->bytes_readonly -= num_bytes;
1959 WARN_ON(1);
1960 }
1959 btrfs_set_block_group_used(&cache->item, old_val); 1961 btrfs_set_block_group_used(&cache->item, old_val);
1960 spin_unlock(&cache->lock); 1962 spin_unlock(&cache->lock);
1961 spin_unlock(&cache->space_info->lock); 1963 spin_unlock(&cache->space_info->lock);
1962 } else { 1964 } else {
1963 old_val -= num_bytes; 1965 old_val -= num_bytes;
1964 cache->space_info->bytes_used -= num_bytes; 1966 cache->space_info->bytes_used -= num_bytes;
1967 if (cache->ro)
1968 cache->space_info->bytes_readonly += num_bytes;
1965 btrfs_set_block_group_used(&cache->item, old_val); 1969 btrfs_set_block_group_used(&cache->item, old_val);
1966 spin_unlock(&cache->lock); 1970 spin_unlock(&cache->lock);
1967 spin_unlock(&cache->space_info->lock); 1971 spin_unlock(&cache->space_info->lock);
@@ -5560,8 +5564,7 @@ int btrfs_relocate_block_group(struct btrfs_root *root, u64 group_start)
5560 BUG_ON(IS_ERR(reloc_inode)); 5564 BUG_ON(IS_ERR(reloc_inode));
5561 5565
5562 __alloc_chunk_for_shrink(root, block_group, 1); 5566 __alloc_chunk_for_shrink(root, block_group, 1);
5563 block_group->ro = 1; 5567 set_block_group_readonly(block_group);
5564 block_group->space_info->total_bytes -= block_group->key.offset;
5565 5568
5566 btrfs_start_delalloc_inodes(info->tree_root); 5569 btrfs_start_delalloc_inodes(info->tree_root);
5567 btrfs_wait_ordered_extents(info->tree_root, 0); 5570 btrfs_wait_ordered_extents(info->tree_root, 0);
@@ -5868,6 +5871,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
5868 5871
5869 block_group = btrfs_lookup_block_group(root->fs_info, group_start); 5872 block_group = btrfs_lookup_block_group(root->fs_info, group_start);
5870 BUG_ON(!block_group); 5873 BUG_ON(!block_group);
5874 BUG_ON(!block_group->ro);
5871 5875
5872 memcpy(&key, &block_group->key, sizeof(key)); 5876 memcpy(&key, &block_group->key, sizeof(key));
5873 5877
@@ -5881,6 +5885,11 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
5881 list_del(&block_group->list); 5885 list_del(&block_group->list);
5882 up_write(&block_group->space_info->groups_sem); 5886 up_write(&block_group->space_info->groups_sem);
5883 5887
5888 spin_lock(&block_group->space_info->lock);
5889 block_group->space_info->total_bytes -= block_group->key.offset;
5890 block_group->space_info->bytes_readonly -= block_group->key.offset;
5891 spin_unlock(&block_group->space_info->lock);
5892
5884 /* 5893 /*
5885 memset(shrink_block_group, 0, sizeof(*shrink_block_group)); 5894 memset(shrink_block_group, 0, sizeof(*shrink_block_group));
5886 kfree(shrink_block_group); 5895 kfree(shrink_block_group);