diff options
Diffstat (limited to 'fs/btrfs/volumes.c')
-rw-r--r-- | fs/btrfs/volumes.c | 36 |
1 files changed, 25 insertions, 11 deletions
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index e53835b88594..a6d35b0054ca 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1440,6 +1440,7 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1440 | device->io_align = root->sectorsize; | 1440 | device->io_align = root->sectorsize; |
1441 | device->sector_size = root->sectorsize; | 1441 | device->sector_size = root->sectorsize; |
1442 | device->total_bytes = i_size_read(bdev->bd_inode); | 1442 | device->total_bytes = i_size_read(bdev->bd_inode); |
1443 | device->disk_total_bytes = device->total_bytes; | ||
1443 | device->dev_root = root->fs_info->dev_root; | 1444 | device->dev_root = root->fs_info->dev_root; |
1444 | device->bdev = bdev; | 1445 | device->bdev = bdev; |
1445 | device->in_fs_metadata = 1; | 1446 | device->in_fs_metadata = 1; |
@@ -1543,7 +1544,7 @@ static noinline int btrfs_update_device(struct btrfs_trans_handle *trans, | |||
1543 | btrfs_set_device_io_align(leaf, dev_item, device->io_align); | 1544 | btrfs_set_device_io_align(leaf, dev_item, device->io_align); |
1544 | btrfs_set_device_io_width(leaf, dev_item, device->io_width); | 1545 | btrfs_set_device_io_width(leaf, dev_item, device->io_width); |
1545 | btrfs_set_device_sector_size(leaf, dev_item, device->sector_size); | 1546 | btrfs_set_device_sector_size(leaf, dev_item, device->sector_size); |
1546 | btrfs_set_device_total_bytes(leaf, dev_item, device->total_bytes); | 1547 | btrfs_set_device_total_bytes(leaf, dev_item, device->disk_total_bytes); |
1547 | btrfs_set_device_bytes_used(leaf, dev_item, device->bytes_used); | 1548 | btrfs_set_device_bytes_used(leaf, dev_item, device->bytes_used); |
1548 | btrfs_mark_buffer_dirty(leaf); | 1549 | btrfs_mark_buffer_dirty(leaf); |
1549 | 1550 | ||
@@ -1940,14 +1941,6 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) | |||
1940 | device->total_bytes = new_size; | 1941 | device->total_bytes = new_size; |
1941 | if (device->writeable) | 1942 | if (device->writeable) |
1942 | device->fs_devices->total_rw_bytes -= diff; | 1943 | device->fs_devices->total_rw_bytes -= diff; |
1943 | ret = btrfs_update_device(trans, device); | ||
1944 | if (ret) { | ||
1945 | unlock_chunks(root); | ||
1946 | btrfs_end_transaction(trans, root); | ||
1947 | goto done; | ||
1948 | } | ||
1949 | WARN_ON(diff > old_total); | ||
1950 | btrfs_set_super_total_bytes(super_copy, old_total - diff); | ||
1951 | unlock_chunks(root); | 1944 | unlock_chunks(root); |
1952 | btrfs_end_transaction(trans, root); | 1945 | btrfs_end_transaction(trans, root); |
1953 | 1946 | ||
@@ -1979,7 +1972,7 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) | |||
1979 | length = btrfs_dev_extent_length(l, dev_extent); | 1972 | length = btrfs_dev_extent_length(l, dev_extent); |
1980 | 1973 | ||
1981 | if (key.offset + length <= new_size) | 1974 | if (key.offset + length <= new_size) |
1982 | goto done; | 1975 | break; |
1983 | 1976 | ||
1984 | chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent); | 1977 | chunk_tree = btrfs_dev_extent_chunk_tree(l, dev_extent); |
1985 | chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent); | 1978 | chunk_objectid = btrfs_dev_extent_chunk_objectid(l, dev_extent); |
@@ -1992,6 +1985,26 @@ int btrfs_shrink_device(struct btrfs_device *device, u64 new_size) | |||
1992 | goto done; | 1985 | goto done; |
1993 | } | 1986 | } |
1994 | 1987 | ||
1988 | /* Shrinking succeeded, else we would be at "done". */ | ||
1989 | trans = btrfs_start_transaction(root, 1); | ||
1990 | if (!trans) { | ||
1991 | ret = -ENOMEM; | ||
1992 | goto done; | ||
1993 | } | ||
1994 | lock_chunks(root); | ||
1995 | |||
1996 | device->disk_total_bytes = new_size; | ||
1997 | /* Now btrfs_update_device() will change the on-disk size. */ | ||
1998 | ret = btrfs_update_device(trans, device); | ||
1999 | if (ret) { | ||
2000 | unlock_chunks(root); | ||
2001 | btrfs_end_transaction(trans, root); | ||
2002 | goto done; | ||
2003 | } | ||
2004 | WARN_ON(diff > old_total); | ||
2005 | btrfs_set_super_total_bytes(super_copy, old_total - diff); | ||
2006 | unlock_chunks(root); | ||
2007 | btrfs_end_transaction(trans, root); | ||
1995 | done: | 2008 | done: |
1996 | btrfs_free_path(path); | 2009 | btrfs_free_path(path); |
1997 | return ret; | 2010 | return ret; |
@@ -3076,7 +3089,8 @@ static int fill_device_from_item(struct extent_buffer *leaf, | |||
3076 | unsigned long ptr; | 3089 | unsigned long ptr; |
3077 | 3090 | ||
3078 | device->devid = btrfs_device_id(leaf, dev_item); | 3091 | device->devid = btrfs_device_id(leaf, dev_item); |
3079 | device->total_bytes = btrfs_device_total_bytes(leaf, dev_item); | 3092 | device->disk_total_bytes = btrfs_device_total_bytes(leaf, dev_item); |
3093 | device->total_bytes = device->disk_total_bytes; | ||
3080 | device->bytes_used = btrfs_device_bytes_used(leaf, dev_item); | 3094 | device->bytes_used = btrfs_device_bytes_used(leaf, dev_item); |
3081 | device->type = btrfs_device_type(leaf, dev_item); | 3095 | device->type = btrfs_device_type(leaf, dev_item); |
3082 | device->io_align = btrfs_device_io_align(leaf, dev_item); | 3096 | device->io_align = btrfs_device_io_align(leaf, dev_item); |