mkfs.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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_disk_key_objectid(&item.key, BTRFS_EXTENT_TREE_OBJECTID);
  49. btrfs_set_disk_key_offset(&item.key, 0);
  50. btrfs_set_disk_key_flags(&item.key, 0);
  51. btrfs_set_disk_key_type(&item.key, BTRFS_ROOT_ITEM_KEY);
  52. memcpy(empty_leaf->items, &item, sizeof(item));
  53. memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
  54. &root_item, sizeof(root_item));
  55. btrfs_set_root_blocknr(&root_item, start_block + 3);
  56. itemoff = itemoff - sizeof(root_item);
  57. btrfs_set_item_offset(&item, itemoff);
  58. btrfs_set_disk_key_objectid(&item.key, BTRFS_FS_TREE_OBJECTID);
  59. memcpy(empty_leaf->items + 1, &item, sizeof(item));
  60. memcpy(btrfs_leaf_data(empty_leaf) + itemoff,
  61. &root_item, sizeof(root_item));
  62. ret = pwrite(fd, empty_leaf, blocksize, (start_block + 1) * blocksize);
  63. /* create the items for the extent tree */
  64. btrfs_set_header_parentid(&empty_leaf->header,
  65. BTRFS_EXTENT_TREE_OBJECTID);
  66. btrfs_set_header_blocknr(&empty_leaf->header, start_block + 2);
  67. btrfs_set_header_nritems(&empty_leaf->header, 4);
  68. /* item1, reserve blocks 0-16 */
  69. btrfs_set_disk_key_objectid(&item.key, 0);
  70. btrfs_set_disk_key_offset(&item.key, start_block + 1);
  71. btrfs_set_disk_key_flags(&item.key, 0);
  72. btrfs_set_disk_key_type(&item.key, BTRFS_EXTENT_ITEM_KEY);
  73. itemoff = __BTRFS_LEAF_DATA_SIZE(blocksize) -
  74. sizeof(struct btrfs_extent_item);
  75. btrfs_set_item_offset(&item, itemoff);
  76. btrfs_set_item_size(&item, sizeof(struct btrfs_extent_item));
  77. btrfs_set_extent_refs(&extent_item, 1);
  78. btrfs_set_extent_owner(&extent_item, 0);
  79. memcpy(empty_leaf->items, &item, sizeof(item));
  80. memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
  81. &extent_item, btrfs_item_size(&item));
  82. /* item2, give block 17 to the root */
  83. btrfs_set_disk_key_objectid(&item.key, start_block + 1);
  84. btrfs_set_disk_key_offset(&item.key, 1);
  85. itemoff = itemoff - sizeof(struct btrfs_extent_item);
  86. btrfs_set_item_offset(&item, itemoff);
  87. btrfs_set_extent_owner(&extent_item, BTRFS_ROOT_TREE_OBJECTID);
  88. memcpy(empty_leaf->items + 1, &item, sizeof(item));
  89. memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
  90. &extent_item, btrfs_item_size(&item));
  91. /* item3, give block 18 to the extent root */
  92. btrfs_set_disk_key_objectid(&item.key, start_block + 2);
  93. btrfs_set_disk_key_offset(&item.key, 1);
  94. itemoff = itemoff - sizeof(struct btrfs_extent_item);
  95. btrfs_set_item_offset(&item, itemoff);
  96. btrfs_set_extent_owner(&extent_item, BTRFS_EXTENT_TREE_OBJECTID);
  97. memcpy(empty_leaf->items + 2, &item, sizeof(item));
  98. memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
  99. &extent_item, btrfs_item_size(&item));
  100. /* item4, give block 19 to the FS root */
  101. btrfs_set_disk_key_objectid(&item.key, start_block + 3);
  102. btrfs_set_disk_key_offset(&item.key, 1);
  103. itemoff = itemoff - sizeof(struct btrfs_extent_item);
  104. btrfs_set_item_offset(&item, itemoff);
  105. btrfs_set_extent_owner(&extent_item, BTRFS_FS_TREE_OBJECTID);
  106. memcpy(empty_leaf->items + 3, &item, sizeof(item));
  107. memcpy(btrfs_leaf_data(empty_leaf) + btrfs_item_offset(&item),
  108. &extent_item, btrfs_item_size(&item));
  109. ret = pwrite(fd, empty_leaf, blocksize, (start_block + 2) * blocksize);
  110. if (ret != blocksize)
  111. return -1;
  112. /* finally create the FS root */
  113. btrfs_set_header_parentid(&empty_leaf->header, BTRFS_FS_TREE_OBJECTID);
  114. btrfs_set_header_blocknr(&empty_leaf->header, start_block + 3);
  115. btrfs_set_header_nritems(&empty_leaf->header, 0);
  116. ret = pwrite(fd, empty_leaf, blocksize, (start_block + 3) * blocksize);
  117. if (ret != blocksize)
  118. return -1;
  119. return 0;
  120. }