@@ -49,6 +49,7 @@
#define STRIPE_LEN (64 * 1024)
#define EXT2_IMAGE_SUBVOL_OBJECTID BTRFS_FIRST_FREE_OBJECTID
+static int nodesize = 0;
/*
* Open Ext2fs in readonly mode, read block allocation bitmap and
* inode bitmap into memory.
@@ -1806,20 +1807,20 @@ static int prepare_system_chunk_sb(struct btrfs_super_block *super)
return 0;
}
-static int prepare_system_chunk(int fd, u64 sb_bytenr, u32 sectorsize)
+static int prepare_system_chunk(int fd, u64 sb_bytenr, u32 nodesize)
{
int ret;
struct extent_buffer *buf;
struct btrfs_super_block *super;
- BUG_ON(sectorsize < sizeof(*super));
- buf = malloc(sizeof(*buf) + sectorsize);
+ BUG_ON(nodesize < sizeof(*super));
+ buf = malloc(sizeof(*buf) + nodesize);
if (!buf)
return -ENOMEM;
- buf->len = sectorsize;
- ret = pread(fd, buf->data, sectorsize, sb_bytenr);
- if (ret != sectorsize)
+ buf->len = nodesize;
+ ret = pread(fd, buf->data, nodesize, sb_bytenr);
+ if (ret != nodesize)
goto fail;
super = (struct btrfs_super_block *)buf->data;
@@ -1830,9 +1831,9 @@ static int prepare_system_chunk(int fd, u64 sb_bytenr, u32 sectorsize)
if (ret)
goto fail;
- csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 0);
- ret = pwrite(fd, buf->data, sectorsize, sb_bytenr);
- if (ret != sectorsize)
+ csum_tree_block_size(buf, BTRFS_CRC32_SIZE, 1);
+ ret = pwrite(fd, buf->data, nodesize, sb_bytenr);
+ if (ret != nodesize)
goto fail;
ret = 0;
@@ -2317,14 +2318,14 @@ int do_convert(const char *devname, int datacsum, int packing, int noxattr)
goto fail;
}
ret = make_btrfs(fd, devname, ext2_fs->super->s_volume_name,
- blocks, total_bytes, blocksize, blocksize,
+ blocks, total_bytes, nodesize, nodesize,
blocksize, blocksize);
if (ret) {
fprintf(stderr, "unable to create initial ctree\n");
goto fail;
}
/* create a system chunk that maps the whole device */
- ret = prepare_system_chunk(fd, super_bytenr, blocksize);
+ ret = prepare_system_chunk(fd, super_bytenr, nodesize);
if (ret) {
fprintf(stderr, "unable to update system chunk\n");
goto fail;
@@ -2753,13 +2754,36 @@ fail:
return -1;
}
+/* copied from mkfs.c */
+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;
+}
+
static void print_usage(void)
{
- printf("usage: btrfs-convert [-d] [-i] [-n] [-r] device\n");
+ printf("usage: btrfs-convert [-d] [-i] [-n] [-r] [-l size] device\n");
printf("\t-d disable data checksum\n");
printf("\t-i ignore xattrs and ACLs\n");
printf("\t-n disable packing of small files\n");
printf("\t-r roll back to ext2fs\n");
+ printf("\t-l set leafsize/nodesize of btrfs metadata\n");
}
int main(int argc, char *argv[])
@@ -2770,8 +2794,10 @@ int main(int argc, char *argv[])
int datacsum = 1;
int rollback = 0;
char *file;
+
+ nodesize = 4096;
while(1) {
- int c = getopt(argc, argv, "dinr");
+ int c = getopt(argc, argv, "dinrl:");
if (c < 0)
break;
switch(c) {
@@ -2787,6 +2813,11 @@ int main(int argc, char *argv[])
case 'r':
rollback = 1;
break;
+ case 'l':
+ nodesize = parse_size(optarg);
+ if (check_leaf_or_node_size(nodesize, 4096))
+ exit(1);
+ break;
default:
print_usage();
return 1;