mkfs.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #define _XOPEN_SOURCE 500
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <sys/types.h>
  5. #include <sys/stat.h>
  6. #include <fcntl.h>
  7. #include <unistd.h>
  8. #include "kerncompat.h"
  9. #include "radix-tree.h"
  10. #include "ctree.h"
  11. #include "disk-io.h"
  12. int mkfs(int fd, u64 num_blocks, u32 blocksize)
  13. {
  14. struct btrfs_super_block super;
  15. struct btrfs_leaf *empty_leaf;
  16. struct btrfs_root_item root_item;
  17. struct btrfs_item item;
  18. struct btrfs_extent_item extent_item;
  19. char *block;
  20. int ret;
  21. u32 itemoff;
  22. u32 start_block = BTRFS_SUPER_INFO_OFFSET / blocksize;
  23. btrfs_set_super_blocknr(&super, start_block);
  24. btrfs_set_super_root(&super, start_block + 1);
  25. strcpy((char *)(&super.magic), BTRFS_MAGIC);
  26. btrfs_set_super_blocksize(&super, blocksize);
  27. btrfs_set_super_total_blocks(&super, num_blocks);
  28. btrfs_set_super_blocks_used(&super, 0);
  29. block = malloc(blocksize);
  30. memset(block, 0, blocksize);
  31. BUG_ON(sizeof(super) > blocksize);
  32. memcpy(block, &super, sizeof(super));
  33. ret = pwrite(fd, block, blocksize, BTRFS_SUPER_INFO_OFFSET);
  34. BUG_ON(ret != blocksize);
  35. /* create the tree of root objects */
  36. empty_leaf = malloc(blocksize);
  37. memset(empty_leaf, 0, blocksize);
  38. btrfs_set_header_parentid(&empty_leaf->header,
  39. BTRFS_ROOT_TREE_OBJECTID);
  40. btrfs_set_header_blocknr(&empty_leaf->header, start_block + 1);
  41. btrfs_set_header_nritems(&empty_leaf->header, 2);
  42. /* create the items for the root tree */
  43. btrfs_set_root_blocknr(&root_item, start_block + 2);
  44. btrfs_set_root_refs(&root_item, 1);
  45. itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) - sizeof(root_item);
  46. btrfs_set_item_offset(&item, itemoff);
  47. btrfs_set_item_size(&item, sizeof(root_item));
  48. btrfs_set_key_objectid(&item.key, BTRFS_EXTENT_TREE_OBJECTID);
  49. btrfs_set_key_offset(&item.key, 0);
  50. btrfs_set_key_flags(&item.key, 0);
  51. memcpy(empty_leaf->items, &item, sizeof(item));
  52. memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
  53. &root_item, sizeof(root_item));
  54. btrfs_set_root_blocknr(&root_item, start_block + 3);
  55. itemoff = itemoff - sizeof(root_item);
  56. btrfs_set_item_offset(&item, itemoff);
  57. btrfs_set_key_objectid(&item.key, BTRFS_FS_TREE_OBJECTID);
  58. memcpy(empty_leaf->items + 1, &item, sizeof(item));
  59. memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
  60. &root_item, sizeof(root_item));
  61. ret = pwrite(fd, empty_leaf, blocksize, (start_block + 1) * blocksize);
  62. /* create the items for the extent tree */
  63. btrfs_set_header_parentid(&empty_leaf->header,
  64. BTRFS_EXTENT_TREE_OBJECTID);
  65. btrfs_set_header_blocknr(&empty_leaf->header, start_block + 2);
  66. btrfs_set_header_nritems(&empty_leaf->header, 4);
  67. /* item1, reserve blocks 0-16 */
  68. btrfs_set_key_objectid(&item.key, 0);
  69. btrfs_set_key_offset(&item.key, start_block + 1);
  70. btrfs_set_key_flags(&item.key, 0);
  71. itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) -
  72. sizeof(struct btrfs_extent_item);
  73. btrfs_set_item_offset(&item, itemoff);
  74. btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
  75. btrfs_set_extent_refs(&extent_item, 1);
  76. btrfs_set_extent_owner(&extent_item, 0);
  77. memcpy(empty_leaf->items, &item, sizeof(item));
  78. memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
  79. &extent_item, btrfs_item_size(&item));
  80. /* item2, give block 17 to the root */
  81. btrfs_set_key_objectid(&item.key, start_block + 1);
  82. btrfs_set_key_offset(&item.key, 1);
  83. itemoff = itemoff - sizeof(struct btrfs_extent_item);
  84. btrfs_set_item_offset(&item, itemoff);
  85. btrfs_set_extent_owner(&extent_item, BTRFS_ROOT_TREE_OBJECTID);
  86. memcpy(empty_leaf->items + 1, &item, sizeof(item));
  87. memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
  88. &extent_item, btrfs_item_size(&item));
  89. /* item3, give block 18 to the extent root */
  90. btrfs_set_key_objectid(&item.key, start_block + 2);
  91. btrfs_set_key_offset(&item.key, 1);
  92. itemoff = itemoff - sizeof(struct btrfs_extent_item);
  93. btrfs_set_item_offset(&item, itemoff);
  94. btrfs_set_extent_owner(&extent_item, BTRFS_EXTENT_TREE_OBJECTID);
  95. memcpy(empty_leaf->items + 2, &item, sizeof(item));
  96. memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
  97. &extent_item, btrfs_item_size(&item));
  98. /* item4, give block 19 to the FS root */
  99. btrfs_set_key_objectid(&item.key, start_block + 3);
  100. btrfs_set_key_offset(&item.key, 1);
  101. itemoff = itemoff - sizeof(struct btrfs_extent_item);
  102. btrfs_set_item_offset(&item, itemoff);
  103. btrfs_set_extent_owner(&extent_item, BTRFS_FS_TREE_OBJECTID);
  104. memcpy(empty_leaf->items + 3, &item, sizeof(item));
  105. memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
  106. &extent_item, btrfs_item_size(&item));
  107. ret = pwrite(fd, empty_leaf, blocksize, (start_block + 2) * blocksize);
  108. if (ret != blocksize)
  109. return -1;
  110. /* finally create the FS root */
  111. btrfs_set_header_parentid(&empty_leaf->header, BTRFS_FS_TREE_OBJECTID);
  112. btrfs_set_header_blocknr(&empty_leaf->header, start_block + 3);
  113. btrfs_set_header_nritems(&empty_leaf->header, 0);
  114. ret = pwrite(fd, empty_leaf, blocksize, (start_block + 3) * blocksize);
  115. if (ret != blocksize)
  116. return -1;
  117. return 0;
  118. }