btree.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498
  1. /*
  2. * linux/fs/hfsplus/btree.c
  3. *
  4. * Copyright (C) 2001
  5. * Brad Boyer (flar@allandria.com)
  6. * (C) 2003 Ardis Technologies <roman@ardistech.com>
  7. *
  8. * Handle opening/closing btree
  9. */
  10. #include <linux/slab.h>
  11. #include <linux/pagemap.h>
  12. #include <linux/log2.h>
  13. #include "hfsplus_fs.h"
  14. #include "hfsplus_raw.h"
  15. /*
  16. * Initial source code of clump size calculation is gotten
  17. * from http://opensource.apple.com/tarballs/diskdev_cmds/
  18. */
  19. #define CLUMP_ENTRIES 15
  20. static short clumptbl[CLUMP_ENTRIES * 3] = {
  21. /*
  22. * Volume Attributes Catalog Extents
  23. * Size Clump (MB) Clump (MB) Clump (MB)
  24. */
  25. /* 1GB */ 4, 4, 4,
  26. /* 2GB */ 6, 6, 4,
  27. /* 4GB */ 8, 8, 4,
  28. /* 8GB */ 11, 11, 5,
  29. /*
  30. * For volumes 16GB and larger, we want to make sure that a full OS
  31. * install won't require fragmentation of the Catalog or Attributes
  32. * B-trees. We do this by making the clump sizes sufficiently large,
  33. * and by leaving a gap after the B-trees for them to grow into.
  34. *
  35. * For SnowLeopard 10A298, a FullNetInstall with all packages selected
  36. * results in:
  37. * Catalog B-tree Header
  38. * nodeSize: 8192
  39. * totalNodes: 31616
  40. * freeNodes: 1978
  41. * (used = 231.55 MB)
  42. * Attributes B-tree Header
  43. * nodeSize: 8192
  44. * totalNodes: 63232
  45. * freeNodes: 958
  46. * (used = 486.52 MB)
  47. *
  48. * We also want Time Machine backup volumes to have a sufficiently
  49. * large clump size to reduce fragmentation.
  50. *
  51. * The series of numbers for Catalog and Attribute form a geometric
  52. * series. For Catalog (16GB to 512GB), each term is 8**(1/5) times
  53. * the previous term. For Attributes (16GB to 512GB), each term is
  54. * 4**(1/5) times the previous term. For 1TB to 16TB, each term is
  55. * 2**(1/5) times the previous term.
  56. */
  57. /* 16GB */ 64, 32, 5,
  58. /* 32GB */ 84, 49, 6,
  59. /* 64GB */ 111, 74, 7,
  60. /* 128GB */ 147, 111, 8,
  61. /* 256GB */ 194, 169, 9,
  62. /* 512GB */ 256, 256, 11,
  63. /* 1TB */ 294, 294, 14,
  64. /* 2TB */ 338, 338, 16,
  65. /* 4TB */ 388, 388, 20,
  66. /* 8TB */ 446, 446, 25,
  67. /* 16TB */ 512, 512, 32
  68. };
  69. u32 hfsplus_calc_btree_clump_size(u32 block_size, u32 node_size,
  70. u64 sectors, int file_id)
  71. {
  72. u32 mod = max(node_size, block_size);
  73. u32 clump_size;
  74. int column;
  75. int i;
  76. /* Figure out which column of the above table to use for this file. */
  77. switch (file_id) {
  78. case HFSPLUS_ATTR_CNID:
  79. column = 0;
  80. break;
  81. case HFSPLUS_CAT_CNID:
  82. column = 1;
  83. break;
  84. default:
  85. column = 2;
  86. break;
  87. }
  88. /*
  89. * The default clump size is 0.8% of the volume size. And
  90. * it must also be a multiple of the node and block size.
  91. */
  92. if (sectors < 0x200000) {
  93. clump_size = sectors << 2; /* 0.8 % */
  94. if (clump_size < (8 * node_size))
  95. clump_size = 8 * node_size;
  96. } else {
  97. /* turn exponent into table index... */
  98. for (i = 0, sectors = sectors >> 22;
  99. sectors && (i < CLUMP_ENTRIES - 1);
  100. ++i, sectors = sectors >> 1) {
  101. /* empty body */
  102. }
  103. clump_size = clumptbl[column + (i) * 3] * 1024 * 1024;
  104. }
  105. /*
  106. * Round the clump size to a multiple of node and block size.
  107. * NOTE: This rounds down.
  108. */
  109. clump_size /= mod;
  110. clump_size *= mod;
  111. /*
  112. * Rounding down could have rounded down to 0 if the block size was
  113. * greater than the clump size. If so, just use one block or node.
  114. */
  115. if (clump_size == 0)
  116. clump_size = mod;
  117. return clump_size;
  118. }
  119. /* Get a reference to a B*Tree and do some initial checks */
  120. struct hfs_btree *hfs_btree_open(struct super_block *sb, u32 id)
  121. {
  122. struct hfs_btree *tree;
  123. struct hfs_btree_header_rec *head;
  124. struct address_space *mapping;
  125. struct inode *inode;
  126. struct page *page;
  127. unsigned int size;
  128. tree = kzalloc(sizeof(*tree), GFP_KERNEL);
  129. if (!tree)
  130. return NULL;
  131. mutex_init(&tree->tree_lock);
  132. spin_lock_init(&tree->hash_lock);
  133. tree->sb = sb;
  134. tree->cnid = id;
  135. inode = hfsplus_iget(sb, id);
  136. if (IS_ERR(inode))
  137. goto free_tree;
  138. tree->inode = inode;
  139. if (!HFSPLUS_I(tree->inode)->first_blocks) {
  140. pr_err("invalid btree extent records (0 size)\n");
  141. goto free_inode;
  142. }
  143. mapping = tree->inode->i_mapping;
  144. page = read_mapping_page(mapping, 0, NULL);
  145. if (IS_ERR(page))
  146. goto free_inode;
  147. /* Load the header */
  148. head = (struct hfs_btree_header_rec *)(kmap(page) +
  149. sizeof(struct hfs_bnode_desc));
  150. tree->root = be32_to_cpu(head->root);
  151. tree->leaf_count = be32_to_cpu(head->leaf_count);
  152. tree->leaf_head = be32_to_cpu(head->leaf_head);
  153. tree->leaf_tail = be32_to_cpu(head->leaf_tail);
  154. tree->node_count = be32_to_cpu(head->node_count);
  155. tree->free_nodes = be32_to_cpu(head->free_nodes);
  156. tree->attributes = be32_to_cpu(head->attributes);
  157. tree->node_size = be16_to_cpu(head->node_size);
  158. tree->max_key_len = be16_to_cpu(head->max_key_len);
  159. tree->depth = be16_to_cpu(head->depth);
  160. /* Verify the tree and set the correct compare function */
  161. switch (id) {
  162. case HFSPLUS_EXT_CNID:
  163. if (tree->max_key_len != HFSPLUS_EXT_KEYLEN - sizeof(u16)) {
  164. pr_err("invalid extent max_key_len %d\n",
  165. tree->max_key_len);
  166. goto fail_page;
  167. }
  168. if (tree->attributes & HFS_TREE_VARIDXKEYS) {
  169. pr_err("invalid extent btree flag\n");
  170. goto fail_page;
  171. }
  172. tree->keycmp = hfsplus_ext_cmp_key;
  173. break;
  174. case HFSPLUS_CAT_CNID:
  175. if (tree->max_key_len != HFSPLUS_CAT_KEYLEN - sizeof(u16)) {
  176. pr_err("invalid catalog max_key_len %d\n",
  177. tree->max_key_len);
  178. goto fail_page;
  179. }
  180. if (!(tree->attributes & HFS_TREE_VARIDXKEYS)) {
  181. pr_err("invalid catalog btree flag\n");
  182. goto fail_page;
  183. }
  184. if (test_bit(HFSPLUS_SB_HFSX, &HFSPLUS_SB(sb)->flags) &&
  185. (head->key_type == HFSPLUS_KEY_BINARY))
  186. tree->keycmp = hfsplus_cat_bin_cmp_key;
  187. else {
  188. tree->keycmp = hfsplus_cat_case_cmp_key;
  189. set_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
  190. }
  191. break;
  192. case HFSPLUS_ATTR_CNID:
  193. if (tree->max_key_len != HFSPLUS_ATTR_KEYLEN - sizeof(u16)) {
  194. pr_err("invalid attributes max_key_len %d\n",
  195. tree->max_key_len);
  196. goto fail_page;
  197. }
  198. tree->keycmp = hfsplus_attr_bin_cmp_key;
  199. break;
  200. default:
  201. pr_err("unknown B*Tree requested\n");
  202. goto fail_page;
  203. }
  204. if (!(tree->attributes & HFS_TREE_BIGKEYS)) {
  205. pr_err("invalid btree flag\n");
  206. goto fail_page;
  207. }
  208. size = tree->node_size;
  209. if (!is_power_of_2(size))
  210. goto fail_page;
  211. if (!tree->node_count)
  212. goto fail_page;
  213. tree->node_size_shift = ffs(size) - 1;
  214. tree->pages_per_bnode =
  215. (tree->node_size + PAGE_SIZE - 1) >>
  216. PAGE_SHIFT;
  217. kunmap(page);
  218. put_page(page);
  219. return tree;
  220. fail_page:
  221. put_page(page);
  222. free_inode:
  223. tree->inode->i_mapping->a_ops = &hfsplus_aops;
  224. iput(tree->inode);
  225. free_tree:
  226. kfree(tree);
  227. return NULL;
  228. }
  229. /* Release resources used by a btree */
  230. void hfs_btree_close(struct hfs_btree *tree)
  231. {
  232. struct hfs_bnode *node;
  233. int i;
  234. if (!tree)
  235. return;
  236. for (i = 0; i < NODE_HASH_SIZE; i++) {
  237. while ((node = tree->node_hash[i])) {
  238. tree->node_hash[i] = node->next_hash;
  239. if (atomic_read(&node->refcnt))
  240. pr_crit("node %d:%d "
  241. "still has %d user(s)!\n",
  242. node->tree->cnid, node->this,
  243. atomic_read(&node->refcnt));
  244. hfs_bnode_free(node);
  245. tree->node_hash_cnt--;
  246. }
  247. }
  248. iput(tree->inode);
  249. kfree(tree);
  250. }
  251. int hfs_btree_write(struct hfs_btree *tree)
  252. {
  253. struct hfs_btree_header_rec *head;
  254. struct hfs_bnode *node;
  255. struct page *page;
  256. node = hfs_bnode_find(tree, 0);
  257. if (IS_ERR(node))
  258. /* panic? */
  259. return -EIO;
  260. /* Load the header */
  261. page = node->page[0];
  262. head = (struct hfs_btree_header_rec *)(kmap(page) +
  263. sizeof(struct hfs_bnode_desc));
  264. head->root = cpu_to_be32(tree->root);
  265. head->leaf_count = cpu_to_be32(tree->leaf_count);
  266. head->leaf_head = cpu_to_be32(tree->leaf_head);
  267. head->leaf_tail = cpu_to_be32(tree->leaf_tail);
  268. head->node_count = cpu_to_be32(tree->node_count);
  269. head->free_nodes = cpu_to_be32(tree->free_nodes);
  270. head->attributes = cpu_to_be32(tree->attributes);
  271. head->depth = cpu_to_be16(tree->depth);
  272. kunmap(page);
  273. set_page_dirty(page);
  274. hfs_bnode_put(node);
  275. return 0;
  276. }
  277. static struct hfs_bnode *hfs_bmap_new_bmap(struct hfs_bnode *prev, u32 idx)
  278. {
  279. struct hfs_btree *tree = prev->tree;
  280. struct hfs_bnode *node;
  281. struct hfs_bnode_desc desc;
  282. __be32 cnid;
  283. node = hfs_bnode_create(tree, idx);
  284. if (IS_ERR(node))
  285. return node;
  286. tree->free_nodes--;
  287. prev->next = idx;
  288. cnid = cpu_to_be32(idx);
  289. hfs_bnode_write(prev, &cnid, offsetof(struct hfs_bnode_desc, next), 4);
  290. node->type = HFS_NODE_MAP;
  291. node->num_recs = 1;
  292. hfs_bnode_clear(node, 0, tree->node_size);
  293. desc.next = 0;
  294. desc.prev = 0;
  295. desc.type = HFS_NODE_MAP;
  296. desc.height = 0;
  297. desc.num_recs = cpu_to_be16(1);
  298. desc.reserved = 0;
  299. hfs_bnode_write(node, &desc, 0, sizeof(desc));
  300. hfs_bnode_write_u16(node, 14, 0x8000);
  301. hfs_bnode_write_u16(node, tree->node_size - 2, 14);
  302. hfs_bnode_write_u16(node, tree->node_size - 4, tree->node_size - 6);
  303. return node;
  304. }
  305. struct hfs_bnode *hfs_bmap_alloc(struct hfs_btree *tree)
  306. {
  307. struct hfs_bnode *node, *next_node;
  308. struct page **pagep;
  309. u32 nidx, idx;
  310. unsigned off;
  311. u16 off16;
  312. u16 len;
  313. u8 *data, byte, m;
  314. int i;
  315. while (!tree->free_nodes) {
  316. struct inode *inode = tree->inode;
  317. struct hfsplus_inode_info *hip = HFSPLUS_I(inode);
  318. u32 count;
  319. int res;
  320. res = hfsplus_file_extend(inode, hfs_bnode_need_zeroout(tree));
  321. if (res)
  322. return ERR_PTR(res);
  323. hip->phys_size = inode->i_size =
  324. (loff_t)hip->alloc_blocks <<
  325. HFSPLUS_SB(tree->sb)->alloc_blksz_shift;
  326. hip->fs_blocks =
  327. hip->alloc_blocks << HFSPLUS_SB(tree->sb)->fs_shift;
  328. inode_set_bytes(inode, inode->i_size);
  329. count = inode->i_size >> tree->node_size_shift;
  330. tree->free_nodes = count - tree->node_count;
  331. tree->node_count = count;
  332. }
  333. nidx = 0;
  334. node = hfs_bnode_find(tree, nidx);
  335. if (IS_ERR(node))
  336. return node;
  337. len = hfs_brec_lenoff(node, 2, &off16);
  338. off = off16;
  339. off += node->page_offset;
  340. pagep = node->page + (off >> PAGE_SHIFT);
  341. data = kmap(*pagep);
  342. off &= ~PAGE_MASK;
  343. idx = 0;
  344. for (;;) {
  345. while (len) {
  346. byte = data[off];
  347. if (byte != 0xff) {
  348. for (m = 0x80, i = 0; i < 8; m >>= 1, i++) {
  349. if (!(byte & m)) {
  350. idx += i;
  351. data[off] |= m;
  352. set_page_dirty(*pagep);
  353. kunmap(*pagep);
  354. tree->free_nodes--;
  355. mark_inode_dirty(tree->inode);
  356. hfs_bnode_put(node);
  357. return hfs_bnode_create(tree,
  358. idx);
  359. }
  360. }
  361. }
  362. if (++off >= PAGE_SIZE) {
  363. kunmap(*pagep);
  364. data = kmap(*++pagep);
  365. off = 0;
  366. }
  367. idx += 8;
  368. len--;
  369. }
  370. kunmap(*pagep);
  371. nidx = node->next;
  372. if (!nidx) {
  373. hfs_dbg(BNODE_MOD, "create new bmap node\n");
  374. next_node = hfs_bmap_new_bmap(node, idx);
  375. } else
  376. next_node = hfs_bnode_find(tree, nidx);
  377. hfs_bnode_put(node);
  378. if (IS_ERR(next_node))
  379. return next_node;
  380. node = next_node;
  381. len = hfs_brec_lenoff(node, 0, &off16);
  382. off = off16;
  383. off += node->page_offset;
  384. pagep = node->page + (off >> PAGE_SHIFT);
  385. data = kmap(*pagep);
  386. off &= ~PAGE_MASK;
  387. }
  388. }
  389. void hfs_bmap_free(struct hfs_bnode *node)
  390. {
  391. struct hfs_btree *tree;
  392. struct page *page;
  393. u16 off, len;
  394. u32 nidx;
  395. u8 *data, byte, m;
  396. hfs_dbg(BNODE_MOD, "btree_free_node: %u\n", node->this);
  397. BUG_ON(!node->this);
  398. tree = node->tree;
  399. nidx = node->this;
  400. node = hfs_bnode_find(tree, 0);
  401. if (IS_ERR(node))
  402. return;
  403. len = hfs_brec_lenoff(node, 2, &off);
  404. while (nidx >= len * 8) {
  405. u32 i;
  406. nidx -= len * 8;
  407. i = node->next;
  408. hfs_bnode_put(node);
  409. if (!i) {
  410. /* panic */;
  411. pr_crit("unable to free bnode %u. "
  412. "bmap not found!\n",
  413. node->this);
  414. return;
  415. }
  416. node = hfs_bnode_find(tree, i);
  417. if (IS_ERR(node))
  418. return;
  419. if (node->type != HFS_NODE_MAP) {
  420. /* panic */;
  421. pr_crit("invalid bmap found! "
  422. "(%u,%d)\n",
  423. node->this, node->type);
  424. hfs_bnode_put(node);
  425. return;
  426. }
  427. len = hfs_brec_lenoff(node, 0, &off);
  428. }
  429. off += node->page_offset + nidx / 8;
  430. page = node->page[off >> PAGE_SHIFT];
  431. data = kmap(page);
  432. off &= ~PAGE_MASK;
  433. m = 1 << (~nidx & 7);
  434. byte = data[off];
  435. if (!(byte & m)) {
  436. pr_crit("trying to free free bnode "
  437. "%u(%d)\n",
  438. node->this, node->type);
  439. kunmap(page);
  440. hfs_bnode_put(node);
  441. return;
  442. }
  443. data[off] = byte & ~m;
  444. set_page_dirty(page);
  445. kunmap(page);
  446. hfs_bnode_put(node);
  447. tree->free_nodes++;
  448. mark_inode_dirty(tree->inode);
  449. }