aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/disk-io.c208
-rw-r--r--fs/btrfs/disk-io.h17
-rw-r--r--fs/btrfs/extent-tree.c54
-rw-r--r--fs/btrfs/free-space-cache.c1
-rw-r--r--fs/btrfs/transaction.c2
-rw-r--r--fs/btrfs/tree-log.c3
-rw-r--r--fs/btrfs/volumes.c107
-rw-r--r--fs/btrfs/volumes.h6
8 files changed, 279 insertions, 119 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 61dc3b2c834b..c72f4f3b912c 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
1908static int write_all_supers(struct btrfs_root *root) 1907struct 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
1948static 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
2037int 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
2028int write_ctree_super(struct btrfs_trans_handle *trans, struct btrfs_root 2106int 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 717e94811e4e..c0ff404c31b7 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
28static 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
24struct btrfs_device; 36struct btrfs_device;
25struct btrfs_fs_devices; 37struct btrfs_fs_devices;
26 38
@@ -37,7 +49,8 @@ struct btrfs_root *open_ctree(struct super_block *sb,
37 char *options); 49 char *options);
38int close_ctree(struct btrfs_root *root); 50int close_ctree(struct btrfs_root *root);
39int write_ctree_super(struct btrfs_trans_handle *trans, 51int write_ctree_super(struct btrfs_trans_handle *trans,
40 struct btrfs_root *root); 52 struct btrfs_root *root, int max_mirrors);
53struct buffer_head *btrfs_read_dev_super(struct block_device *bdev);
41int btrfs_commit_super(struct btrfs_root *root); 54int btrfs_commit_super(struct btrfs_root *root);
42struct extent_buffer *btrfs_find_tree_block(struct btrfs_root *root, 55struct 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 d15638529389..803647bc8400 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
192static 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
192static int cache_block_group(struct btrfs_root *root, 215static 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;
284err: 288err:
@@ -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 09462adfbe33..2e69b9c30437 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 c38f6a0e30b1..47cd5fcad2c8 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 08469ec05850..d3f9c2c663c4 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,
2006out: 2006out:
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 2049d179ccd5..a79b3cc09e94 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
556error_brelse:
557 brelse(bh); 547 brelse(bh);
558error_close: 548error_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
2551int 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
2566int btrfs_unplug_page(struct btrfs_mapping_tree *map_tree, 2633int 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
3006int btrfs_read_sys_array(struct btrfs_root *root) 3073int 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 fcbdcb3ae13e..bdebe83c3195 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,
125int btrfs_map_block(struct btrfs_mapping_tree *map_tree, int rw, 124int 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);
128int btrfs_read_sys_array(struct btrfs_root *root); 127int 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);
130int btrfs_read_sys_array(struct btrfs_root *root, u64 sb_bytenr);
129int btrfs_read_chunk_tree(struct btrfs_root *root); 131int btrfs_read_chunk_tree(struct btrfs_root *root);
130int btrfs_alloc_chunk(struct btrfs_trans_handle *trans, 132int btrfs_alloc_chunk(struct btrfs_trans_handle *trans,
131 struct btrfs_root *extent_root, u64 type); 133 struct btrfs_root *extent_root, u64 type);