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