[PATCH v3 2/2] btrfs-progs: limit the min value of total_bytes
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -b 1048576 /dev/sda will report error: mkfs.btrfs: volumes.c:796: btrfs_alloc_chunk: Assertion `!(ret)' failed. Aborted because the length of dev_extent is 4MB. For the single/single case it's 5MB but for the dup/dup it's 156MB. It's due to the known bug in the blockgroup creation with multiple devices (applies on dup as well here) that leads to: # btrfs fi df . System, DUP: total=8.00MB, used=4.00KB System: total=4.00MB, used=0.00 Data+Metadata, DUP: total=64.00MB, used=24.00KB Data+Metadata: total=8.00MB, used=0.00 8*2 + 4 + 64*2 + 8 = 156 Signed-off-by: Robin Dong --- v3 <- v2: - change the max value of total_bytes to 156MB. mkfs.c |7 ++- utils.h |1 + 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/mkfs.c b/mkfs.c index 93672b9..982a113 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1345,7 +1345,12 @@ int main(int ac, char **av) &dev_block_count, &mixed, nodiscard); if (block_count == 0) block_count = dev_block_count; - else if (block_count > dev_block_count) { + else if (block_count < BTRFS_MKFS_SYSTEM_MAX_SIZE) { + fprintf(stderr, "Illegal total number of bytes %u " + "(smaller than %u)\n", + block_count, BTRFS_MKFS_SYSTEM_MAX_SIZE); + exit(1); + } else if (block_count > dev_block_count) { fprintf(stderr, "%s is smaller than requested size\n", file); exit(1); } diff --git a/utils.h b/utils.h index c147c12..b63f69a 100644 --- a/utils.h +++ b/utils.h @@ -20,6 +20,7 @@ #define __UTILS__ #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) +#define BTRFS_MKFS_SYSTEM_MAX_SIZE (156 * 1024 * 1024) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/2] btrfs-progs: limit the max value of leafsize and nodesize
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -l 131072 /dev/sda will return no error, but after mount it, the dmesg will report: BTRFS: couldn't mount because metadata blocksize (131072) was too large The leafsize and nodesize are equal at present, so we just use one function "check_leaf_or_node_size" to limit leaf and node size below BTRFS_MAX_METADATA_BLOCKSIZE. Signed-off-by: Robin Dong --- v2 <- v1: - add function check_leaf_or_node_size to limit leafsize and nodesize. v3 <- v2: - add quota string "sectorsize". ctree.h |6 ++ mkfs.c | 29 +++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/ctree.h b/ctree.h index 7f55229..75c1e0a 100644 --- a/ctree.h +++ b/ctree.h @@ -111,6 +111,12 @@ struct btrfs_trans_handle; #define BTRFS_DEV_ITEMS_OBJECTID 1ULL /* + * the max metadata block size. This limit is somewhat artificial, + * but the memmove costs go through the roof for larger blocks. + */ +#define BTRFS_MAX_METADATA_BLOCKSIZE 65536 + +/* * we can actually store much bigger names, but lets not confuse the rest * of linux */ diff --git a/mkfs.c b/mkfs.c index dff5eb8..93672b9 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1201,6 +1201,27 @@ static int zero_output_file(int out_fd, u64 size, u32 sectorsize) return ret; } +static int check_leaf_or_node_size(u32 size, u32 sectorsize) +{ + if (size < sectorsize) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (smaller than sectorsize %u)\n", + size, sectorsize); + return -1; + } else if (size > BTRFS_MAX_METADATA_BLOCKSIZE) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (larger than %u)\n", + size, BTRFS_MAX_METADATA_BLOCKSIZE); + return -1; + } else if (size & (sectorsize - 1)) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (not aligned to %u)\n", + size, sectorsize); + return -1; + } + return 0; +} + int main(int ac, char **av) { char *file; @@ -1291,14 +1312,10 @@ int main(int ac, char **av) } } sectorsize = max(sectorsize, (u32)getpagesize()); - if (leafsize < sectorsize || (leafsize & (sectorsize - 1))) { - fprintf(stderr, "Illegal leafsize %u\n", leafsize); + if (check_leaf_or_node_size(leafsize, sectorsize)) exit(1); - } - if (nodesize < sectorsize || (nodesize & (sectorsize - 1))) { - fprintf(stderr, "Illegal nodesize %u\n", nodesize); + if (check_leaf_or_node_size(nodesize, sectorsize)) exit(1); - } ac = ac - optind; if (ac == 0) print_usage(); -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/2] btrfs-progs: limit the min value of total_bytes
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -b 1048576 /dev/sda will report error: mkfs.btrfs: volumes.c:796: btrfs_alloc_chunk: Assertion `!(ret)' failed. Aborted because the length of dev_extent is 4MB. For the single/single case it's 5MB but for the dup/dup it's 156MB. It's due to the known bug in the blockgroup creation with multiple devices (applies on dup as well here) that leads to: # btrfs fi df . System, DUP: total=8.00MB, used=4.00KB System: total=4.00MB, used=0.00 Data+Metadata, DUP: total=64.00MB, used=24.00KB Data+Metadata: total=8.00MB, used=0.00 8*2 + 4 + 64*2 + 8 = 156 Signed-off-by: Robin Dong Reviewed-by: David Sterba --- mkfs.c |7 ++- utils.h |1 + 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/mkfs.c b/mkfs.c index 93672b9..982a113 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1345,7 +1345,12 @@ int main(int ac, char **av) &dev_block_count, &mixed, nodiscard); if (block_count == 0) block_count = dev_block_count; - else if (block_count > dev_block_count) { + else if (block_count < BTRFS_MKFS_SYSTEM_MAX_SIZE) { + fprintf(stderr, "Illegal total number of bytes %u " + "(smaller than %u)\n", + block_count, BTRFS_MKFS_SYSTEM_MAX_SIZE); + exit(1); + } else if (block_count > dev_block_count) { fprintf(stderr, "%s is smaller than requested size\n", file); exit(1); } diff --git a/utils.h b/utils.h index c147c12..b63f69a 100644 --- a/utils.h +++ b/utils.h @@ -20,6 +20,7 @@ #define __UTILS__ #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) +#define BTRFS_MKFS_SYSTEM_MAX_SIZE (156 * 1024 * 1024) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/2] btrfs-progs: limit the min value of total_bytes
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -b 1048576 /dev/sda will report error: mkfs.btrfs: volumes.c:796: btrfs_alloc_chunk: Assertion `!(ret)' failed. Aborted because the length of dev_extent is 4MB. For the single/single case it's 5MB but for the dup/dup it's 156MB. It's due to the known bug in the blockgroup creation with multiple devices (applies on dup as well here) that leads to: # btrfs fi df . System, DUP: total=8.00MB, used=4.00KB System: total=4.00MB, used=0.00 Data+Metadata, DUP: total=64.00MB, used=24.00KB Data+Metadata: total=8.00MB, used=0.00 8*2 + 4 + 64*2 + 8 = 156 Signed-off-by: Robin Dong Reviewed-by: David Sterba --- mkfs.c |7 ++- utils.h |1 + 2 files changed, 7 insertions(+), 1 deletions(-) diff --git a/mkfs.c b/mkfs.c index 93672b9..982a113 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1345,7 +1345,12 @@ int main(int ac, char **av) &dev_block_count, &mixed, nodiscard); if (block_count == 0) block_count = dev_block_count; - else if (block_count > dev_block_count) { + else if (block_count < BTRFS_MKFS_SYSTEM_MAX_SIZE) { + fprintf(stderr, "Illegal total number of bytes %u " + "(smaller than %u)\n", + block_count, BTRFS_MKFS_SYSTEM_MAX_SIZE); + exit(1); + } else if (block_count > dev_block_count) { fprintf(stderr, "%s is smaller than requested size\n", file); exit(1); } diff --git a/utils.h b/utils.h index c147c12..b63f69a 100644 --- a/utils.h +++ b/utils.h @@ -20,6 +20,7 @@ #define __UTILS__ #define BTRFS_MKFS_SYSTEM_GROUP_SIZE (4 * 1024 * 1024) +#define BTRFS_MKFS_SYSTEM_MAX_SIZE (156 * 1024 * 1024) int make_btrfs(int fd, const char *device, const char *label, u64 blocks[6], u64 num_bytes, u32 nodesize, -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/2] btrfs-progs: limit the max value of leafsize and nodesize
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -l 131072 /dev/sda will return no error, but after mount it, the dmesg will report: BTRFS: couldn't mount because metadata blocksize (131072) was too large The leafsize and nodesize are equal at present, so we just use one function "check_leaf_or_node_size" to limit leaf and node size below BTRFS_MAX_METADATA_BLOCKSIZE. Signed-off-by: Robin Dong Reviewed-by: David Sterba --- ctree.h |6 ++ mkfs.c | 29 +++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/ctree.h b/ctree.h index 7f55229..75c1e0a 100644 --- a/ctree.h +++ b/ctree.h @@ -111,6 +111,12 @@ struct btrfs_trans_handle; #define BTRFS_DEV_ITEMS_OBJECTID 1ULL /* + * the max metadata block size. This limit is somewhat artificial, + * but the memmove costs go through the roof for larger blocks. + */ +#define BTRFS_MAX_METADATA_BLOCKSIZE 65536 + +/* * we can actually store much bigger names, but lets not confuse the rest * of linux */ diff --git a/mkfs.c b/mkfs.c index dff5eb8..93672b9 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1201,6 +1201,27 @@ static int zero_output_file(int out_fd, u64 size, u32 sectorsize) return ret; } +static int check_leaf_or_node_size(u32 size, u32 sectorsize) +{ + if (size < sectorsize) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (smaller than sectorsize %u)\n", + size, sectorsize); + return -1; + } else if (size > BTRFS_MAX_METADATA_BLOCKSIZE) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (larger than %u)\n", + size, BTRFS_MAX_METADATA_BLOCKSIZE); + return -1; + } else if (size & (sectorsize - 1)) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (not aligned to %u)\n", + size, sectorsize); + return -1; + } + return 0; +} + int main(int ac, char **av) { char *file; @@ -1291,14 +1312,10 @@ int main(int ac, char **av) } } sectorsize = max(sectorsize, (u32)getpagesize()); - if (leafsize < sectorsize || (leafsize & (sectorsize - 1))) { - fprintf(stderr, "Illegal leafsize %u\n", leafsize); + if (check_leaf_or_node_size(leafsize, sectorsize)) exit(1); - } - if (nodesize < sectorsize || (nodesize & (sectorsize - 1))) { - fprintf(stderr, "Illegal nodesize %u\n", nodesize); + if (check_leaf_or_node_size(nodesize, sectorsize)) exit(1); - } ac = ac - optind; if (ac == 0) print_usage(); -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 2/2] btrfs-progs: limit the min value of total_bytes
2012/10/1 David Sterba : > On Fri, Sep 28, 2012 at 11:02:40AM +0800, Robin Dong wrote: >> From: Robin Dong >> >> Using mkfs.btrfs like: >> >> mkfs.btrfs -b 1048576 /dev/sda >> >> will report error: >> >> mkfs.btrfs: volumes.c:796: btrfs_alloc_chunk: Assertion `!(ret)' >> failed. >> Aborted >> >> because the length of dev_extent is 4MB. >> >> But if we use mkfs.btrfs with 8MB total bytes, the newly mounted btrfs >> filesystem >> would not contain even one empty file. So 12MB will be good min-value for >> block_count. > > I'm not able to create a single file even on a 12MB filesystem > (with -d single -m single --mixed), so any limit that would let the mkfs > finish normally should be fine. For the single/single case it's 5MB but > for the dup/dup it's 156MB. It's due to the known bug in the blockgroup > creation with multiple devices (applies on dup as well here) that leads > to: > > # btrfs fi df . > System, DUP: total=8.00MB, used=4.00KB > System: total=4.00MB, used=0.00 > Data+Metadata, DUP: total=64.00MB, used=24.00KB > Data+Metadata: total=8.00MB, used=0.00 > > 8*2 + 4 + 64*2 + 8 = 156 > > so, 12M is too small to avoid the mkfs crash. Thanks for your notice! > > david -- -- Best Regard Robin Dong -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] btrfs: move inline function code to header file
From: Robin Dong When building btrfs from kernel code, it will report: fs/btrfs/extent_io.h:281: warning: 'extent_buffer_page' declared inline after being called fs/btrfs/extent_io.h:281: warning: previous declaration of 'extent_buffer_page' was here fs/btrfs/extent_io.h:280: warning: 'num_extent_pages' declared inline after being called fs/btrfs/extent_io.h:280: warning: previous declaration of 'num_extent_pages' was here because of the wrong declaration of inline functions. Signed-off-by: Robin Dong --- fs/btrfs/extent_io.c | 12 fs/btrfs/extent_io.h | 14 -- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 4c87847..82abd4e 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3914,18 +3914,6 @@ out: return ret; } -inline struct page *extent_buffer_page(struct extent_buffer *eb, - unsigned long i) -{ - return eb->pages[i]; -} - -inline unsigned long num_extent_pages(u64 start, u64 len) -{ - return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) - - (start >> PAGE_CACHE_SHIFT); -} - static void __free_extent_buffer(struct extent_buffer *eb) { #if LEAK_DEBUG diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 25900af..0ebe4b5 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -277,8 +277,18 @@ void free_extent_buffer_stale(struct extent_buffer *eb); int read_extent_buffer_pages(struct extent_io_tree *tree, struct extent_buffer *eb, u64 start, int wait, get_extent_t *get_extent, int mirror_num); -unsigned long num_extent_pages(u64 start, u64 len); -struct page *extent_buffer_page(struct extent_buffer *eb, unsigned long i); + +static inline unsigned long num_extent_pages(u64 start, u64 len) +{ + return ((start + len + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT) - + (start >> PAGE_CACHE_SHIFT); +} + +static inline struct page *extent_buffer_page(struct extent_buffer *eb, + unsigned long i) +{ + return eb->pages[i]; +} static inline void extent_buffer_get(struct extent_buffer *eb) { -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] btrfs: remove unused function btrfs_insert_some_items()
From: Robin Dong The function btrfs_insert_some_items() would not be called by any other functions, so remove it. Signed-off-by: Robin Dong --- fs/btrfs/ctree.c | 143 -- 1 files changed, 0 insertions(+), 143 deletions(-) diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 6d183f6..3878c0a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c @@ -4402,149 +4402,6 @@ void btrfs_extend_item(struct btrfs_trans_handle *trans, } /* - * Given a key and some data, insert items into the tree. - * This does all the path init required, making room in the tree if needed. - * Returns the number of keys that were inserted. - */ -int btrfs_insert_some_items(struct btrfs_trans_handle *trans, - struct btrfs_root *root, - struct btrfs_path *path, - struct btrfs_key *cpu_key, u32 *data_size, - int nr) -{ - struct extent_buffer *leaf; - struct btrfs_item *item; - int ret = 0; - int slot; - int i; - u32 nritems; - u32 total_data = 0; - u32 total_size = 0; - unsigned int data_end; - struct btrfs_disk_key disk_key; - struct btrfs_key found_key; - struct btrfs_map_token token; - - btrfs_init_map_token(&token); - - for (i = 0; i < nr; i++) { - if (total_size + data_size[i] + sizeof(struct btrfs_item) > - BTRFS_LEAF_DATA_SIZE(root)) { - break; - nr = i; - } - total_data += data_size[i]; - total_size += data_size[i] + sizeof(struct btrfs_item); - } - BUG_ON(nr == 0); - - ret = btrfs_search_slot(trans, root, cpu_key, path, total_size, 1); - if (ret == 0) - return -EEXIST; - if (ret < 0) - goto out; - - leaf = path->nodes[0]; - - nritems = btrfs_header_nritems(leaf); - data_end = leaf_data_end(root, leaf); - - if (btrfs_leaf_free_space(root, leaf) < total_size) { - for (i = nr; i >= 0; i--) { - total_data -= data_size[i]; - total_size -= data_size[i] + sizeof(struct btrfs_item); - if (total_size < btrfs_leaf_free_space(root, leaf)) - break; - } - nr = i; - } - - slot = path->slots[0]; - BUG_ON(slot < 0); - - if (slot != nritems) { - unsigned int old_data = btrfs_item_end_nr(leaf, slot); - - item = btrfs_item_nr(leaf, slot); - btrfs_item_key_to_cpu(leaf, &found_key, slot); - - /* figure out how many keys we can insert in here */ - total_data = data_size[0]; - for (i = 1; i < nr; i++) { - if (btrfs_comp_cpu_keys(&found_key, cpu_key + i) <= 0) - break; - total_data += data_size[i]; - } - nr = i; - - if (old_data < data_end) { - btrfs_print_leaf(root, leaf); - printk(KERN_CRIT "slot %d old_data %d data_end %d\n", - slot, old_data, data_end); - BUG_ON(1); - } - /* -* item0..itemN ... dataN.offset..dataN.size .. data0.size -*/ - /* first correct the data pointers */ - for (i = slot; i < nritems; i++) { - u32 ioff; - - item = btrfs_item_nr(leaf, i); - ioff = btrfs_token_item_offset(leaf, item, &token); - btrfs_set_token_item_offset(leaf, item, - ioff - total_data, &token); - } - /* shift the items */ - memmove_extent_buffer(leaf, btrfs_item_nr_offset(slot + nr), - btrfs_item_nr_offset(slot), - (nritems - slot) * sizeof(struct btrfs_item)); - - /* shift the data */ - memmove_extent_buffer(leaf, btrfs_leaf_data(leaf) + - data_end - total_data, btrfs_leaf_data(leaf) + - data_end, old_data - data_end); - data_end = old_data; - } else { - /* -* this sucks but it has to be done, if we are inserting at -* the end of the leaf only insert 1 of the items, since we -* have no way of knowing whats on the next leaf and we'd have -* to drop our current locks to figure it out -*/ - nr = 1; - } - - /* setup the item for the new data */ -
[PATCH v2 2/2] btrfs-progs: limit the min value of total_bytes
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -b 1048576 /dev/sda will report error: mkfs.btrfs: volumes.c:796: btrfs_alloc_chunk: Assertion `!(ret)' failed. Aborted because the length of dev_extent is 4MB. But if we use mkfs.btrfs with 8MB total bytes, the newly mounted btrfs filesystem would not contain even one empty file. So 12MB will be good min-value for block_count. Signed-off-by: Robin Dong --- mkfs.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/mkfs.c b/mkfs.c index 8420482..496faa8 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1345,7 +1345,11 @@ int main(int ac, char **av) &dev_block_count, &mixed, nodiscard); if (block_count == 0) block_count = dev_block_count; - else if (block_count > dev_block_count) { + else if (block_count < 3 * BTRFS_MKFS_SYSTEM_GROUP_SIZE) { + fprintf(stderr, "Illegal total number of bytes %u\n", + block_count); + exit(1); + } else if (block_count > dev_block_count) { fprintf(stderr, "%s is smaller than requested size\n", file); exit(1); } -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 1/2] btrfs-progs: limit the max value of leafsize and nodesize
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -l 131072 /dev/sda will return no error, but after mount it, the dmesg will report: BTRFS: couldn't mount because metadata blocksize (131072) was too large The leafsize and nodesize are equal at present, so we just use one function "check_leaf_or_node_size" to limit leaf and node size below BTRFS_MAX_METADATA_BLOCKSIZE. Signed-off-by: Robin Dong Reviewed-by: David Sterba --- ctree.h |6 ++ mkfs.c | 29 +++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/ctree.h b/ctree.h index 7f55229..75c1e0a 100644 --- a/ctree.h +++ b/ctree.h @@ -111,6 +111,12 @@ struct btrfs_trans_handle; #define BTRFS_DEV_ITEMS_OBJECTID 1ULL /* + * the max metadata block size. This limit is somewhat artificial, + * but the memmove costs go through the roof for larger blocks. + */ +#define BTRFS_MAX_METADATA_BLOCKSIZE 65536 + +/* * we can actually store much bigger names, but lets not confuse the rest * of linux */ diff --git a/mkfs.c b/mkfs.c index dff5eb8..8420482 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1201,6 +1201,27 @@ static int zero_output_file(int out_fd, u64 size, u32 sectorsize) return ret; } +static int check_leaf_or_node_size(u32 size, u32 sectorsize) +{ + if (size < sectorsize) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (smaller than %u)\n", + size, sectorsize); + return -1; + } else if (size > BTRFS_MAX_METADATA_BLOCKSIZE) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (larger than %u)\n", + size, BTRFS_MAX_METADATA_BLOCKSIZE); + return -1; + } else if (size & (sectorsize - 1)) { + fprintf(stderr, + "Illegal leafsize (or nodesize) %u (not align to %u)\n", + size, sectorsize); + return -1; + } + return 0; +} + int main(int ac, char **av) { char *file; @@ -1291,14 +1312,10 @@ int main(int ac, char **av) } } sectorsize = max(sectorsize, (u32)getpagesize()); - if (leafsize < sectorsize || (leafsize & (sectorsize - 1))) { - fprintf(stderr, "Illegal leafsize %u\n", leafsize); + if (check_leaf_or_node_size(leafsize, sectorsize)) exit(1); - } - if (nodesize < sectorsize || (nodesize & (sectorsize - 1))) { - fprintf(stderr, "Illegal nodesize %u\n", nodesize); + if (check_leaf_or_node_size(nodesize, sectorsize)) exit(1); - } ac = ac - optind; if (ac == 0) print_usage(); -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] btrfs-progs: limit the min value of total_bytes
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -b 1048576 /dev/sda will report error: mkfs.btrfs: volumes.c:796: btrfs_alloc_chunk: Assertion `!(ret)' failed. Aborted because the length of dev_extent is 4MB. But if we use mkfs.btrfs with 8MB total bytes, the newly mounted btrfs filesystem would not contain even one empty file. So 12MB will be good min value for block_count. Signed-off-by: Robin Dong --- mkfs.c |6 +- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/mkfs.c b/mkfs.c index bb01f64..23bde2d 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1330,7 +1330,11 @@ int main(int ac, char **av) &dev_block_count, &mixed, nodiscard); if (block_count == 0) block_count = dev_block_count; - else if (block_count > dev_block_count) { + else if (block_count < 3 * BTRFS_MKFS_SYSTEM_GROUP_SIZE) { + fprintf(stderr, "Illegal total number of bytes %u\n", + block_count); + exit(1); + } else if (block_count > dev_block_count) { fprintf(stderr, "%s is smaller than requested size\n", file); exit(1); } -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] btrfs-progs: limit the max value of leafsize and nodesize
From: Robin Dong Using mkfs.btrfs like: mkfs.btrfs -l 131072 /dev/sda will return no error, but after mount it, the dmesg will report: BTRFS: couldn't mount because metadata blocksize (131072) was too large The user tools should use BTRFS_MAX_METADATA_BLOCKSIZE to limit leaf and node size. Signed-off-by: Robin Dong --- ctree.h |6 ++ mkfs.c |6 -- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/ctree.h b/ctree.h index 7f55229..75c1e0a 100644 --- a/ctree.h +++ b/ctree.h @@ -111,6 +111,12 @@ struct btrfs_trans_handle; #define BTRFS_DEV_ITEMS_OBJECTID 1ULL /* + * the max metadata block size. This limit is somewhat artificial, + * but the memmove costs go through the roof for larger blocks. + */ +#define BTRFS_MAX_METADATA_BLOCKSIZE 65536 + +/* * we can actually store much bigger names, but lets not confuse the rest * of linux */ diff --git a/mkfs.c b/mkfs.c index dff5eb8..bb01f64 100644 --- a/mkfs.c +++ b/mkfs.c @@ -1291,11 +1291,13 @@ int main(int ac, char **av) } } sectorsize = max(sectorsize, (u32)getpagesize()); - if (leafsize < sectorsize || (leafsize & (sectorsize - 1))) { + if (leafsize < sectorsize || leafsize > BTRFS_MAX_METADATA_BLOCKSIZE || + (leafsize & (sectorsize - 1))) { fprintf(stderr, "Illegal leafsize %u\n", leafsize); exit(1); } - if (nodesize < sectorsize || (nodesize & (sectorsize - 1))) { + if (nodesize < sectorsize || nodesize > BTRFS_MAX_METADATA_BLOCKSIZE || + (nodesize & (sectorsize - 1))) { fprintf(stderr, "Illegal nodesize %u\n", nodesize); exit(1); } -- 1.7.3.2 -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html