btree.c (c2b3e1f76e5c90215bc7f740b376c0220eb8a8e3) btree.c (d614267329f2bee7a082ed8781c581c0f3aaa808)
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

--- 26 unchanged lines hidden (view full) ---

35 tree->sb = sb;
36 tree->cnid = id;
37 inode = hfsplus_iget(sb, id);
38 if (IS_ERR(inode))
39 goto free_tree;
40 tree->inode = inode;
41
42 if (!HFSPLUS_I(tree->inode)->first_blocks) {
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

--- 26 unchanged lines hidden (view full) ---

35 tree->sb = sb;
36 tree->cnid = id;
37 inode = hfsplus_iget(sb, id);
38 if (IS_ERR(inode))
39 goto free_tree;
40 tree->inode = inode;
41
42 if (!HFSPLUS_I(tree->inode)->first_blocks) {
43 printk(KERN_ERR
44 "hfs: invalid btree extent records (0 size).\n");
43 pr_err("invalid btree extent records (0 size)\n");
45 goto free_inode;
46 }
47
48 mapping = tree->inode->i_mapping;
49 page = read_mapping_page(mapping, 0, NULL);
50 if (IS_ERR(page))
51 goto free_inode;
52

--- 10 unchanged lines hidden (view full) ---

63 tree->node_size = be16_to_cpu(head->node_size);
64 tree->max_key_len = be16_to_cpu(head->max_key_len);
65 tree->depth = be16_to_cpu(head->depth);
66
67 /* Verify the tree and set the correct compare function */
68 switch (id) {
69 case HFSPLUS_EXT_CNID:
70 if (tree->max_key_len != HFSPLUS_EXT_KEYLEN - sizeof(u16)) {
44 goto free_inode;
45 }
46
47 mapping = tree->inode->i_mapping;
48 page = read_mapping_page(mapping, 0, NULL);
49 if (IS_ERR(page))
50 goto free_inode;
51

--- 10 unchanged lines hidden (view full) ---

62 tree->node_size = be16_to_cpu(head->node_size);
63 tree->max_key_len = be16_to_cpu(head->max_key_len);
64 tree->depth = be16_to_cpu(head->depth);
65
66 /* Verify the tree and set the correct compare function */
67 switch (id) {
68 case HFSPLUS_EXT_CNID:
69 if (tree->max_key_len != HFSPLUS_EXT_KEYLEN - sizeof(u16)) {
71 printk(KERN_ERR "hfs: invalid extent max_key_len %d\n",
70 pr_err("invalid extent max_key_len %d\n",
72 tree->max_key_len);
73 goto fail_page;
74 }
75 if (tree->attributes & HFS_TREE_VARIDXKEYS) {
71 tree->max_key_len);
72 goto fail_page;
73 }
74 if (tree->attributes & HFS_TREE_VARIDXKEYS) {
76 printk(KERN_ERR "hfs: invalid extent btree flag\n");
75 pr_err("invalid extent btree flag\n");
77 goto fail_page;
78 }
79
80 tree->keycmp = hfsplus_ext_cmp_key;
81 break;
82 case HFSPLUS_CAT_CNID:
83 if (tree->max_key_len != HFSPLUS_CAT_KEYLEN - sizeof(u16)) {
76 goto fail_page;
77 }
78
79 tree->keycmp = hfsplus_ext_cmp_key;
80 break;
81 case HFSPLUS_CAT_CNID:
82 if (tree->max_key_len != HFSPLUS_CAT_KEYLEN - sizeof(u16)) {
84 printk(KERN_ERR "hfs: invalid catalog max_key_len %d\n",
83 pr_err("invalid catalog max_key_len %d\n",
85 tree->max_key_len);
86 goto fail_page;
87 }
88 if (!(tree->attributes & HFS_TREE_VARIDXKEYS)) {
84 tree->max_key_len);
85 goto fail_page;
86 }
87 if (!(tree->attributes & HFS_TREE_VARIDXKEYS)) {
89 printk(KERN_ERR "hfs: invalid catalog btree flag\n");
88 pr_err("invalid catalog btree flag\n");
90 goto fail_page;
91 }
92
93 if (test_bit(HFSPLUS_SB_HFSX, &HFSPLUS_SB(sb)->flags) &&
94 (head->key_type == HFSPLUS_KEY_BINARY))
95 tree->keycmp = hfsplus_cat_bin_cmp_key;
96 else {
97 tree->keycmp = hfsplus_cat_case_cmp_key;
98 set_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
99 }
100 break;
101 case HFSPLUS_ATTR_CNID:
102 if (tree->max_key_len != HFSPLUS_ATTR_KEYLEN - sizeof(u16)) {
89 goto fail_page;
90 }
91
92 if (test_bit(HFSPLUS_SB_HFSX, &HFSPLUS_SB(sb)->flags) &&
93 (head->key_type == HFSPLUS_KEY_BINARY))
94 tree->keycmp = hfsplus_cat_bin_cmp_key;
95 else {
96 tree->keycmp = hfsplus_cat_case_cmp_key;
97 set_bit(HFSPLUS_SB_CASEFOLD, &HFSPLUS_SB(sb)->flags);
98 }
99 break;
100 case HFSPLUS_ATTR_CNID:
101 if (tree->max_key_len != HFSPLUS_ATTR_KEYLEN - sizeof(u16)) {
103 printk(KERN_ERR "hfs: invalid attributes max_key_len %d\n",
102 pr_err("invalid attributes max_key_len %d\n",
104 tree->max_key_len);
105 goto fail_page;
106 }
107 tree->keycmp = hfsplus_attr_bin_cmp_key;
108 break;
109 default:
103 tree->max_key_len);
104 goto fail_page;
105 }
106 tree->keycmp = hfsplus_attr_bin_cmp_key;
107 break;
108 default:
110 printk(KERN_ERR "hfs: unknown B*Tree requested\n");
109 pr_err("unknown B*Tree requested\n");
111 goto fail_page;
112 }
113
114 if (!(tree->attributes & HFS_TREE_BIGKEYS)) {
110 goto fail_page;
111 }
112
113 if (!(tree->attributes & HFS_TREE_BIGKEYS)) {
115 printk(KERN_ERR "hfs: invalid btree flag\n");
114 pr_err("invalid btree flag\n");
116 goto fail_page;
117 }
118
119 size = tree->node_size;
120 if (!is_power_of_2(size))
121 goto fail_page;
122 if (!tree->node_count)
123 goto fail_page;

--- 26 unchanged lines hidden (view full) ---

150
151 if (!tree)
152 return;
153
154 for (i = 0; i < NODE_HASH_SIZE; i++) {
155 while ((node = tree->node_hash[i])) {
156 tree->node_hash[i] = node->next_hash;
157 if (atomic_read(&node->refcnt))
115 goto fail_page;
116 }
117
118 size = tree->node_size;
119 if (!is_power_of_2(size))
120 goto fail_page;
121 if (!tree->node_count)
122 goto fail_page;

--- 26 unchanged lines hidden (view full) ---

149
150 if (!tree)
151 return;
152
153 for (i = 0; i < NODE_HASH_SIZE; i++) {
154 while ((node = tree->node_hash[i])) {
155 tree->node_hash[i] = node->next_hash;
156 if (atomic_read(&node->refcnt))
158 printk(KERN_CRIT "hfs: node %d:%d "
157 pr_crit("node %d:%d "
159 "still has %d user(s)!\n",
160 node->tree->cnid, node->this,
161 atomic_read(&node->refcnt));
162 hfs_bnode_free(node);
163 tree->node_hash_cnt--;
164 }
165 }
166 iput(tree->inode);

--- 173 unchanged lines hidden (view full) ---

340 while (nidx >= len * 8) {
341 u32 i;
342
343 nidx -= len * 8;
344 i = node->next;
345 hfs_bnode_put(node);
346 if (!i) {
347 /* panic */;
158 "still has %d user(s)!\n",
159 node->tree->cnid, node->this,
160 atomic_read(&node->refcnt));
161 hfs_bnode_free(node);
162 tree->node_hash_cnt--;
163 }
164 }
165 iput(tree->inode);

--- 173 unchanged lines hidden (view full) ---

339 while (nidx >= len * 8) {
340 u32 i;
341
342 nidx -= len * 8;
343 i = node->next;
344 hfs_bnode_put(node);
345 if (!i) {
346 /* panic */;
348 printk(KERN_CRIT "hfs: unable to free bnode %u. "
347 pr_crit("unable to free bnode %u. "
349 "bmap not found!\n",
350 node->this);
351 return;
352 }
353 node = hfs_bnode_find(tree, i);
354 if (IS_ERR(node))
355 return;
356 if (node->type != HFS_NODE_MAP) {
357 /* panic */;
348 "bmap not found!\n",
349 node->this);
350 return;
351 }
352 node = hfs_bnode_find(tree, i);
353 if (IS_ERR(node))
354 return;
355 if (node->type != HFS_NODE_MAP) {
356 /* panic */;
358 printk(KERN_CRIT "hfs: invalid bmap found! "
357 pr_crit("invalid bmap found! "
359 "(%u,%d)\n",
360 node->this, node->type);
361 hfs_bnode_put(node);
362 return;
363 }
364 len = hfs_brec_lenoff(node, 0, &off);
365 }
366 off += node->page_offset + nidx / 8;
367 page = node->page[off >> PAGE_CACHE_SHIFT];
368 data = kmap(page);
369 off &= ~PAGE_CACHE_MASK;
370 m = 1 << (~nidx & 7);
371 byte = data[off];
372 if (!(byte & m)) {
358 "(%u,%d)\n",
359 node->this, node->type);
360 hfs_bnode_put(node);
361 return;
362 }
363 len = hfs_brec_lenoff(node, 0, &off);
364 }
365 off += node->page_offset + nidx / 8;
366 page = node->page[off >> PAGE_CACHE_SHIFT];
367 data = kmap(page);
368 off &= ~PAGE_CACHE_MASK;
369 m = 1 << (~nidx & 7);
370 byte = data[off];
371 if (!(byte & m)) {
373 printk(KERN_CRIT "hfs: trying to free free bnode "
372 pr_crit("trying to free free bnode "
374 "%u(%d)\n",
375 node->this, node->type);
376 kunmap(page);
377 hfs_bnode_put(node);
378 return;
379 }
380 data[off] = byte & ~m;
381 set_page_dirty(page);
382 kunmap(page);
383 hfs_bnode_put(node);
384 tree->free_nodes++;
385 mark_inode_dirty(tree->inode);
386}
373 "%u(%d)\n",
374 node->this, node->type);
375 kunmap(page);
376 hfs_bnode_put(node);
377 return;
378 }
379 data[off] = byte & ~m;
380 set_page_dirty(page);
381 kunmap(page);
382 hfs_bnode_put(node);
383 tree->free_nodes++;
384 mark_inode_dirty(tree->inode);
385}