aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 20:44:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 20:44:56 -0400
commitd3304cadb2e24517938e24efd58fd9ee6504fefe (patch)
tree5bf53a560d3df9c89b5b0d5ed095fc386c91fca4
parent1a892b485f328224b4882818f84fcc0a3208677d (diff)
parentd9ed71e5457c8c5bf1dc706e06468eab9e2aa87e (diff)
Merge branch 'for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "Some fixes from Omar and Dave Sterba for our new free space tree. This isn't heavily used yet, but as we move toward making it the new default we wanted to nail down an endian bug" * 'for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: btrfs: tests: uninline member definitions in free_space_extent btrfs: tests: constify free space extent specs Btrfs: expand free space tree sanity tests to catch endianness bug Btrfs: fix extent buffer bitmap tests on big-endian systems Btrfs: catch invalid free space trees Btrfs: fix mount -o clear_cache,space_cache=v2 Btrfs: fix free space tree bitmaps on big-endian systems
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/disk-io.c33
-rw-r--r--fs/btrfs/extent_io.c64
-rw-r--r--fs/btrfs/extent_io.h22
-rw-r--r--fs/btrfs/free-space-tree.c19
-rw-r--r--fs/btrfs/tests/extent-io-tests.c87
-rw-r--r--fs/btrfs/tests/free-space-tree-tests.c189
-rw-r--r--include/uapi/linux/btrfs.h12
8 files changed, 272 insertions, 157 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 6c21bad26a27..0b8ce2b9f7d0 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -252,7 +252,8 @@ struct btrfs_super_block {
252#define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL 252#define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL
253 253
254#define BTRFS_FEATURE_COMPAT_RO_SUPP \ 254#define BTRFS_FEATURE_COMPAT_RO_SUPP \
255 (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE) 255 (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \
256 BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID)
256 257
257#define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL 258#define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL
258#define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL 259#define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e720d3e6ec20..3a57f99d96aa 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2586,6 +2586,7 @@ int open_ctree(struct super_block *sb,
2586 int num_backups_tried = 0; 2586 int num_backups_tried = 0;
2587 int backup_index = 0; 2587 int backup_index = 0;
2588 int max_active; 2588 int max_active;
2589 int clear_free_space_tree = 0;
2589 2590
2590 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL); 2591 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
2591 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL); 2592 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
@@ -3148,6 +3149,26 @@ retry_root_backup:
3148 if (sb->s_flags & MS_RDONLY) 3149 if (sb->s_flags & MS_RDONLY)
3149 return 0; 3150 return 0;
3150 3151
3152 if (btrfs_test_opt(fs_info, CLEAR_CACHE) &&
3153 btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
3154 clear_free_space_tree = 1;
3155 } else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
3156 !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) {
3157 btrfs_warn(fs_info, "free space tree is invalid");
3158 clear_free_space_tree = 1;
3159 }
3160
3161 if (clear_free_space_tree) {
3162 btrfs_info(fs_info, "clearing free space tree");
3163 ret = btrfs_clear_free_space_tree(fs_info);
3164 if (ret) {
3165 btrfs_warn(fs_info,
3166 "failed to clear free space tree: %d", ret);
3167 close_ctree(tree_root);
3168 return ret;
3169 }
3170 }
3171
3151 if (btrfs_test_opt(tree_root->fs_info, FREE_SPACE_TREE) && 3172 if (btrfs_test_opt(tree_root->fs_info, FREE_SPACE_TREE) &&
3152 !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { 3173 !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
3153 btrfs_info(fs_info, "creating free space tree"); 3174 btrfs_info(fs_info, "creating free space tree");
@@ -3185,18 +3206,6 @@ retry_root_backup:
3185 3206
3186 btrfs_qgroup_rescan_resume(fs_info); 3207 btrfs_qgroup_rescan_resume(fs_info);
3187 3208
3188 if (btrfs_test_opt(tree_root->fs_info, CLEAR_CACHE) &&
3189 btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
3190 btrfs_info(fs_info, "clearing free space tree");
3191 ret = btrfs_clear_free_space_tree(fs_info);
3192 if (ret) {
3193 btrfs_warn(fs_info,
3194 "failed to clear free space tree: %d", ret);
3195 close_ctree(tree_root);
3196 return ret;
3197 }
3198 }
3199
3200 if (!fs_info->uuid_root) { 3209 if (!fs_info->uuid_root) {
3201 btrfs_info(fs_info, "creating UUID tree"); 3210 btrfs_info(fs_info, "creating UUID tree");
3202 ret = btrfs_create_uuid_tree(fs_info); 3211 ret = btrfs_create_uuid_tree(fs_info);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index ee40384c394d..66a755150056 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -5558,17 +5558,45 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
5558 } 5558 }
5559} 5559}
5560 5560
5561/* 5561void le_bitmap_set(u8 *map, unsigned int start, int len)
5562 * The extent buffer bitmap operations are done with byte granularity because 5562{
5563 * bitmap items are not guaranteed to be aligned to a word and therefore a 5563 u8 *p = map + BIT_BYTE(start);
5564 * single word in a bitmap may straddle two pages in the extent buffer. 5564 const unsigned int size = start + len;
5565 */ 5565 int bits_to_set = BITS_PER_BYTE - (start % BITS_PER_BYTE);
5566#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) 5566 u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(start);
5567#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1) 5567
5568#define BITMAP_FIRST_BYTE_MASK(start) \ 5568 while (len - bits_to_set >= 0) {
5569 ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK) 5569 *p |= mask_to_set;
5570#define BITMAP_LAST_BYTE_MASK(nbits) \ 5570 len -= bits_to_set;
5571 (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1))) 5571 bits_to_set = BITS_PER_BYTE;
5572 mask_to_set = ~(u8)0;
5573 p++;
5574 }
5575 if (len) {
5576 mask_to_set &= BITMAP_LAST_BYTE_MASK(size);
5577 *p |= mask_to_set;
5578 }
5579}
5580
5581void le_bitmap_clear(u8 *map, unsigned int start, int len)
5582{
5583 u8 *p = map + BIT_BYTE(start);
5584 const unsigned int size = start + len;
5585 int bits_to_clear = BITS_PER_BYTE - (start % BITS_PER_BYTE);
5586 u8 mask_to_clear = BITMAP_FIRST_BYTE_MASK(start);
5587
5588 while (len - bits_to_clear >= 0) {
5589 *p &= ~mask_to_clear;
5590 len -= bits_to_clear;
5591 bits_to_clear = BITS_PER_BYTE;
5592 mask_to_clear = ~(u8)0;
5593 p++;
5594 }
5595 if (len) {
5596 mask_to_clear &= BITMAP_LAST_BYTE_MASK(size);
5597 *p &= ~mask_to_clear;
5598 }
5599}
5572 5600
5573/* 5601/*
5574 * eb_bitmap_offset() - calculate the page and offset of the byte containing the 5602 * eb_bitmap_offset() - calculate the page and offset of the byte containing the
@@ -5612,7 +5640,7 @@ static inline void eb_bitmap_offset(struct extent_buffer *eb,
5612int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start, 5640int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
5613 unsigned long nr) 5641 unsigned long nr)
5614{ 5642{
5615 char *kaddr; 5643 u8 *kaddr;
5616 struct page *page; 5644 struct page *page;
5617 unsigned long i; 5645 unsigned long i;
5618 size_t offset; 5646 size_t offset;
@@ -5634,13 +5662,13 @@ int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
5634void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start, 5662void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
5635 unsigned long pos, unsigned long len) 5663 unsigned long pos, unsigned long len)
5636{ 5664{
5637 char *kaddr; 5665 u8 *kaddr;
5638 struct page *page; 5666 struct page *page;
5639 unsigned long i; 5667 unsigned long i;
5640 size_t offset; 5668 size_t offset;
5641 const unsigned int size = pos + len; 5669 const unsigned int size = pos + len;
5642 int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE); 5670 int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
5643 unsigned int mask_to_set = BITMAP_FIRST_BYTE_MASK(pos); 5671 u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(pos);
5644 5672
5645 eb_bitmap_offset(eb, start, pos, &i, &offset); 5673 eb_bitmap_offset(eb, start, pos, &i, &offset);
5646 page = eb->pages[i]; 5674 page = eb->pages[i];
@@ -5651,7 +5679,7 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
5651 kaddr[offset] |= mask_to_set; 5679 kaddr[offset] |= mask_to_set;
5652 len -= bits_to_set; 5680 len -= bits_to_set;
5653 bits_to_set = BITS_PER_BYTE; 5681 bits_to_set = BITS_PER_BYTE;
5654 mask_to_set = ~0U; 5682 mask_to_set = ~(u8)0;
5655 if (++offset >= PAGE_SIZE && len > 0) { 5683 if (++offset >= PAGE_SIZE && len > 0) {
5656 offset = 0; 5684 offset = 0;
5657 page = eb->pages[++i]; 5685 page = eb->pages[++i];
@@ -5676,13 +5704,13 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
5676void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start, 5704void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
5677 unsigned long pos, unsigned long len) 5705 unsigned long pos, unsigned long len)
5678{ 5706{
5679 char *kaddr; 5707 u8 *kaddr;
5680 struct page *page; 5708 struct page *page;
5681 unsigned long i; 5709 unsigned long i;
5682 size_t offset; 5710 size_t offset;
5683 const unsigned int size = pos + len; 5711 const unsigned int size = pos + len;
5684 int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE); 5712 int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
5685 unsigned int mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos);