blob: 4ada525c5c43781aeb5060455c01d5c2511fd368 [file] [log] [blame]
Greg Kroah-Hartmanb2441312017-11-01 15:07:57 +01001// SPDX-License-Identifier: GPL-2.0
Linus Torvalds1da177e2005-04-16 15:20:36 -07002/*
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
12static 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)) {
Mikulas Patocka0b697602011-05-08 20:44:26 +020018 if (de == fde) return ((loff_t) le32_to_cpu(d->self) << 4) | (loff_t)i;
Linus Torvalds1da177e2005-04-16 15:20:36 -070019 i++;
20 }
Fabian Frederick1749a102014-06-06 14:36:35 -070021 pr_info("%s(): not_found\n", __func__);
Mikulas Patocka0b697602011-05-08 20:44:26 +020022 return ((loff_t)le32_to_cpu(d->self) << 4) | (loff_t)1;
Linus Torvalds1da177e2005-04-16 15:20:36 -070023}
24
Al Viroe82c3142016-05-12 19:35:57 -040025int hpfs_add_pos(struct inode *inode, loff_t *pos)
Linus Torvalds1da177e2005-04-16 15:20:36 -070026{
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++)
Al Viroe82c3142016-05-12 19:35:57 -040033 if (hpfs_inode->i_rddir_off[i] == pos)
34 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070035 if (!(i&0x0f)) {
Kees Cook6da2ec52018-06-12 13:55:00 -070036 ppos = kmalloc_array(i + 0x11, sizeof(loff_t *), GFP_NOFS);
37 if (!ppos) {
Fabian Fredericka19189e2014-06-06 14:36:36 -070038 pr_err("out of memory for position list\n");
Al Viroe82c3142016-05-12 19:35:57 -040039 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -070040 }
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;
Al Viroe82c3142016-05-12 19:35:57 -040049 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -070050}
51
52void 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:
Fabian Frederick14da17f2014-06-06 14:36:34 -070070 /*pr_warn("position pointer %p->%08x not found\n",
Fabian Frederickb7cb1ce2014-06-06 14:36:34 -070071 pos, (int)*pos);*/
Linus Torvalds1da177e2005-04-16 15:20:36 -070072 return;
73}
74
75static 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
86static 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
96static 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;
Fabian Frederickb7cb1ce2014-06-06 14:36:34 -0700100 if (n > 0x3f)
Fabian Fredericka19189e2014-06-06 14:36:36 -0700101 pr_err("%s(): %08x + %d\n",
Fabian Frederick1749a102014-06-06 14:36:35 -0700102 __func__, (int)*p, (int)c >> 8);
Fabian Frederickb7cb1ce2014-06-06 14:36:34 -0700103 else
104 *p = (*p & ~0x3f) | n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105 }
106}
107
108static 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;
Fabian Frederickb7cb1ce2014-06-06 14:36:34 -0700112 if (n < 1)
Fabian Fredericka19189e2014-06-06 14:36:36 -0700113 pr_err("%s(): %08x - %d\n",
Fabian Frederick1749a102014-06-06 14:36:35 -0700114 __func__, (int)*p, (int)c >> 8);
Fabian Frederickb7cb1ce2014-06-06 14:36:34 -0700115 else
116 *p = (*p & ~0x3f) | n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700117 }
118}
119
120static 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
130static 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
140static 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))) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200144 hpfs_error(s, "set_last_pointer: empty dnode %08x", le32_to_cpu(d->self));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700145 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",
Mikulas Patocka0b697602011-05-08 20:44:26 +0200150 le32_to_cpu(d->self), de_down_pointer(de));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700151 return;
152 }
Mikulas Patocka0b697602011-05-08 20:44:26 +0200153 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));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700155 return;
156 }
157 }
158 if (ptr) {
Wei Yongjun32daab92012-10-04 17:14:39 -0700159 le32_add_cpu(&d->first_free, 4);
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200160 if (le32_to_cpu(d->first_free) > 2048) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200161 hpfs_error(s, "set_last_pointer: too long dnode %08x", le32_to_cpu(d->self));
Wei Yongjun32daab92012-10-04 17:14:39 -0700162 le32_add_cpu(&d->first_free, -4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700163 return;
164 }
Mikulas Patocka0b697602011-05-08 20:44:26 +0200165 de->length = cpu_to_le16(36);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700166 de->down = 1;
Al Viro46287aa2012-04-17 16:20:49 -0400167 *(__le32 *)((char *)de + 32) = cpu_to_le32(ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700168 }
169}
170
171/* Add an entry to dnode and don't care if it grows over 2048 bytes */
172
Al Viro7e7742e2010-01-31 17:09:29 -0500173struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d,
174 const unsigned char *name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700175 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) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200183 hpfs_error(s, "name (%c,%d) already exists in dnode %08x", *name, namelen, le32_to_cpu(d->self));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700184 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) {
Al Viro46287aa2012-04-17 16:20:49 -0400191 *(__le32 *)((char *)de + d_size - 4) = cpu_to_le32(down_ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700192 de->down = 1;
193 }
Mikulas Patocka0b697602011-05-08 20:44:26 +0200194 de->length = cpu_to_le16(d_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 de->not_8x3 = hpfs_is_name_long(name, namelen);
196 de->namelen = namelen;
197 memcpy(de->name, name, namelen);
Wei Yongjun32daab92012-10-04 17:14:39 -0700198 le32_add_cpu(&d->first_free, d_size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700199 return de;
200}
201
202/* Delete dirent and don't care about its subtree */
203
204static void hpfs_delete_de(struct super_block *s, struct dnode *d,
205 struct hpfs_dirent *de)
206{
207 if (de->last) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200208 hpfs_error(s, "attempt to delete last dirent in dnode %08x", le32_to_cpu(d->self));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700209 return;
210 }
Mikulas Patocka0b697602011-05-08 20:44:26 +0200211 d->first_free = cpu_to_le32(le32_to_cpu(d->first_free) - le16_to_cpu(de->length));
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200212 memmove(de, de_next_de(de), le32_to_cpu(d->first_free) + (char *)d - (char *)de);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700213}
214
215static 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);
Mikulas Patocka0b697602011-05-08 20:44:26 +0200219 dnode_secno dno = le32_to_cpu(d->self);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700220 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))) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200225 if (le32_to_cpu(dd->up) != dno || dd->root_dnode) {
226 dd->up = cpu_to_le32(dno);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227 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
237static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
Al Viro7e7742e2010-01-31 17:09:29 -0500238 const unsigned char *name, unsigned namelen,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239 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;
Al Viro7e7742e2010-01-31 17:09:29 -0500246 unsigned char *nname;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700247 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))) {
Fabian Fredericka19189e2014-06-06 14:36:36 -0700253 pr_err("out of memory, can't add to dnode\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 return 1;
255 }
256 go_up:
257 if (namelen >= 256) {
Fabian Frederick1749a102014-06-06 14:36:35 -0700258 hpfs_error(i->i_sb, "%s(): namelen == %d", __func__, namelen);
Jesper Juhlf99d49a2005-11-07 01:01:34 -0800259 kfree(nd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 kfree(nname);
261 return 1;
262 }
263 if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) {
Jesper Juhlf99d49a2005-11-07 01:01:34 -0800264 kfree(nd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700265 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);
Jesper Juhlf99d49a2005-11-07 01:01:34 -0800272 kfree(nd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700273 kfree(nname);
274 return 1;
275 }
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200276 if (le32_to_cpu(d->first_free) + de_size(namelen, down_ptr) <= 2048) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700277 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);
Jesper Juhlf99d49a2005-11-07 01:01:34 -0800285 kfree(nd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286 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. */
Fabian Fredericka19189e2014-06-06 14:36:36 -0700295 pr_err("out of memory for dnode splitting\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700296 hpfs_brelse4(&qbh);
297 kfree(nname);
298 return 1;
299 }
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200300 memcpy(nd, d, le32_to_cpu(d->first_free));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700301 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;
Mikulas Patocka0b697602011-05-08 20:44:26 +0200304 if (!(ad = hpfs_alloc_dnode(i->i_sb, le32_to_cpu(d->up), &adno, &qbh1))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700305 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);
Al Viro7e7742e2010-01-31 17:09:29 -0500320 memcpy(nname, de->name, de->namelen);
321 name = nname;
322 namelen = de->namelen;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700323 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);
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200327 memmove((char *)nd + 20, de, le32_to_cpu(nd->first_free) + (char *)nd - (char *)de);
Wei Yongjun32daab92012-10-04 17:14:39 -0700328 le32_add_cpu(&nd->first_free, -((char *)de - (char *)nd - 20));
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200329 memcpy(d, nd, le32_to_cpu(nd->first_free));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700330 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) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200333 ad->up = d->up;
334 dno = le32_to_cpu(ad->up);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 hpfs_mark_4buffers_dirty(&qbh);
336 hpfs_brelse4(&qbh);
337 hpfs_mark_4buffers_dirty(&qbh1);
338 hpfs_brelse4(&qbh1);
339 goto go_up;
340 }
Mikulas Patocka0b697602011-05-08 20:44:26 +0200341 if (!(rd = hpfs_alloc_dnode(i->i_sb, le32_to_cpu(d->up), &rdno, &qbh2))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700342 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;
Mikulas Patocka0b697602011-05-08 20:44:26 +0200353 if (!(fnode = hpfs_map_fnode(i->i_sb, le32_to_cpu(d->up), &bh))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354 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 }
Mikulas Patocka0b697602011-05-08 20:44:26 +0200362 fnode->u.external[0].disk_secno = cpu_to_le32(rdno);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 mark_buffer_dirty(bh);
364 brelse(bh);
Mikulas Patocka0b697602011-05-08 20:44:26 +0200365 hpfs_i(i)->i_dno = rdno;
366 d->up = ad->up = cpu_to_le32(rdno);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 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
Al Viro7e7742e2010-01-31 17:09:29 -0500387int hpfs_add_dirent(struct inode *i,
388 const unsigned char *name, unsigned namelen,
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200389 struct hpfs_dirent *new_de)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390{
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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700419 if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_ADD)) {
420 c = 1;
421 goto ret;
422 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 c = hpfs_add_to_dnode(i, dno, name, namelen, new_de, 0);
424 ret:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700425 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
433static 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) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200450 if (le32_to_cpu(dnode->up) != chk_up) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 hpfs_error(i->i_sb, "move_to_top: up pointer from %08x should be %08x, is %08x",
Mikulas Patocka0b697602011-05-08 20:44:26 +0200452 dno, chk_up, le32_to_cpu(dnode->up));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700453 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))) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200468 dnode_secno up = le32_to_cpu(dnode->up);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700469 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 }
Wei Yongjun32daab92012-10-04 17:14:39 -0700487 le32_add_cpu(&dnode->first_free, -4);
488 le16_add_cpu(&de->length, -4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 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);
Mikulas Patocka0b697602011-05-08 20:44:26 +0200496 if (!(nde = kmalloc(le16_to_cpu(de->length), GFP_NOFS))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497 hpfs_error(i->i_sb, "out of memory for dirent - directory will be corrupted");
498 hpfs_brelse4(&qbh);
499 return 0;
500 }
Mikulas Patocka0b697602011-05-08 20:44:26 +0200501 memcpy(nde, de, le16_to_cpu(de->length));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700502 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
518static 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;
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200530 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) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700532 struct hpfs_dirent *de_end;
533 int root = dnode->root_dnode;
Mikulas Patocka0b697602011-05-08 20:44:26 +0200534 up = le32_to_cpu(dnode->up);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700535 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;
Randy Dunlap18debbb2006-12-06 20:37:05 -0800550 if (hpfs_sb(i->i_sb)->sb_chk)
Fabian Frederickf58d6c72014-08-08 14:21:16 -0700551 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 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200559 d1->up = cpu_to_le32(up);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 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))) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200565 fnode->u.external[0].disk_secno = cpu_to_le32(down);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 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;
Wei Yongjun32daab92012-10-04 17:14:39 -0700584 le16_add_cpu(&de->length, -4);
585 le32_add_cpu(&dnode->first_free, -4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 memmove(de_next_de(de), (char *)de_next_de(de) + 4,
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200587 (char *)dnode + le32_to_cpu(dnode->first_free) - (char *)de_next_de(de));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 } else {
589 struct dnode *d1;
590 struct quad_buffer_head qbh1;
Mikulas Patocka0b697602011-05-08 20:44:26 +0200591 *(dnode_secno *) ((void *) de + le16_to_cpu(de->length) - 4) = down;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592 if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200593 d1->up = cpu_to_le32(up);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 hpfs_mark_4buffers_dirty(&qbh1);
595 hpfs_brelse4(&qbh1);
596 }
597 }
598 } else {
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200599 hpfs_error(i->i_sb, "delete_empty_dnode: dnode %08x, first_free == %03x", dno, le32_to_cpu(dnode->first_free));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700600 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);
Mikulas Patocka0b697602011-05-08 20:44:26 +0200610 if (!(de_cp = kmalloc(le16_to_cpu(de->length), GFP_NOFS))) {
Fabian Fredericka19189e2014-06-06 14:36:36 -0700611 pr_err("out of memory for dtree balancing\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 goto endm;
613 }
Mikulas Patocka0b697602011-05-08 20:44:26 +0200614 memcpy(de_cp, de, le16_to_cpu(de->length));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 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))) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200621 d1->up = cpu_to_le32(ndown);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700622 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);
Fabian Frederickb7cb1ce2014-06-06 14:36:34 -0700626 /*pr_info("UP-TO-DNODE: %08x (ndown = %08x, down = %08x, dno = %08x)\n",
627 up, ndown, down, dno);*/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700628 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) {
Mikulas Patocka7d23ce32011-05-08 20:43:06 +0200650 if (le32_to_cpu(d1->first_free) > 2044) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 if (hpfs_sb(i->i_sb)->sb_chk >= 2) {
Fabian Fredericka19189e2014-06-06 14:36:36 -0700652 pr_err("unbalanced dnode tree, see hpfs.txt 4 more info\n");
653 pr_err("terminating balancing operation\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 }
655 hpfs_brelse4(&qbh1);
656 goto endm;
657 }
658 if (hpfs_sb(i->i_sb)->sb_chk >= 2) {
Fabian Fredericka19189e2014-06-06 14:36:36 -0700659 pr_err("unbalanced dnode tree, see hpfs.txt 4 more info\n");
660 pr_err("goin'on\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700661 }
Wei Yongjun32daab92012-10-04 17:14:39 -0700662 le16_add_cpu(&del->length, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700663 del->down = 1;
Wei Yongjun32daab92012-10-04 17:14:39 -0700664 le32_add_cpu(&d1->first_free, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 }
666 if (dlp && !down) {
Wei Yongjun32daab92012-10-04 17:14:39 -0700667 le16_add_cpu(&del->length, -4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700668 del->down = 0;
Wei Yongjun32daab92012-10-04 17:14:39 -0700669 le32_add_cpu(&d1->first_free, -4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 } else if (down)
Al Viro46287aa2012-04-17 16:20:49 -0400671 *(__le32 *) ((void *) del + le16_to_cpu(del->length) - 4) = cpu_to_le32(down);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 } else goto endm;
Mikulas Patocka0b697602011-05-08 20:44:26 +0200673 if (!(de_cp = kmalloc(le16_to_cpu(de_prev->length), GFP_NOFS))) {
Fabian Fredericka19189e2014-06-06 14:36:36 -0700674 pr_err("out of memory for dtree balancing\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700675 hpfs_brelse4(&qbh1);
676 goto endm;
677 }
678 hpfs_mark_4buffers_dirty(&qbh1);
679 hpfs_brelse4(&qbh1);
Mikulas Patocka0b697602011-05-08 20:44:26 +0200680 memcpy(de_cp, de_prev, le16_to_cpu(de_prev->length));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700681 hpfs_delete_de(i->i_sb, dnode, de_prev);
682 if (!de_prev->down) {
Wei Yongjun32daab92012-10-04 17:14:39 -0700683 le16_add_cpu(&de_prev->length, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684 de_prev->down = 1;
Wei Yongjun32daab92012-10-04 17:14:39 -0700685 le32_add_cpu(&dnode->first_free, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 }
Al Viro46287aa2012-04-17 16:20:49 -0400687 *(__le32 *) ((void *) de_prev + le16_to_cpu(de_prev->length) - 4) = cpu_to_le32(ndown);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700688 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))) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200693 d1->up = cpu_to_le32(ndown);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 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
711int 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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700716 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))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_DEL)) {
725 hpfs_brelse4(qbh);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726 return 2;
727 }
728 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729 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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 return !a;
738 }
739 delete_empty_dnode(i, dno);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700740 return 0;
741}
742
743void 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;
Mikulas Patocka0b697602011-05-08 20:44:26 +0200759 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));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700761 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;
Mikulas Patocka0b697602011-05-08 20:44:26 +0200784 dno = le32_to_cpu(dnode->up);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785 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
796static 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
818dnode_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)
Mikulas Patocka0b697602011-05-08 20:44:26 +0200832 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));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700834 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
844struct 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)) {
Randy Dunlap18debbb2006-12-06 20:37:05 -0800866 hpfs_error(inode->i_sb,
867 "map_pos_dirent: pos crossed dnode boundary; pos = %08llx",
868 (unsigned long long)*posp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700869 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
Mikulas Patocka0b697602011-05-08 20:44:26 +0200882 if (!(up_dnode = hpfs_map_dnode(inode->i_sb, le32_to_cpu(dnode->up), &qbh0)))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 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,
Mikulas Patocka0b697602011-05-08 20:44:26 +0200890 "map_pos_dirent: pos crossed dnode boundary; dnode = %08x", le32_to_cpu(dnode->up));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 if (up_de->down && de_down_pointer(up_de) == dno) {
Mikulas Patocka0b697602011-05-08 20:44:26 +0200892 *posp = ((loff_t) le32_to_cpu(dnode->up) << 4) + c;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 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",
Mikulas Patocka0b697602011-05-08 20:44:26 +0200899 dno, le32_to_cpu(dnode->up));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 hpfs_brelse4(&qbh0);
901
902 bail:
903 *posp = 12;
904 return de;
905}
906
907/* Find a dirent in tree */
908
Al Viro7e7742e2010-01-31 17:09:29 -0500909struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno,
910 const unsigned char *name, unsigned len,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700911 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
950void 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
998struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
999 struct fnode *f, struct quad_buffer_head *qbh)
1000{
Al Viro7e7742e2010-01-31 17:09:29 -05001001 unsigned char *name1;
1002 unsigned char *name2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 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))) {
Fabian Fredericka19189e2014-06-06 14:36:36 -07001014 pr_err("out of memory, can't map dirent\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 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 }
Mikulas Patocka0b697602011-05-08 20:44:26 +02001025 if (!(upf = hpfs_map_fnode(s, le32_to_cpu(f->up), &bh))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001026 kfree(name2);
1027 return NULL;
1028 }
Al Viroc4c99542012-04-06 14:30:07 -04001029 if (!fnode_is_dir(upf)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001030 brelse(bh);
Mikulas Patocka0b697602011-05-08 20:44:26 +02001031 hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, le32_to_cpu(f->up));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 kfree(name2);
1033 return NULL;
1034 }
Mikulas Patocka0b697602011-05-08 20:44:26 +02001035 dno = le32_to_cpu(upf->u.external[0].disk_secno);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 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:
Mikulas Patocka0b697602011-05-08 20:44:26 +02001057 if (le32_to_cpu(de->fnode) == fno) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001058 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")) {
Fabian Frederickf58d6c72014-08-08 14:21:16 -07001067 kfree(name2);
1068 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 }
1070 goto go_down;
1071 }
1072 f:
Mikulas Patocka0b697602011-05-08 20:44:26 +02001073 if (le32_to_cpu(de->fnode) == fno) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 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;
Mikulas Patocka0b697602011-05-08 20:44:26 +02001082 dno = le32_to_cpu(d->up);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083 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}