diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/btrfs/disk-io.c | 208 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.h | 17 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 54 | ||||
| -rw-r--r-- | fs/btrfs/free-space-cache.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/transaction.c | 2 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 3 | ||||
| -rw-r--r-- | fs/btrfs/volumes.c | 107 | ||||
| -rw-r--r-- | fs/btrfs/volumes.h | 6 |
8 files changed, 279 insertions, 119 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 61dc3b2c834..c72f4f3b912 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1595,8 +1595,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1595 | fs_info, BTRFS_ROOT_TREE_OBJECTID); | 1595 | fs_info, BTRFS_ROOT_TREE_OBJECTID); |
| 1596 | 1596 | ||
| 1597 | 1597 | ||
| 1598 | bh = __bread(fs_devices->latest_bdev, | 1598 | bh = btrfs_read_dev_super(fs_devices->latest_bdev); |
| 1599 | BTRFS_SUPER_INFO_OFFSET / 4096, 4096); | ||
| 1600 | if (!bh) | 1599 | if (!bh) |
| 1601 | goto fail_iput; | 1600 | goto fail_iput; |
| 1602 | 1601 | ||
| @@ -1710,7 +1709,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 1710 | } | 1709 | } |
| 1711 | 1710 | ||
| 1712 | mutex_lock(&fs_info->chunk_mutex); | 1711 | mutex_lock(&fs_info->chunk_mutex); |
| 1713 | ret = btrfs_read_sys_array(tree_root); | 1712 | ret = btrfs_read_sys_array(tree_root, btrfs_super_bytenr(disk_super)); |
| 1714 | mutex_unlock(&fs_info->chunk_mutex); | 1713 | mutex_unlock(&fs_info->chunk_mutex); |
| 1715 | if (ret) { | 1714 | if (ret) { |
| 1716 | printk("btrfs: failed to read the system array on %s\n", | 1715 | printk("btrfs: failed to read the system array on %s\n", |
| @@ -1905,19 +1904,147 @@ static void btrfs_end_buffer_write_sync(struct buffer_head *bh, int uptodate) | |||
| 1905 | put_bh(bh); | 1904 | put_bh(bh); |
| 1906 | } | 1905 | } |
| 1907 | 1906 | ||
| 1908 | static int write_all_supers(struct btrfs_root *root) | 1907 | struct buffer_head *btrfs_read_dev_super(struct block_device *bdev) |
| 1908 | { | ||
| 1909 | struct buffer_head *bh; | ||
| 1910 | struct buffer_head *latest = NULL; | ||
| 1911 | struct btrfs_super_block *super; | ||
| 1912 | int i; | ||
| 1913 | u64 transid = 0; | ||
| 1914 | u64 bytenr; | ||
| 1915 | |||
| 1916 | /* we would like to check all the supers, but that would make | ||
| 1917 | * a btrfs mount succeed after a mkfs from a different FS. | ||
| 1918 | * So, we need to add a special mount option to scan for | ||
| 1919 | * later supers, using BTRFS_SUPER_MIRROR_MAX instead | ||
| 1920 | */ | ||
| 1921 | for (i = 0; i < 1; i++) { | ||
| 1922 | bytenr = btrfs_sb_offset(i); | ||
| 1923 | if (bytenr + 4096 >= i_size_read(bdev->bd_inode)) | ||
| 1924 | break; | ||
| 1925 | bh = __bread(bdev, bytenr / 4096, 4096); | ||
| 1926 | if (!bh) | ||
| 1927 | continue; | ||
| 1928 | |||
| 1929 | super = (struct btrfs_super_block *)bh->b_data; | ||
| 1930 | if (btrfs_super_bytenr(super) != bytenr || | ||
| 1931 | strncmp((char *)(&super->magic), BTRFS_MAGIC, | ||
| 1932 | sizeof(super->magic))) { | ||
| 1933 | brelse(bh); | ||
| 1934 | continue; | ||
| 1935 | } | ||
| 1936 | |||
| 1937 | if (!latest || btrfs_super_generation(super) > transid) { | ||
| 1938 | brelse(latest); | ||
| 1939 | latest = bh; | ||
| 1940 | transid = btrfs_super_generation(super); | ||
| 1941 | } else { | ||
| 1942 | brelse(bh); | ||
| 1943 | } | ||
| 1944 | } | ||
| 1945 | return latest; | ||
| 1946 | } | ||
| 1947 | |||
| 1948 | static int write_dev_supers(struct btrfs_device *device, | ||
| 1949 | struct btrfs_super_block *sb, | ||
| 1950 | int do_barriers, int wait, int max_mirrors) | ||
| 1951 | { | ||
| 1952 | struct buffer_head *bh; | ||
| 1953 | int i; | ||
| 1954 | int ret; | ||
| 1955 | int errors = 0; | ||
| 1956 | u32 crc; | ||
| 1957 | u64 bytenr; | ||
| 1958 | int last_barrier = 0; | ||
| 1959 | |||
| 1960 | if (max_mirrors == 0) | ||
| 1961 | max_mirrors = BTRFS_SUPER_MIRROR_MAX; | ||
| 1962 | |||
| 1963 | /* make sure only the last submit_bh does a barrier */ | ||
| 1964 | if (do_barriers) { | ||
| 1965 | for (i = 0; i < max_mirrors; i++) { | ||
| 1966 | bytenr = btrfs_sb_offset(i); | ||
| 1967 | if (bytenr + BTRFS_SUPER_INFO_SIZE >= | ||
| 1968 | device->total_bytes) | ||
| 1969 | break; | ||
| 1970 | last_barrier = i; | ||
| 1971 | } | ||
| 1972 | } | ||
| 1973 | |||
| 1974 | for (i = 0; i < max_mirrors; i++) { | ||
| 1975 | bytenr = btrfs_sb_offset(i); | ||
| 1976 | if (bytenr + BTRFS_SUPER_INFO_SIZE >= device->total_bytes) | ||
| 1977 | break; | ||
| 1978 | |||
| 1979 | if (wait) { | ||
| 1980 | bh = __find_get_block(device->bdev, bytenr / 4096, | ||
| 1981 | BTRFS_SUPER_INFO_SIZE); | ||
| 1982 | BUG_ON(!bh); | ||
| 1983 | brelse(bh); | ||
| 1984 | wait_on_buffer(bh); | ||
| 1985 | if (buffer_uptodate(bh)) { | ||
| 1986 | brelse(bh); | ||
| 1987 | continue; | ||
| 1988 | } | ||
| 1989 | } else { | ||
| 1990 | btrfs_set_super_bytenr(sb, bytenr); | ||
| 1991 | |||
| 1992 | crc = ~(u32)0; | ||
| 1993 | crc = btrfs_csum_data(NULL, (char *)sb + | ||
| 1994 | BTRFS_CSUM_SIZE, crc, | ||
| 1995 | BTRFS_SUPER_INFO_SIZE - | ||
| 1996 | BTRFS_CSUM_SIZE); | ||
| 1997 | btrfs_csum_final(crc, sb->csum); | ||
| 1998 | |||
| 1999 | bh = __getblk(device->bdev, bytenr / 4096, | ||
| 2000 | BTRFS_SUPER_INFO_SIZE); | ||
| 2001 | memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE); | ||
| 2002 | |||
| 2003 | set_buffer_uptodate(bh); | ||
| 2004 | get_bh(bh); | ||
| 2005 | lock_buffer(bh); | ||
| 2006 | bh->b_end_io = btrfs_end_buffer_write_sync; | ||
| 2007 | } | ||
| 2008 | |||
| 2009 | if (i == last_barrier && do_barriers && device->barriers) { | ||
| 2010 | ret = submit_bh(WRITE_BARRIER, bh); | ||
| 2011 | if (ret == -EOPNOTSUPP) { | ||
| 2012 | printk("btrfs: disabling barriers on dev %s\n", | ||
| 2013 | device->name); | ||
| 2014 | set_buffer_uptodate(bh); | ||
| 2015 | device->barriers = 0; | ||
| 2016 | get_bh(bh); | ||
| 2017 | lock_buffer(bh); | ||
| 2018 | ret = submit_bh(WRITE, bh); | ||
| 2019 | } | ||
| 2020 | } else { | ||
| 2021 | ret = submit_bh(WRITE, bh); | ||
| 2022 | } | ||
| 2023 | |||
| 2024 | if (!ret && wait) { | ||
| 2025 | wait_on_buffer(bh); | ||
| 2026 | if (!buffer_uptodate(bh)) | ||
| 2027 | errors++; | ||
| 2028 | } else if (ret) { | ||
| 2029 | errors++; | ||
| 2030 | } | ||
| 2031 | if (wait) | ||
| 2032 | brelse(bh); | ||
| 2033 | } | ||
| 2034 | return errors < i ? 0 : -1; | ||
| 2035 | } | ||
| 2036 | |||
| 2037 | int write_all_supers(struct btrfs_root *root, int max_mirrors) | ||
| 1909 | { | 2038 | { |
| 1910 | struct list_head *cur; | 2039 | struct list_head *cur; |
| 1911 | struct list_head *head = &root->fs_info->fs_devices->devices; | 2040 | struct list_head *head = &root->fs_info->fs_devices->devices; |
| 1912 | struct btrfs_device *dev; | 2041 | struct btrfs_device *dev; |
| 1913 | struct btrfs_super_block *sb; | 2042 | struct btrfs_super_block *sb; |
| 1914 | struct btrfs_dev_item *dev_item; | 2043 | struct btrfs_dev_item *dev_item; |
| 1915 | struct buffer_head *bh; | ||
| 1916 | int ret; | 2044 | int ret; |
| 1917 | int do_barriers; | 2045 | int do_barriers; |
| 1918 | int max_errors; | 2046 | int max_errors; |
| 1919 | int total_errors = 0; | 2047 | int total_errors = 0; |
| 1920 | u32 crc; | ||
| 1921 | u64 flags; | 2048 | u64 flags; |
| 1922 | 2049 | ||
| 1923 | max_errors = btrfs_super_num_devices(&root->fs_info->super_copy) - 1; | 2050 | max_errors = btrfs_super_num_devices(&root->fs_info->super_copy) - 1; |
| @@ -1944,40 +2071,11 @@ static int write_all_supers(struct btrfs_root *root) | |||
| 1944 | btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); | 2071 | btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); |
| 1945 | memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE); | 2072 | memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE); |
| 1946 | memcpy(dev_item->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE); | 2073 | memcpy(dev_item->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE); |
| 2074 | |||
| 1947 | flags = btrfs_super_flags(sb); | 2075 | flags = btrfs_super_flags(sb); |
| 1948 | btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); | 2076 | btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); |
| 1949 | 2077 | ||
| 1950 | 2078 | ret = write_dev_supers(dev, sb, do_barriers, 0, max_mirrors); | |
| 1951 | crc = ~(u32)0; | ||
| 1952 | crc = btrfs_csum_data(root, (char *)sb + BTRFS_CSUM_SIZE, crc, | ||
| 1953 | BTRFS_SUPER_INFO_SIZE - BTRFS_CSUM_SIZE); | ||
| 1954 | btrfs_csum_final(crc, sb->csum); | ||
| 1955 | |||
| 1956 | bh = __getblk(dev->bdev, BTRFS_SUPER_INFO_OFFSET / 4096, | ||
| 1957 | BTRFS_SUPER_INFO_SIZE); | ||
| 1958 | |||
| 1959 | memcpy(bh->b_data, sb, BTRFS_SUPER_INFO_SIZE); | ||
| 1960 | dev->pending_io = bh; | ||
| 1961 | |||
| 1962 | get_bh(bh); | ||
| 1963 | set_buffer_uptodate(bh); | ||
| 1964 | lock_buffer(bh); | ||
| 1965 | bh->b_end_io = btrfs_end_buffer_write_sync; | ||
| 1966 | |||
| 1967 | if (do_barriers && dev->barriers) { | ||
| 1968 | ret = submit_bh(WRITE_BARRIER, bh); | ||
| 1969 | if (ret == -EOPNOTSUPP) { | ||
| 1970 | printk("btrfs: disabling barriers on dev %s\n", | ||
| 1971 | dev->name); | ||
| 1972 | set_buffer_uptodate(bh); | ||
| 1973 | dev->barriers = 0; | ||
| 1974 | get_bh(bh); | ||
| 1975 | lock_buffer(bh); | ||
| 1976 | ret = submit_bh(WRITE, bh); | ||
| 1977 | } | ||
| 1978 | } else { | ||
| 1979 | ret = submit_bh(WRITE, bh); | ||
| 1980 | } | ||
| 1981 | if (ret) | 2079 | if (ret) |
| 1982 | total_errors++; | 2080 | total_errors++; |
| 1983 | } | 2081 | } |
| @@ -1985,8 +2083,8 @@ static int write_all_supers(struct btrfs_root *root) | |||
| 1985 | printk("btrfs: %d errors while writing supers\n", total_errors); | 2083 | printk("btrfs: %d errors while writing supers\n", total_errors); |
| 1986 | BUG(); | 2084 | BUG(); |
| 1987 | } | 2085 | } |
| 1988 | total_errors = 0; | ||
| 1989 | 2086 | ||
| 2087 | total_errors = 0; | ||
| 1990 | list_for_each(cur, head) { | 2088 | list_for_each(cur, head) { |
| 1991 | dev = list_entry(cur, struct btrfs_device, dev_list); | 2089 | dev = list_entry(cur, struct btrfs_device, dev_list); |
| 1992 | if (!dev->bdev) | 2090 | if (!dev->bdev) |
| @@ -1994,29 +2092,9 @@ static int write_all_supers(struct btrfs_root *root) | |||
| 1994 | if (!dev->in_fs_metadata || !dev->writeable) | 2092 | if (!dev->in_fs_metadata || !dev->writeable) |
| 1995 | continue; | 2093 | continue; |
| 1996 | 2094 | ||
| 1997 | BUG_ON(!dev->pending_io); | 2095 | ret = write_dev_supers(dev, sb, do_barriers, 1, max_mirrors); |
| 1998 | bh = dev->pending_io; | 2096 | if (ret) |
| 1999 | wait_on_buffer(bh); | 2097 | total_errors++; |
| 2000 | if (!buffer_uptodate(dev->pending_io)) { | ||
| 2001 | if (do_barriers && dev->barriers) { | ||
| 2002 | printk("btrfs: disabling barriers on dev %s\n", | ||
| 2003 | dev->name); | ||
| 2004 | set_buffer_uptodate(bh); | ||
| 2005 | get_bh(bh); | ||
| 2006 | lock_buffer(bh); | ||
| 2007 | dev->barriers = 0; | ||
| 2008 | ret = submit_bh(WRITE, bh); | ||
| 2009 | BUG_ON(ret); | ||
| 2010 | wait_on_buffer(bh); | ||
| 2011 | if (!buffer_uptodate(bh)) | ||
| 2012 | total_errors++; | ||
| 2013 | } else { | ||
| 2014 | total_errors++; | ||
| 2015 | } | ||
| 2016 | |||
| 2017 | } | ||
| 2018 | dev->pending_io = NULL; | ||
| 2019 | brelse(bh); | ||
| 2020 | } | 2098 | } |
| 2021 | if (total_errors > max_errors) { | 2099 | if (total_errors > max_errors) { |
| 2022 | printk("btrfs: %d errors while writing supers\n", total_errors); | 2100 | printk("btrfs: %d errors while writing supers\n", total_errors); |
| @@ -2025,12 +2103,12 @@ static int write_all_supers(struct btrfs_root *root) | |||
| 2025 | return 0; | 2103 | return 0; |
| 2026 | } | 2104 | } |
| 2027 | 2105 | ||
| 2028 | int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root | 2106 | int write_ctree_super(struct btrfs_trans_handle *trans, |
| 2029 | *root) | 2107 | struct btrfs_root *root, int max_mirrors) |
| 2030 | { | 2108 | { |
| 2031 | int ret; | 2109 | int ret; |
| 2032 | 2110 | ||
| 2033 | ret = write_all_supers(root); | 2111 | ret = write_all_supers(root, max_mirrors); |
| 2034 | return ret; | 2112 | return ret; |
| 2035 | } | 2113 | } |
| 2036 | 2114 | ||
| @@ -2116,7 +2194,7 @@ int btrfs_commit_super(struct btrfs_root *root) | |||
| 2116 | ret = btrfs_write_and_wait_transaction(NULL, root); | 2194 | ret = btrfs_write_and_wait_transaction(NULL, root); |
| 2117 | BUG_ON(ret); | 2195 | BUG_ON(ret); |
| 2118 | 2196 | ||
| 2119 | ret = write_ctree_super(NULL, root); | 2197 | ret = write_ctree_super(NULL, root, 0); |
| 2120 | return ret; | 2198 | return ret; |
| 2121 | } | 2199 | } |
| 2122 | 2200 | ||
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 717e94811e4..c0ff404c31b 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
| @@ -19,8 +19,20 @@ | |||
| 19 | #ifndef __DISKIO__ | 19 | #ifndef __DISKIO__ |
| 20 | #define __DISKIO__ | 20 | #define __DISKIO__ |
| 21 | 21 | ||
| 22 | #define BTRFS_SUPER_INFO_OFFSET (16 * 1024) | 22 | #define BTRFS_SUPER_INFO_OFFSET (64 * 1024) |
| 23 | #define BTRFS_SUPER_INFO_SIZE 4096 | 23 | #define BTRFS_SUPER_INFO_SIZE 4096 |
| 24 | |||
| 25 | #define BTRFS_SUPER_MIRROR_MAX 3 | ||
| 26 | #define BTRFS_SUPER_MIRROR_SHIFT 12 | ||
| 27 | |||
| 28 | static inline u64 btrfs_sb_offset(int mirror) | ||
| 29 | { | ||
| 30 | u64 start = 16 * 1024; | ||
| 31 | if (mirror) | ||
| 32 | return start << (BTRFS_SUPER_MIRROR_SHIFT * mirror); | ||
| 33 | return BTRFS_SUPER_INFO_OFFSET; | ||
| 34 | } | ||
| 35 | |||
| 24 | struct btrfs_device; | 36 | struct btrfs_device; |
| 25 | struct btrfs_fs_devices; | 37 | struct btrfs_fs_devices; |
| 26 | 38 | ||
| @@ -37,7 +49,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
| 37 | char *options); | 49 | char *options); |
| 38 | int close_ctree(struct btrfs_root *root); | 50 | int close_ctree(struct btrfs_root *root); |
| 39 | int write_ctree_super(struct btrfs_trans_handle *trans, | 51 | int write_ctree_super(struct btrfs_trans_handle *trans, |
| 40 | struct btrfs_root *root); | 52 | struct btrfs_root *root, int max_mirrors); |
| 53 | struct buffer_head *btrfs_read_dev_super(struct block_device *bdev); | ||
| 41 | int btrfs_commit_super(struct btrfs_root *root); | 54 | int btrfs_commit_super(struct btrfs_root *root); |
| 42 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, | 55 | struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, |
| 43 | u64 bytenr, u32 blocksize); | 56 | u64 bytenr, u32 blocksize); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d1563852938..803647bc840 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -189,6 +189,29 @@ static int add_new_free_space(struct btrfs_block_group_cache *block_group, | |||
| 189 | return 0; | 189 | return 0; |
| 190 | } | 190 | } |
| 191 | 191 | ||
| 192 | static int remove_sb_from_cache(struct btrfs_root *root, | ||
| 193 | struct btrfs_block_group_cache *cache) | ||
| 194 | { | ||
| 195 | u64 bytenr; | ||
| 196 | u64 *logical; | ||
| 197 | int stripe_len; | ||
| 198 | int i, nr, ret; | ||
| 199 | |||
| 200 | for (i = 0; i < BTRFS_SUPER_MIRROR_MAX; i++) { | ||
| 201 | bytenr = btrfs_sb_offset(i); | ||
| 202 | ret = btrfs_rmap_block(&root->fs_info->mapping_tree, | ||
| 203 | cache->key.objectid, bytenr, 0, | ||
| 204 | &logical, &nr, &stripe_len); | ||
| 205 | BUG_ON(ret); | ||
| 206 | while (nr--) { | ||
| 207 | btrfs_remove_free_space(cache, logical[nr], | ||
| 208 | stripe_len); | ||
| 209 | } | ||
| 210 | kfree(logical); | ||
| 211 | } | ||
| 212 | return 0; | ||
| 213 | } | ||
| 214 | |||
| 192 | static int cache_block_group(struct btrfs_root *root, | 215 | static int cache_block_group(struct btrfs_root *root, |
| 193 | struct btrfs_block_group_cache *block_group) | 216 | struct btrfs_block_group_cache *block_group) |
| 194 | { | 217 | { |
| @@ -197,9 +220,7 @@ static int cache_block_group(struct btrfs_root *root, | |||
| 197 | struct btrfs_key key; | 220 | struct btrfs_key key; |
| 198 | struct extent_buffer *leaf; | 221 | struct extent_buffer *leaf; |
| 199 | int slot; | 222 | int slot; |
| 200 | u64 last = 0; | 223 | u64 last = block_group->key.objectid; |
| 201 | u64 first_free; | ||
| 202 | int found = 0; | ||
| 203 | 224 | ||
| 204 | if (!block_group) | 225 | if (!block_group) |
| 205 | return 0; | 226 | return 0; |
| @@ -220,23 +241,13 @@ static int cache_block_group(struct btrfs_root *root, | |||
| 220 | * skip the locking here | 241 | * skip the locking here |
| 221 | */ | 242 | */ |
| 222 | path->skip_locking = 1; | 243 | path->skip_locking = 1; |
| 223 | first_free = max_t(u64, block_group->key.objectid, | 244 | key.objectid = last; |
| 224 | BTRFS_SUPER_INFO_OFFSET + BTRFS_SUPER_INFO_SIZE); | ||
| 225 | key.objectid = block_group->key.objectid; | ||
| 226 | key.offset = 0; | 245 | key.offset = 0; |
| 227 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | 246 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); |
| 228 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); | 247 | ret = btrfs_search_slot(NULL, root, &key, path, 0, 0); |
| 229 | if (ret < 0) | 248 | if (ret < 0) |
| 230 | goto err; | 249 | goto err; |
| 231 | ret = btrfs_previous_item(root, path, 0, BTRFS_EXTENT_ITEM_KEY); | 250 | |
| 232 | if (ret < 0) | ||
| 233 | goto err; | ||
| 234 | if (ret == 0) { | ||
| 235 | leaf = path->nodes[0]; | ||
| 236 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | ||
| 237 | if (key.objectid + key.offset > first_free) | ||
| 238 | first_free = key.objectid + key.offset; | ||
| 239 | } | ||
| 240 | while(1) { | 251 | while(1) { |
| 241 | leaf = path->nodes[0]; | 252 | leaf = path->nodes[0]; |
| 242 | slot = path->slots[0]; | 253 | slot = path->slots[0]; |
| @@ -258,11 +269,6 @@ static int cache_block_group(struct btrfs_root *root, | |||
| 258 | break; | 269 | break; |
| 259 | 270 | ||
| 260 | if (btrfs_key_type(&key) == BTRFS_EXTENT_ITEM_KEY) { | 271 | if (btrfs_key_type(&key) == BTRFS_EXTENT_ITEM_KEY) { |
| 261 | if (!found) { | ||
| 262 | last = first_free; | ||
| 263 | found = 1; | ||
| 264 | } | ||
| 265 | |||
| 266 | add_new_free_space(block_group, root->fs_info, last, | 272 | add_new_free_space(block_group, root->fs_info, last, |
| 267 | key.objectid); | 273 | key.objectid); |
| 268 | 274 | ||
| @@ -272,13 +278,11 @@ next: | |||
| 272 | path->slots[0]++; | 278 | path->slots[0]++; |
| 273 | } | 279 | } |
| 274 | 280 | ||
| 275 | if (!found) | ||
| 276 | last = first_free; | ||
| 277 | |||
| 278 | add_new_free_space(block_group, root->fs_info, last, | 281 | add_new_free_space(block_group, root->fs_info, last, |
| 279 | block_group->key.objectid + | 282 | block_group->key.objectid + |
| 280 | block_group->key.offset); | 283 | block_group->key.offset); |
| 281 | 284 | ||
| 285 | remove_sb_from_cache(root, block_group); | ||
| 282 | block_group->cached = 1; | 286 | block_group->cached = 1; |
| 283 | ret = 0; | 287 | ret = 0; |
| 284 | err: | 288 | err: |
| @@ -1974,10 +1978,8 @@ static int update_block_group(struct btrfs_trans_handle *trans, | |||
| 1974 | if (alloc) { | 1978 | if (alloc) { |
| 1975 | old_val += num_bytes; | 1979 | old_val += num_bytes; |
| 1976 | cache->space_info->bytes_used += num_bytes; | 1980 | cache->space_info->bytes_used += num_bytes; |
| 1977 | if (cache->ro) { | 1981 | if (cache->ro) |
| 1978 | cache->space_info->bytes_readonly -= num_bytes; | 1982 | cache->space_info->bytes_readonly -= num_bytes; |
| 1979 | WARN_ON(1); | ||
| 1980 | } | ||
| 1981 | btrfs_set_block_group_used(&cache->item, old_val); | 1983 | btrfs_set_block_group_used(&cache->item, old_val); |
| 1982 | spin_unlock(&cache->lock); | 1984 | spin_unlock(&cache->lock); |
| 1983 | spin_unlock(&cache->space_info->lock); | 1985 | spin_unlock(&cache->space_info->lock); |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 09462adfbe3..2e69b9c3043 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
| @@ -290,7 +290,6 @@ __btrfs_remove_free_space(struct btrfs_block_group_cache *block_group, | |||
| 290 | ret = -EINVAL; | 290 | ret = -EINVAL; |
| 291 | goto out; | 291 | goto out; |
| 292 | } | 292 | } |
| 293 | |||
| 294 | unlink_free_space(block_group, info); | 293 | unlink_free_space(block_group, info); |
| 295 | 294 | ||
| 296 | if (info->bytes == bytes) { | 295 | if (info->bytes == bytes) { |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index c38f6a0e30b..47cd5fcad2c 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -1038,7 +1038,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1038 | mutex_unlock(&root->fs_info->trans_mutex); | 1038 | mutex_unlock(&root->fs_info->trans_mutex); |
| 1039 | ret = btrfs_write_and_wait_transaction(trans, root); | 1039 | ret = btrfs_write_and_wait_transaction(trans, root); |
| 1040 | BUG_ON(ret); | 1040 | BUG_ON(ret); |
| 1041 | write_ctree_super(trans, root); | 1041 | write_ctree_super(trans, root, 0); |
| 1042 | 1042 | ||
| 1043 | /* | 1043 | /* |
| 1044 | * the super is written, we can safely allow the tree-loggers | 1044 | * the super is written, we can safely allow the tree-loggers |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 08469ec0585..d3f9c2c663c 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
| @@ -1996,7 +1996,7 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 1996 | btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, | 1996 | btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, |
| 1997 | btrfs_header_level(log->fs_info->log_root_tree->node)); | 1997 | btrfs_header_level(log->fs_info->log_root_tree->node)); |
| 1998 | 1998 | ||
| 1999 | write_ctree_super(trans, log->fs_info->tree_root); | 1999 | write_ctree_super(trans, log->fs_info->tree_root, 2); |
| 2000 | log->fs_info->tree_log_transid++; | 2000 | log->fs_info->tree_log_transid++; |
| 2001 | log->fs_info->tree_log_batch = 0; | 2001 | log->fs_info->tree_log_batch = 0; |
| 2002 | atomic_set(&log->fs_info->tree_log_commit, 0); | 2002 | atomic_set(&log->fs_info->tree_log_commit, 0); |
| @@ -2006,7 +2006,6 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, | |||
| 2006 | out: | 2006 | out: |
| 2007 | mutex_unlock(&log->fs_info->tree_log_mutex); | 2007 | mutex_unlock(&log->fs_info->tree_log_mutex); |
| 2008 | return 0; | 2008 | return 0; |
| 2009 | |||
| 2010 | } | 2009 | } |
| 2011 | 2010 | ||
| 2012 | /* * free all the extents used by the tree log. This should be called | 2011 | /* * free all the extents used by the tree log. This should be called |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 2049d179ccd..a79b3cc09e9 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
| @@ -423,15 +423,11 @@ int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
| 423 | } | 423 | } |
| 424 | set_blocksize(bdev, 4096); | 424 | set_blocksize(bdev, 4096); |
| 425 | 425 | ||
| 426 | bh = __bread(bdev, BTRFS_SUPER_INFO_OFFSET / 4096, 4096); | 426 | bh = btrfs_read_dev_super(bdev); |
| 427 | if (!bh) | 427 | if (!bh) |
| 428 | goto error_close; | 428 | goto error_close; |
| 429 | 429 | ||
| 430 | disk_super = (struct btrfs_super_block *)bh->b_data; | 430 | disk_super = (struct btrfs_super_block *)bh->b_data; |
| 431 | if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC, | ||
| 432 | sizeof(disk_super->magic))) | ||
| 433 | goto error_brelse; | ||
| 434 | |||
| 435 | devid = le64_to_cpu(disk_super->dev_item.devid); | 431 | devid = le64_to_cpu(disk_super->dev_item.devid); |
| 436 | if (devid != device->devid) | 432 | if (devid != device->devid) |
| 437 | goto error_brelse; | 433 | goto error_brelse; |
| @@ -529,17 +525,12 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
| 529 | ret = set_blocksize(bdev, 4096); | 525 | ret = set_blocksize(bdev, 4096); |
| 530 | if (ret) | 526 | if (ret) |
| 531 | goto error_close; | 527 | goto error_close; |
| 532 | bh = __bread(bdev, BTRFS_SUPER_INFO_OFFSET / 4096, 4096); | 528 | bh = btrfs_read_dev_super(bdev); |
| 533 | if (!bh) { | 529 | if (!bh) { |
| 534 | ret = -EIO; | 530 | ret = -EIO; |
| 535 | goto error_close; | 531 | goto error_close; |
| 536 | } | 532 | } |
| 537 | disk_super = (struct btrfs_super_block *)bh->b_data; | 533 | disk_super = (struct btrfs_super_block *)bh->b_data; |
| 538 | if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC, | ||
| 539 | sizeof(disk_super->magic))) { | ||
| 540 | ret = -EINVAL; | ||
| 541 | goto error_brelse; | ||
| 542 | } | ||
| 543 | devid = le64_to_cpu(disk_super->dev_item.devid); | 534 | devid = le64_to_cpu(disk_super->dev_item.devid); |
| 544 | transid = btrfs_super_generation(disk_super); | 535 | transid = btrfs_super_generation(disk_super); |
| 545 | if (disk_super->label[0]) | 536 | if (disk_super->label[0]) |
| @@ -553,7 +544,6 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, | |||
| 553 | printk("devid %Lu transid %Lu %s\n", devid, transid, path); | 544 | printk("devid %Lu transid %Lu %s\n", devid, transid, path); |
| 554 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); | 545 | ret = device_list_add(path, disk_super, devid, fs_devices_ret); |
| 555 | 546 | ||
| 556 | error_brelse: | ||
| 557 | brelse(bh); | 547 | brelse(bh); |
| 558 | error_close: | 548 | error_close: |
| 559 | close_bdev_exclusive(bdev, flags); | 549 | close_bdev_exclusive(bdev, flags); |
| @@ -1016,17 +1006,12 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
| 1016 | } | 1006 | } |
| 1017 | 1007 | ||
| 1018 | set_blocksize(bdev, 4096); | 1008 | set_blocksize(bdev, 4096); |
| 1019 | bh = __bread(bdev, BTRFS_SUPER_INFO_OFFSET / 4096, 4096); | 1009 | bh = btrfs_read_dev_super(bdev); |
| 1020 | if (!bh) { | 1010 | if (!bh) { |
| 1021 | ret = -EIO; | 1011 | ret = -EIO; |
| 1022 | goto error_close; | 1012 | goto error_close; |
| 1023 | } | 1013 | } |
| 1024 | disk_super = (struct btrfs_super_block *)bh->b_data; | 1014 | disk_super = (struct btrfs_super_block *)bh->b_data; |
| 1025 | if (strncmp((char *)(&disk_super->magic), BTRFS_MAGIC, | ||
| 1026 | sizeof(disk_super->magic))) { | ||
| 1027 | ret = -ENOENT; | ||
| 1028 | goto error_brelse; | ||
| 1029 | } | ||
| 1030 | devid = le64_to_cpu(disk_super->dev_item.devid); | 1015 | devid = le64_to_cpu(disk_super->dev_item.devid); |
| 1031 | dev_uuid = disk_super->dev_item.uuid; | 1016 | dev_uuid = disk_super->dev_item.uuid; |
| 1032 | device = btrfs_find_device(root, devid, dev_uuid, | 1017 | device = btrfs_find_device(root, devid, dev_uuid, |
| @@ -2563,6 +2548,88 @@ int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, | |||
| 2563 | mirror_num, NULL); | 2548 | mirror_num, NULL); |
| 2564 | } | 2549 | } |
| 2565 | 2550 | ||
| 2551 | int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, | ||
| 2552 | u64 chunk_start, u64 physical, u64 devid, | ||
| 2553 | u64 **logical, int *naddrs, int *stripe_len) | ||
| 2554 | { | ||
| 2555 | struct extent_map_tree *em_tree = &map_tree->map_tree; | ||
| 2556 | struct extent_map *em; | ||
| 2557 | struct map_lookup *map; | ||
| 2558 | u64 *buf; | ||
| 2559 | u64 bytenr; | ||
| 2560 | u64 length; | ||
| 2561 | u64 stripe_nr; | ||
| 2562 | int i, j, nr = 0; | ||
| 2563 | |||
| 2564 | spin_lock(&em_tree->lock); | ||
| 2565 | em = lookup_extent_mapping(em_tree, chunk_start, 1); | ||
| 2566 | spin_unlock(&em_tree->lock); | ||
| 2567 | |||
| 2568 | BUG_ON(!em || em->start != chunk_start); | ||
| 2569 | map = (struct map_lookup *)em->bdev; | ||
| 2570 | |||
| 2571 | length = em->len; | ||
| 2572 | if (map->type & BTRFS_BLOCK_GROUP_RAID10) | ||
| 2573 | do_div(length, map->num_stripes / map->sub_stripes); | ||
| 2574 | else if (map->type & BTRFS_BLOCK_GROUP_RAID0) | ||
| 2575 | do_div(length, map->num_stripes); | ||
| 2576 | |||
| 2577 | buf = kzalloc(sizeof(u64) * map->num_stripes, GFP_NOFS); | ||
| 2578 | BUG_ON(!buf); | ||
| 2579 | |||
| 2580 | for (i = 0; i < map->num_stripes; i++) { | ||
| 2581 | if (devid && map->stripes[i].dev->devid != devid) | ||
| 2582 | continue; | ||
| 2583 | if (map->stripes[i].physical > physical || | ||
| 2584 | map->stripes[i].physical + length <= physical) | ||
| 2585 | continue; | ||
| 2586 | |||
| 2587 | stripe_nr = physical - map->stripes[i].physical; | ||
| 2588 | do_div(stripe_nr, map->stripe_len); | ||
| 2589 | |||
| 2590 | if (map->type & BTRFS_BLOCK_GROUP_RAID10) { | ||
| 2591 | stripe_nr = stripe_nr * map->num_stripes + i; | ||
| 2592 | do_div(stripe_nr, map->sub_stripes); | ||
| 2593 | } else if (map->type & BTRFS_BLOCK_GROUP_RAID0) { | ||
| 2594 | stripe_nr = stripe_nr * map->num_stripes + i; | ||
| 2595 | } | ||
| 2596 | bytenr = chunk_start + stripe_nr * map->stripe_len; | ||
| 2597 | for (j = 0; j < nr; j++) { | ||
| 2598 | if (buf[j] == bytenr) | ||
| 2599 | break; | ||
| 2600 | } | ||
| 2601 | if (j == nr) | ||
| 2602 | buf[nr++] = bytenr; | ||
| 2603 | } | ||
| 2604 | |||
| 2605 | for (i = 0; i > nr; i++) { | ||
| 2606 | struct btrfs_multi_bio *multi; | ||
| 2607 | struct btrfs_bio_stripe *stripe; | ||
| 2608 | int ret; | ||
| 2609 | |||
| 2610 | length = 1; | ||
| 2611 | ret = btrfs_map_block(map_tree, WRITE, buf[i], | ||
| 2612 | &length, &multi, 0); | ||
| 2613 | BUG_ON(ret); | ||
| 2614 | |||
| 2615 | stripe = multi->stripes; | ||
| 2616 | for (j = 0; j < multi->num_stripes; j++) { | ||
| 2617 | if (stripe->physical >= physical && | ||
| 2618 | physical < stripe->physical + length) | ||
| 2619 | break; | ||
| 2620 | } | ||
| 2621 | BUG_ON(j >= multi->num_stripes); | ||
| 2622 | kfree(multi); | ||
| 2623 | } | ||
| 2624 | |||
| 2625 | *logical = buf; | ||
| 2626 | *naddrs = nr; | ||
| 2627 | *stripe_len = map->stripe_len; | ||
| 2628 | |||
| 2629 | free_extent_map(em); | ||
| 2630 | return 0; | ||
| 2631 | } | ||
| 2632 | |||
| 2566 | int btrfs_unplug_page(struct btrfs_mapping_tree *map_tree, | 2633 | int btrfs_unplug_page(struct btrfs_mapping_tree *map_tree, |
| 2567 | u64 logical, struct page *page) | 2634 | u64 logical, struct page *page) |
| 2568 | { | 2635 | { |
| @@ -3003,7 +3070,7 @@ int btrfs_read_super_device(struct btrfs_root *root, struct extent_buffer *buf) | |||
| 3003 | return read_one_dev(root, buf, dev_item); | 3070 | return read_one_dev(root, buf, dev_item); |
| 3004 | } | 3071 | } |
| 3005 | 3072 | ||
| 3006 | int btrfs_read_sys_array(struct btrfs_root *root) | 3073 | int btrfs_read_sys_array(struct btrfs_root *root, u64 sb_bytenr) |
| 3007 | { | 3074 | { |
| 3008 | struct btrfs_super_block *super_copy = &root->fs_info->super_copy; | 3075 | struct btrfs_super_block *super_copy = &root->fs_info->super_copy; |
| 3009 | struct extent_buffer *sb; | 3076 | struct extent_buffer *sb; |
| @@ -3018,7 +3085,7 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
| 3018 | u32 cur; | 3085 | u32 cur; |
| 3019 | struct btrfs_key key; | 3086 | struct btrfs_key key; |
| 3020 | 3087 | ||
| 3021 | sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET, | 3088 | sb = btrfs_find_create_tree_block(root, sb_bytenr, |
| 3022 | BTRFS_SUPER_INFO_SIZE); | 3089 | BTRFS_SUPER_INFO_SIZE); |
| 3023 | if (!sb) | 3090 | if (!sb) |
| 3024 | return -ENOMEM; | 3091 | return -ENOMEM; |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index fcbdcb3ae13..bdebe83c319 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
| @@ -28,7 +28,6 @@ struct btrfs_device { | |||
| 28 | struct list_head dev_alloc_list; | 28 | struct list_head dev_alloc_list; |
| 29 | struct btrfs_fs_devices *fs_devices; | 29 | struct btrfs_fs_devices *fs_devices; |
| 30 | struct btrfs_root *dev_root; | 30 | struct btrfs_root *dev_root; |
| 31 | struct buffer_head *pending_io; | ||
| 32 | struct bio *pending_bios; | 31 | struct bio *pending_bios; |
| 33 | struct bio *pending_bio_tail; | 32 | struct bio *pending_bio_tail; |
| 34 | int running_pending; | 33 | int running_pending; |
| @@ -125,7 +124,10 @@ int btrfs_alloc_dev_extent(struct btrfs_trans_handle *trans, | |||
| 125 | int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, | 124 | int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, |
| 126 | u64 logical, u64 *length, | 125 | u64 logical, u64 *length, |
| 127 | struct btrfs_multi_bio **multi_ret, int mirror_num); | 126 | struct btrfs_multi_bio **multi_ret, int mirror_num); |
| 128 | int btrfs_read_sys_array(struct btrfs_root *root); | 127 | int btrfs_rmap_block(struct btrfs_mapping_tree *map_tree, |
| 128 | u64 chunk_start, u64 physical, u64 devid, | ||
| 129 | u64 **logical, int *naddrs, int *stripe_len); | ||
| 130 | int btrfs_read_sys_array(struct btrfs_root *root, u64 sb_bytenr); | ||
| 129 | int btrfs_read_chunk_tree(struct btrfs_root *root); | 131 | int btrfs_read_chunk_tree(struct btrfs_root *root); |
| 130 | int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | 132 | int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, |
| 131 | struct btrfs_root *extent_root, u64 type); | 133 | struct btrfs_root *extent_root, u64 type); |
