2 * linux/fs/hpfs/dnode.c
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
6 * handling directory dnode tree - adding, deleteing & searching for dirents
11 static loff_t
get_pos(struct dnode
*d
, struct hpfs_dirent
*fde
)
13 struct hpfs_dirent
*de
;
14 struct hpfs_dirent
*de_end
= dnode_end_de(d
);
16 for (de
= dnode_first_de(d
); de
< de_end
; de
= de_next_de(de
)) {
17 if (de
== fde
) return ((loff_t
) d
->self
<< 4) | (loff_t
)i
;
20 printk("HPFS: get_pos: not_found\n");
21 return ((loff_t
)d
->self
<< 4) | (loff_t
)1;
24 void hpfs_add_pos(struct inode
*inode
, loff_t
*pos
)
26 struct hpfs_inode_info
*hpfs_inode
= hpfs_i(inode
);
30 if (hpfs_inode
->i_rddir_off
)
31 for (; hpfs_inode
->i_rddir_off
[i
]; i
++)
32 if (hpfs_inode
->i_rddir_off
[i
] == pos
) return;
34 if (!(ppos
= kmalloc((i
+0x11) * sizeof(loff_t
*), GFP_NOFS
))) {
35 printk("HPFS: out of memory for position list\n");
38 if (hpfs_inode
->i_rddir_off
) {
39 memcpy(ppos
, hpfs_inode
->i_rddir_off
, i
* sizeof(loff_t
));
40 kfree(hpfs_inode
->i_rddir_off
);
42 hpfs_inode
->i_rddir_off
= ppos
;
44 hpfs_inode
->i_rddir_off
[i
] = pos
;
45 hpfs_inode
->i_rddir_off
[i
+ 1] = NULL
;
48 void hpfs_del_pos(struct inode
*inode
, loff_t
*pos
)
50 struct hpfs_inode_info
*hpfs_inode
= hpfs_i(inode
);
53 if (!hpfs_inode
->i_rddir_off
) goto not_f
;
54 for (i
= hpfs_inode
->i_rddir_off
; *i
; i
++) if (*i
== pos
) goto fnd
;
57 for (j
= i
+ 1; *j
; j
++) ;
60 if (j
- 1 == hpfs_inode
->i_rddir_off
) {
61 kfree(hpfs_inode
->i_rddir_off
);
62 hpfs_inode
->i_rddir_off
= NULL
;
66 /*printk("HPFS: warning: position pointer %p->%08x not found\n", pos, (int)*pos);*/
70 static void for_all_poss(struct inode
*inode
, void (*f
)(loff_t
*, loff_t
, loff_t
),
73 struct hpfs_inode_info
*hpfs_inode
= hpfs_i(inode
);
76 if (!hpfs_inode
->i_rddir_off
) return;
77 for (i
= hpfs_inode
->i_rddir_off
; *i
; i
++) (*f
)(*i
, p1
, p2
);
81 static void hpfs_pos_subst(loff_t
*p
, loff_t f
, loff_t t
)
86 /*void hpfs_hpfs_pos_substd(loff_t *p, loff_t f, loff_t t)
88 if ((*p & ~0x3f) == (f & ~0x3f)) *p = (t & ~0x3f) | (*p & 0x3f);
91 static void hpfs_pos_ins(loff_t
*p
, loff_t d
, loff_t c
)
93 if ((*p
& ~0x3f) == (d
& ~0x3f) && (*p
& 0x3f) >= (d
& 0x3f)) {
94 int n
= (*p
& 0x3f) + c
;
95 if (n
> 0x3f) printk("HPFS: hpfs_pos_ins: %08x + %d\n", (int)*p
, (int)c
>> 8);
96 else *p
= (*p
& ~0x3f) | n
;
100 static void hpfs_pos_del(loff_t
*p
, loff_t d
, loff_t c
)
102 if ((*p
& ~0x3f) == (d
& ~0x3f) && (*p
& 0x3f) >= (d
& 0x3f)) {
103 int n
= (*p
& 0x3f) - c
;
104 if (n
< 1) printk("HPFS: hpfs_pos_ins: %08x - %d\n", (int)*p
, (int)c
>> 8);
105 else *p
= (*p
& ~0x3f) | n
;
109 static struct hpfs_dirent
*dnode_pre_last_de(struct dnode
*d
)
111 struct hpfs_dirent
*de
, *de_end
, *dee
= NULL
, *deee
= NULL
;
112 de_end
= dnode_end_de(d
);
113 for (de
= dnode_first_de(d
); de
< de_end
; de
= de_next_de(de
)) {
114 deee
= dee
; dee
= de
;
119 static struct hpfs_dirent
*dnode_last_de(struct dnode
*d
)
121 struct hpfs_dirent
*de
, *de_end
, *dee
= NULL
;
122 de_end
= dnode_end_de(d
);
123 for (de
= dnode_first_de(d
); de
< de_end
; de
= de_next_de(de
)) {
129 static void set_last_pointer(struct super_block
*s
, struct dnode
*d
, dnode_secno ptr
)
131 struct hpfs_dirent
*de
;
132 if (!(de
= dnode_last_de(d
))) {
133 hpfs_error(s
, "set_last_pointer: empty dnode %08x", d
->self
);
136 if (hpfs_sb(s
)->sb_chk
) {
138 hpfs_error(s
, "set_last_pointer: dnode %08x has already last pointer %08x",
139 d
->self
, de_down_pointer(de
));
142 if (de
->length
!= 32) {
143 hpfs_error(s
, "set_last_pointer: bad last dirent in dnode %08x", d
->self
);
148 if ((d
->first_free
+= 4) > 2048) {
149 hpfs_error(s
,"set_last_pointer: too long dnode %08x", d
->self
);
155 *(dnode_secno
*)((char *)de
+ 32) = ptr
;
159 /* Add an entry to dnode and don't care if it grows over 2048 bytes */
161 struct hpfs_dirent
*hpfs_add_de(struct super_block
*s
, struct dnode
*d
,
162 const unsigned char *name
,
163 unsigned namelen
, secno down_ptr
)
165 struct hpfs_dirent
*de
;
166 struct hpfs_dirent
*de_end
= dnode_end_de(d
);
167 unsigned d_size
= de_size(namelen
, down_ptr
);
168 for (de
= dnode_first_de(d
); de
< de_end
; de
= de_next_de(de
)) {
169 int c
= hpfs_compare_names(s
, name
, namelen
, de
->name
, de
->namelen
, de
->last
);
171 hpfs_error(s
, "name (%c,%d) already exists in dnode %08x", *name
, namelen
, d
->self
);
176 memmove((char *)de
+ d_size
, de
, (char *)de_end
- (char *)de
);
177 memset(de
, 0, d_size
);
179 *(int *)((char *)de
+ d_size
- 4) = down_ptr
;
183 if (down_ptr
) de
->down
= 1;
184 de
->not_8x3
= hpfs_is_name_long(name
, namelen
);
185 de
->namelen
= namelen
;
186 memcpy(de
->name
, name
, namelen
);
187 d
->first_free
+= d_size
;
191 /* Delete dirent and don't care about its subtree */
193 static void hpfs_delete_de(struct super_block
*s
, struct dnode
*d
,
194 struct hpfs_dirent
*de
)
197 hpfs_error(s
, "attempt to delete last dirent in dnode %08x", d
->self
);
200 d
->first_free
-= de
->length
;
201 memmove(de
, de_next_de(de
), d
->first_free
+ (char *)d
- (char *)de
);
204 static void fix_up_ptrs(struct super_block
*s
, struct dnode
*d
)
206 struct hpfs_dirent
*de
;
207 struct hpfs_dirent
*de_end
= dnode_end_de(d
);
208 dnode_secno dno
= d
->self
;
209 for (de
= dnode_first_de(d
); de
< de_end
; de
= de_next_de(de
))
211 struct quad_buffer_head qbh
;
213 if ((dd
= hpfs_map_dnode(s
, de_down_pointer(de
), &qbh
))) {
214 if (dd
->up
!= dno
|| dd
->root_dnode
) {
217 hpfs_mark_4buffers_dirty(&qbh
);
224 /* Add an entry to dnode and do dnode splitting if required */
226 static int hpfs_add_to_dnode(struct inode
*i
, dnode_secno dno
,
227 const unsigned char *name
, unsigned namelen
,
228 struct hpfs_dirent
*new_de
, dnode_secno down_ptr
)
230 struct quad_buffer_head qbh
, qbh1
, qbh2
;
231 struct dnode
*d
, *ad
, *rd
, *nd
= NULL
;
232 dnode_secno adno
, rdno
;
233 struct hpfs_dirent
*de
;
234 struct hpfs_dirent nde
;
235 unsigned char *nname
;
238 struct buffer_head
*bh
;
241 if (!(nname
= kmalloc(256, GFP_NOFS
))) {
242 printk("HPFS: out of memory, can't add to dnode\n");
246 if (namelen
>= 256) {
247 hpfs_error(i
->i_sb
, "hpfs_add_to_dnode: namelen == %d", namelen
);
252 if (!(d
= hpfs_map_dnode(i
->i_sb
, dno
, &qbh
))) {
258 if (hpfs_sb(i
->i_sb
)->sb_chk
)
259 if (hpfs_stop_cycles(i
->i_sb
, dno
, &c1
, &c2
, "hpfs_add_to_dnode")) {
265 if (d
->first_free
+ de_size(namelen
, down_ptr
) <= 2048) {
267 copy_de(de
=hpfs_add_de(i
->i_sb
, d
, name
, namelen
, down_ptr
), new_de
);
269 for_all_poss(i
, hpfs_pos_ins
, t
, 1);
270 for_all_poss(i
, hpfs_pos_subst
, 4, t
);
271 for_all_poss(i
, hpfs_pos_subst
, 5, t
+ 1);
272 hpfs_mark_4buffers_dirty(&qbh
);
278 if (!nd
) if (!(nd
= kmalloc(0x924, GFP_NOFS
))) {
279 /* 0x924 is a max size of dnode after adding a dirent with
280 max name length. We alloc this only once. There must
281 not be any error while splitting dnodes, otherwise the
282 whole directory, not only file we're adding, would
284 printk("HPFS: out of memory for dnode splitting\n");
289 memcpy(nd
, d
, d
->first_free
);
290 copy_de(de
= hpfs_add_de(i
->i_sb
, nd
, name
, namelen
, down_ptr
), new_de
);
291 for_all_poss(i
, hpfs_pos_ins
, get_pos(nd
, de
), 1);
292 h
= ((char *)dnode_last_de(nd
) - (char *)nd
) / 2 + 10;
293 if (!(ad
= hpfs_alloc_dnode(i
->i_sb
, d
->up
, &adno
, &qbh1
, 0))) {
294 hpfs_error(i
->i_sb
, "unable to alloc dnode - dnode tree will be corrupted");
303 for (de
= dnode_first_de(nd
); (char *)de_next_de(de
) - (char *)nd
< h
; de
= de_next_de(de
)) {
304 copy_de(hpfs_add_de(i
->i_sb
, ad
, de
->name
, de
->namelen
, de
->down
? de_down_pointer(de
) : 0), de
);
305 for_all_poss(i
, hpfs_pos_subst
, ((loff_t
)dno
<< 4) | pos
, ((loff_t
)adno
<< 4) | pos
);
308 copy_de(new_de
= &nde
, de
);
309 memcpy(nname
, de
->name
, de
->namelen
);
311 namelen
= de
->namelen
;
312 for_all_poss(i
, hpfs_pos_subst
, ((loff_t
)dno
<< 4) | pos
, 4);
314 set_last_pointer(i
->i_sb
, ad
, de
->down
? de_down_pointer(de
) : 0);
316 memmove((char *)nd
+ 20, de
, nd
->first_free
+ (char *)nd
- (char *)de
);
317 nd
->first_free
-= (char *)de
- (char *)nd
- 20;
318 memcpy(d
, nd
, nd
->first_free
);
319 for_all_poss(i
, hpfs_pos_del
, (loff_t
)dno
<< 4, pos
);
320 fix_up_ptrs(i
->i_sb
, ad
);
321 if (!d
->root_dnode
) {
322 dno
= ad
->up
= d
->up
;
323 hpfs_mark_4buffers_dirty(&qbh
);
325 hpfs_mark_4buffers_dirty(&qbh1
);
329 if (!(rd
= hpfs_alloc_dnode(i
->i_sb
, d
->up
, &rdno
, &qbh2
, 0))) {
330 hpfs_error(i
->i_sb
, "unable to alloc dnode - dnode tree will be corrupted");
341 if (!(fnode
= hpfs_map_fnode(i
->i_sb
, d
->up
, &bh
))) {
342 hpfs_free_dnode(i
->i_sb
, rdno
);
350 fnode
->u
.external
[0].disk_secno
= rdno
;
351 mark_buffer_dirty(bh
);
353 d
->up
= ad
->up
= hpfs_i(i
)->i_dno
= rdno
;
354 d
->root_dnode
= ad
->root_dnode
= 0;
355 hpfs_mark_4buffers_dirty(&qbh
);
357 hpfs_mark_4buffers_dirty(&qbh1
);
360 set_last_pointer(i
->i_sb
, rd
, dno
);
367 * Add an entry to directory btree.
368 * I hate such crazy directory structure.
369 * It's easy to read but terrible to write.
370 * I wrote this directory code 4 times.
371 * I hope, now it's finally bug-free.
374 int hpfs_add_dirent(struct inode
*i
,
375 const unsigned char *name
, unsigned namelen
,
376 struct hpfs_dirent
*new_de
, int cdepth
)
378 struct hpfs_inode_info
*hpfs_inode
= hpfs_i(i
);
380 struct hpfs_dirent
*de
, *de_end
;
381 struct quad_buffer_head qbh
;
385 dno
= hpfs_inode
->i_dno
;
387 if (hpfs_sb(i
->i_sb
)->sb_chk
)
388 if (hpfs_stop_cycles(i
->i_sb
, dno
, &c1
, &c2
, "hpfs_add_dirent")) return 1;
389 if (!(d
= hpfs_map_dnode(i
->i_sb
, dno
, &qbh
))) return 1;
390 de_end
= dnode_end_de(d
);
391 for (de
= dnode_first_de(d
); de
< de_end
; de
= de_next_de(de
)) {
392 if (!(c
= hpfs_compare_names(i
->i_sb
, name
, namelen
, de
->name
, de
->namelen
, de
->last
))) {
398 dno
= de_down_pointer(de
);
406 if (!cdepth
) hpfs_lock_creation(i
->i_sb
);
407 if (hpfs_check_free_dnodes(i
->i_sb
, FREE_DNODES_ADD
)) {
412 c
= hpfs_add_to_dnode(i
, dno
, name
, namelen
, new_de
, 0);
414 if (!cdepth
) hpfs_unlock_creation(i
->i_sb
);
419 * Find dirent with higher name in 'from' subtree and move it to 'to' dnode.
420 * Return the dnode we moved from (to be checked later if it's empty)
423 static secno
move_to_top(struct inode
*i
, dnode_secno from
, dnode_secno to
)
425 dnode_secno dno
, ddno
;
426 dnode_secno chk_up
= to
;
428 struct quad_buffer_head qbh
;
429 struct hpfs_dirent
*de
, *nde
;
435 if (hpfs_sb(i
->i_sb
)->sb_chk
)
436 if (hpfs_stop_cycles(i
->i_sb
, dno
, &c1
, &c2
, "move_to_top"))
438 if (!(dnode
= hpfs_map_dnode(i
->i_sb
, dno
, &qbh
))) return 0;
439 if (hpfs_sb(i
->i_sb
)->sb_chk
) {
440 if (dnode
->up
!= chk_up
) {
441 hpfs_error(i
->i_sb
, "move_to_top: up pointer from %08x should be %08x, is %08x",
442 dno
, chk_up
, dnode
->up
);
448 if (!(de
= dnode_last_de(dnode
))) {
449 hpfs_error(i
->i_sb
, "move_to_top: dnode %08x has no last de", dno
);
453 if (!de
->down
) break;
454 dno
= de_down_pointer(de
);
457 while (!(de
= dnode_pre_last_de(dnode
))) {
458 dnode_secno up
= dnode
->up
;
460 hpfs_free_dnode(i
->i_sb
, dno
);
463 for_all_poss(i
, hpfs_pos_subst
, ((loff_t
)dno
<< 4) | 1, 5);
464 if (up
== to
) return to
;
465 if (!(dnode
= hpfs_map_dnode(i
->i_sb
, up
, &qbh
))) return 0;
466 if (dnode
->root_dnode
) {
467 hpfs_error(i
->i_sb
, "move_to_top: got to root_dnode while moving from %08x to %08x", from
, to
);
471 de
= dnode_last_de(dnode
);
472 if (!de
|| !de
->down
) {
473 hpfs_error(i
->i_sb
, "move_to_top: dnode %08x doesn't point down to %08x", up
, dno
);
477 dnode
->first_free
-= 4;
480 hpfs_mark_4buffers_dirty(&qbh
);
483 t
= get_pos(dnode
, de
);
484 for_all_poss(i
, hpfs_pos_subst
, t
, 4);
485 for_all_poss(i
, hpfs_pos_subst
, t
+ 1, 5);
486 if (!(nde
= kmalloc(de
->length
, GFP_NOFS
))) {
487 hpfs_error(i
->i_sb
, "out of memory for dirent - directory will be corrupted");
491 memcpy(nde
, de
, de
->length
);
492 ddno
= de
->down
? de_down_pointer(de
) : 0;
493 hpfs_delete_de(i
->i_sb
, dnode
, de
);
494 set_last_pointer(i
->i_sb
, dnode
, ddno
);
495 hpfs_mark_4buffers_dirty(&qbh
);
497 a
= hpfs_add_to_dnode(i
, to
, nde
->name
, nde
->namelen
, nde
, from
);
504 * Check if a dnode is empty and delete it from the tree
505 * (chkdsk doesn't like empty dnodes)
508 static void delete_empty_dnode(struct inode
*i
, dnode_secno dno
)
510 struct hpfs_inode_info
*hpfs_inode
= hpfs_i(i
);
511 struct quad_buffer_head qbh
;
513 dnode_secno down
, up
, ndown
;
515 struct hpfs_dirent
*de
;
518 if (hpfs_stop_cycles(i
->i_sb
, dno
, &c1
, &c2
, "delete_empty_dnode")) return;
519 if (!(dnode
= hpfs_map_dnode(i
->i_sb
, dno
, &qbh
))) return;
520 if (dnode
->first_free
> 56) goto end
;
521 if (dnode
->first_free
== 52 || dnode
->first_free
== 56) {
522 struct hpfs_dirent
*de_end
;
523 int root
= dnode
->root_dnode
;
525 de
= dnode_first_de(dnode
);
526 down
= de
->down
? de_down_pointer(de
) : 0;
527 if (hpfs_sb(i
->i_sb
)->sb_chk
) if (root
&& !down
) {
528 hpfs_error(i
->i_sb
, "delete_empty_dnode: root dnode %08x is empty", dno
);
532 hpfs_free_dnode(i
->i_sb
, dno
);
537 struct buffer_head
*bh
;
539 struct quad_buffer_head qbh1
;
540 if (hpfs_sb(i
->i_sb
)->sb_chk
)
541 if (up
!= i
->i_ino
) {
543 "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08lx",
544 dno
, up
, (unsigned long)i
->i_ino
);
547 if ((d1
= hpfs_map_dnode(i
->i_sb
, down
, &qbh1
))) {
550 hpfs_mark_4buffers_dirty(&qbh1
);
553 if ((fnode
= hpfs_map_fnode(i
->i_sb
, up
, &bh
))) {
554 fnode
->u
.external
[0].disk_secno
= down
;
555 mark_buffer_dirty(bh
);
558 hpfs_inode
->i_dno
= down
;
559 for_all_poss(i
, hpfs_pos_subst
, ((loff_t
)dno
<< 4) | 1, (loff_t
) 12);
562 if (!(dnode
= hpfs_map_dnode(i
->i_sb
, up
, &qbh
))) return;
564 de_end
= dnode_end_de(dnode
);
565 for (de
= dnode_first_de(dnode
); de
< de_end
; de
= de_next_de(de
), p
++)
566 if (de
->down
) if (de_down_pointer(de
) == dno
) goto fnd
;
567 hpfs_error(i
->i_sb
, "delete_empty_dnode: pointer to dnode %08x not found in dnode %08x", dno
, up
);
570 for_all_poss(i
, hpfs_pos_subst
, ((loff_t
)dno
<< 4) | 1, ((loff_t
)up
<< 4) | p
);
574 dnode
->first_free
-= 4;
575 memmove(de_next_de(de
), (char *)de_next_de(de
) + 4,
576 (char *)dnode
+ dnode
->first_free
- (char *)de_next_de(de
));
579 struct quad_buffer_head qbh1
;
580 *(dnode_secno
*) ((void *) de
+ de
->length
- 4) = down
;
581 if ((d1
= hpfs_map_dnode(i
->i_sb
, down
, &qbh1
))) {
583 hpfs_mark_4buffers_dirty(&qbh1
);
588 hpfs_error(i
->i_sb
, "delete_empty_dnode: dnode %08x, first_free == %03x", dno
, dnode
->first_free
);
593 struct hpfs_dirent
*de_next
= de_next_de(de
);
594 struct hpfs_dirent
*de_cp
;
596 struct quad_buffer_head qbh1
;
597 if (!de_next
->down
) goto endm
;
598 ndown
= de_down_pointer(de_next
);
599 if (!(de_cp
= kmalloc(de
->length
, GFP_NOFS
))) {
600 printk("HPFS: out of memory for dtree balancing\n");
603 memcpy(de_cp
, de
, de
->length
);
604 hpfs_delete_de(i
->i_sb
, dnode
, de
);
605 hpfs_mark_4buffers_dirty(&qbh
);
607 for_all_poss(i
, hpfs_pos_subst
, ((loff_t
)up
<< 4) | p
, 4);
608 for_all_poss(i
, hpfs_pos_del
, ((loff_t
)up
<< 4) | p
, 1);
609 if (de_cp
->down
) if ((d1
= hpfs_map_dnode(i
->i_sb
, de_down_pointer(de_cp
), &qbh1
))) {
611 hpfs_mark_4buffers_dirty(&qbh1
);
614 hpfs_add_to_dnode(i
, ndown
, de_cp
->name
, de_cp
->namelen
, de_cp
, de_cp
->down
? de_down_pointer(de_cp
) : 0);
615 /*printk("UP-TO-DNODE: %08x (ndown = %08x, down = %08x, dno = %08x)\n", up, ndown, down, dno);*/
620 struct hpfs_dirent
*de_prev
= dnode_pre_last_de(dnode
);
621 struct hpfs_dirent
*de_cp
;
623 struct quad_buffer_head qbh1
;
626 hpfs_error(i
->i_sb
, "delete_empty_dnode: empty dnode %08x", up
);
627 hpfs_mark_4buffers_dirty(&qbh
);
632 if (!de_prev
->down
) goto endm
;
633 ndown
= de_down_pointer(de_prev
);
634 if ((d1
= hpfs_map_dnode(i
->i_sb
, ndown
, &qbh1
))) {
635 struct hpfs_dirent
*del
= dnode_last_de(d1
);
636 dlp
= del
->down
? de_down_pointer(del
) : 0;
638 if (d1
->first_free
> 2044) {
639 if (hpfs_sb(i
->i_sb
)->sb_chk
>= 2) {
640 printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
641 printk("HPFS: warning: terminating balancing operation\n");
646 if (hpfs_sb(i
->i_sb
)->sb_chk
>= 2) {
647 printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
648 printk("HPFS: warning: goin'on\n");
659 *(dnode_secno
*) ((void *) del
+ del
->length
- 4) = down
;
661 if (!(de_cp
= kmalloc(de_prev
->length
, GFP_NOFS
))) {
662 printk("HPFS: out of memory for dtree balancing\n");
666 hpfs_mark_4buffers_dirty(&qbh1
);
668 memcpy(de_cp
, de_prev
, de_prev
->length
);
669 hpfs_delete_de(i
->i_sb
, dnode
, de_prev
);
670 if (!de_prev
->down
) {
671 de_prev
->length
+= 4;
673 dnode
->first_free
+= 4;
675 *(dnode_secno
*) ((void *) de_prev
+ de_prev
->length
- 4) = ndown
;
676 hpfs_mark_4buffers_dirty(&qbh
);
678 for_all_poss(i
, hpfs_pos_subst
, ((loff_t
)up
<< 4) | (p
- 1), 4);
679 for_all_poss(i
, hpfs_pos_subst
, ((loff_t
)up
<< 4) | p
, ((loff_t
)up
<< 4) | (p
- 1));
680 if (down
) if ((d1
= hpfs_map_dnode(i
->i_sb
, de_down_pointer(de
), &qbh1
))) {
682 hpfs_mark_4buffers_dirty(&qbh1
);
685 hpfs_add_to_dnode(i
, ndown
, de_cp
->name
, de_cp
->namelen
, de_cp
, dlp
);
691 hpfs_mark_4buffers_dirty(&qbh
);
697 /* Delete dirent from directory */
699 int hpfs_remove_dirent(struct inode
*i
, dnode_secno dno
, struct hpfs_dirent
*de
,
700 struct quad_buffer_head
*qbh
, int depth
)
702 struct dnode
*dnode
= qbh
->data
;
703 dnode_secno down
= 0;
706 if (de
->first
|| de
->last
) {
707 hpfs_error(i
->i_sb
, "hpfs_remove_dirent: attempt to delete first or last dirent in dnode %08x", dno
);
711 if (de
->down
) down
= de_down_pointer(de
);
712 if (depth
&& (de
->down
|| (de
== dnode_first_de(dnode
) && de_next_de(de
)->last
))) {
714 hpfs_lock_creation(i
->i_sb
);
715 if (hpfs_check_free_dnodes(i
->i_sb
, FREE_DNODES_DEL
)) {
717 hpfs_unlock_creation(i
->i_sb
);
722 for_all_poss(i
, hpfs_pos_del
, (t
= get_pos(dnode
, de
)) + 1, 1);
723 hpfs_delete_de(i
->i_sb
, dnode
, de
);
724 hpfs_mark_4buffers_dirty(qbh
);
727 dnode_secno a
= move_to_top(i
, down
, dno
);
728 for_all_poss(i
, hpfs_pos_subst
, 5, t
);
729 if (a
) delete_empty_dnode(i
, a
);
730 if (lock
) hpfs_unlock_creation(i
->i_sb
);
733 delete_empty_dnode(i
, dno
);
734 if (lock
) hpfs_unlock_creation(i
->i_sb
);
738 void hpfs_count_dnodes(struct super_block
*s
, dnode_secno dno
, int *n_dnodes
,
739 int *n_subdirs
, int *n_items
)
742 struct quad_buffer_head qbh
;
743 struct hpfs_dirent
*de
;
744 dnode_secno ptr
, odno
= 0;
748 if (n_dnodes
) (*n_dnodes
)++;
749 if (hpfs_sb(s
)->sb_chk
)
750 if (hpfs_stop_cycles(s
, dno
, &c1
, &c2
, "hpfs_count_dnodes #1")) return;
753 if (!(dnode
= hpfs_map_dnode(s
, dno
, &qbh
))) return;
754 if (hpfs_sb(s
)->sb_chk
) if (odno
&& odno
!= -1 && dnode
->up
!= odno
)
755 hpfs_error(s
, "hpfs_count_dnodes: bad up pointer; dnode %08x, down %08x points to %08x", odno
, dno
, dnode
->up
);
756 de
= dnode_first_de(dnode
);
758 if (de
->down
) if (de_down_pointer(de
) == ptr
) goto process_de
;
761 hpfs_error(s
, "hpfs_count_dnodes: pointer to dnode %08x not found in dnode %08x, got here from %08x",
770 dno
= de_down_pointer(de
);
775 if (!de
->first
&& !de
->last
&& de
->directory
&& n_subdirs
) (*n_subdirs
)++;
776 if (!de
->first
&& !de
->last
&& n_items
) (*n_items
)++;
777 if ((de
= de_next_de(de
)) < dnode_end_de(dnode
)) goto next_de
;
780 if (dnode
->root_dnode
) {
785 if (hpfs_sb(s
)->sb_chk
)
786 if (hpfs_stop_cycles(s
, ptr
, &d1
, &d2
, "hpfs_count_dnodes #2")) return;
791 static struct hpfs_dirent
*map_nth_dirent(struct super_block
*s
, dnode_secno dno
, int n
,
792 struct quad_buffer_head
*qbh
, struct dnode
**dn
)
795 struct hpfs_dirent
*de
, *de_end
;
797 dnode
= hpfs_map_dnode(s
, dno
, qbh
);
798 if (!dnode
) return NULL
;
800 de
= dnode_first_de(dnode
);
801 de_end
= dnode_end_de(dnode
);
802 for (i
= 1; de
< de_end
; i
++, de
= de_next_de(de
)) {
809 hpfs_error(s
, "map_nth_dirent: n too high; dnode = %08x, requested %08x", dno
, n
);
813 dnode_secno
hpfs_de_as_down_as_possible(struct super_block
*s
, dnode_secno dno
)
815 struct quad_buffer_head qbh
;
818 struct hpfs_dirent
*de
;
822 if (hpfs_sb(s
)->sb_chk
)
823 if (hpfs_stop_cycles(s
, d
, &c1
, &c2
, "hpfs_de_as_down_as_possible"))
825 if (!(de
= map_nth_dirent(s
, d
, 1, &qbh
, NULL
))) return dno
;
826 if (hpfs_sb(s
)->sb_chk
)
827 if (up
&& ((struct dnode
*)qbh
.data
)->up
!= up
)
828 hpfs_error(s
, "hpfs_de_as_down_as_possible: bad up pointer; dnode %08x, down %08x points to %08x", up
, d
, ((struct dnode
*)qbh
.data
)->up
);
834 d
= de_down_pointer(de
);
839 struct hpfs_dirent
*map_pos_dirent(struct inode
*inode
, loff_t
*posp
,
840 struct quad_buffer_head
*qbh
)
845 struct hpfs_dirent
*de
, *d
;
846 struct hpfs_dirent
*up_de
;
847 struct hpfs_dirent
*end_up_de
;
849 struct dnode
*up_dnode
;
850 struct quad_buffer_head qbh0
;
855 if (!(de
= map_nth_dirent(inode
->i_sb
, dno
, pos
, qbh
, &dnode
)))
858 /* Going to the next dirent */
859 if ((d
= de_next_de(de
)) < dnode_end_de(dnode
)) {
860 if (!(++*posp
& 077)) {
861 hpfs_error(inode
->i_sb
,
862 "map_pos_dirent: pos crossed dnode boundary; pos = %08llx",
863 (unsigned long long)*posp
);
866 /* We're going down the tree */
868 *posp
= ((loff_t
) hpfs_de_as_down_as_possible(inode
->i_sb
, de_down_pointer(d
)) << 4) + 1;
875 if (dnode
->root_dnode
) goto bail
;
877 if (!(up_dnode
= hpfs_map_dnode(inode
->i_sb
, dnode
->up
, &qbh0
)))
880 end_up_de
= dnode_end_de(up_dnode
);
882 for (up_de
= dnode_first_de(up_dnode
); up_de
< end_up_de
;
883 up_de
= de_next_de(up_de
)) {
884 if (!(++c
& 077)) hpfs_error(inode
->i_sb
,
885 "map_pos_dirent: pos crossed dnode boundary; dnode = %08x", dnode
->up
);
886 if (up_de
->down
&& de_down_pointer(up_de
) == dno
) {
887 *posp
= ((loff_t
) dnode
->up
<< 4) + c
;
893 hpfs_error(inode
->i_sb
, "map_pos_dirent: pointer to dnode %08x not found in parent dnode %08x",
902 /* Find a dirent in tree */
904 struct hpfs_dirent
*map_dirent(struct inode
*inode
, dnode_secno dno
,
905 const unsigned char *name
, unsigned len
,
906 dnode_secno
*dd
, struct quad_buffer_head
*qbh
)
909 struct hpfs_dirent
*de
;
910 struct hpfs_dirent
*de_end
;
913 if (!S_ISDIR(inode
->i_mode
)) hpfs_error(inode
->i_sb
, "map_dirent: not a directory\n");
915 if (hpfs_sb(inode
->i_sb
)->sb_chk
)
916 if (hpfs_stop_cycles(inode
->i_sb
, dno
, &c1
, &c2
, "map_dirent")) return NULL
;
917 if (!(dnode
= hpfs_map_dnode(inode
->i_sb
, dno
, qbh
))) return NULL
;
919 de_end
= dnode_end_de(dnode
);
920 for (de
= dnode_first_de(dnode
); de
< de_end
; de
= de_next_de(de
)) {
921 int t
= hpfs_compare_names(inode
->i_sb
, name
, len
, de
->name
, de
->namelen
, de
->last
);
928 dno
= de_down_pointer(de
);
940 * Remove empty directory. In normal cases it is only one dnode with two
941 * entries, but we must handle also such obscure cases when it's a tree
945 void hpfs_remove_dtree(struct super_block
*s
, dnode_secno dno
)
947 struct quad_buffer_head qbh
;
949 struct hpfs_dirent
*de
;
950 dnode_secno d1
, d2
, rdno
= dno
;
952 if (!(dnode
= hpfs_map_dnode(s
, dno
, &qbh
))) return;
953 de
= dnode_first_de(dnode
);
955 if (de
->down
) d1
= de_down_pointer(de
);
958 hpfs_free_dnode(s
, dno
);
962 if (!de
->first
) goto error
;
963 d1
= de
->down
? de_down_pointer(de
) : 0;
965 if (!de
->last
) goto error
;
966 d2
= de
->down
? de_down_pointer(de
) : 0;
968 hpfs_free_dnode(s
, dno
);
971 if (!(dnode
= hpfs_map_dnode(s
, dno
= d1
, &qbh
))) return;
972 de
= dnode_first_de(dnode
);
973 if (!de
->last
) goto error
;
974 d1
= de
->down
? de_down_pointer(de
) : 0;
976 hpfs_free_dnode(s
, dno
);
984 hpfs_free_dnode(s
, dno
);
985 hpfs_error(s
, "directory %08x is corrupted or not empty", rdno
);
989 * Find dirent for specified fnode. Use truncated 15-char name in fnode as
990 * a help for searching.
993 struct hpfs_dirent
*map_fnode_dirent(struct super_block
*s
, fnode_secno fno
,
994 struct fnode
*f
, struct quad_buffer_head
*qbh
)
996 unsigned char *name1
;
997 unsigned char *name2
;
998 int name1len
, name2len
;
1000 dnode_secno dno
, downd
;
1002 struct buffer_head
*bh
;
1003 struct hpfs_dirent
*de
, *de_end
;
1008 if (!(name2
= kmalloc(256, GFP_NOFS
))) {
1009 printk("HPFS: out of memory, can't map dirent\n");
1013 memcpy(name2
, name1
, name1len
= name2len
= f
->len
);
1015 memcpy(name2
, name1
, 15);
1016 memset(name2
+ 15, 0xff, 256 - 15);
1017 /*name2[15] = 0xff;*/
1018 name1len
= 15; name2len
= 256;
1020 if (!(upf
= hpfs_map_fnode(s
, f
->up
, &bh
))) {
1024 if (!upf
->dirflag
) {
1026 hpfs_error(s
, "fnode %08x has non-directory parent %08x", fno
, f
->up
);
1030 dno
= upf
->u
.external
[0].disk_secno
;
1035 if (!(d
= hpfs_map_dnode(s
, dno
, qbh
))) {
1039 de_end
= dnode_end_de(d
);
1040 de
= dnode_first_de(d
);
1042 while (de
< de_end
) {
1043 if (de
->down
) if (de_down_pointer(de
) == downd
) goto f
;
1044 de
= de_next_de(de
);
1046 hpfs_error(s
, "pointer to dnode %08x not found in dnode %08x", downd
, dno
);
1052 if (de
->fnode
== fno
) {
1056 c
= hpfs_compare_names(s
, name1
, name1len
, de
->name
, de
->namelen
, de
->last
);
1057 if (c
< 0 && de
->down
) {
1058 dno
= de_down_pointer(de
);
1060 if (hpfs_sb(s
)->sb_chk
)
1061 if (hpfs_stop_cycles(s
, dno
, &c1
, &c2
, "map_fnode_dirent #1")) {
1068 if (de
->fnode
== fno
) {
1072 c
= hpfs_compare_names(s
, name2
, name2len
, de
->name
, de
->namelen
, de
->last
);
1073 if (c
< 0 && !de
->last
) goto not_found
;
1074 if ((de
= de_next_de(de
)) < de_end
) goto next_de
;
1075 if (d
->root_dnode
) goto not_found
;
1079 if (hpfs_sb(s
)->sb_chk
)
1080 if (hpfs_stop_cycles(s
, downd
, &d1
, &d2
, "map_fnode_dirent #2")) {
1087 hpfs_error(s
, "dirent for fnode %08x not found", fno
);