diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-18 17:20:00 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-18 17:20:00 -0400 |
commit | 5c80c71b9a0ec518b4b58d2a61de01a04f4a4453 (patch) | |
tree | 57e575e546dfa3d17ddc0532715feedb87c82487 /fs | |
parent | 01fa4ba52c36224783107a40126f1c6354d4e965 (diff) | |
parent | 81d86e1b70961f4816f961875e0c706b0954acad (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
Btrfs: set i_size properly when fallocating and we already
btrfs: unlock on error in btrfs_file_llseek()
btrfs: btrfs_permission's RO check shouldn't apply to device nodes
Btrfs: truncate pages from clone ioctl target range
Btrfs: fix uninitialized sync_pending
Btrfs: fix wrong free space information
btrfs: memory leak in btrfs_add_inode_defrag()
Btrfs: use plain page_address() in header fields setget functions
Btrfs: forced readonly when btrfs_drop_snapshot() fails
Btrfs: check if there is enough space for balancing smarter
Btrfs: fix a bug of balance on full multi-disk partitions
Btrfs: fix an oops of log replay
Btrfs: detect wether a device supports discard
Btrfs: force unplugs when switching from high to regular priority bios
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/ctree.h | 10 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 75 | ||||
-rw-r--r-- | fs/btrfs/file.c | 28 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 16 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 12 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 4 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 28 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 51 | ||||
-rw-r--r-- | fs/btrfs/volumes.h | 2 |
9 files changed, 183 insertions, 43 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 0469263e327e..03912c5c6f49 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -1415,17 +1415,15 @@ void btrfs_set_##name(struct extent_buffer *eb, type *s, u##bits val); | |||
1415 | #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ | 1415 | #define BTRFS_SETGET_HEADER_FUNCS(name, type, member, bits) \ |
1416 | static inline u##bits btrfs_##name(struct extent_buffer *eb) \ | 1416 | static inline u##bits btrfs_##name(struct extent_buffer *eb) \ |
1417 | { \ | 1417 | { \ |
1418 | type *p = kmap_atomic(eb->first_page, KM_USER0); \ | 1418 | type *p = page_address(eb->first_page); \ |
1419 | u##bits res = le##bits##_to_cpu(p->member); \ | 1419 | u##bits res = le##bits##_to_cpu(p->member); \ |
1420 | kunmap_atomic(p, KM_USER0); \ | ||
1421 | return res; \ | 1420 | return res; \ |
1422 | } \ | 1421 | } \ |
1423 | static inline void btrfs_set_##name(struct extent_buffer *eb, \ | 1422 | static inline void btrfs_set_##name(struct extent_buffer *eb, \ |
1424 | u##bits val) \ | 1423 | u##bits val) \ |
1425 | { \ | 1424 | { \ |
1426 | type *p = kmap_atomic(eb->first_page, KM_USER0); \ | 1425 | type *p = page_address(eb->first_page); \ |
1427 | p->member = cpu_to_le##bits(val); \ | 1426 | p->member = cpu_to_le##bits(val); \ |
1428 | kunmap_atomic(p, KM_USER0); \ | ||
1429 | } | 1427 | } |
1430 | 1428 | ||
1431 | #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ | 1429 | #define BTRFS_SETGET_STACK_FUNCS(name, type, member, bits) \ |
@@ -2367,8 +2365,8 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, | |||
2367 | int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); | 2365 | int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); |
2368 | int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); | 2366 | int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); |
2369 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); | 2367 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); |
2370 | int btrfs_drop_snapshot(struct btrfs_root *root, | 2368 | void btrfs_drop_snapshot(struct btrfs_root *root, |
2371 | struct btrfs_block_rsv *block_rsv, int update_ref); | 2369 | struct btrfs_block_rsv *block_rsv, int update_ref); |
2372 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | 2370 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, |
2373 | struct btrfs_root *root, | 2371 | struct btrfs_root *root, |
2374 | struct extent_buffer *node, | 2372 | struct extent_buffer *node, |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 66bac226944e..80d6148f60ac 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1782,6 +1782,9 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1782 | 1782 | ||
1783 | 1783 | ||
1784 | for (i = 0; i < multi->num_stripes; i++, stripe++) { | 1784 | for (i = 0; i < multi->num_stripes; i++, stripe++) { |
1785 | if (!stripe->dev->can_discard) | ||
1786 | continue; | ||
1787 | |||
1785 | ret = btrfs_issue_discard(stripe->dev->bdev, | 1788 | ret = btrfs_issue_discard(stripe->dev->bdev, |
1786 | stripe->physical, | 1789 | stripe->physical, |
1787 | stripe->length); | 1790 | stripe->length); |
@@ -1789,11 +1792,16 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1789 | discarded_bytes += stripe->length; | 1792 | discarded_bytes += stripe->length; |
1790 | else if (ret != -EOPNOTSUPP) | 1793 | else if (ret != -EOPNOTSUPP) |
1791 | break; | 1794 | break; |
1795 | |||
1796 | /* | ||
1797 | * Just in case we get back EOPNOTSUPP for some reason, | ||
1798 | * just ignore the return value so we don't screw up | ||
1799 | * people calling discard_extent. | ||
1800 | */ | ||
1801 | ret = 0; | ||
1792 | } | 1802 | } |
1793 | kfree(multi); | 1803 | kfree(multi); |
1794 | } | 1804 | } |
1795 | if (discarded_bytes && ret == -EOPNOTSUPP) | ||
1796 | ret = 0; | ||
1797 | 1805 | ||
1798 | if (actual_bytes) | 1806 | if (actual_bytes) |
1799 | *actual_bytes = discarded_bytes; | 1807 | *actual_bytes = discarded_bytes; |
@@ -6269,8 +6277,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, | |||
6269 | * also make sure backrefs for the shared block and all lower level | 6277 | * also make sure backrefs for the shared block and all lower level |
6270 | * blocks are properly updated. | 6278 | * blocks are properly updated. |
6271 | */ | 6279 | */ |
6272 | int btrfs_drop_snapshot(struct btrfs_root *root, | 6280 | void btrfs_drop_snapshot(struct btrfs_root *root, |
6273 | struct btrfs_block_rsv *block_rsv, int update_ref) | 6281 | struct btrfs_block_rsv *block_rsv, int update_ref) |
6274 | { | 6282 | { |
6275 | struct btrfs_path *path; | 6283 | struct btrfs_path *path; |
6276 | struct btrfs_trans_handle *trans; | 6284 | struct btrfs_trans_handle *trans; |
@@ -6283,13 +6291,16 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
6283 | int level; | 6291 | int level; |
6284 | 6292 | ||
6285 | path = btrfs_alloc_path(); | 6293 | path = btrfs_alloc_path(); |
6286 | if (!path) | 6294 | if (!path) { |
6287 | return -ENOMEM; | 6295 | err = -ENOMEM; |
6296 | goto out; | ||
6297 | } | ||
6288 | 6298 | ||
6289 | wc = kzalloc(sizeof(*wc), GFP_NOFS); | 6299 | wc = kzalloc(sizeof(*wc), GFP_NOFS); |
6290 | if (!wc) { | 6300 | if (!wc) { |
6291 | btrfs_free_path(path); | 6301 | btrfs_free_path(path); |
6292 | return -ENOMEM; | 6302 | err = -ENOMEM; |
6303 | goto out; | ||
6293 | } | 6304 | } |
6294 | 6305 | ||
6295 | trans = btrfs_start_transaction(tree_root, 0); | 6306 | trans = btrfs_start_transaction(tree_root, 0); |
@@ -6318,7 +6329,7 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
6318 | path->lowest_level = 0; | 6329 | path->lowest_level = 0; |
6319 | if (ret < 0) { | 6330 | if (ret < 0) { |
6320 | err = ret; | 6331 | err = ret; |
6321 | goto out; | 6332 | goto out_free; |
6322 | } | 6333 | } |
6323 | WARN_ON(ret > 0); | 6334 | WARN_ON(ret > 0); |
6324 | 6335 | ||
@@ -6425,11 +6436,14 @@ int btrfs_drop_snapshot(struct btrfs_root *root, | |||
6425 | free_extent_buffer(root->commit_root); | 6436 | free_extent_buffer(root->commit_root); |
6426 | kfree(root); | 6437 | kfree(root); |
6427 | } | 6438 | } |
6428 | out: | 6439 | out_free: |
6429 | btrfs_end_transaction_throttle(trans, tree_root); | 6440 | btrfs_end_transaction_throttle(trans, tree_root); |
6430 | kfree(wc); | 6441 | kfree(wc); |
6431 | btrfs_free_path(path); | 6442 | btrfs_free_path(path); |
6432 | return err; | 6443 | out: |
6444 | if (err) | ||
6445 | btrfs_std_error(root->fs_info, err); | ||
6446 | return; | ||
6433 | } | 6447 | } |
6434 | 6448 | ||
6435 | /* | 6449 | /* |
@@ -6720,6 +6734,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) | |||
6720 | struct btrfs_space_info *space_info; | 6734 | struct btrfs_space_info *space_info; |
6721 | struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; | 6735 | struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; |
6722 | struct btrfs_device *device; | 6736 | struct btrfs_device *device; |
6737 | u64 min_free; | ||
6738 | int index; | ||
6739 | int dev_nr = 0; | ||
6740 | int dev_min = 1; | ||
6723 | int full = 0; | 6741 | int full = 0; |
6724 | int ret = 0; | 6742 | int ret = 0; |
6725 | 6743 | ||
@@ -6729,8 +6747,10 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) | |||
6729 | if (!block_group) | 6747 | if (!block_group) |
6730 | return -1; | 6748 | return -1; |
6731 | 6749 | ||
6750 | min_free = btrfs_block_group_used(&block_group->item); | ||
6751 | |||
6732 | /* no bytes used, we're good */ | 6752 | /* no bytes used, we're good */ |
6733 | if (!btrfs_block_group_used(&block_group->item)) | 6753 | if (!min_free) |
6734 | goto out; | 6754 | goto out; |
6735 | 6755 | ||
6736 | space_info = block_group->space_info; | 6756 | space_info = block_group->space_info; |
@@ -6746,10 +6766,9 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) | |||
6746 | * all of the extents from this block group. If we can, we're good | 6766 | * all of the extents from this block group. If we can, we're good |
6747 | */ | 6767 | */ |
6748 | if ((space_info->total_bytes != block_group->key.offset) && | 6768 | if ((space_info->total_bytes != block_group->key.offset) && |
6749 | (space_info->bytes_used + space_info->bytes_reserved + | 6769 | (space_info->bytes_used + space_info->bytes_reserved + |
6750 | space_info->bytes_pinned + space_info->bytes_readonly + | 6770 | space_info->bytes_pinned + space_info->bytes_readonly + |
6751 | btrfs_block_group_used(&block_group->item) < | 6771 | min_free < space_info->total_bytes)) { |
6752 | space_info->total_bytes)) { | ||
6753 | spin_unlock(&space_info->lock); | 6772 | spin_unlock(&space_info->lock); |
6754 | goto out; | 6773 | goto out; |
6755 | } | 6774 | } |
@@ -6766,9 +6785,29 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) | |||
6766 | if (full) | 6785 | if (full) |
6767 | goto out; | 6786 | goto out; |
6768 | 6787 | ||
6788 | /* | ||
6789 | * index: | ||
6790 | * 0: raid10 | ||
6791 | * 1: raid1 | ||
6792 | * 2: dup | ||
6793 | * 3: raid0 | ||
6794 | * 4: single | ||
6795 | */ | ||
6796 | index = get_block_group_index(block_group); | ||
6797 | if (index == 0) { | ||
6798 | dev_min = 4; | ||
6799 | min_free /= 2; | ||
6800 | } else if (index == 1) { | ||
6801 | dev_min = 2; | ||
6802 | } else if (index == 2) { | ||
6803 | min_free *= 2; | ||
6804 | } else if (index == 3) { | ||
6805 | dev_min = fs_devices->rw_devices; | ||
6806 | min_free /= dev_min; | ||
6807 | } | ||
6808 | |||
6769 | mutex_lock(&root->fs_info->chunk_mutex); | 6809 | mutex_lock(&root->fs_info->chunk_mutex); |
6770 | list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { | 6810 | list_for_each_entry(device, &fs_devices->alloc_list, dev_alloc_list) { |
6771 | u64 min_free = btrfs_block_group_used(&block_group->item); | ||
6772 | u64 dev_offset; | 6811 | u64 dev_offset; |
6773 | 6812 | ||
6774 | /* | 6813 | /* |
@@ -6779,7 +6818,11 @@ int btrfs_can_relocate(struct btrfs_root *root, u64 bytenr) | |||
6779 | ret = find_free_dev_extent(NULL, device, min_free, | 6818 | ret = find_free_dev_extent(NULL, device, min_free, |
6780 | &dev_offset, NULL); | 6819 | &dev_offset, NULL); |
6781 | if (!ret) | 6820 | if (!ret) |
6821 | dev_nr++; | ||
6822 | |||
6823 | if (dev_nr >= dev_min) | ||
6782 | break; | 6824 | break; |
6825 | |||
6783 | ret = -1; | 6826 | ret = -1; |
6784 | } | 6827 | } |
6785 | } | 6828 | } |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 658d66959abe..e7872e485f13 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -150,6 +150,8 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans, | |||
150 | spin_lock(&root->fs_info->defrag_inodes_lock); | 150 | spin_lock(&root->fs_info->defrag_inodes_lock); |
151 | if (!BTRFS_I(inode)->in_defrag) | 151 | if (!BTRFS_I(inode)->in_defrag) |
152 | __btrfs_add_inode_defrag(inode, defrag); | 152 | __btrfs_add_inode_defrag(inode, defrag); |
153 | else | ||
154 | kfree(defrag); | ||
153 | spin_unlock(&root->fs_info->defrag_inodes_lock); | 155 | spin_unlock(&root->fs_info->defrag_inodes_lock); |
154 | return 0; | 156 | return 0; |
155 | } | 157 | } |
@@ -1638,11 +1640,15 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1638 | 1640 | ||
1639 | cur_offset = alloc_start; | 1641 | cur_offset = alloc_start; |
1640 | while (1) { | 1642 | while (1) { |
1643 | u64 actual_end; | ||
1644 | |||
1641 | em = btrfs_get_extent(inode, NULL, 0, cur_offset, | 1645 | em = btrfs_get_extent(inode, NULL, 0, cur_offset, |
1642 | alloc_end - cur_offset, 0); | 1646 | alloc_end - cur_offset, 0); |
1643 | BUG_ON(IS_ERR_OR_NULL(em)); | 1647 | BUG_ON(IS_ERR_OR_NULL(em)); |
1644 | last_byte = min(extent_map_end(em), alloc_end); | 1648 | last_byte = min(extent_map_end(em), alloc_end); |
1649 | actual_end = min_t(u64, extent_map_end(em), offset + len); | ||
1645 | last_byte = (last_byte + mask) & ~mask; | 1650 | last_byte = (last_byte + mask) & ~mask; |
1651 | |||
1646 | if (em->block_start == EXTENT_MAP_HOLE || | 1652 | if (em->block_start == EXTENT_MAP_HOLE || |
1647 | (cur_offset >= inode->i_size && | 1653 | (cur_offset >= inode->i_size && |
1648 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { | 1654 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { |
@@ -1655,6 +1661,16 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1655 | free_extent_map(em); | 1661 | free_extent_map(em); |
1656 | break; | 1662 | break; |
1657 | } | 1663 | } |
1664 | } else if (actual_end > inode->i_size && | ||
1665 | !(mode & FALLOC_FL_KEEP_SIZE)) { | ||
1666 | /* | ||
1667 | * We didn't need to allocate any more space, but we | ||
1668 | * still extended the size of the file so we need to | ||
1669 | * update i_size. | ||
1670 | */ | ||
1671 | inode->i_ctime = CURRENT_TIME; | ||
1672 | i_size_write(inode, actual_end); | ||
1673 | btrfs_ordered_update_i_size(inode, actual_end, NULL); | ||
1658 | } | 1674 | } |
1659 | free_extent_map(em); | 1675 | free_extent_map(em); |
1660 | 1676 | ||
@@ -1804,10 +1820,14 @@ static loff_t btrfs_file_llseek(struct file *file, loff_t offset, int origin) | |||
1804 | } | 1820 | } |
1805 | } | 1821 | } |
1806 | 1822 | ||
1807 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) | 1823 | if (offset < 0 && !(file->f_mode & FMODE_UNSIGNED_OFFSET)) { |
1808 | return -EINVAL; | 1824 | ret = -EINVAL; |
1809 | if (offset > inode->i_sb->s_maxbytes) | 1825 | goto out; |
1810 | return -EINVAL; | 1826 | } |
1827 | if (offset > inode->i_sb->s_maxbytes) { | ||
1828 | ret = -EINVAL; | ||
1829 | goto out; | ||
1830 | } | ||
1811 | 1831 | ||
1812 | /* Special lock needed here? */ | 1832 | /* Special lock needed here? */ |
1813 | if (offset != file->f_pos) { | 1833 | if (offset != file->f_pos) { |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 6377713f639c..6a265b9f85f2 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -1168,9 +1168,9 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl) | |||
1168 | div64_u64(extent_bytes, (sizeof(struct btrfs_free_space))); | 1168 | div64_u64(extent_bytes, (sizeof(struct btrfs_free_space))); |
1169 | } | 1169 | } |
1170 | 1170 | ||
1171 | static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, | 1171 | static inline void __bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, |
1172 | struct btrfs_free_space *info, u64 offset, | 1172 | struct btrfs_free_space *info, |
1173 | u64 bytes) | 1173 | u64 offset, u64 bytes) |
1174 | { | 1174 | { |
1175 | unsigned long start, count; | 1175 | unsigned long start, count; |
1176 | 1176 | ||
@@ -1181,6 +1181,13 @@ static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, | |||
1181 | bitmap_clear(info->bitmap, start, count); | 1181 | bitmap_clear(info->bitmap, start, count); |
1182 | 1182 | ||
1183 | info->bytes -= bytes; | 1183 | info->bytes -= bytes; |
1184 | } | ||
1185 | |||
1186 | static void bitmap_clear_bits(struct btrfs_free_space_ctl *ctl, | ||
1187 | struct btrfs_free_space *info, u64 offset, | ||
1188 | u64 bytes) | ||
1189 | { | ||
1190 | __bitmap_clear_bits(ctl, info, offset, bytes); | ||
1184 | ctl->free_space -= bytes; | 1191 | ctl->free_space -= bytes; |
1185 | } | 1192 | } |
1186 | 1193 | ||
@@ -1984,7 +1991,7 @@ static u64 btrfs_alloc_from_bitmap(struct btrfs_block_group_cache *block_group, | |||
1984 | return 0; | 1991 | return 0; |
1985 | 1992 | ||
1986 | ret = search_start; | 1993 | ret = search_start; |
1987 | bitmap_clear_bits(ctl, entry, ret, bytes); | 1994 | __bitmap_clear_bits(ctl, entry, ret, bytes); |
1988 | 1995 | ||
1989 | return ret; | 1996 | return ret; |
1990 | } | 1997 | } |
@@ -2039,7 +2046,6 @@ u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group, | |||
2039 | continue; | 2046 | continue; |
2040 | } | 2047 | } |
2041 | } else { | 2048 | } else { |
2042 | |||
2043 | ret = entry->offset; | 2049 | ret = entry->offset; |
2044 | 2050 | ||
2045 | entry->offset += bytes; | 2051 | entry->offset += bytes; |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 15fceefbca0a..0ccc7438ad34 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -7354,11 +7354,15 @@ static int btrfs_set_page_dirty(struct page *page) | |||
7354 | static int btrfs_permission(struct inode *inode, int mask) | 7354 | static int btrfs_permission(struct inode *inode, int mask) |
7355 | { | 7355 | { |
7356 | struct btrfs_root *root = BTRFS_I(inode)->root; | 7356 | struct btrfs_root *root = BTRFS_I(inode)->root; |
7357 | umode_t mode = inode->i_mode; | ||
7357 | 7358 | ||
7358 | if (btrfs_root_readonly(root) && (mask & MAY_WRITE)) | 7359 | if (mask & MAY_WRITE && |
7359 | return -EROFS; | 7360 | (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) { |
7360 | if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE)) | 7361 | if (btrfs_root_readonly(root)) |
7361 | return -EACCES; | 7362 | return -EROFS; |
7363 | if (BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) | ||
7364 | return -EACCES; | ||
7365 | } | ||
7362 | return generic_permission(inode, mask); | 7366 | return generic_permission(inode, mask); |
7363 | } | 7367 | } |
7364 | 7368 | ||
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7cf013349941..970977aab224 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -2236,6 +2236,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2236 | btrfs_wait_ordered_range(src, off, len); | 2236 | btrfs_wait_ordered_range(src, off, len); |
2237 | } | 2237 | } |
2238 | 2238 | ||
2239 | /* truncate page cache pages from target inode range */ | ||
2240 | truncate_inode_pages_range(&inode->i_data, off, | ||
2241 | ALIGN(off + len, PAGE_CACHE_SIZE) - 1); | ||
2242 | |||
2239 | /* clone data */ | 2243 | /* clone data */ |
2240 | key.objectid = btrfs_ino(src); | 2244 | key.objectid = btrfs_ino(src); |
2241 | key.type = BTRFS_EXTENT_DATA_KEY; | 2245 | key.type = BTRFS_EXTENT_DATA_KEY; |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index babee65f8eda..786639fca067 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -799,14 +799,15 @@ static noinline int add_inode_ref(struct btrfs_trans_handle *trans, | |||
799 | struct extent_buffer *eb, int slot, | 799 | struct extent_buffer *eb, int slot, |
800 | struct btrfs_key *key) | 800 | struct btrfs_key *key) |
801 | { | 801 | { |
802 | struct inode *dir; | ||
803 | int ret; | ||
804 | struct btrfs_inode_ref *ref; | 802 | struct btrfs_inode_ref *ref; |
803 | struct btrfs_dir_item *di; | ||
804 | struct inode *dir; | ||
805 | struct inode *inode; | 805 | struct inode *inode; |
806 | char *name; | ||
807 | int namelen; | ||
808 | unsigned long ref_ptr; | 806 | unsigned long ref_ptr; |
809 | unsigned long ref_end; | 807 | unsigned long ref_end; |
808 | char *name; | ||
809 | int namelen; | ||
810 | int ret; | ||
810 | int search_done = 0; | 811 | int search_done = 0; |
811 | 812 | ||
812 | /* | 813 | /* |
@@ -909,6 +910,25 @@ again: | |||
909 | } | 910 | } |
910 | btrfs_release_path(path); | 911 | btrfs_release_path(path); |
911 | 912 | ||
913 | /* look for a conflicting sequence number */ | ||
914 | di = btrfs_lookup_dir_index_item(trans, root, path, btrfs_ino(dir), | ||
915 | btrfs_inode_ref_index(eb, ref), | ||
916 | name, namelen, 0); | ||
917 | if (di && !IS_ERR(di)) { | ||
918 | ret = drop_one_dir_item(trans, root, path, dir, di); | ||
919 | BUG_ON(ret); | ||
920 | } | ||
921 | btrfs_release_path(path); | ||
922 | |||
923 | /* look for a conflicing name */ | ||
924 | di = btrfs_lookup_dir_item(trans, root, path, btrfs_ino(dir), | ||
925 | name, namelen, 0); | ||
926 | if (di && !IS_ERR(di)) { | ||
927 | ret = drop_one_dir_item(trans, root, path, dir, di); | ||
928 | BUG_ON(ret); | ||
929 | } | ||
930 | btrfs_release_path(path); | ||
931 | |||
912 | insert: | 932 | insert: |
913 | /* insert our name */ | 933 | /* insert our name */ |
914 | ret = btrfs_add_link(trans, dir, inode, name, namelen, 0, | 934 | ret = btrfs_add_link(trans, dir, inode, name, namelen, 0, |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 53875ae73ad4..f2a4cc79da61 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -142,6 +142,7 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) | |||
142 | unsigned long limit; | 142 | unsigned long limit; |
143 | unsigned long last_waited = 0; | 143 | unsigned long last_waited = 0; |
144 | int force_reg = 0; | 144 | int force_reg = 0; |
145 | int sync_pending = 0; | ||
145 | struct blk_plug plug; | 146 | struct blk_plug plug; |
146 | 147 | ||
147 | /* | 148 | /* |
@@ -229,6 +230,22 @@ loop_lock: | |||
229 | 230 | ||
230 | BUG_ON(atomic_read(&cur->bi_cnt) == 0); | 231 | BUG_ON(atomic_read(&cur->bi_cnt) == 0); |
231 | 232 | ||
233 | /* | ||
234 | * if we're doing the sync list, record that our | ||
235 | * plug has some sync requests on it | ||
236 | * | ||
237 | * If we're doing the regular list and there are | ||
238 | * sync requests sitting around, unplug before | ||
239 | * we add more | ||
240 | */ | ||
241 | if (pending_bios == &device->pending_sync_bios) { | ||
242 | sync_pending = 1; | ||
243 | } else if (sync_pending) { | ||
244 | blk_finish_plug(&plug); | ||
245 | blk_start_plug(&plug); | ||
246 | sync_pending = 0; | ||
247 | } | ||
248 | |||
232 | submit_bio(cur->bi_rw, cur); | 249 | submit_bio(cur->bi_rw, cur); |
233 | num_run++; | 250 | num_run++; |
234 | batch_run++; | 251 | batch_run++; |
@@ -500,6 +517,9 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
500 | fs_devices->rw_devices--; | 517 | fs_devices->rw_devices--; |
501 | } | 518 | } |
502 | 519 | ||
520 | if (device->can_discard) | ||
521 | fs_devices->num_can_discard--; | ||
522 | |||
503 | new_device = kmalloc(sizeof(*new_device), GFP_NOFS); | 523 | new_device = kmalloc(sizeof(*new_device), GFP_NOFS); |
504 | BUG_ON(!new_device); | 524 | BUG_ON(!new_device); |
505 | memcpy(new_device, device, sizeof(*new_device)); | 525 | memcpy(new_device, device, sizeof(*new_device)); |
@@ -508,6 +528,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
508 | new_device->bdev = NULL; | 528 | new_device->bdev = NULL; |
509 | new_device->writeable = 0; | 529 | new_device->writeable = 0; |
510 | new_device->in_fs_metadata = 0; | 530 | new_device->in_fs_metadata = 0; |
531 | new_device->can_discard = 0; | ||
511 | list_replace_rcu(&device->dev_list, &new_device->dev_list); | 532 | list_replace_rcu(&device->dev_list, &new_device->dev_list); |
512 | 533 | ||
513 | call_rcu(&device->rcu, free_device); | 534 | call_rcu(&device->rcu, free_device); |
@@ -547,6 +568,7 @@ int btrfs_close_devices(struct btrfs_fs_devices *fs_devices) | |||
547 | static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | 568 | static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, |
548 | fmode_t flags, void *holder) | 569 | fmode_t flags, void *holder) |
549 | { | 570 | { |
571 | struct request_queue *q; | ||
550 | struct block_device *bdev; | 572 | struct block_device *bdev; |
551 | struct list_head *head = &fs_devices->devices; | 573 | struct list_head *head = &fs_devices->devices; |
552 | struct btrfs_device *device; | 574 | struct btrfs_device *device; |
@@ -603,6 +625,12 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, | |||
603 | seeding = 0; | 625 | seeding = 0; |
604 | } | 626 | } |
605 | 627 | ||
628 | q = bdev_get_queue(bdev); | ||
629 | if (blk_queue_discard(q)) { | ||
630 | device->can_discard = 1; | ||
631 | fs_devices->num_can_discard++; | ||
632 | } | ||
633 | |||
606 | device->bdev = bdev; | 634 | device->bdev = bdev; |
607 | device->in_fs_metadata = 0; | 635 | device->in_fs_metadata = 0; |
608 | device->mode = flags; | 636 | device->mode = flags; |
@@ -835,6 +863,7 @@ int find_free_dev_extent(struct btrfs_trans_handle *trans, | |||
835 | 863 | ||
836 | max_hole_start = search_start; | 864 | max_hole_start = search_start; |
837 | max_hole_size = 0; | 865 | max_hole_size = 0; |
866 | hole_size = 0; | ||
838 | 867 | ||
839 | if (search_start >= search_end) { | 868 | if (search_start >= search_end) { |
840 | ret = -ENOSPC; | 869 | ret = -ENOSPC; |
@@ -917,7 +946,14 @@ next: | |||
917 | cond_resched(); | 946 | cond_resched(); |
918 | } | 947 | } |
919 | 948 | ||
920 | hole_size = search_end- search_start; | 949 | /* |
950 | * At this point, search_start should be the end of | ||
951 | * allocated dev extents, and when shrinking the device, | ||
952 | * search_end may be smaller than search_start. | ||
953 | */ | ||
954 | if (search_end > search_start) | ||
955 | hole_size = search_end - search_start; | ||
956 | |||
921 | if (hole_size > max_hole_size) { | 957 | if (hole_size > max_hole_size) { |
922 | max_hole_start = search_start; | 958 | max_hole_start = search_start; |
923 | max_hole_size = hole_size; | 959 | max_hole_size = hole_size; |
@@ -1543,6 +1579,7 @@ error: | |||
1543 | 1579 | ||
1544 | int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | 1580 | int btrfs_init_new_device(struct btrfs_root *root, char *device_path) |
1545 | { | 1581 | { |
1582 | struct request_queue *q; | ||
1546 | struct btrfs_trans_handle *trans; | 1583 | struct btrfs_trans_handle *trans; |
1547 | struct btrfs_device *device; | 1584 | struct btrfs_device *device; |
1548 | struct block_device *bdev; | 1585 | struct block_device *bdev; |
@@ -1612,6 +1649,9 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1612 | 1649 | ||
1613 | lock_chunks(root); | 1650 | lock_chunks(root); |
1614 | 1651 | ||
1652 | q = bdev_get_queue(bdev); | ||
1653 | if (blk_queue_discard(q)) | ||
1654 | device->can_discard = 1; | ||
1615 | device->writeable = 1; | 1655 | device->writeable = 1; |
1616 | device->work.func = pending_bios_fn; | 1656 | device->work.func = pending_bios_fn; |
1617 | generate_random_uuid(device->uuid); | 1657 | generate_random_uuid(device->uuid); |
@@ -1647,6 +1687,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1647 | root->fs_info->fs_devices->num_devices++; | 1687 | root->fs_info->fs_devices->num_devices++; |
1648 | root->fs_info->fs_devices->open_devices++; | 1688 | root->fs_info->fs_devices->open_devices++; |
1649 | root->fs_info->fs_devices->rw_devices++; | 1689 | root->fs_info->fs_devices->rw_devices++; |
1690 | if (device->can_discard) | ||
1691 | root->fs_info->fs_devices->num_can_discard++; | ||
1650 | root->fs_info->fs_devices->total_rw_bytes += device->total_bytes; | 1692 | root->fs_info->fs_devices->total_rw_bytes += device->total_bytes; |
1651 | 1693 | ||
1652 | if (!blk_queue_nonrot(bdev_get_queue(bdev))) | 1694 | if (!blk_queue_nonrot(bdev_get_queue(bdev))) |
@@ -2413,9 +2455,10 @@ static int __btrfs_alloc_chunk(struct btrfs_trans_handle *trans, | |||
2413 | total_avail = device->total_bytes - device->bytes_used; | 2455 | total_avail = device->total_bytes - device->bytes_used; |
2414 | else | 2456 | else |
2415 | total_avail = 0; | 2457 | total_avail = 0; |
2416 | /* avail is off by max(alloc_start, 1MB), but that is the same | 2458 | |
2417 | * for all devices, so it doesn't hurt the sorting later on | 2459 | /* If there is no space on this device, skip it. */ |
2418 | */ | 2460 | if (total_avail == 0) |
2461 | continue; | ||
2419 | 2462 | ||
2420 | ret = find_free_dev_extent(trans, device, | 2463 | ret = find_free_dev_extent(trans, device, |
2421 | max_stripe_size * dev_stripes, | 2464 | max_stripe_size * dev_stripes, |
diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 7c12d61ae7ae..6d866db4e177 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h | |||
@@ -48,6 +48,7 @@ struct btrfs_device { | |||
48 | int writeable; | 48 | int writeable; |
49 | int in_fs_metadata; | 49 | int in_fs_metadata; |
50 | int missing; | 50 | int missing; |
51 | int can_discard; | ||
51 | 52 | ||
52 | spinlock_t io_lock; | 53 | spinlock_t io_lock; |
53 | 54 | ||
@@ -104,6 +105,7 @@ struct btrfs_fs_devices { | |||
104 | u64 rw_devices; | 105 | u64 rw_devices; |
105 | u64 missing_devices; | 106 | u64 missing_devices; |
106 | u64 total_rw_bytes; | 107 | u64 total_rw_bytes; |
108 | u64 num_can_discard; | ||
107 | struct block_device *latest_bdev; | 109 | struct block_device *latest_bdev; |
108 | 110 | ||
109 | /* all of the devices in the FS, protected by a mutex | 111 | /* all of the devices in the FS, protected by a mutex |