1 /*
2 * linux/fs/hpfs/dnode.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * handling directory dnode tree - adding, deleteing & searching for dirents
7 */
8
9 #include "hpfs_fn.h"
10
get_pos(struct dnode * d,struct hpfs_dirent * fde)11 static loff_t get_pos(struct dnode *d, struct hpfs_dirent *fde)
12 {
13 struct hpfs_dirent *de;
14 struct hpfs_dirent *de_end = dnode_end_de(d);
15 int i = 1;
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;
18 i++;
19 }
20 printk("HPFS: get_pos: not_found\n");
21 return ((loff_t)d->self << 4) | (loff_t)1;
22 }
23
hpfs_add_pos(struct inode * inode,loff_t * pos)24 void hpfs_add_pos(struct inode *inode, loff_t *pos)
25 {
26 int i = 0;
27 loff_t **ppos;
28 if (inode->i_hpfs_rddir_off)
29 for (; inode->i_hpfs_rddir_off[i]; i++)
30 if (inode->i_hpfs_rddir_off[i] == pos) return;
31 if (!(i&0x0f)) {
32 if (!(ppos = kmalloc((i+0x11) * sizeof(loff_t*), GFP_KERNEL))) {
33 printk("HPFS: out of memory for position list\n");
34 return;
35 }
36 if (inode->i_hpfs_rddir_off) {
37 memcpy(ppos, inode->i_hpfs_rddir_off, i * sizeof(loff_t));
38 kfree(inode->i_hpfs_rddir_off);
39 }
40 inode->i_hpfs_rddir_off = ppos;
41 }
42 inode->i_hpfs_rddir_off[i] = pos;
43 inode->i_hpfs_rddir_off[i + 1] = NULL;
44 }
45
hpfs_del_pos(struct inode * inode,loff_t * pos)46 void hpfs_del_pos(struct inode *inode, loff_t *pos)
47 {
48 loff_t **i, **j;
49 if (!inode->i_hpfs_rddir_off) goto not_f;
50 for (i = inode->i_hpfs_rddir_off; *i; i++) if (*i == pos) goto fnd;
51 goto not_f;
52 fnd:
53 for (j = i + 1; *j; j++) ;
54 *i = *(j - 1);
55 *(j - 1) = NULL;
56 if (j - 1 == inode->i_hpfs_rddir_off) {
57 kfree(inode->i_hpfs_rddir_off);
58 inode->i_hpfs_rddir_off = NULL;
59 }
60 return;
61 not_f:
62 /*printk("HPFS: warning: position pointer %p->%08x not found\n", pos, (int)*pos);*/
63 return;
64 }
65
for_all_poss(struct inode * inode,void (* f)(loff_t *,loff_t,loff_t),loff_t p1,loff_t p2)66 static void for_all_poss(struct inode *inode, void (*f)(loff_t *, loff_t, loff_t),
67 loff_t p1, loff_t p2)
68 {
69 loff_t **i;
70 if (!inode->i_hpfs_rddir_off) return;
71 for (i = inode->i_hpfs_rddir_off; *i; i++) (*f)(*i, p1, p2);
72 return;
73 }
74
hpfs_pos_subst(loff_t * p,loff_t f,loff_t t)75 void hpfs_pos_subst(loff_t *p, loff_t f, loff_t t)
76 {
77 if (*p == f) *p = t;
78 }
79
80 /*void hpfs_hpfs_pos_substd(loff_t *p, loff_t f, loff_t t)
81 {
82 if ((*p & ~0x3f) == (f & ~0x3f)) *p = (t & ~0x3f) | (*p & 0x3f);
83 }*/
84
hpfs_pos_ins(loff_t * p,loff_t d,loff_t c)85 void hpfs_pos_ins(loff_t *p, loff_t d, loff_t c)
86 {
87 if ((*p & ~0x3f) == (d & ~0x3f) && (*p & 0x3f) >= (d & 0x3f)) {
88 int n = (*p & 0x3f) + c;
89 if (n > 0x3f) printk("HPFS: hpfs_pos_ins: %08x + %d\n", (int)*p, (int)c >> 8);
90 else *p = (*p & ~0x3f) | n;
91 }
92 }
93
hpfs_pos_del(loff_t * p,loff_t d,loff_t c)94 void hpfs_pos_del(loff_t *p, loff_t d, loff_t c)
95 {
96 if ((*p & ~0x3f) == (d & ~0x3f) && (*p & 0x3f) >= (d & 0x3f)) {
97 int n = (*p & 0x3f) - c;
98 if (n < 1) printk("HPFS: hpfs_pos_ins: %08x - %d\n", (int)*p, (int)c >> 8);
99 else *p = (*p & ~0x3f) | n;
100 }
101 }
102
dnode_pre_last_de(struct dnode * d)103 static struct hpfs_dirent *dnode_pre_last_de(struct dnode *d)
104 {
105 struct hpfs_dirent *de, *de_end, *dee = NULL, *deee = NULL;
106 de_end = dnode_end_de(d);
107 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
108 deee = dee; dee = de;
109 }
110 return deee;
111 }
112
dnode_last_de(struct dnode * d)113 static struct hpfs_dirent *dnode_last_de(struct dnode *d)
114 {
115 struct hpfs_dirent *de, *de_end, *dee = NULL;
116 de_end = dnode_end_de(d);
117 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
118 dee = de;
119 }
120 return dee;
121 }
122
set_last_pointer(struct super_block * s,struct dnode * d,dnode_secno ptr)123 static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno ptr)
124 {
125 struct hpfs_dirent *de;
126 if (!(de = dnode_last_de(d))) {
127 hpfs_error(s, "set_last_pointer: empty dnode %08x", d->self);
128 return;
129 }
130 if (s->s_hpfs_chk) {
131 if (de->down) {
132 hpfs_error(s, "set_last_pointer: dnode %08x has already last pointer %08x",
133 d->self, de_down_pointer(de));
134 return;
135 }
136 if (de->length != 32) {
137 hpfs_error(s, "set_last_pointer: bad last dirent in dnode %08x", d->self);
138 return;
139 }
140 }
141 if (ptr) {
142 if ((d->first_free += 4) > 2048) {
143 hpfs_error(s,"set_last_pointer: too long dnode %08x", d->self);
144 d->first_free -= 4;
145 return;
146 }
147 de->length = 36;
148 de->down = 1;
149 *(dnode_secno *)((char *)de + 32) = ptr;
150 }
151 }
152
153 /* Add an entry to dnode and don't care if it grows over 2048 bytes */
154
hpfs_add_de(struct super_block * s,struct dnode * d,unsigned char * name,unsigned namelen,secno down_ptr)155 struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d, unsigned char *name,
156 unsigned namelen, secno down_ptr)
157 {
158 struct hpfs_dirent *de;
159 struct hpfs_dirent *de_end = dnode_end_de(d);
160 unsigned d_size = de_size(namelen, down_ptr);
161 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
162 int c = hpfs_compare_names(s, name, namelen, de->name, de->namelen, de->last);
163 if (!c) {
164 hpfs_error(s, "name (%c,%d) already exists in dnode %08x", *name, namelen, d->self);
165 return NULL;
166 }
167 if (c < 0) break;
168 }
169 memmove((char *)de + d_size, de, (char *)de_end - (char *)de);
170 memset(de, 0, d_size);
171 if (down_ptr) {
172 *(int *)((char *)de + d_size - 4) = down_ptr;
173 de->down = 1;
174 }
175 de->length = d_size;
176 if (down_ptr) de->down = 1;
177 de->not_8x3 = hpfs_is_name_long(name, namelen);
178 de->namelen = namelen;
179 memcpy(de->name, name, namelen);
180 d->first_free += d_size;
181 return de;
182 }
183
184 /* Delete dirent and don't care about it's subtree */
185
hpfs_delete_de(struct super_block * s,struct dnode * d,struct hpfs_dirent * de)186 void hpfs_delete_de(struct super_block *s, struct dnode *d, struct hpfs_dirent *de)
187 {
188 if (de->last) {
189 hpfs_error(s, "attempt to delete last dirent in dnode %08x", d->self);
190 return;
191 }
192 d->first_free -= de->length;
193 memmove(de, de_next_de(de), d->first_free + (char *)d - (char *)de);
194 }
195
fix_up_ptrs(struct super_block * s,struct dnode * d)196 static void fix_up_ptrs(struct super_block *s, struct dnode *d)
197 {
198 struct hpfs_dirent *de;
199 struct hpfs_dirent *de_end = dnode_end_de(d);
200 dnode_secno dno = d->self;
201 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de))
202 if (de->down) {
203 struct quad_buffer_head qbh;
204 struct dnode *dd;
205 if ((dd = hpfs_map_dnode(s, de_down_pointer(de), &qbh))) {
206 if (dd->up != dno || dd->root_dnode) {
207 dd->up = dno;
208 dd->root_dnode = 0;
209 hpfs_mark_4buffers_dirty(&qbh);
210 }
211 hpfs_brelse4(&qbh);
212 }
213 }
214 }
215
216 /* Add an entry to dnode and do dnode splitting if required */
217
hpfs_add_to_dnode(struct inode * i,dnode_secno dno,unsigned char * name,unsigned namelen,struct hpfs_dirent * new_de,dnode_secno down_ptr)218 int hpfs_add_to_dnode(struct inode *i, dnode_secno dno, unsigned char *name, unsigned namelen,
219 struct hpfs_dirent *new_de, dnode_secno down_ptr)
220 {
221 struct quad_buffer_head qbh, qbh1, qbh2;
222 struct dnode *d, *ad, *rd, *nd = NULL;
223 dnode_secno adno, rdno;
224 struct hpfs_dirent *de;
225 struct hpfs_dirent nde;
226 char *nname;
227 int h;
228 int pos;
229 struct buffer_head *bh;
230 struct fnode *fnode;
231 int c1, c2 = 0;
232 if (!(nname = kmalloc(256, GFP_KERNEL))) {
233 printk("HPFS: out of memory, can't add to dnode\n");
234 return 1;
235 }
236 go_up:
237 if (namelen >= 256) {
238 hpfs_error(i->i_sb, "hpfs_add_to_dnode: namelen == %d", namelen);
239 if (nd) kfree(nd);
240 kfree(nname);
241 return 1;
242 }
243 if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) {
244 if (nd) kfree(nd);
245 kfree(nname);
246 return 1;
247 }
248 go_up_a:
249 if (i->i_sb->s_hpfs_chk)
250 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_to_dnode")) {
251 hpfs_brelse4(&qbh);
252 if (nd) kfree(nd);
253 kfree(nname);
254 return 1;
255 }
256 if (d->first_free + de_size(namelen, down_ptr) <= 2048) {
257 loff_t t;
258 copy_de(de=hpfs_add_de(i->i_sb, d, name, namelen, down_ptr), new_de);
259 t = get_pos(d, de);
260 for_all_poss(i, hpfs_pos_ins, t, 1);
261 for_all_poss(i, hpfs_pos_subst, 4, t);
262 for_all_poss(i, hpfs_pos_subst, 5, t + 1);
263 hpfs_mark_4buffers_dirty(&qbh);
264 hpfs_brelse4(&qbh);
265 if (nd) kfree(nd);
266 kfree(nname);
267 return 0;
268 }
269 if (!nd) if (!(nd = kmalloc(0x924, GFP_KERNEL))) {
270 /* 0x924 is a max size of dnode after adding a dirent with
271 max name length. We alloc this only once. There must
272 not be any error while splitting dnodes, otherwise the
273 whole directory, not only file we're adding, would
274 be lost. */
275 printk("HPFS: out of memory for dnode splitting\n");
276 hpfs_brelse4(&qbh);
277 kfree(nname);
278 return 1;
279 }
280 memcpy(nd, d, d->first_free);
281 copy_de(de = hpfs_add_de(i->i_sb, nd, name, namelen, down_ptr), new_de);
282 for_all_poss(i, hpfs_pos_ins, get_pos(nd, de), 1);
283 h = ((char *)dnode_last_de(nd) - (char *)nd) / 2 + 10;
284 if (!(ad = hpfs_alloc_dnode(i->i_sb, d->up, &adno, &qbh1, 0))) {
285 hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
286 hpfs_brelse4(&qbh);
287 kfree(nd);
288 kfree(nname);
289 return 1;
290 }
291 i->i_size += 2048;
292 i->i_blocks += 4;
293 pos = 1;
294 for (de = dnode_first_de(nd); (char *)de_next_de(de) - (char *)nd < h; de = de_next_de(de)) {
295 copy_de(hpfs_add_de(i->i_sb, ad, de->name, de->namelen, de->down ? de_down_pointer(de) : 0), de);
296 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | pos, ((loff_t)adno << 4) | pos);
297 pos++;
298 }
299 copy_de(new_de = &nde, de);
300 memcpy(name = nname, de->name, namelen = de->namelen);
301 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | pos, 4);
302 down_ptr = adno;
303 set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0);
304 de = de_next_de(de);
305 memmove((char *)nd + 20, de, nd->first_free + (char *)nd - (char *)de);
306 nd->first_free -= (char *)de - (char *)nd - 20;
307 memcpy(d, nd, nd->first_free);
308 for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos);
309 fix_up_ptrs(i->i_sb, ad);
310 if (!d->root_dnode) {
311 dno = ad->up = d->up;
312 hpfs_mark_4buffers_dirty(&qbh);
313 hpfs_brelse4(&qbh);
314 hpfs_mark_4buffers_dirty(&qbh1);
315 hpfs_brelse4(&qbh1);
316 goto go_up;
317 }
318 if (!(rd = hpfs_alloc_dnode(i->i_sb, d->up, &rdno, &qbh2, 0))) {
319 hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
320 hpfs_brelse4(&qbh);
321 hpfs_brelse4(&qbh1);
322 kfree(nd);
323 kfree(nname);
324 return 1;
325 }
326 i->i_size += 2048;
327 i->i_blocks += 4;
328 rd->root_dnode = 1;
329 rd->up = d->up;
330 if (!(fnode = hpfs_map_fnode(i->i_sb, d->up, &bh))) {
331 hpfs_free_dnode(i->i_sb, rdno);
332 hpfs_brelse4(&qbh);
333 hpfs_brelse4(&qbh1);
334 hpfs_brelse4(&qbh2);
335 kfree(nd);
336 kfree(nname);
337 return 1;
338 }
339 fnode->u.external[0].disk_secno = rdno;
340 mark_buffer_dirty(bh);
341 brelse(bh);
342 d->up = ad->up = i->i_hpfs_dno = rdno;
343 d->root_dnode = ad->root_dnode = 0;
344 hpfs_mark_4buffers_dirty(&qbh);
345 hpfs_brelse4(&qbh);
346 hpfs_mark_4buffers_dirty(&qbh1);
347 hpfs_brelse4(&qbh1);
348 qbh = qbh2;
349 set_last_pointer(i->i_sb, rd, dno);
350 dno = rdno;
351 d = rd;
352 goto go_up_a;
353 }
354
355 /*
356 * Add an entry to directory btree.
357 * I hate such crazy directory structure.
358 * It's easy to read but terrible to write.
359 * I wrote this directory code 4 times.
360 * I hope, now it's finally bug-free.
361 */
362
hpfs_add_dirent(struct inode * i,unsigned char * name,unsigned namelen,struct hpfs_dirent * new_de,int cdepth)363 int hpfs_add_dirent(struct inode *i, unsigned char *name, unsigned namelen,
364 struct hpfs_dirent *new_de, int cdepth)
365 {
366 struct dnode *d;
367 struct hpfs_dirent *de, *de_end;
368 struct quad_buffer_head qbh;
369 dnode_secno dno;
370 int c;
371 int c1, c2 = 0;
372 dno = i->i_hpfs_dno;
373 down:
374 if (i->i_sb->s_hpfs_chk)
375 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_dirent")) return 1;
376 if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 1;
377 de_end = dnode_end_de(d);
378 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
379 if (!(c = hpfs_compare_names(i->i_sb, name, namelen, de->name, de->namelen, de->last))) {
380 hpfs_brelse4(&qbh);
381 return -1;
382 }
383 if (c < 0) {
384 if (de->down) {
385 dno = de_down_pointer(de);
386 hpfs_brelse4(&qbh);
387 goto down;
388 }
389 break;
390 }
391 }
392 hpfs_brelse4(&qbh);
393 if (!cdepth) hpfs_lock_creation(i->i_sb);
394 if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_ADD)) {
395 c = 1;
396 goto ret;
397 }
398 i->i_version = ++event;
399 c = hpfs_add_to_dnode(i, dno, name, namelen, new_de, 0);
400 ret:
401 if (!cdepth) hpfs_unlock_creation(i->i_sb);
402 return c;
403 }
404
405 /*
406 * Find dirent with higher name in 'from' subtree and move it to 'to' dnode.
407 * Return the dnode we moved from (to be checked later if it's empty)
408 */
409
move_to_top(struct inode * i,dnode_secno from,dnode_secno to)410 static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
411 {
412 dnode_secno dno, ddno;
413 dnode_secno chk_up = to;
414 struct dnode *dnode;
415 struct quad_buffer_head qbh;
416 struct hpfs_dirent *de, *nde;
417 int a;
418 loff_t t;
419 int c1, c2 = 0;
420 dno = from;
421 while (1) {
422 if (i->i_sb->s_hpfs_chk)
423 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "move_to_top"))
424 return 0;
425 if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 0;
426 if (i->i_sb->s_hpfs_chk) {
427 if (dnode->up != chk_up) {
428 hpfs_error(i->i_sb, "move_to_top: up pointer from %08x should be %08x, is %08x",
429 dno, chk_up, dnode->up);
430 hpfs_brelse4(&qbh);
431 return 0;
432 }
433 chk_up = dno;
434 }
435 if (!(de = dnode_last_de(dnode))) {
436 hpfs_error(i->i_sb, "move_to_top: dnode %08x has no last de", dno);
437 hpfs_brelse4(&qbh);
438 return 0;
439 }
440 if (!de->down) break;
441 dno = de_down_pointer(de);
442 hpfs_brelse4(&qbh);
443 }
444 while (!(de = dnode_pre_last_de(dnode))) {
445 dnode_secno up = dnode->up;
446 hpfs_brelse4(&qbh);
447 hpfs_free_dnode(i->i_sb, dno);
448 i->i_size -= 2048;
449 i->i_blocks -= 4;
450 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, 5);
451 if (up == to) return to;
452 if (!(dnode = hpfs_map_dnode(i->i_sb, up, &qbh))) return 0;
453 if (dnode->root_dnode) {
454 hpfs_error(i->i_sb, "move_to_top: got to root_dnode while moving from %08x to %08x", from, to);
455 hpfs_brelse4(&qbh);
456 return 0;
457 }
458 de = dnode_last_de(dnode);
459 if (!de || !de->down) {
460 hpfs_error(i->i_sb, "move_to_top: dnode %08x doesn't point down to %08x", up, dno);
461 hpfs_brelse4(&qbh);
462 return 0;
463 }
464 dnode->first_free -= 4;
465 de->length -= 4;
466 de->down = 0;
467 hpfs_mark_4buffers_dirty(&qbh);
468 dno = up;
469 }
470 t = get_pos(dnode, de);
471 for_all_poss(i, hpfs_pos_subst, t, 4);
472 for_all_poss(i, hpfs_pos_subst, t + 1, 5);
473 if (!(nde = kmalloc(de->length, GFP_KERNEL))) {
474 hpfs_error(i->i_sb, "out of memory for dirent - directory will be corrupted");
475 hpfs_brelse4(&qbh);
476 return 0;
477 }
478 memcpy(nde, de, de->length);
479 ddno = de->down ? de_down_pointer(de) : 0;
480 hpfs_delete_de(i->i_sb, dnode, de);
481 set_last_pointer(i->i_sb, dnode, ddno);
482 hpfs_mark_4buffers_dirty(&qbh);
483 hpfs_brelse4(&qbh);
484 a = hpfs_add_to_dnode(i, to, nde->name, nde->namelen, nde, from);
485 kfree(nde);
486 if (a) return 0;
487 return dno;
488 }
489
490 /*
491 * Check if a dnode is empty and delete it from the tree
492 * (chkdsk doesn't like empty dnodes)
493 */
494
delete_empty_dnode(struct inode * i,dnode_secno dno)495 static void delete_empty_dnode(struct inode *i, dnode_secno dno)
496 {
497 struct quad_buffer_head qbh;
498 struct dnode *dnode;
499 dnode_secno down, up, ndown;
500 int p;
501 struct hpfs_dirent *de;
502 int c1, c2 = 0;
503 try_it_again:
504 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "delete_empty_dnode")) return;
505 if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return;
506 if (dnode->first_free > 56) goto end;
507 if (dnode->first_free == 52 || dnode->first_free == 56) {
508 struct hpfs_dirent *de_end;
509 int root = dnode->root_dnode;
510 up = dnode->up;
511 de = dnode_first_de(dnode);
512 down = de->down ? de_down_pointer(de) : 0;
513 if (i->i_sb->s_hpfs_chk) if (root && !down) {
514 hpfs_error(i->i_sb, "delete_empty_dnode: root dnode %08x is empty", dno);
515 goto end;
516 }
517 hpfs_brelse4(&qbh);
518 hpfs_free_dnode(i->i_sb, dno);
519 i->i_size -= 2048;
520 i->i_blocks -= 4;
521 if (root) {
522 struct fnode *fnode;
523 struct buffer_head *bh;
524 struct dnode *d1;
525 struct quad_buffer_head qbh1;
526 if (i->i_sb->s_hpfs_chk) if (up != i->i_ino) {
527 hpfs_error(i->i_sb, "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08x", dno, up, i->i_ino);
528 return;
529 }
530 if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
531 d1->up = up;
532 d1->root_dnode = 1;
533 hpfs_mark_4buffers_dirty(&qbh1);
534 hpfs_brelse4(&qbh1);
535 }
536 if ((fnode = hpfs_map_fnode(i->i_sb, up, &bh))) {
537 fnode->u.external[0].disk_secno = down;
538 mark_buffer_dirty(bh);
539 brelse(bh);
540 }
541 i->i_hpfs_dno = down;
542 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, (loff_t) 12);
543 return;
544 }
545 if (!(dnode = hpfs_map_dnode(i->i_sb, up, &qbh))) return;
546 p = 1;
547 de_end = dnode_end_de(dnode);
548 for (de = dnode_first_de(dnode); de < de_end; de = de_next_de(de), p++)
549 if (de->down) if (de_down_pointer(de) == dno) goto fnd;
550 hpfs_error(i->i_sb, "delete_empty_dnode: pointer to dnode %08x not found in dnode %08x", dno, up);
551 goto end;
552 fnd:
553 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, ((loff_t)up << 4) | p);
554 if (!down) {
555 de->down = 0;
556 de->length -= 4;
557 dnode->first_free -= 4;
558 memmove(de_next_de(de), (char *)de_next_de(de) + 4,
559 (char *)dnode + dnode->first_free - (char *)de_next_de(de));
560 } else {
561 struct dnode *d1;
562 struct quad_buffer_head qbh1;
563 *(dnode_secno *) ((void *) de + de->length - 4) = down;
564 if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
565 d1->up = up;
566 hpfs_mark_4buffers_dirty(&qbh1);
567 hpfs_brelse4(&qbh1);
568 }
569 }
570 } else {
571 hpfs_error(i->i_sb, "delete_empty_dnode: dnode %08x, first_free == %03x", dno, dnode->first_free);
572 goto end;
573 }
574
575 if (!de->last) {
576 struct hpfs_dirent *de_next = de_next_de(de);
577 struct hpfs_dirent *de_cp;
578 struct dnode *d1;
579 struct quad_buffer_head qbh1;
580 if (!de_next->down) goto endm;
581 ndown = de_down_pointer(de_next);
582 if (!(de_cp = kmalloc(de->length, GFP_KERNEL))) {
583 printk("HPFS: out of memory for dtree balancing\n");
584 goto endm;
585 }
586 memcpy(de_cp, de, de->length);
587 hpfs_delete_de(i->i_sb, dnode, de);
588 hpfs_mark_4buffers_dirty(&qbh);
589 hpfs_brelse4(&qbh);
590 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, 4);
591 for_all_poss(i, hpfs_pos_del, ((loff_t)up << 4) | p, 1);
592 if (de_cp->down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de_cp), &qbh1))) {
593 d1->up = ndown;
594 hpfs_mark_4buffers_dirty(&qbh1);
595 hpfs_brelse4(&qbh1);
596 }
597 hpfs_add_to_dnode(i, ndown, de_cp->name, de_cp->namelen, de_cp, de_cp->down ? de_down_pointer(de_cp) : 0);
598 /*printk("UP-TO-DNODE: %08x (ndown = %08x, down = %08x, dno = %08x)\n", up, ndown, down, dno);*/
599 dno = up;
600 kfree(de_cp);
601 goto try_it_again;
602 } else {
603 struct hpfs_dirent *de_prev = dnode_pre_last_de(dnode);
604 struct hpfs_dirent *de_cp;
605 struct dnode *d1;
606 struct quad_buffer_head qbh1;
607 dnode_secno dlp;
608 if (!de_prev) {
609 hpfs_error(i->i_sb, "delete_empty_dnode: empty dnode %08x", up);
610 hpfs_mark_4buffers_dirty(&qbh);
611 hpfs_brelse4(&qbh);
612 dno = up;
613 goto try_it_again;
614 }
615 if (!de_prev->down) goto endm;
616 ndown = de_down_pointer(de_prev);
617 if ((d1 = hpfs_map_dnode(i->i_sb, ndown, &qbh1))) {
618 struct hpfs_dirent *del = dnode_last_de(d1);
619 dlp = del->down ? de_down_pointer(del) : 0;
620 if (!dlp && down) {
621 if (d1->first_free > 2044) {
622 if (i->i_sb->s_hpfs_chk >= 2) {
623 printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
624 printk("HPFS: warning: terminating balancing operation\n");
625 }
626 hpfs_brelse4(&qbh1);
627 goto endm;
628 }
629 if (i->i_sb->s_hpfs_chk >= 2) {
630 printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
631 printk("HPFS: warning: goin'on\n");
632 }
633 del->length += 4;
634 del->down = 1;
635 d1->first_free += 4;
636 }
637 if (dlp && !down) {
638 del->length -= 4;
639 del->down = 0;
640 d1->first_free -= 4;
641 } else if (down)
642 *(dnode_secno *) ((void *) del + del->length - 4) = down;
643 } else goto endm;
644 if (!(de_cp = kmalloc(de_prev->length, GFP_KERNEL))) {
645 printk("HPFS: out of memory for dtree balancing\n");
646 hpfs_brelse4(&qbh1);
647 goto endm;
648 }
649 hpfs_mark_4buffers_dirty(&qbh1);
650 hpfs_brelse4(&qbh1);
651 memcpy(de_cp, de_prev, de_prev->length);
652 hpfs_delete_de(i->i_sb, dnode, de_prev);
653 if (!de_prev->down) {
654 de_prev->length += 4;
655 de_prev->down = 1;
656 dnode->first_free += 4;
657 }
658 *(dnode_secno *) ((void *) de_prev + de_prev->length - 4) = ndown;
659 hpfs_mark_4buffers_dirty(&qbh);
660 hpfs_brelse4(&qbh);
661 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | (p - 1), 4);
662 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, ((loff_t)up << 4) | (p - 1));
663 if (down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de), &qbh1))) {
664 d1->up = ndown;
665 hpfs_mark_4buffers_dirty(&qbh1);
666 hpfs_brelse4(&qbh1);
667 }
668 hpfs_add_to_dnode(i, ndown, de_cp->name, de_cp->namelen, de_cp, dlp);
669 dno = up;
670 kfree(de_cp);
671 goto try_it_again;
672 }
673 endm:
674 hpfs_mark_4buffers_dirty(&qbh);
675 end:
676 hpfs_brelse4(&qbh);
677 }
678
679
680 /* Delete dirent from directory */
681
hpfs_remove_dirent(struct inode * i,dnode_secno dno,struct hpfs_dirent * de,struct quad_buffer_head * qbh,int depth)682 int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de,
683 struct quad_buffer_head *qbh, int depth)
684 {
685 struct dnode *dnode = qbh->data;
686 dnode_secno down = 0;
687 int lock = 0;
688 loff_t t;
689 if (de->first || de->last) {
690 hpfs_error(i->i_sb, "hpfs_remove_dirent: attempt to delete first or last dirent in dnode %08x", dno);
691 hpfs_brelse4(qbh);
692 return 1;
693 }
694 if (de->down) down = de_down_pointer(de);
695 if (depth && (de->down || (de == dnode_first_de(dnode) && de_next_de(de)->last))) {
696 lock = 1;
697 hpfs_lock_creation(i->i_sb);
698 if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_DEL)) {
699 hpfs_brelse4(qbh);
700 hpfs_unlock_creation(i->i_sb);
701 return 2;
702 }
703 }
704 i->i_version = ++event;
705 for_all_poss(i, hpfs_pos_del, (t = get_pos(dnode, de)) + 1, 1);
706 hpfs_delete_de(i->i_sb, dnode, de);
707 hpfs_mark_4buffers_dirty(qbh);
708 hpfs_brelse4(qbh);
709 if (down) {
710 dnode_secno a = move_to_top(i, down, dno);
711 for_all_poss(i, hpfs_pos_subst, 5, t);
712 if (a) delete_empty_dnode(i, a);
713 if (lock) hpfs_unlock_creation(i->i_sb);
714 return !a;
715 }
716 delete_empty_dnode(i, dno);
717 if (lock) hpfs_unlock_creation(i->i_sb);
718 return 0;
719 }
720
hpfs_count_dnodes(struct super_block * s,dnode_secno dno,int * n_dnodes,int * n_subdirs,int * n_items)721 void hpfs_count_dnodes(struct super_block *s, dnode_secno dno, int *n_dnodes,
722 int *n_subdirs, int *n_items)
723 {
724 struct dnode *dnode;
725 struct quad_buffer_head qbh;
726 struct hpfs_dirent *de;
727 dnode_secno ptr, odno = 0;
728 int c1, c2 = 0;
729 int d1, d2 = 0;
730 go_down:
731 if (n_dnodes) (*n_dnodes)++;
732 if (s->s_hpfs_chk)
733 if (hpfs_stop_cycles(s, dno, &c1, &c2, "hpfs_count_dnodes #1")) return;
734 ptr = 0;
735 go_up:
736 if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return;
737 if (s->s_hpfs_chk) if (odno && odno != -1 && dnode->up != odno)
738 hpfs_error(s, "hpfs_count_dnodes: bad up pointer; dnode %08x, down %08x points to %08x", odno, dno, dnode->up);
739 de = dnode_first_de(dnode);
740 if (ptr) while(1) {
741 if (de->down) if (de_down_pointer(de) == ptr) goto process_de;
742 if (de->last) {
743 hpfs_brelse4(&qbh);
744 hpfs_error(s, "hpfs_count_dnodes: pointer to dnode %08x not found in dnode %08x, got here from %08x",
745 ptr, dno, odno);
746 return;
747 }
748 de = de_next_de(de);
749 }
750 next_de:
751 if (de->down) {
752 odno = dno;
753 dno = de_down_pointer(de);
754 hpfs_brelse4(&qbh);
755 goto go_down;
756 }
757 process_de:
758 if (!de->first && !de->last && de->directory && n_subdirs) (*n_subdirs)++;
759 if (!de->first && !de->last && n_items) (*n_items)++;
760 if ((de = de_next_de(de)) < dnode_end_de(dnode)) goto next_de;
761 ptr = dno;
762 dno = dnode->up;
763 if (dnode->root_dnode) {
764 hpfs_brelse4(&qbh);
765 return;
766 }
767 hpfs_brelse4(&qbh);
768 if (s->s_hpfs_chk)
769 if (hpfs_stop_cycles(s, ptr, &d1, &d2, "hpfs_count_dnodes #2")) return;
770 odno = -1;
771 goto go_up;
772 }
773
map_nth_dirent(struct super_block * s,dnode_secno dno,int n,struct quad_buffer_head * qbh,struct dnode ** dn)774 static struct hpfs_dirent *map_nth_dirent(struct super_block *s, dnode_secno dno, int n,
775 struct quad_buffer_head *qbh, struct dnode **dn)
776 {
777 int i;
778 struct hpfs_dirent *de, *de_end;
779 struct dnode *dnode;
780 dnode = hpfs_map_dnode(s, dno, qbh);
781 if (!dnode) return NULL;
782 if (dn) *dn=dnode;
783 de = dnode_first_de(dnode);
784 de_end = dnode_end_de(dnode);
785 for (i = 1; de < de_end; i++, de = de_next_de(de)) {
786 if (i == n) {
787 return de;
788 }
789 if (de->last) break;
790 }
791 hpfs_brelse4(qbh);
792 hpfs_error(s, "map_nth_dirent: n too high; dnode = %08x, requested %08x", dno, n);
793 return NULL;
794 }
795
hpfs_de_as_down_as_possible(struct super_block * s,dnode_secno dno)796 dnode_secno hpfs_de_as_down_as_possible(struct super_block *s, dnode_secno dno)
797 {
798 struct quad_buffer_head qbh;
799 dnode_secno d = dno;
800 dnode_secno up = 0;
801 struct hpfs_dirent *de;
802 int c1, c2 = 0;
803
804 again:
805 if (s->s_hpfs_chk)
806 if (hpfs_stop_cycles(s, d, &c1, &c2, "hpfs_de_as_down_as_possible"))
807 return d;
808 if (!(de = map_nth_dirent(s, d, 1, &qbh, NULL))) return dno;
809 if (s->s_hpfs_chk)
810 if (up && ((struct dnode *)qbh.data)->up != up)
811 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);
812 if (!de->down) {
813 hpfs_brelse4(&qbh);
814 return d;
815 }
816 up = d;
817 d = de_down_pointer(de);
818 hpfs_brelse4(&qbh);
819 goto again;
820 }
821
map_pos_dirent(struct inode * inode,loff_t * posp,struct quad_buffer_head * qbh)822 struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
823 struct quad_buffer_head *qbh)
824 {
825 loff_t pos;
826 unsigned c;
827 dnode_secno dno;
828 struct hpfs_dirent *de, *d;
829 struct hpfs_dirent *up_de;
830 struct hpfs_dirent *end_up_de;
831 struct dnode *dnode;
832 struct dnode *up_dnode;
833 struct quad_buffer_head qbh0;
834
835 pos = *posp;
836 dno = pos >> 6 << 2;
837 pos &= 077;
838 if (!(de = map_nth_dirent(inode->i_sb, dno, pos, qbh, &dnode)))
839 goto bail;
840
841 /* Going to the next dirent */
842 if ((d = de_next_de(de)) < dnode_end_de(dnode)) {
843 if (!(++*posp & 077)) {
844 hpfs_error(inode->i_sb, "map_pos_dirent: pos crossed dnode boundary; pos = %08x", *posp);
845 goto bail;
846 }
847 /* We're going down the tree */
848 if (d->down) {
849 *posp = ((loff_t) hpfs_de_as_down_as_possible(inode->i_sb, de_down_pointer(d)) << 4) + 1;
850 }
851
852 return de;
853 }
854
855 /* Going up */
856 if (dnode->root_dnode) goto bail;
857
858 if (!(up_dnode = hpfs_map_dnode(inode->i_sb, dnode->up, &qbh0)))
859 goto bail;
860
861 end_up_de = dnode_end_de(up_dnode);
862 c = 0;
863 for (up_de = dnode_first_de(up_dnode); up_de < end_up_de;
864 up_de = de_next_de(up_de)) {
865 if (!(++c & 077)) hpfs_error(inode->i_sb,
866 "map_pos_dirent: pos crossed dnode boundary; dnode = %08x", dnode->up);
867 if (up_de->down && de_down_pointer(up_de) == dno) {
868 *posp = ((loff_t) dnode->up << 4) + c;
869 hpfs_brelse4(&qbh0);
870 return de;
871 }
872 }
873
874 hpfs_error(inode->i_sb, "map_pos_dirent: pointer to dnode %08x not found in parent dnode %08x",
875 dno, dnode->up);
876 hpfs_brelse4(&qbh0);
877
878 bail:
879 *posp = 12;
880 return de;
881 }
882
883 /* Find a dirent in tree */
884
map_dirent(struct inode * inode,dnode_secno dno,char * name,unsigned len,dnode_secno * dd,struct quad_buffer_head * qbh)885 struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno, char *name, unsigned len,
886 dnode_secno *dd, struct quad_buffer_head *qbh)
887 {
888 struct dnode *dnode;
889 struct hpfs_dirent *de;
890 struct hpfs_dirent *de_end;
891 int c1, c2 = 0;
892
893 if (!S_ISDIR(inode->i_mode)) hpfs_error(inode->i_sb, "map_dirent: not a directory\n");
894 again:
895 if (inode->i_sb->s_hpfs_chk)
896 if (hpfs_stop_cycles(inode->i_sb, dno, &c1, &c2, "map_dirent")) return NULL;
897 if (!(dnode = hpfs_map_dnode(inode->i_sb, dno, qbh))) return NULL;
898
899 de_end = dnode_end_de(dnode);
900 for (de = dnode_first_de(dnode); de < de_end; de = de_next_de(de)) {
901 int t = hpfs_compare_names(inode->i_sb, name, len, de->name, de->namelen, de->last);
902 if (!t) {
903 if (dd) *dd = dno;
904 return de;
905 }
906 if (t < 0) {
907 if (de->down) {
908 dno = de_down_pointer(de);
909 hpfs_brelse4(qbh);
910 goto again;
911 }
912 break;
913 }
914 }
915 hpfs_brelse4(qbh);
916 return NULL;
917 }
918
919 /*
920 * Remove empty directory. In normal cases it is only one dnode with two
921 * entries, but we must handle also such obscure cases when it's a tree
922 * of empty dnodes.
923 */
924
hpfs_remove_dtree(struct super_block * s,dnode_secno dno)925 void hpfs_remove_dtree(struct super_block *s, dnode_secno dno)
926 {
927 struct quad_buffer_head qbh;
928 struct dnode *dnode;
929 struct hpfs_dirent *de;
930 dnode_secno d1, d2, rdno = dno;
931 while (1) {
932 if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return;
933 de = dnode_first_de(dnode);
934 if (de->last) {
935 if (de->down) d1 = de_down_pointer(de);
936 else goto error;
937 hpfs_brelse4(&qbh);
938 hpfs_free_dnode(s, dno);
939 dno = d1;
940 } else break;
941 }
942 if (!de->first) goto error;
943 d1 = de->down ? de_down_pointer(de) : 0;
944 de = de_next_de(de);
945 if (!de->last) goto error;
946 d2 = de->down ? de_down_pointer(de) : 0;
947 hpfs_brelse4(&qbh);
948 hpfs_free_dnode(s, dno);
949 do {
950 while (d1) {
951 if (!(dnode = hpfs_map_dnode(s, dno = d1, &qbh))) return;
952 de = dnode_first_de(dnode);
953 if (!de->last) goto error;
954 d1 = de->down ? de_down_pointer(de) : 0;
955 hpfs_brelse4(&qbh);
956 hpfs_free_dnode(s, dno);
957 }
958 d1 = d2;
959 d2 = 0;
960 } while (d1);
961 return;
962 error:
963 hpfs_brelse4(&qbh);
964 hpfs_free_dnode(s, dno);
965 hpfs_error(s, "directory %08x is corrupted or not empty", rdno);
966 }
967
968 /*
969 * Find dirent for specified fnode. Use truncated 15-char name in fnode as
970 * a help for searching.
971 */
972
map_fnode_dirent(struct super_block * s,fnode_secno fno,struct fnode * f,struct quad_buffer_head * qbh)973 struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
974 struct fnode *f, struct quad_buffer_head *qbh)
975 {
976 char *name1;
977 char *name2;
978 int name1len, name2len;
979 struct dnode *d;
980 dnode_secno dno, downd;
981 struct fnode *upf;
982 struct buffer_head *bh;
983 struct hpfs_dirent *de, *de_end;
984 int c;
985 int c1, c2 = 0;
986 int d1, d2 = 0;
987 name1 = f->name;
988 if (!(name2 = kmalloc(256, GFP_KERNEL))) {
989 printk("HPFS: out of memory, can't map dirent\n");
990 return NULL;
991 }
992 if (f->len <= 15)
993 memcpy(name2, name1, name1len = name2len = f->len);
994 else {
995 memcpy(name2, name1, 15);
996 memset(name2 + 15, 0xff, 256 - 15);
997 /*name2[15] = 0xff;*/
998 name1len = 15; name2len = 256;
999 }
1000 if (!(upf = hpfs_map_fnode(s, f->up, &bh))) {
1001 kfree(name2);
1002 return NULL;
1003 }
1004 if (!upf->dirflag) {
1005 brelse(bh);
1006 hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, f->up);
1007 kfree(name2);
1008 return NULL;
1009 }
1010 dno = upf->u.external[0].disk_secno;
1011 brelse(bh);
1012 go_down:
1013 downd = 0;
1014 go_up:
1015 if (!(d = hpfs_map_dnode(s, dno, qbh))) {
1016 kfree(name2);
1017 return NULL;
1018 }
1019 de_end = dnode_end_de(d);
1020 de = dnode_first_de(d);
1021 if (downd) {
1022 while (de < de_end) {
1023 if (de->down) if (de_down_pointer(de) == downd) goto f;
1024 de = de_next_de(de);
1025 }
1026 hpfs_error(s, "pointer to dnode %08x not found in dnode %08x", downd, dno);
1027 hpfs_brelse4(qbh);
1028 kfree(name2);
1029 return NULL;
1030 }
1031 next_de:
1032 if (de->fnode == fno) {
1033 kfree(name2);
1034 return de;
1035 }
1036 c = hpfs_compare_names(s, name1, name1len, de->name, de->namelen, de->last);
1037 if (c < 0 && de->down) {
1038 dno = de_down_pointer(de);
1039 hpfs_brelse4(qbh);
1040 if (s->s_hpfs_chk)
1041 if (hpfs_stop_cycles(s, dno, &c1, &c2, "map_fnode_dirent #1")) {
1042 kfree(name2);
1043 return NULL;
1044 }
1045 goto go_down;
1046 }
1047 f:
1048 if (de->fnode == fno) {
1049 kfree(name2);
1050 return de;
1051 }
1052 c = hpfs_compare_names(s, name2, name2len, de->name, de->namelen, de->last);
1053 if (c < 0 && !de->last) goto not_found;
1054 if ((de = de_next_de(de)) < de_end) goto next_de;
1055 if (d->root_dnode) goto not_found;
1056 downd = dno;
1057 dno = d->up;
1058 hpfs_brelse4(qbh);
1059 if (s->s_hpfs_chk)
1060 if (hpfs_stop_cycles(s, downd, &d1, &d2, "map_fnode_dirent #2")) {
1061 kfree(name2);
1062 return NULL;
1063 }
1064 goto go_up;
1065 not_found:
1066 hpfs_brelse4(qbh);
1067 hpfs_error(s, "dirent for fnode %08x not found", fno);
1068 kfree(name2);
1069 return NULL;
1070 }
1071