2 * linux/fs/hfsplus/bnode.c
5 * Brad Boyer (flar@allandria.com)
6 * (C) 2003 Ardis Technologies <roman@ardistech.com>
8 * Handle basic btree node operations
11 #include <linux/string.h>
12 #include <linux/slab.h>
13 #include <linux/pagemap.h>
15 #include <linux/swap.h>
17 #include "hfsplus_fs.h"
18 #include "hfsplus_raw.h"
20 /* Copy a specified range of bytes from the raw data of a node */
21 void hfs_bnode_read(struct hfs_bnode
*node
, void *buf
, int off
, int len
)
26 off
+= node
->page_offset
;
27 pagep
= node
->page
+ (off
>> PAGE_CACHE_SHIFT
);
28 off
&= ~PAGE_CACHE_MASK
;
30 l
= min(len
, (int)PAGE_CACHE_SIZE
- off
);
31 memcpy(buf
, kmap(*pagep
) + off
, l
);
34 while ((len
-= l
) != 0) {
36 l
= min(len
, (int)PAGE_CACHE_SIZE
);
37 memcpy(buf
, kmap(*++pagep
), l
);
42 u16
hfs_bnode_read_u16(struct hfs_bnode
*node
, int off
)
46 hfs_bnode_read(node
, &data
, off
, 2);
47 return be16_to_cpu(data
);
50 u8
hfs_bnode_read_u8(struct hfs_bnode
*node
, int off
)
54 hfs_bnode_read(node
, &data
, off
, 1);
58 void hfs_bnode_read_key(struct hfs_bnode
*node
, void *key
, int off
)
60 struct hfs_btree
*tree
;
64 if (node
->type
== HFS_NODE_LEAF
||
65 tree
->attributes
& HFS_TREE_VARIDXKEYS
)
66 key_len
= hfs_bnode_read_u16(node
, off
) + 2;
68 key_len
= tree
->max_key_len
+ 2;
70 hfs_bnode_read(node
, key
, off
, key_len
);
73 void hfs_bnode_write(struct hfs_bnode
*node
, void *buf
, int off
, int len
)
78 off
+= node
->page_offset
;
79 pagep
= node
->page
+ (off
>> PAGE_CACHE_SHIFT
);
80 off
&= ~PAGE_CACHE_MASK
;
82 l
= min(len
, (int)PAGE_CACHE_SIZE
- off
);
83 memcpy(kmap(*pagep
) + off
, buf
, l
);
84 set_page_dirty(*pagep
);
87 while ((len
-= l
) != 0) {
89 l
= min(len
, (int)PAGE_CACHE_SIZE
);
90 memcpy(kmap(*++pagep
), buf
, l
);
91 set_page_dirty(*pagep
);
96 void hfs_bnode_write_u16(struct hfs_bnode
*node
, int off
, u16 data
)
98 __be16 v
= cpu_to_be16(data
);
100 hfs_bnode_write(node
, &v
, off
, 2);
103 void hfs_bnode_clear(struct hfs_bnode
*node
, int off
, int len
)
108 off
+= node
->page_offset
;
109 pagep
= node
->page
+ (off
>> PAGE_CACHE_SHIFT
);
110 off
&= ~PAGE_CACHE_MASK
;
112 l
= min(len
, (int)PAGE_CACHE_SIZE
- off
);
113 memset(kmap(*pagep
) + off
, 0, l
);
114 set_page_dirty(*pagep
);
117 while ((len
-= l
) != 0) {
118 l
= min(len
, (int)PAGE_CACHE_SIZE
);
119 memset(kmap(*++pagep
), 0, l
);
120 set_page_dirty(*pagep
);
125 void hfs_bnode_copy(struct hfs_bnode
*dst_node
, int dst
,
126 struct hfs_bnode
*src_node
, int src
, int len
)
128 struct hfs_btree
*tree
;
129 struct page
**src_page
, **dst_page
;
132 dprint(DBG_BNODE_MOD
, "copybytes: %u,%u,%u\n", dst
, src
, len
);
135 tree
= src_node
->tree
;
136 src
+= src_node
->page_offset
;
137 dst
+= dst_node
->page_offset
;
138 src_page
= src_node
->page
+ (src
>> PAGE_CACHE_SHIFT
);
139 src
&= ~PAGE_CACHE_MASK
;
140 dst_page
= dst_node
->page
+ (dst
>> PAGE_CACHE_SHIFT
);
141 dst
&= ~PAGE_CACHE_MASK
;
144 l
= min(len
, (int)PAGE_CACHE_SIZE
- src
);
145 memcpy(kmap(*dst_page
) + src
, kmap(*src_page
) + src
, l
);
147 set_page_dirty(*dst_page
);
150 while ((len
-= l
) != 0) {
151 l
= min(len
, (int)PAGE_CACHE_SIZE
);
152 memcpy(kmap(*++dst_page
), kmap(*++src_page
), l
);
154 set_page_dirty(*dst_page
);
158 void *src_ptr
, *dst_ptr
;
161 src_ptr
= kmap(*src_page
) + src
;
162 dst_ptr
= kmap(*dst_page
) + dst
;
163 if (PAGE_CACHE_SIZE
- src
< PAGE_CACHE_SIZE
- dst
) {
164 l
= PAGE_CACHE_SIZE
- src
;
168 l
= PAGE_CACHE_SIZE
- dst
;
173 memcpy(dst_ptr
, src_ptr
, l
);
175 set_page_dirty(*dst_page
);
181 } while ((len
-= l
));
185 void hfs_bnode_move(struct hfs_bnode
*node
, int dst
, int src
, int len
)
187 struct page
**src_page
, **dst_page
;
190 dprint(DBG_BNODE_MOD
, "movebytes: %u,%u,%u\n", dst
, src
, len
);
193 src
+= node
->page_offset
;
194 dst
+= node
->page_offset
;
197 src_page
= node
->page
+ (src
>> PAGE_CACHE_SHIFT
);
198 src
= (src
& ~PAGE_CACHE_MASK
) + 1;
200 dst_page
= node
->page
+ (dst
>> PAGE_CACHE_SHIFT
);
201 dst
= (dst
& ~PAGE_CACHE_MASK
) + 1;
205 memmove(kmap(*dst_page
), kmap(*src_page
), src
);
207 set_page_dirty(*dst_page
);
210 src
= PAGE_CACHE_SIZE
;
215 memmove(kmap(*dst_page
) + src
, kmap(*src_page
) + src
, len
);
217 set_page_dirty(*dst_page
);
220 void *src_ptr
, *dst_ptr
;
223 src_ptr
= kmap(*src_page
) + src
;
224 dst_ptr
= kmap(*dst_page
) + dst
;
227 src
= PAGE_CACHE_SIZE
;
232 dst
= PAGE_CACHE_SIZE
;
235 memmove(dst_ptr
- l
, src_ptr
- l
, l
);
237 set_page_dirty(*dst_page
);
239 if (dst
== PAGE_CACHE_SIZE
)
243 } while ((len
-= l
));
246 src_page
= node
->page
+ (src
>> PAGE_CACHE_SHIFT
);
247 src
&= ~PAGE_CACHE_MASK
;
248 dst_page
= node
->page
+ (dst
>> PAGE_CACHE_SHIFT
);
249 dst
&= ~PAGE_CACHE_MASK
;
252 l
= min(len
, (int)PAGE_CACHE_SIZE
- src
);
253 memmove(kmap(*dst_page
) + src
, kmap(*src_page
) + src
, l
);
255 set_page_dirty(*dst_page
);
258 while ((len
-= l
) != 0) {
259 l
= min(len
, (int)PAGE_CACHE_SIZE
);
260 memmove(kmap(*++dst_page
), kmap(*++src_page
), l
);
262 set_page_dirty(*dst_page
);
266 void *src_ptr
, *dst_ptr
;
269 src_ptr
= kmap(*src_page
) + src
;
270 dst_ptr
= kmap(*dst_page
) + dst
;
271 if (PAGE_CACHE_SIZE
- src
< PAGE_CACHE_SIZE
- dst
) {
272 l
= PAGE_CACHE_SIZE
- src
;
276 l
= PAGE_CACHE_SIZE
- dst
;
281 memmove(dst_ptr
, src_ptr
, l
);
283 set_page_dirty(*dst_page
);
289 } while ((len
-= l
));
294 void hfs_bnode_dump(struct hfs_bnode
*node
)
296 struct hfs_bnode_desc desc
;
300 dprint(DBG_BNODE_MOD
, "bnode: %d\n", node
->this);
301 hfs_bnode_read(node
, &desc
, 0, sizeof(desc
));
302 dprint(DBG_BNODE_MOD
, "%d, %d, %d, %d, %d\n",
303 be32_to_cpu(desc
.next
), be32_to_cpu(desc
.prev
),
304 desc
.type
, desc
.height
, be16_to_cpu(desc
.num_recs
));
306 off
= node
->tree
->node_size
- 2;
307 for (i
= be16_to_cpu(desc
.num_recs
); i
>= 0; off
-= 2, i
--) {
308 key_off
= hfs_bnode_read_u16(node
, off
);
309 dprint(DBG_BNODE_MOD
, " %d", key_off
);
310 if (i
&& node
->type
== HFS_NODE_INDEX
) {
313 if (node
->tree
->attributes
& HFS_TREE_VARIDXKEYS
)
314 tmp
= hfs_bnode_read_u16(node
, key_off
) + 2;
316 tmp
= node
->tree
->max_key_len
+ 2;
317 dprint(DBG_BNODE_MOD
, " (%d", tmp
);
318 hfs_bnode_read(node
, &cnid
, key_off
+ tmp
, 4);
319 dprint(DBG_BNODE_MOD
, ",%d)", be32_to_cpu(cnid
));
320 } else if (i
&& node
->type
== HFS_NODE_LEAF
) {
323 tmp
= hfs_bnode_read_u16(node
, key_off
);
324 dprint(DBG_BNODE_MOD
, " (%d)", tmp
);
327 dprint(DBG_BNODE_MOD
, "\n");
330 void hfs_bnode_unlink(struct hfs_bnode
*node
)
332 struct hfs_btree
*tree
;
333 struct hfs_bnode
*tmp
;
338 tmp
= hfs_bnode_find(tree
, node
->prev
);
341 tmp
->next
= node
->next
;
342 cnid
= cpu_to_be32(tmp
->next
);
343 hfs_bnode_write(tmp
, &cnid
, offsetof(struct hfs_bnode_desc
, next
), 4);
345 } else if (node
->type
== HFS_NODE_LEAF
)
346 tree
->leaf_head
= node
->next
;
349 tmp
= hfs_bnode_find(tree
, node
->next
);
352 tmp
->prev
= node
->prev
;
353 cnid
= cpu_to_be32(tmp
->prev
);
354 hfs_bnode_write(tmp
, &cnid
, offsetof(struct hfs_bnode_desc
, prev
), 4);
356 } else if (node
->type
== HFS_NODE_LEAF
)
357 tree
->leaf_tail
= node
->prev
;
360 if (!node
->prev
&& !node
->next
) {
361 printk(KERN_DEBUG
"hfs_btree_del_level\n");
367 set_bit(HFS_BNODE_DELETED
, &node
->flags
);
370 static inline int hfs_bnode_hash(u32 num
)
372 num
= (num
>> 16) + num
;
374 return num
& (NODE_HASH_SIZE
- 1);
377 struct hfs_bnode
*hfs_bnode_findhash(struct hfs_btree
*tree
, u32 cnid
)
379 struct hfs_bnode
*node
;
381 if (cnid
>= tree
->node_count
) {
382 printk(KERN_ERR
"hfs: request for non-existent node %d in B*Tree\n", cnid
);
386 for (node
= tree
->node_hash
[hfs_bnode_hash(cnid
)];
387 node
; node
= node
->next_hash
) {
388 if (node
->this == cnid
) {
395 static struct hfs_bnode
*__hfs_bnode_create(struct hfs_btree
*tree
, u32 cnid
)
397 struct super_block
*sb
;
398 struct hfs_bnode
*node
, *node2
;
399 struct address_space
*mapping
;
401 int size
, block
, i
, hash
;
404 if (cnid
>= tree
->node_count
) {
405 printk(KERN_ERR
"hfs: request for non-existent node %d in B*Tree\n", cnid
);
409 sb
= tree
->inode
->i_sb
;
410 size
= sizeof(struct hfs_bnode
) + tree
->pages_per_bnode
*
411 sizeof(struct page
*);
412 node
= kmalloc(size
, GFP_KERNEL
);
415 memset(node
, 0, size
);
418 set_bit(HFS_BNODE_NEW
, &node
->flags
);
419 atomic_set(&node
->refcnt
, 1);
420 dprint(DBG_BNODE_REFS
, "new_node(%d:%d): 1\n",
421 node
->tree
->cnid
, node
->this);
422 init_waitqueue_head(&node
->lock_wq
);
423 spin_lock(&tree
->hash_lock
);
424 node2
= hfs_bnode_findhash(tree
, cnid
);
426 hash
= hfs_bnode_hash(cnid
);
427 node
->next_hash
= tree
->node_hash
[hash
];
428 tree
->node_hash
[hash
] = node
;
429 tree
->node_hash_cnt
++;
431 spin_unlock(&tree
->hash_lock
);
433 wait_event(node2
->lock_wq
, !test_bit(HFS_BNODE_NEW
, &node2
->flags
));
436 spin_unlock(&tree
->hash_lock
);
438 mapping
= tree
->inode
->i_mapping
;
439 off
= (loff_t
)cnid
<< tree
->node_size_shift
;
440 block
= off
>> PAGE_CACHE_SHIFT
;
441 node
->page_offset
= off
& ~PAGE_CACHE_MASK
;
442 for (i
= 0; i
< tree
->pages_per_bnode
; block
++, i
++) {
443 page
= read_cache_page(mapping
, block
, (filler_t
*)mapping
->a_ops
->readpage
, NULL
);
446 if (PageError(page
)) {
447 page_cache_release(page
);
450 page_cache_release(page
);
451 node
->page
[i
] = page
;
456 set_bit(HFS_BNODE_ERROR
, &node
->flags
);
460 void hfs_bnode_unhash(struct hfs_bnode
*node
)
462 struct hfs_bnode
**p
;
464 dprint(DBG_BNODE_REFS
, "remove_node(%d:%d): %d\n",
465 node
->tree
->cnid
, node
->this, atomic_read(&node
->refcnt
));
466 for (p
= &node
->tree
->node_hash
[hfs_bnode_hash(node
->this)];
467 *p
&& *p
!= node
; p
= &(*p
)->next_hash
)
471 *p
= node
->next_hash
;
472 node
->tree
->node_hash_cnt
--;
475 /* Load a particular node out of a tree */
476 struct hfs_bnode
*hfs_bnode_find(struct hfs_btree
*tree
, u32 num
)
478 struct hfs_bnode
*node
;
479 struct hfs_bnode_desc
*desc
;
480 int i
, rec_off
, off
, next_off
;
481 int entry_size
, key_size
;
483 spin_lock(&tree
->hash_lock
);
484 node
= hfs_bnode_findhash(tree
, num
);
487 spin_unlock(&tree
->hash_lock
);
488 wait_event(node
->lock_wq
, !test_bit(HFS_BNODE_NEW
, &node
->flags
));
489 if (test_bit(HFS_BNODE_ERROR
, &node
->flags
))
493 spin_unlock(&tree
->hash_lock
);
494 node
= __hfs_bnode_create(tree
, num
);
496 return ERR_PTR(-ENOMEM
);
497 if (test_bit(HFS_BNODE_ERROR
, &node
->flags
))
499 if (!test_bit(HFS_BNODE_NEW
, &node
->flags
))
502 desc
= (struct hfs_bnode_desc
*)(kmap(node
->page
[0]) + node
->page_offset
);
503 node
->prev
= be32_to_cpu(desc
->prev
);
504 node
->next
= be32_to_cpu(desc
->next
);
505 node
->num_recs
= be16_to_cpu(desc
->num_recs
);
506 node
->type
= desc
->type
;
507 node
->height
= desc
->height
;
508 kunmap(node
->page
[0]);
510 switch (node
->type
) {
511 case HFS_NODE_HEADER
:
513 if (node
->height
!= 0)
517 if (node
->height
!= 1)
521 if (node
->height
<= 1 || node
->height
> tree
->depth
)
528 rec_off
= tree
->node_size
- 2;
529 off
= hfs_bnode_read_u16(node
, rec_off
);
530 if (off
!= sizeof(struct hfs_bnode_desc
))
532 for (i
= 1; i
<= node
->num_recs
; off
= next_off
, i
++) {
534 next_off
= hfs_bnode_read_u16(node
, rec_off
);
535 if (next_off
<= off
||
536 next_off
> tree
->node_size
||
539 entry_size
= next_off
- off
;
540 if (node
->type
!= HFS_NODE_INDEX
&&
541 node
->type
!= HFS_NODE_LEAF
)
543 key_size
= hfs_bnode_read_u16(node
, off
) + 2;
544 if (key_size
>= entry_size
|| key_size
& 1)
547 clear_bit(HFS_BNODE_NEW
, &node
->flags
);
548 wake_up(&node
->lock_wq
);
552 set_bit(HFS_BNODE_ERROR
, &node
->flags
);
553 clear_bit(HFS_BNODE_NEW
, &node
->flags
);
554 wake_up(&node
->lock_wq
);
556 return ERR_PTR(-EIO
);
559 void hfs_bnode_free(struct hfs_bnode
*node
)
563 //for (i = 0; i < node->tree->pages_per_bnode; i++)
564 // if (node->page[i])
565 // page_cache_release(node->page[i]);
569 struct hfs_bnode
*hfs_bnode_create(struct hfs_btree
*tree
, u32 num
)
571 struct hfs_bnode
*node
;
575 spin_lock(&tree
->hash_lock
);
576 node
= hfs_bnode_findhash(tree
, num
);
577 spin_unlock(&tree
->hash_lock
);
579 printk(KERN_CRIT
"new node %u already hashed?\n", num
);
583 node
= __hfs_bnode_create(tree
, num
);
585 return ERR_PTR(-ENOMEM
);
586 if (test_bit(HFS_BNODE_ERROR
, &node
->flags
)) {
588 return ERR_PTR(-EIO
);
592 memset(kmap(*pagep
) + node
->page_offset
, 0,
593 min((int)PAGE_CACHE_SIZE
, (int)tree
->node_size
));
594 set_page_dirty(*pagep
);
596 for (i
= 1; i
< tree
->pages_per_bnode
; i
++) {
597 memset(kmap(*++pagep
), 0, PAGE_CACHE_SIZE
);
598 set_page_dirty(*pagep
);
601 clear_bit(HFS_BNODE_NEW
, &node
->flags
);
602 wake_up(&node
->lock_wq
);
607 void hfs_bnode_get(struct hfs_bnode
*node
)
610 atomic_inc(&node
->refcnt
);
611 dprint(DBG_BNODE_REFS
, "get_node(%d:%d): %d\n",
612 node
->tree
->cnid
, node
->this, atomic_read(&node
->refcnt
));
616 /* Dispose of resources used by a node */
617 void hfs_bnode_put(struct hfs_bnode
*node
)
620 struct hfs_btree
*tree
= node
->tree
;
623 dprint(DBG_BNODE_REFS
, "put_node(%d:%d): %d\n",
624 node
->tree
->cnid
, node
->this, atomic_read(&node
->refcnt
));
625 if (!atomic_read(&node
->refcnt
))
627 if (!atomic_dec_and_lock(&node
->refcnt
, &tree
->hash_lock
))
629 for (i
= 0; i
< tree
->pages_per_bnode
; i
++) {
632 mark_page_accessed(node
->page
[i
]);
635 if (test_bit(HFS_BNODE_DELETED
, &node
->flags
)) {
636 hfs_bnode_unhash(node
);
637 spin_unlock(&tree
->hash_lock
);
639 hfs_bnode_free(node
);
642 spin_unlock(&tree
->hash_lock
);