aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hpfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/hpfs')
-rw-r--r--fs/hpfs/Makefile8
-rw-r--r--fs/hpfs/alloc.c456
-rw-r--r--fs/hpfs/anode.c491
-rw-r--r--fs/hpfs/buffer.c175
-rw-r--r--fs/hpfs/dentry.c60
-rw-r--r--fs/hpfs/dir.c320
-rw-r--r--fs/hpfs/dnode.c1080
-rw-r--r--fs/hpfs/ea.c363
-rw-r--r--fs/hpfs/file.c140
-rw-r--r--fs/hpfs/hpfs.h493
-rw-r--r--fs/hpfs/hpfs_fn.h338
-rw-r--r--fs/hpfs/inode.c291
-rw-r--r--fs/hpfs/map.c275
-rw-r--r--fs/hpfs/name.c144
-rw-r--r--fs/hpfs/namei.c673
-rw-r--r--fs/hpfs/super.c701
16 files changed, 6008 insertions, 0 deletions
diff --git a/fs/hpfs/Makefile b/fs/hpfs/Makefile
new file mode 100644
index 000000000000..57b786fb9827
--- /dev/null
+++ b/fs/hpfs/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the Linux hpfs filesystem routines.
3#
4
5obj-$(CONFIG_HPFS_FS) += hpfs.o
6
7hpfs-objs := alloc.o anode.o buffer.o dentry.o dir.o dnode.o ea.o file.o \
8 inode.o map.o name.o namei.o super.o
diff --git a/fs/hpfs/alloc.c b/fs/hpfs/alloc.c
new file mode 100644
index 000000000000..5503e2c28910
--- /dev/null
+++ b/fs/hpfs/alloc.c
@@ -0,0 +1,456 @@
1/*
2 * linux/fs/hpfs/alloc.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * HPFS bitmap operations
7 */
8
9#include "hpfs_fn.h"
10
11static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec);
12
13/*
14 * Check if a sector is allocated in bitmap
15 * This is really slow. Turned on only if chk==2
16 */
17
18static int chk_if_allocated(struct super_block *s, secno sec, char *msg)
19{
20 struct quad_buffer_head qbh;
21 unsigned *bmp;
22 if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "chk"))) goto fail;
23 if ((bmp[(sec & 0x3fff) >> 5] >> (sec & 0x1f)) & 1) {
24 hpfs_error(s, "sector '%s' - %08x not allocated in bitmap", msg, sec);
25 goto fail1;
26 }
27 hpfs_brelse4(&qbh);
28 if (sec >= hpfs_sb(s)->sb_dirband_start && sec < hpfs_sb(s)->sb_dirband_start + hpfs_sb(s)->sb_dirband_size) {
29 unsigned ssec = (sec - hpfs_sb(s)->sb_dirband_start) / 4;
30 if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) goto fail;
31 if ((bmp[ssec >> 5] >> (ssec & 0x1f)) & 1) {
32 hpfs_error(s, "sector '%s' - %08x not allocated in directory bitmap", msg, sec);
33 goto fail1;
34 }
35 hpfs_brelse4(&qbh);
36 }
37 return 0;
38 fail1:
39 hpfs_brelse4(&qbh);
40 fail:
41 return 1;
42}
43
44/*
45 * Check if sector(s) have proper number and additionally check if they're
46 * allocated in bitmap.
47 */
48
49int hpfs_chk_sectors(struct super_block *s, secno start, int len, char *msg)
50{
51 if (start + len < start || start < 0x12 ||
52 start + len > hpfs_sb(s)->sb_fs_size) {
53 hpfs_error(s, "sector(s) '%s' badly placed at %08x", msg, start);
54 return 1;
55 }
56 if (hpfs_sb(s)->sb_chk>=2) {
57 int i;
58 for (i = 0; i < len; i++)
59 if (chk_if_allocated(s, start + i, msg)) return 1;
60 }
61 return 0;
62}
63
64static secno alloc_in_bmp(struct super_block *s, secno near, unsigned n, unsigned forward)
65{
66 struct quad_buffer_head qbh;
67 unsigned *bmp;
68 unsigned bs = near & ~0x3fff;
69 unsigned nr = (near & 0x3fff) & ~(n - 1);
70 /*unsigned mnr;*/
71 unsigned i, q;
72 int a, b;
73 secno ret = 0;
74 if (n != 1 && n != 4) {
75 hpfs_error(s, "Bad allocation size: %d", n);
76 return 0;
77 }
78 lock_super(s);
79 if (bs != ~0x3fff) {
80 if (!(bmp = hpfs_map_bitmap(s, near >> 14, &qbh, "aib"))) goto uls;
81 } else {
82 if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) goto uls;
83 }
84 if (!tstbits(bmp, nr, n + forward)) {
85 ret = bs + nr;
86 goto rt;
87 }
88 /*if (!tstbits(bmp, nr + n, n + forward)) {
89 ret = bs + nr + n;
90 goto rt;
91 }*/
92 q = nr + n; b = 0;
93 while ((a = tstbits(bmp, q, n + forward)) != 0) {
94 q += a;
95 if (n != 1) q = ((q-1)&~(n-1))+n;
96 if (!b) {
97 if (q>>5 != nr>>5) {
98 b = 1;
99 q = nr & 0x1f;
100 }
101 } else if (q > nr) break;
102 }
103 if (!a) {
104 ret = bs + q;
105 goto rt;
106 }
107 nr >>= 5;
108 /*for (i = nr + 1; i != nr; i++, i &= 0x1ff) {*/
109 i = nr;
110 do {
111 if (!bmp[i]) goto cont;
112 if (n + forward >= 0x3f && bmp[i] != -1) goto cont;
113 q = i<<5;
114 if (i > 0) {
115 unsigned k = bmp[i-1];
116 while (k & 0x80000000) {
117 q--; k <<= 1;
118 }
119 }
120 if (n != 1) q = ((q-1)&~(n-1))+n;
121 while ((a = tstbits(bmp, q, n + forward)) != 0) {
122 q += a;
123 if (n != 1) q = ((q-1)&~(n-1))+n;
124 if (q>>5 > i) break;
125 }
126 if (!a) {
127 ret = bs + q;
128 goto rt;
129 }
130 cont:
131 i++, i &= 0x1ff;
132 } while (i != nr);
133 rt:
134 if (ret) {
135 if (hpfs_sb(s)->sb_chk && ((ret >> 14) != (bs >> 14) || (bmp[(ret & 0x3fff) >> 5] | ~(((1 << n) - 1) << (ret & 0x1f))) != 0xffffffff)) {
136 hpfs_error(s, "Allocation doesn't work! Wanted %d, allocated at %08x", n, ret);
137 ret = 0;
138 goto b;
139 }
140 bmp[(ret & 0x3fff) >> 5] &= ~(((1 << n) - 1) << (ret & 0x1f));
141 hpfs_mark_4buffers_dirty(&qbh);
142 }
143 b:
144 hpfs_brelse4(&qbh);
145 uls:
146 unlock_super(s);
147 return ret;
148}
149
150/*
151 * Allocation strategy: 1) search place near the sector specified
152 * 2) search bitmap where free sectors last found
153 * 3) search all bitmaps
154 * 4) search all bitmaps ignoring number of pre-allocated
155 * sectors
156 */
157
158secno hpfs_alloc_sector(struct super_block *s, secno near, unsigned n, int forward, int lock)
159{
160 secno sec;
161 int i;
162 unsigned n_bmps;
163 struct hpfs_sb_info *sbi = hpfs_sb(s);
164 int f_p = 0;
165 int near_bmp;
166 if (forward < 0) {
167 forward = -forward;
168 f_p = 1;
169 }
170 if (lock) hpfs_lock_creation(s);
171 n_bmps = (sbi->sb_fs_size + 0x4000 - 1) >> 14;
172 if (near && near < sbi->sb_fs_size) {
173 if ((sec = alloc_in_bmp(s, near, n, f_p ? forward : forward/4))) goto ret;
174 near_bmp = near >> 14;
175 } else near_bmp = n_bmps / 2;
176 /*
177 if (b != -1) {
178 if ((sec = alloc_in_bmp(s, b<<14, n, f_p ? forward : forward/2))) {
179 b &= 0x0fffffff;
180 goto ret;
181 }
182 if (b > 0x10000000) if ((sec = alloc_in_bmp(s, (b&0xfffffff)<<14, n, f_p ? forward : 0))) goto ret;
183 */
184 if (!f_p) if (forward > sbi->sb_max_fwd_alloc) forward = sbi->sb_max_fwd_alloc;
185 less_fwd:
186 for (i = 0; i < n_bmps; i++) {
187 if (near_bmp+i < n_bmps && ((sec = alloc_in_bmp(s, (near_bmp+i) << 14, n, forward)))) {
188 sbi->sb_c_bitmap = near_bmp+i;
189 goto ret;
190 }
191 if (!forward) {
192 if (near_bmp-i-1 >= 0 && ((sec = alloc_in_bmp(s, (near_bmp-i-1) << 14, n, forward)))) {
193 sbi->sb_c_bitmap = near_bmp-i-1;
194 goto ret;
195 }
196 } else {
197 if (near_bmp+i >= n_bmps && ((sec = alloc_in_bmp(s, (near_bmp+i-n_bmps) << 14, n, forward)))) {
198 sbi->sb_c_bitmap = near_bmp+i-n_bmps;
199 goto ret;
200 }
201 }
202 if (i == 1 && sbi->sb_c_bitmap != -1 && ((sec = alloc_in_bmp(s, (sbi->sb_c_bitmap) << 14, n, forward)))) {
203 goto ret;
204 }
205 }
206 if (!f_p) {
207 if (forward) {
208 sbi->sb_max_fwd_alloc = forward * 3 / 4;
209 forward /= 2;
210 goto less_fwd;
211 }
212 }
213 sec = 0;
214 ret:
215 if (sec && f_p) {
216 for (i = 0; i < forward; i++) {
217 if (!hpfs_alloc_if_possible_nolock(s, sec + i + 1)) {
218 hpfs_error(s, "Prealloc doesn't work! Wanted %d, allocated at %08x, can't allocate %d", forward, sec, i);
219 sec = 0;
220 break;
221 }
222 }
223 }
224 if (lock) hpfs_unlock_creation(s);
225 return sec;
226}
227
228static secno alloc_in_dirband(struct super_block *s, secno near, int lock)
229{
230 unsigned nr = near;
231 secno sec;
232 struct hpfs_sb_info *sbi = hpfs_sb(s);
233 if (nr < sbi->sb_dirband_start)
234 nr = sbi->sb_dirband_start;
235 if (nr >= sbi->sb_dirband_start + sbi->sb_dirband_size)
236 nr = sbi->sb_dirband_start + sbi->sb_dirband_size - 4;
237 nr -= sbi->sb_dirband_start;
238 nr >>= 2;
239 if (lock) hpfs_lock_creation(s);
240 sec = alloc_in_bmp(s, (~0x3fff) | nr, 1, 0);
241 if (lock) hpfs_unlock_creation(s);
242 if (!sec) return 0;
243 return ((sec & 0x3fff) << 2) + sbi->sb_dirband_start;
244}
245
246/* Alloc sector if it's free */
247
248static int hpfs_alloc_if_possible_nolock(struct super_block *s, secno sec)
249{
250 struct quad_buffer_head qbh;
251 unsigned *bmp;
252 lock_super(s);
253 if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "aip"))) goto end;
254 if (bmp[(sec & 0x3fff) >> 5] & (1 << (sec & 0x1f))) {
255 bmp[(sec & 0x3fff) >> 5] &= ~(1 << (sec & 0x1f));
256 hpfs_mark_4buffers_dirty(&qbh);
257 hpfs_brelse4(&qbh);
258 unlock_super(s);
259 return 1;
260 }
261 hpfs_brelse4(&qbh);
262 end:
263 unlock_super(s);
264 return 0;
265}
266
267int hpfs_alloc_if_possible(struct super_block *s, secno sec)
268{
269 int r;
270 hpfs_lock_creation(s);
271 r = hpfs_alloc_if_possible_nolock(s, sec);
272 hpfs_unlock_creation(s);
273 return r;
274}
275
276/* Free sectors in bitmaps */
277
278void hpfs_free_sectors(struct super_block *s, secno sec, unsigned n)
279{
280 struct quad_buffer_head qbh;
281 unsigned *bmp;
282 struct hpfs_sb_info *sbi = hpfs_sb(s);
283 /*printk("2 - ");*/
284 if (!n) return;
285 if (sec < 0x12) {
286 hpfs_error(s, "Trying to free reserved sector %08x", sec);
287 return;
288 }
289 lock_super(s);
290 sbi->sb_max_fwd_alloc += n > 0xffff ? 0xffff : n;
291 if (sbi->sb_max_fwd_alloc > 0xffffff) sbi->sb_max_fwd_alloc = 0xffffff;
292 new_map:
293 if (!(bmp = hpfs_map_bitmap(s, sec >> 14, &qbh, "free"))) {
294 unlock_super(s);
295 return;
296 }
297 new_tst:
298 if ((bmp[(sec & 0x3fff) >> 5] >> (sec & 0x1f) & 1)) {
299 hpfs_error(s, "sector %08x not allocated", sec);
300 hpfs_brelse4(&qbh);
301 unlock_super(s);
302 return;
303 }
304 bmp[(sec & 0x3fff) >> 5] |= 1 << (sec & 0x1f);
305 if (!--n) {
306 hpfs_mark_4buffers_dirty(&qbh);
307 hpfs_brelse4(&qbh);
308 unlock_super(s);
309 return;
310 }
311 if (!(++sec & 0x3fff)) {
312 hpfs_mark_4buffers_dirty(&qbh);
313 hpfs_brelse4(&qbh);
314 goto new_map;
315 }
316 goto new_tst;
317}
318
319/*
320 * Check if there are at least n free dnodes on the filesystem.
321 * Called before adding to dnode. If we run out of space while
322 * splitting dnodes, it would corrupt dnode tree.
323 */
324
325int hpfs_check_free_dnodes(struct super_block *s, int n)
326{
327 int n_bmps = (hpfs_sb(s)->sb_fs_size + 0x4000 - 1) >> 14;
328 int b = hpfs_sb(s)->sb_c_bitmap & 0x0fffffff;
329 int i, j;
330 unsigned *bmp;
331 struct quad_buffer_head qbh;
332 if ((bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
333 for (j = 0; j < 512; j++) {
334 unsigned k;
335 if (!bmp[j]) continue;
336 for (k = bmp[j]; k; k >>= 1) if (k & 1) if (!--n) {
337 hpfs_brelse4(&qbh);
338 return 0;
339 }
340 }
341 }
342 hpfs_brelse4(&qbh);
343 i = 0;
344 if (hpfs_sb(s)->sb_c_bitmap != -1) {
345 bmp = hpfs_map_bitmap(s, b, &qbh, "chkdn1");
346 goto chk_bmp;
347 }
348 chk_next:
349 if (i == b) i++;
350 if (i >= n_bmps) return 1;
351 bmp = hpfs_map_bitmap(s, i, &qbh, "chkdn2");
352 chk_bmp:
353 if (bmp) {
354 for (j = 0; j < 512; j++) {
355 unsigned k;
356 if (!bmp[j]) continue;
357 for (k = 0xf; k; k <<= 4)
358 if ((bmp[j] & k) == k) {
359 if (!--n) {
360 hpfs_brelse4(&qbh);
361 return 0;
362 }
363 }
364 }
365 hpfs_brelse4(&qbh);
366 }
367 i++;
368 goto chk_next;
369}
370
371void hpfs_free_dnode(struct super_block *s, dnode_secno dno)
372{
373 if (hpfs_sb(s)->sb_chk) if (dno & 3) {
374 hpfs_error(s, "hpfs_free_dnode: dnode %08x not aligned", dno);
375 return;
376 }
377 if (dno < hpfs_sb(s)->sb_dirband_start ||
378 dno >= hpfs_sb(s)->sb_dirband_start + hpfs_sb(s)->sb_dirband_size) {
379 hpfs_free_sectors(s, dno, 4);
380 } else {
381 struct quad_buffer_head qbh;
382 unsigned *bmp;
383 unsigned ssec = (dno - hpfs_sb(s)->sb_dirband_start) / 4;
384 lock_super(s);
385 if (!(bmp = hpfs_map_dnode_bitmap(s, &qbh))) {
386 unlock_super(s);
387 return;
388 }
389 bmp[ssec >> 5] |= 1 << (ssec & 0x1f);
390 hpfs_mark_4buffers_dirty(&qbh);
391 hpfs_brelse4(&qbh);
392 unlock_super(s);
393 }
394}
395
396struct dnode *hpfs_alloc_dnode(struct super_block *s, secno near,
397 dnode_secno *dno, struct quad_buffer_head *qbh,
398 int lock)
399{
400 struct dnode *d;
401 if (hpfs_count_one_bitmap(s, hpfs_sb(s)->sb_dmap) > FREE_DNODES_ADD) {
402 if (!(*dno = alloc_in_dirband(s, near, lock)))
403 if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock))) return NULL;
404 } else {
405 if (!(*dno = hpfs_alloc_sector(s, near, 4, 0, lock)))
406 if (!(*dno = alloc_in_dirband(s, near, lock))) return NULL;
407 }
408 if (!(d = hpfs_get_4sectors(s, *dno, qbh))) {
409 hpfs_free_dnode(s, *dno);
410 return NULL;
411 }
412 memset(d, 0, 2048);
413 d->magic = DNODE_MAGIC;
414 d->first_free = 52;
415 d->dirent[0] = 32;
416 d->dirent[2] = 8;
417 d->dirent[30] = 1;
418 d->dirent[31] = 255;
419 d->self = *dno;
420 return d;
421}
422
423struct fnode *hpfs_alloc_fnode(struct super_block *s, secno near, fnode_secno *fno,
424 struct buffer_head **bh)
425{
426 struct fnode *f;
427 if (!(*fno = hpfs_alloc_sector(s, near, 1, FNODE_ALLOC_FWD, 1))) return NULL;
428 if (!(f = hpfs_get_sector(s, *fno, bh))) {
429 hpfs_free_sectors(s, *fno, 1);
430 return NULL;
431 }
432 memset(f, 0, 512);
433 f->magic = FNODE_MAGIC;
434 f->ea_offs = 0xc4;
435 f->btree.n_free_nodes = 8;
436 f->btree.first_free = 8;
437 return f;
438}
439
440struct anode *hpfs_alloc_anode(struct super_block *s, secno near, anode_secno *ano,
441 struct buffer_head **bh)
442{
443 struct anode *a;
444 if (!(*ano = hpfs_alloc_sector(s, near, 1, ANODE_ALLOC_FWD, 1))) return NULL;
445 if (!(a = hpfs_get_sector(s, *ano, bh))) {
446 hpfs_free_sectors(s, *ano, 1);
447 return NULL;
448 }
449 memset(a, 0, 512);
450 a->magic = ANODE_MAGIC;
451 a->self = *ano;
452 a->btree.n_free_nodes = 40;
453 a->btree.n_used_nodes = 0;
454 a->btree.first_free = 8;
455 return a;
456}
diff --git a/fs/hpfs/anode.c b/fs/hpfs/anode.c
new file mode 100644
index 000000000000..1aa88c4e0964
--- /dev/null
+++ b/fs/hpfs/anode.c
@@ -0,0 +1,491 @@
1/*
2 * linux/fs/hpfs/anode.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * handling HPFS anode tree that contains file allocation info
7 */
8
9#include "hpfs_fn.h"
10
11/* Find a sector in allocation tree */
12
13secno hpfs_bplus_lookup(struct super_block *s, struct inode *inode,
14 struct bplus_header *btree, unsigned sec,
15 struct buffer_head *bh)
16{
17 anode_secno a = -1;
18 struct anode *anode;
19 int i;
20 int c1, c2 = 0;
21 go_down:
22 if (hpfs_sb(s)->sb_chk) if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_bplus_lookup")) return -1;
23 if (btree->internal) {
24 for (i = 0; i < btree->n_used_nodes; i++)
25 if (btree->u.internal[i].file_secno > sec) {
26 a = btree->u.internal[i].down;
27 brelse(bh);
28 if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
29 btree = &anode->btree;
30 goto go_down;
31 }
32 hpfs_error(s, "sector %08x not found in internal anode %08x", sec, a);
33 brelse(bh);
34 return -1;
35 }
36 for (i = 0; i < btree->n_used_nodes; i++)
37 if (btree->u.external[i].file_secno <= sec &&
38 btree->u.external[i].file_secno + btree->u.external[i].length > sec) {
39 a = btree->u.external[i].disk_secno + sec - btree->u.external[i].file_secno;
40 if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, a, 1, "data")) {
41 brelse(bh);
42 return -1;
43 }
44 if (inode) {
45 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
46 hpfs_inode->i_file_sec = btree->u.external[i].file_secno;
47 hpfs_inode->i_disk_sec = btree->u.external[i].disk_secno;
48 hpfs_inode->i_n_secs = btree->u.external[i].length;
49 }
50 brelse(bh);
51 return a;
52 }
53 hpfs_error(s, "sector %08x not found in external anode %08x", sec, a);
54 brelse(bh);
55 return -1;
56}
57
58/* Add a sector to tree */
59
60secno hpfs_add_sector_to_btree(struct super_block *s, secno node, int fnod, unsigned fsecno)
61{
62 struct bplus_header *btree;
63 struct anode *anode = NULL, *ranode = NULL;
64 struct fnode *fnode;
65 anode_secno a, na = -1, ra, up = -1;
66 secno se;
67 struct buffer_head *bh, *bh1, *bh2;
68 int n;
69 unsigned fs;
70 int c1, c2 = 0;
71 if (fnod) {
72 if (!(fnode = hpfs_map_fnode(s, node, &bh))) return -1;
73 btree = &fnode->btree;
74 } else {
75 if (!(anode = hpfs_map_anode(s, node, &bh))) return -1;
76 btree = &anode->btree;
77 }
78 a = node;
79 go_down:
80 if ((n = btree->n_used_nodes - 1) < -!!fnod) {
81 hpfs_error(s, "anode %08x has no entries", a);
82 brelse(bh);
83 return -1;
84 }
85 if (btree->internal) {
86 a = btree->u.internal[n].down;
87 btree->u.internal[n].file_secno = -1;
88 mark_buffer_dirty(bh);
89 brelse(bh);
90 if (hpfs_sb(s)->sb_chk)
91 if (hpfs_stop_cycles(s, a, &c1, &c2, "hpfs_add_sector_to_btree #1")) return -1;
92 if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
93 btree = &anode->btree;
94 goto go_down;
95 }
96 if (n >= 0) {
97 if (btree->u.external[n].file_secno + btree->u.external[n].length != fsecno) {
98 hpfs_error(s, "allocated size %08x, trying to add sector %08x, %cnode %08x",
99 btree->u.external[n].file_secno + btree->u.external[n].length, fsecno,
100 fnod?'f':'a', node);
101 brelse(bh);
102 return -1;
103 }
104 if (hpfs_alloc_if_possible(s, se = btree->u.external[n].disk_secno + btree->u.external[n].length)) {
105 btree->u.external[n].length++;
106 mark_buffer_dirty(bh);
107 brelse(bh);
108 return se;
109 }
110 } else {
111 if (fsecno) {
112 hpfs_error(s, "empty file %08x, trying to add sector %08x", node, fsecno);
113 brelse(bh);
114 return -1;
115 }
116 se = !fnod ? node : (node + 16384) & ~16383;
117 }
118 if (!(se = hpfs_alloc_sector(s, se, 1, fsecno*ALLOC_M>ALLOC_FWD_MAX ? ALLOC_FWD_MAX : fsecno*ALLOC_M<ALLOC_FWD_MIN ? ALLOC_FWD_MIN : fsecno*ALLOC_M, 1))) {
119 brelse(bh);
120 return -1;
121 }
122 fs = n < 0 ? 0 : btree->u.external[n].file_secno + btree->u.external[n].length;
123 if (!btree->n_free_nodes) {
124 up = a != node ? anode->up : -1;
125 if (!(anode = hpfs_alloc_anode(s, a, &na, &bh1))) {
126 brelse(bh);
127 hpfs_free_sectors(s, se, 1);
128 return -1;
129 }
130 if (a == node && fnod) {
131 anode->up = node;
132 anode->btree.fnode_parent = 1;
133 anode->btree.n_used_nodes = btree->n_used_nodes;
134 anode->btree.first_free = btree->first_free;
135 anode->btree.n_free_nodes = 40 - anode->btree.n_used_nodes;
136 memcpy(&anode->u, &btree->u, btree->n_used_nodes * 12);
137 btree->internal = 1;
138 btree->n_free_nodes = 11;
139 btree->n_used_nodes = 1;
140 btree->first_free = (char *)&(btree->u.internal[1]) - (char *)btree;
141 btree->u.internal[0].file_secno = -1;
142 btree->u.internal[0].down = na;
143 mark_buffer_dirty(bh);
144 } else if (!(ranode = hpfs_alloc_anode(s, /*a*/0, &ra, &bh2))) {
145 brelse(bh);
146 brelse(bh1);
147 hpfs_free_sectors(s, se, 1);
148 hpfs_free_sectors(s, na, 1);
149 return -1;
150 }
151 brelse(bh);
152 bh = bh1;
153 btree = &anode->btree;
154 }
155 btree->n_free_nodes--; n = btree->n_used_nodes++;
156 btree->first_free += 12;
157 btree->u.external[n].disk_secno = se;
158 btree->u.external[n].file_secno = fs;
159 btree->u.external[n].length = 1;
160 mark_buffer_dirty(bh);
161 brelse(bh);
162 if ((a == node && fnod) || na == -1) return se;
163 c2 = 0;
164 while (up != -1) {
165 struct anode *new_anode;
166 if (hpfs_sb(s)->sb_chk)
167 if (hpfs_stop_cycles(s, up, &c1, &c2, "hpfs_add_sector_to_btree #2")) return -1;
168 if (up != node || !fnod) {
169 if (!(anode = hpfs_map_anode(s, up, &bh))) return -1;
170 btree = &anode->btree;
171 } else {
172 if (!(fnode = hpfs_map_fnode(s, up, &bh))) return -1;
173 btree = &fnode->btree;
174 }
175 if (btree->n_free_nodes) {
176 btree->n_free_nodes--; n = btree->n_used_nodes++;
177 btree->first_free += 8;
178 btree->u.internal[n].file_secno = -1;
179 btree->u.internal[n].down = na;
180 btree->u.internal[n-1].file_secno = fs;
181 mark_buffer_dirty(bh);
182 brelse(bh);
183 brelse(bh2);
184 hpfs_free_sectors(s, ra, 1);
185 if ((anode = hpfs_map_anode(s, na, &bh))) {
186 anode->up = up;
187 anode->btree.fnode_parent = up == node && fnod;
188 mark_buffer_dirty(bh);
189 brelse(bh);
190 }
191 return se;
192 }
193 up = up != node ? anode->up : -1;
194 btree->u.internal[btree->n_used_nodes - 1].file_secno = /*fs*/-1;
195 mark_buffer_dirty(bh);
196 brelse(bh);
197 a = na;
198 if ((new_anode = hpfs_alloc_anode(s, a, &na, &bh))) {
199 anode = new_anode;
200 /*anode->up = up != -1 ? up : ra;*/
201 anode->btree.internal = 1;
202 anode->btree.n_used_nodes = 1;
203 anode->btree.n_free_nodes = 59;
204 anode->btree.first_free = 16;
205 anode->btree.u.internal[0].down = a;
206 anode->btree.u.internal[0].file_secno = -1;
207 mark_buffer_dirty(bh);
208 brelse(bh);
209 if ((anode = hpfs_map_anode(s, a, &bh))) {
210 anode->up = na;
211 mark_buffer_dirty(bh);
212 brelse(bh);
213 }
214 } else na = a;
215 }
216 if ((anode = hpfs_map_anode(s, na, &bh))) {
217 anode->up = node;
218 if (fnod) anode->btree.fnode_parent = 1;
219 mark_buffer_dirty(bh);
220 brelse(bh);
221 }
222 if (!fnod) {
223 if (!(anode = hpfs_map_anode(s, node, &bh))) {
224 brelse(bh2);
225 return -1;
226 }
227 btree = &anode->btree;
228 } else {
229 if (!(fnode = hpfs_map_fnode(s, node, &bh))) {
230 brelse(bh2);
231 return -1;
232 }
233 btree = &fnode->btree;
234 }
235 ranode->up = node;
236 memcpy(&ranode->btree, btree, btree->first_free);
237 if (fnod) ranode->btree.fnode_parent = 1;
238 ranode->btree.n_free_nodes = (ranode->btree.internal ? 60 : 40) - ranode->btree.n_used_nodes;
239 if (ranode->btree.internal) for (n = 0; n < ranode->btree.n_used_nodes; n++) {
240 struct anode *unode;
241 if ((unode = hpfs_map_anode(s, ranode->u.internal[n].down, &bh1))) {
242 unode->up = ra;
243 unode->btree.fnode_parent = 0;
244 mark_buffer_dirty(bh1);
245 brelse(bh1);
246 }
247 }
248 btree->internal = 1;
249 btree->n_free_nodes = fnod ? 10 : 58;
250 btree->n_used_nodes = 2;
251 btree->first_free = (char *)&btree->u.internal[2] - (char *)btree;
252 btree->u.internal[0].file_secno = fs;
253 btree->u.internal[0].down = ra;
254 btree->u.internal[1].file_secno = -1;
255 btree->u.internal[1].down = na;
256 mark_buffer_dirty(bh);
257 brelse(bh);
258 mark_buffer_dirty(bh2);
259 brelse(bh2);
260 return se;
261}
262
263/*
264 * Remove allocation tree. Recursion would look much nicer but
265 * I want to avoid it because it can cause stack overflow.
266 */
267
268void hpfs_remove_btree(struct super_block *s, struct bplus_header *btree)
269{
270 struct bplus_header *btree1 = btree;
271 struct anode *anode = NULL;
272 anode_secno ano = 0, oano;
273 struct buffer_head *bh;
274 int level = 0;
275 int pos = 0;
276 int i;
277 int c1, c2 = 0;
278 int d1, d2;
279 go_down:
280 d2 = 0;
281 while (btree1->internal) {
282 ano = btree1->u.internal[pos].down;
283 if (level) brelse(bh);
284 if (hpfs_sb(s)->sb_chk)
285 if (hpfs_stop_cycles(s, ano, &d1, &d2, "hpfs_remove_btree #1"))
286 return;
287 if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
288 btree1 = &anode->btree;
289 level++;
290 pos = 0;
291 }
292 for (i = 0; i < btree1->n_used_nodes; i++)
293 hpfs_free_sectors(s, btree1->u.external[i].disk_secno, btree1->u.external[i].length);
294 go_up:
295 if (!level) return;
296 brelse(bh);
297 if (hpfs_sb(s)->sb_chk)
298 if (hpfs_stop_cycles(s, ano, &c1, &c2, "hpfs_remove_btree #2")) return;
299 hpfs_free_sectors(s, ano, 1);
300 oano = ano;
301 ano = anode->up;
302 if (--level) {
303 if (!(anode = hpfs_map_anode(s, ano, &bh))) return;
304 btree1 = &anode->btree;
305 } else btree1 = btree;
306 for (i = 0; i < btree1->n_used_nodes; i++) {
307 if (btree1->u.internal[i].down == oano) {
308 if ((pos = i + 1) < btree1->n_used_nodes)
309 goto go_down;
310 else
311 goto go_up;
312 }
313 }
314 hpfs_error(s,
315 "reference to anode %08x not found in anode %08x "
316 "(probably bad up pointer)",
317 oano, level ? ano : -1);
318 if (level)
319 brelse(bh);
320}
321
322/* Just a wrapper around hpfs_bplus_lookup .. used for reading eas */
323
324static secno anode_lookup(struct super_block *s, anode_secno a, unsigned sec)
325{
326 struct anode *anode;
327 struct buffer_head *bh;
328 if (!(anode = hpfs_map_anode(s, a, &bh))) return -1;
329 return hpfs_bplus_lookup(s, NULL, &anode->btree, sec, bh);
330}
331
332int hpfs_ea_read(struct super_block *s, secno a, int ano, unsigned pos,
333 unsigned len, char *buf)
334{
335 struct buffer_head *bh;
336 char *data;
337 secno sec;
338 unsigned l;
339 while (len) {
340 if (ano) {
341 if ((sec = anode_lookup(s, a, pos >> 9)) == -1)
342 return -1;
343 } else sec = a + (pos >> 9);
344 if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, sec, 1, "ea #1")) return -1;
345 if (!(data = hpfs_map_sector(s, sec, &bh, (len - 1) >> 9)))
346 return -1;
347 l = 0x200 - (pos & 0x1ff); if (l > len) l = len;
348 memcpy(buf, data + (pos & 0x1ff), l);
349 brelse(bh);
350 buf += l; pos += l; len -= l;
351 }
352 return 0;
353}
354
355int hpfs_ea_write(struct super_block *s, secno a, int ano, unsigned pos,
356 unsigned len, char *buf)
357{
358 struct buffer_head *bh;
359 char *data;
360 secno sec;
361 unsigned l;
362 while (len) {
363 if (ano) {
364 if ((sec = anode_lookup(s, a, pos >> 9)) == -1)
365 return -1;
366 } else sec = a + (pos >> 9);
367 if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, sec, 1, "ea #2")) return -1;
368 if (!(data = hpfs_map_sector(s, sec, &bh, (len - 1) >> 9)))
369 return -1;
370 l = 0x200 - (pos & 0x1ff); if (l > len) l = len;
371 memcpy(data + (pos & 0x1ff), buf, l);
372 mark_buffer_dirty(bh);
373 brelse(bh);
374 buf += l; pos += l; len -= l;
375 }
376 return 0;
377}
378
379void hpfs_ea_remove(struct super_block *s, secno a, int ano, unsigned len)
380{
381 struct anode *anode;
382 struct buffer_head *bh;
383 if (ano) {
384 if (!(anode = hpfs_map_anode(s, a, &bh))) return;
385 hpfs_remove_btree(s, &anode->btree);
386 brelse(bh);
387 hpfs_free_sectors(s, a, 1);
388 } else hpfs_free_sectors(s, a, (len + 511) >> 9);
389}
390
391/* Truncate allocation tree. Doesn't join anodes - I hope it doesn't matter */
392
393void hpfs_truncate_btree(struct super_block *s, secno f, int fno, unsigned secs)
394{
395 struct fnode *fnode;
396 struct anode *anode;
397 struct buffer_head *bh;
398 struct bplus_header *btree;
399 anode_secno node = f;
400 int i, j, nodes;
401 int c1, c2 = 0;
402 if (fno) {
403 if (!(fnode = hpfs_map_fnode(s, f, &bh))) return;
404 btree = &fnode->btree;
405 } else {
406 if (!(anode = hpfs_map_anode(s, f, &bh))) return;
407 btree = &anode->btree;
408 }
409 if (!secs) {
410 hpfs_remove_btree(s, btree);
411 if (fno) {
412 btree->n_free_nodes = 8;
413 btree->n_used_nodes = 0;
414 btree->first_free = 8;
415 btree->internal = 0;
416 mark_buffer_dirty(bh);
417 } else hpfs_free_sectors(s, f, 1);
418 brelse(bh);
419 return;
420 }
421 while (btree->internal) {
422 nodes = btree->n_used_nodes + btree->n_free_nodes;
423 for (i = 0; i < btree->n_used_nodes; i++)
424 if (btree->u.internal[i].file_secno >= secs) goto f;
425 brelse(bh);
426 hpfs_error(s, "internal btree %08x doesn't end with -1", node);
427 return;
428 f:
429 for (j = i + 1; j < btree->n_used_nodes; j++)
430 hpfs_ea_remove(s, btree->u.internal[j].down, 1, 0);
431 btree->n_used_nodes = i + 1;
432 btree->n_free_nodes = nodes - btree->n_used_nodes;
433 btree->first_free = 8 + 8 * btree->n_used_nodes;
434 mark_buffer_dirty(bh);
435 if (btree->u.internal[i].file_secno == secs) {
436 brelse(bh);
437 return;
438 }
439 node = btree->u.internal[i].down;
440 brelse(bh);
441 if (hpfs_sb(s)->sb_chk)
442 if (hpfs_stop_cycles(s, node, &c1, &c2, "hpfs_truncate_btree"))
443 return;
444 if (!(anode = hpfs_map_anode(s, node, &bh))) return;
445 btree = &anode->btree;
446 }
447 nodes = btree->n_used_nodes + btree->n_free_nodes;
448 for (i = 0; i < btree->n_used_nodes; i++)
449 if (btree->u.external[i].file_secno + btree->u.external[i].length >= secs) goto ff;
450 brelse(bh);
451 return;
452 ff:
453 if (secs <= btree->u.external[i].file_secno) {
454 hpfs_error(s, "there is an allocation error in file %08x, sector %08x", f, secs);
455 if (i) i--;
456 }
457 else if (btree->u.external[i].file_secno + btree->u.external[i].length > secs) {
458 hpfs_free_sectors(s, btree->u.external[i].disk_secno + secs -
459 btree->u.external[i].file_secno, btree->u.external[i].length
460 - secs + btree->u.external[i].file_secno); /* I hope gcc optimizes this :-) */
461 btree->u.external[i].length = secs - btree->u.external[i].file_secno;
462 }
463 for (j = i + 1; j < btree->n_used_nodes; j++)
464 hpfs_free_sectors(s, btree->u.external[j].disk_secno, btree->u.external[j].length);
465 btree->n_used_nodes = i + 1;
466 btree->n_free_nodes = nodes - btree->n_used_nodes;
467 btree->first_free = 8 + 12 * btree->n_used_nodes;
468 mark_buffer_dirty(bh);
469 brelse(bh);
470}
471
472/* Remove file or directory and it's eas - note that directory must
473 be empty when this is called. */
474
475void hpfs_remove_fnode(struct super_block *s, fnode_secno fno)
476{
477 struct buffer_head *bh;
478 struct fnode *fnode;
479 struct extended_attribute *ea;
480 struct extended_attribute *ea_end;
481 if (!(fnode = hpfs_map_fnode(s, fno, &bh))) return;
482 if (!fnode->dirflag) hpfs_remove_btree(s, &fnode->btree);
483 else hpfs_remove_dtree(s, fnode->u.external[0].disk_secno);
484 ea_end = fnode_end_ea(fnode);
485 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
486 if (ea->indirect)
487 hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
488 hpfs_ea_ext_remove(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l);
489 brelse(bh);
490 hpfs_free_sectors(s, fno, 1);
491}
diff --git a/fs/hpfs/buffer.c b/fs/hpfs/buffer.c
new file mode 100644
index 000000000000..2807aa833e62
--- /dev/null
+++ b/fs/hpfs/buffer.c
@@ -0,0 +1,175 @@
1/*
2 * linux/fs/hpfs/buffer.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * general buffer i/o
7 */
8
9#include "hpfs_fn.h"
10
11void hpfs_lock_creation(struct super_block *s)
12{
13#ifdef DEBUG_LOCKS
14 printk("lock creation\n");
15#endif
16 down(&hpfs_sb(s)->hpfs_creation_de);
17}
18
19void hpfs_unlock_creation(struct super_block *s)
20{
21#ifdef DEBUG_LOCKS
22 printk("unlock creation\n");
23#endif
24 up(&hpfs_sb(s)->hpfs_creation_de);
25}
26
27/* Map a sector into a buffer and return pointers to it and to the buffer. */
28
29void *hpfs_map_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp,
30 int ahead)
31{
32 struct buffer_head *bh;
33
34 cond_resched();
35
36 *bhp = bh = sb_bread(s, secno);
37 if (bh != NULL)
38 return bh->b_data;
39 else {
40 printk("HPFS: hpfs_map_sector: read error\n");
41 return NULL;
42 }
43}
44
45/* Like hpfs_map_sector but don't read anything */
46
47void *hpfs_get_sector(struct super_block *s, unsigned secno, struct buffer_head **bhp)
48{
49 struct buffer_head *bh;
50 /*return hpfs_map_sector(s, secno, bhp, 0);*/
51
52 cond_resched();
53
54 if ((*bhp = bh = sb_getblk(s, secno)) != NULL) {
55 if (!buffer_uptodate(bh)) wait_on_buffer(bh);
56 set_buffer_uptodate(bh);
57 return bh->b_data;
58 } else {
59 printk("HPFS: hpfs_get_sector: getblk failed\n");
60 return NULL;
61 }
62}
63
64/* Map 4 sectors into a 4buffer and return pointers to it and to the buffer. */
65
66void *hpfs_map_4sectors(struct super_block *s, unsigned secno, struct quad_buffer_head *qbh,
67 int ahead)
68{
69 struct buffer_head *bh;
70 char *data;
71
72 cond_resched();
73
74 if (secno & 3) {
75 printk("HPFS: hpfs_map_4sectors: unaligned read\n");
76 return NULL;
77 }
78
79 qbh->data = data = (char *)kmalloc(2048, GFP_NOFS);
80 if (!data) {
81 printk("HPFS: hpfs_map_4sectors: out of memory\n");
82 goto bail;
83 }
84
85 qbh->bh[0] = bh = sb_bread(s, secno);
86 if (!bh)
87 goto bail0;
88 memcpy(data, bh->b_data, 512);
89
90 qbh->bh[1] = bh = sb_bread(s, secno + 1);
91 if (!bh)
92 goto bail1;
93 memcpy(data + 512, bh->b_data, 512);
94
95 qbh->bh[2] = bh = sb_bread(s, secno + 2);
96 if (!bh)
97 goto bail2;
98 memcpy(data + 2 * 512, bh->b_data, 512);
99
100 qbh->bh[3] = bh = sb_bread(s, secno + 3);
101 if (!bh)
102 goto bail3;
103 memcpy(data + 3 * 512, bh->b_data, 512);
104
105 return data;
106
107 bail3:
108 brelse(qbh->bh[2]);
109 bail2:
110 brelse(qbh->bh[1]);
111 bail1:
112 brelse(qbh->bh[0]);
113 bail0:
114 kfree(data);
115 printk("HPFS: hpfs_map_4sectors: read error\n");
116 bail:
117 return NULL;
118}
119
120/* Don't read sectors */
121
122void *hpfs_get_4sectors(struct super_block *s, unsigned secno,
123 struct quad_buffer_head *qbh)
124{
125 cond_resched();
126
127 if (secno & 3) {
128 printk("HPFS: hpfs_get_4sectors: unaligned read\n");
129 return NULL;
130 }
131
132 /*return hpfs_map_4sectors(s, secno, qbh, 0);*/
133 if (!(qbh->data = kmalloc(2048, GFP_NOFS))) {
134 printk("HPFS: hpfs_get_4sectors: out of memory\n");
135 return NULL;
136 }
137 if (!(hpfs_get_sector(s, secno, &qbh->bh[0]))) goto bail0;
138 if (!(hpfs_get_sector(s, secno + 1, &qbh->bh[1]))) goto bail1;
139 if (!(hpfs_get_sector(s, secno + 2, &qbh->bh[2]))) goto bail2;
140 if (!(hpfs_get_sector(s, secno + 3, &qbh->bh[3]))) goto bail3;
141 memcpy(qbh->data, qbh->bh[0]->b_data, 512);
142 memcpy(qbh->data + 512, qbh->bh[1]->b_data, 512);
143 memcpy(qbh->data + 2*512, qbh->bh[2]->b_data, 512);
144 memcpy(qbh->data + 3*512, qbh->bh[3]->b_data, 512);
145 return qbh->data;
146
147 bail3: brelse(qbh->bh[2]);
148 bail2: brelse(qbh->bh[1]);
149 bail1: brelse(qbh->bh[0]);
150 bail0:
151 return NULL;
152}
153
154
155void hpfs_brelse4(struct quad_buffer_head *qbh)
156{
157 brelse(qbh->bh[3]);
158 brelse(qbh->bh[2]);
159 brelse(qbh->bh[1]);
160 brelse(qbh->bh[0]);
161 kfree(qbh->data);
162}
163
164void hpfs_mark_4buffers_dirty(struct quad_buffer_head *qbh)
165{
166 PRINTK(("hpfs_mark_4buffers_dirty\n"));
167 memcpy(qbh->bh[0]->b_data, qbh->data, 512);
168 memcpy(qbh->bh[1]->b_data, qbh->data + 512, 512);
169 memcpy(qbh->bh[2]->b_data, qbh->data + 2 * 512, 512);
170 memcpy(qbh->bh[3]->b_data, qbh->data + 3 * 512, 512);
171 mark_buffer_dirty(qbh->bh[0]);
172 mark_buffer_dirty(qbh->bh[1]);
173 mark_buffer_dirty(qbh->bh[2]);
174 mark_buffer_dirty(qbh->bh[3]);
175}
diff --git a/fs/hpfs/dentry.c b/fs/hpfs/dentry.c
new file mode 100644
index 000000000000..08319126b2af
--- /dev/null
+++ b/fs/hpfs/dentry.c
@@ -0,0 +1,60 @@
1/*
2 * linux/fs/hpfs/dentry.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * dcache operations
7 */
8
9#include "hpfs_fn.h"
10
11/*
12 * Note: the dentry argument is the parent dentry.
13 */
14
15static int hpfs_hash_dentry(struct dentry *dentry, struct qstr *qstr)
16{
17 unsigned long hash;
18 int i;
19 unsigned l = qstr->len;
20
21 if (l == 1) if (qstr->name[0]=='.') goto x;
22 if (l == 2) if (qstr->name[0]=='.' || qstr->name[1]=='.') goto x;
23 hpfs_adjust_length((char *)qstr->name, &l);
24 /*if (hpfs_chk_name((char *)qstr->name,&l))*/
25 /*return -ENAMETOOLONG;*/
26 /*return -ENOENT;*/
27 x:
28
29 hash = init_name_hash();
30 for (i = 0; i < l; i++)
31 hash = partial_name_hash(hpfs_upcase(hpfs_sb(dentry->d_sb)->sb_cp_table,qstr->name[i]), hash);
32 qstr->hash = end_name_hash(hash);
33
34 return 0;
35}
36
37static int hpfs_compare_dentry(struct dentry *dentry, struct qstr *a, struct qstr *b)
38{
39 unsigned al=a->len;
40 unsigned bl=b->len;
41 hpfs_adjust_length((char *)a->name, &al);
42 /*hpfs_adjust_length((char *)b->name, &bl);*/
43 /* 'a' is the qstr of an already existing dentry, so the name
44 * must be valid. 'b' must be validated first.
45 */
46
47 if (hpfs_chk_name((char *)b->name, &bl)) return 1;
48 if (hpfs_compare_names(dentry->d_sb, (char *)a->name, al, (char *)b->name, bl, 0)) return 1;
49 return 0;
50}
51
52static struct dentry_operations hpfs_dentry_operations = {
53 .d_hash = hpfs_hash_dentry,
54 .d_compare = hpfs_compare_dentry,
55};
56
57void hpfs_set_dentry_operations(struct dentry *dentry)
58{
59 dentry->d_op = &hpfs_dentry_operations;
60}
diff --git a/fs/hpfs/dir.c b/fs/hpfs/dir.c
new file mode 100644
index 000000000000..0217c3a04441
--- /dev/null
+++ b/fs/hpfs/dir.c
@@ -0,0 +1,320 @@
1/*
2 * linux/fs/hpfs/dir.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * directory VFS functions
7 */
8
9#include "hpfs_fn.h"
10
11static int hpfs_dir_release(struct inode *inode, struct file *filp)
12{
13 lock_kernel();
14 hpfs_del_pos(inode, &filp->f_pos);
15 /*hpfs_write_if_changed(inode);*/
16 unlock_kernel();
17 return 0;
18}
19
20/* This is slow, but it's not used often */
21
22static loff_t hpfs_dir_lseek(struct file *filp, loff_t off, int whence)
23{
24 loff_t new_off = off + (whence == 1 ? filp->f_pos : 0);
25 loff_t pos;
26 struct quad_buffer_head qbh;
27 struct inode *i = filp->f_dentry->d_inode;
28 struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
29 struct super_block *s = i->i_sb;
30
31 lock_kernel();
32
33 /*printk("dir lseek\n");*/
34 if (new_off == 0 || new_off == 1 || new_off == 11 || new_off == 12 || new_off == 13) goto ok;
35 down(&i->i_sem);
36 pos = ((loff_t) hpfs_de_as_down_as_possible(s, hpfs_inode->i_dno) << 4) + 1;
37 while (pos != new_off) {
38 if (map_pos_dirent(i, &pos, &qbh)) hpfs_brelse4(&qbh);
39 else goto fail;
40 if (pos == 12) goto fail;
41 }
42 up(&i->i_sem);
43ok:
44 unlock_kernel();
45 return filp->f_pos = new_off;
46fail:
47 up(&i->i_sem);
48 /*printk("illegal lseek: %016llx\n", new_off);*/
49 unlock_kernel();
50 return -ESPIPE;
51}
52
53static int hpfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
54{
55 struct inode *inode = filp->f_dentry->d_inode;
56 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
57 struct quad_buffer_head qbh;
58 struct hpfs_dirent *de;
59 int lc;
60 long old_pos;
61 char *tempname;
62 int c1, c2 = 0;
63 int ret = 0;
64
65 lock_kernel();
66
67 if (hpfs_sb(inode->i_sb)->sb_chk) {
68 if (hpfs_chk_sectors(inode->i_sb, inode->i_ino, 1, "dir_fnode")) {
69 ret = -EFSERROR;
70 goto out;
71 }
72 if (hpfs_chk_sectors(inode->i_sb, hpfs_inode->i_dno, 4, "dir_dnode")) {
73 ret = -EFSERROR;
74 goto out;
75 }
76 }
77 if (hpfs_sb(inode->i_sb)->sb_chk >= 2) {
78 struct buffer_head *bh;
79 struct fnode *fno;
80 int e = 0;
81 if (!(fno = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) {
82 ret = -EIOERROR;
83 goto out;
84 }
85 if (!fno->dirflag) {
86 e = 1;
87 hpfs_error(inode->i_sb, "not a directory, fnode %08x",inode->i_ino);
88 }
89 if (hpfs_inode->i_dno != fno->u.external[0].disk_secno) {
90 e = 1;
91 hpfs_error(inode->i_sb, "corrupted inode: i_dno == %08x, fnode -> dnode == %08x", hpfs_inode->i_dno, fno->u.external[0].disk_secno);
92 }
93 brelse(bh);
94 if (e) {
95 ret = -EFSERROR;
96 goto out;
97 }
98 }
99 lc = hpfs_sb(inode->i_sb)->sb_lowercase;
100 if (filp->f_pos == 12) { /* diff -r requires this (note, that diff -r */
101 filp->f_pos = 13; /* also fails on msdos filesystem in 2.0) */
102 goto out;
103 }
104 if (filp->f_pos == 13) {
105 ret = -ENOENT;
106 goto out;
107 }
108
109 while (1) {
110 again:
111 /* This won't work when cycle is longer than number of dirents
112 accepted by filldir, but what can I do?
113 maybe killall -9 ls helps */
114 if (hpfs_sb(inode->i_sb)->sb_chk)
115 if (hpfs_stop_cycles(inode->i_sb, filp->f_pos, &c1, &c2, "hpfs_readdir")) {
116 ret = -EFSERROR;
117 goto out;
118 }
119 if (filp->f_pos == 12)
120 goto out;
121 if (filp->f_pos == 3 || filp->f_pos == 4 || filp->f_pos == 5) {
122 printk("HPFS: warning: pos==%d\n",(int)filp->f_pos);
123 goto out;
124 }
125 if (filp->f_pos == 0) {
126 if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino, DT_DIR) < 0)
127 goto out;
128 filp->f_pos = 11;
129 }
130 if (filp->f_pos == 11) {
131 if (filldir(dirent, "..", 2, filp->f_pos, hpfs_inode->i_parent_dir, DT_DIR) < 0)
132 goto out;
133 filp->f_pos = 1;
134 }
135 if (filp->f_pos == 1) {
136 filp->f_pos = ((loff_t) hpfs_de_as_down_as_possible(inode->i_sb, hpfs_inode->i_dno) << 4) + 1;
137 hpfs_add_pos(inode, &filp->f_pos);
138 filp->f_version = inode->i_version;
139 }
140 old_pos = filp->f_pos;
141 if (!(de = map_pos_dirent(inode, &filp->f_pos, &qbh))) {
142 ret = -EIOERROR;
143 goto out;
144 }
145 if (de->first || de->last) {
146 if (hpfs_sb(inode->i_sb)->sb_chk) {
147 if (de->first && !de->last && (de->namelen != 2 || de ->name[0] != 1 || de->name[1] != 1)) hpfs_error(inode->i_sb, "hpfs_readdir: bad ^A^A entry; pos = %08x", old_pos);
148 if (de->last && (de->namelen != 1 || de ->name[0] != 255)) hpfs_error(inode->i_sb, "hpfs_readdir: bad \\377 entry; pos = %08x", old_pos);
149 }
150 hpfs_brelse4(&qbh);
151 goto again;
152 }
153 tempname = hpfs_translate_name(inode->i_sb, de->name, de->namelen, lc, de->not_8x3);
154 if (filldir(dirent, tempname, de->namelen, old_pos, de->fnode, DT_UNKNOWN) < 0) {
155 filp->f_pos = old_pos;
156 if (tempname != (char *)de->name) kfree(tempname);
157 hpfs_brelse4(&qbh);
158 goto out;
159 }
160 if (tempname != (char *)de->name) kfree(tempname);
161 hpfs_brelse4(&qbh);
162 }
163out:
164 unlock_kernel();
165 return ret;
166}
167
168/*
169 * lookup. Search the specified directory for the specified name, set
170 * *result to the corresponding inode.
171 *
172 * lookup uses the inode number to tell read_inode whether it is reading
173 * the inode of a directory or a file -- file ino's are odd, directory
174 * ino's are even. read_inode avoids i/o for file inodes; everything
175 * needed is up here in the directory. (And file fnodes are out in
176 * the boondocks.)
177 *
178 * - M.P.: this is over, sometimes we've got to read file's fnode for eas
179 * inode numbers are just fnode sector numbers; iget lock is used
180 * to tell read_inode to read fnode or not.
181 */
182
183struct dentry *hpfs_lookup(struct inode *dir, struct dentry *dentry, struct nameidata *nd)
184{
185 const char *name = dentry->d_name.name;
186 unsigned len = dentry->d_name.len;
187 struct quad_buffer_head qbh;
188 struct hpfs_dirent *de;
189 ino_t ino;
190 int err;
191 struct inode *result = NULL;
192 struct hpfs_inode_info *hpfs_result;
193
194 lock_kernel();
195 if ((err = hpfs_chk_name((char *)name, &len))) {
196 if (err == -ENAMETOOLONG) {
197 unlock_kernel();
198 return ERR_PTR(-ENAMETOOLONG);
199 }
200 goto end_add;
201 }
202
203 /*
204 * '.' and '..' will never be passed here.
205 */
206
207 de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *) name, len, NULL, &qbh);
208
209 /*
210 * This is not really a bailout, just means file not found.
211 */
212
213 if (!de) goto end;
214
215 /*
216 * Get inode number, what we're after.
217 */
218
219 ino = de->fnode;
220
221 /*
222 * Go find or make an inode.
223 */
224
225 result = iget_locked(dir->i_sb, ino);
226 if (!result) {
227 hpfs_error(dir->i_sb, "hpfs_lookup: can't get inode");
228 goto bail1;
229 }
230 if (result->i_state & I_NEW) {
231 hpfs_init_inode(result);
232 if (de->directory)
233 hpfs_read_inode(result);
234 else if (de->ea_size && hpfs_sb(dir->i_sb)->sb_eas)
235 hpfs_read_inode(result);
236 else {
237 result->i_mode |= S_IFREG;
238 result->i_mode &= ~0111;
239 result->i_op = &hpfs_file_iops;
240 result->i_fop = &hpfs_file_ops;
241 result->i_nlink = 1;
242 }
243 unlock_new_inode(result);
244 }
245 hpfs_result = hpfs_i(result);
246 if (!de->directory) hpfs_result->i_parent_dir = dir->i_ino;
247
248 hpfs_decide_conv(result, (char *)name, len);
249
250 if (de->has_acl || de->has_xtd_perm) if (!(dir->i_sb->s_flags & MS_RDONLY)) {
251 hpfs_error(result->i_sb, "ACLs or XPERM found. This is probably HPFS386. This driver doesn't support it now. Send me some info on these structures");
252 goto bail1;
253 }
254
255 /*
256 * Fill in the info from the directory if this is a newly created
257 * inode.
258 */
259
260 if (!result->i_ctime.tv_sec) {
261 if (!(result->i_ctime.tv_sec = local_to_gmt(dir->i_sb, de->creation_date)))
262 result->i_ctime.tv_sec = 1;
263 result->i_ctime.tv_nsec = 0;
264 result->i_mtime.tv_sec = local_to_gmt(dir->i_sb, de->write_date);
265 result->i_mtime.tv_nsec = 0;
266 result->i_atime.tv_sec = local_to_gmt(dir->i_sb, de->read_date);
267 result->i_atime.tv_nsec = 0;
268 hpfs_result->i_ea_size = de->ea_size;
269 if (!hpfs_result->i_ea_mode && de->read_only)
270 result->i_mode &= ~0222;
271 if (!de->directory) {
272 if (result->i_size == -1) {
273 result->i_size = de->file_size;
274 result->i_data.a_ops = &hpfs_aops;
275 hpfs_i(result)->mmu_private = result->i_size;
276 /*
277 * i_blocks should count the fnode and any anodes.
278 * We count 1 for the fnode and don't bother about
279 * anodes -- the disk heads are on the directory band
280 * and we want them to stay there.
281 */
282 result->i_blocks = 1 + ((result->i_size + 511) >> 9);
283 }
284 }
285 }
286
287 hpfs_brelse4(&qbh);
288
289 /*
290 * Made it.
291 */
292
293 end:
294 end_add:
295 hpfs_set_dentry_operations(dentry);
296 unlock_kernel();
297 d_add(dentry, result);
298 return NULL;
299
300 /*
301 * Didn't.
302 */
303 bail1:
304
305 hpfs_brelse4(&qbh);
306
307 /*bail:*/
308
309 unlock_kernel();
310 return ERR_PTR(-ENOENT);
311}
312
313struct file_operations hpfs_dir_ops =
314{
315 .llseek = hpfs_dir_lseek,
316 .read = generic_read_dir,
317 .readdir = hpfs_readdir,
318 .release = hpfs_dir_release,
319 .fsync = hpfs_file_fsync,
320};
diff --git a/fs/hpfs/dnode.c b/fs/hpfs/dnode.c
new file mode 100644
index 000000000000..1d21307730a8
--- /dev/null
+++ b/fs/hpfs/dnode.c
@@ -0,0 +1,1080 @@
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
11static 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
24void hpfs_add_pos(struct inode *inode, loff_t *pos)
25{
26 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
27 int i = 0;
28 loff_t **ppos;
29
30 if (hpfs_inode->i_rddir_off)
31 for (; hpfs_inode->i_rddir_off[i]; i++)
32 if (hpfs_inode->i_rddir_off[i] == pos) return;
33 if (!(i&0x0f)) {
34 if (!(ppos = kmalloc((i+0x11) * sizeof(loff_t*), GFP_NOFS))) {
35 printk("HPFS: out of memory for position list\n");
36 return;
37 }
38 if (hpfs_inode->i_rddir_off) {
39 memcpy(ppos, hpfs_inode->i_rddir_off, i * sizeof(loff_t));
40 kfree(hpfs_inode->i_rddir_off);
41 }
42 hpfs_inode->i_rddir_off = ppos;
43 }
44 hpfs_inode->i_rddir_off[i] = pos;
45 hpfs_inode->i_rddir_off[i + 1] = NULL;
46}
47
48void hpfs_del_pos(struct inode *inode, loff_t *pos)
49{
50 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
51 loff_t **i, **j;
52
53 if (!hpfs_inode->i_rddir_off) goto not_f;
54 for (i = hpfs_inode->i_rddir_off; *i; i++) if (*i == pos) goto fnd;
55 goto not_f;
56 fnd:
57 for (j = i + 1; *j; j++) ;
58 *i = *(j - 1);
59 *(j - 1) = NULL;
60 if (j - 1 == hpfs_inode->i_rddir_off) {
61 kfree(hpfs_inode->i_rddir_off);
62 hpfs_inode->i_rddir_off = NULL;
63 }
64 return;
65 not_f:
66 /*printk("HPFS: warning: position pointer %p->%08x not found\n", pos, (int)*pos);*/
67 return;
68}
69
70static void for_all_poss(struct inode *inode, void (*f)(loff_t *, loff_t, loff_t),
71 loff_t p1, loff_t p2)
72{
73 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
74 loff_t **i;
75
76 if (!hpfs_inode->i_rddir_off) return;
77 for (i = hpfs_inode->i_rddir_off; *i; i++) (*f)(*i, p1, p2);
78 return;
79}
80
81static void hpfs_pos_subst(loff_t *p, loff_t f, loff_t t)
82{
83 if (*p == f) *p = t;
84}
85
86/*void hpfs_hpfs_pos_substd(loff_t *p, loff_t f, loff_t t)
87{
88 if ((*p & ~0x3f) == (f & ~0x3f)) *p = (t & ~0x3f) | (*p & 0x3f);
89}*/
90
91static void hpfs_pos_ins(loff_t *p, loff_t d, loff_t c)
92{
93 if ((*p & ~0x3f) == (d & ~0x3f) && (*p & 0x3f) >= (d & 0x3f)) {
94 int n = (*p & 0x3f) + c;
95 if (n > 0x3f) printk("HPFS: hpfs_pos_ins: %08x + %d\n", (int)*p, (int)c >> 8);
96 else *p = (*p & ~0x3f) | n;
97 }
98}
99
100static void hpfs_pos_del(loff_t *p, loff_t d, loff_t c)
101{
102 if ((*p & ~0x3f) == (d & ~0x3f) && (*p & 0x3f) >= (d & 0x3f)) {
103 int n = (*p & 0x3f) - c;
104 if (n < 1) printk("HPFS: hpfs_pos_ins: %08x - %d\n", (int)*p, (int)c >> 8);
105 else *p = (*p & ~0x3f) | n;
106 }
107}
108
109static struct hpfs_dirent *dnode_pre_last_de(struct dnode *d)
110{
111 struct hpfs_dirent *de, *de_end, *dee = NULL, *deee = NULL;
112 de_end = dnode_end_de(d);
113 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
114 deee = dee; dee = de;
115 }
116 return deee;
117}
118
119static struct hpfs_dirent *dnode_last_de(struct dnode *d)
120{
121 struct hpfs_dirent *de, *de_end, *dee = NULL;
122 de_end = dnode_end_de(d);
123 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
124 dee = de;
125 }
126 return dee;
127}
128
129static void set_last_pointer(struct super_block *s, struct dnode *d, dnode_secno ptr)
130{
131 struct hpfs_dirent *de;
132 if (!(de = dnode_last_de(d))) {
133 hpfs_error(s, "set_last_pointer: empty dnode %08x", d->self);
134 return;
135 }
136 if (hpfs_sb(s)->sb_chk) {
137 if (de->down) {
138 hpfs_error(s, "set_last_pointer: dnode %08x has already last pointer %08x",
139 d->self, de_down_pointer(de));
140 return;
141 }
142 if (de->length != 32) {
143 hpfs_error(s, "set_last_pointer: bad last dirent in dnode %08x", d->self);
144 return;
145 }
146 }
147 if (ptr) {
148 if ((d->first_free += 4) > 2048) {
149 hpfs_error(s,"set_last_pointer: too long dnode %08x", d->self);
150 d->first_free -= 4;
151 return;
152 }
153 de->length = 36;
154 de->down = 1;
155 *(dnode_secno *)((char *)de + 32) = ptr;
156 }
157}
158
159/* Add an entry to dnode and don't care if it grows over 2048 bytes */
160
161struct hpfs_dirent *hpfs_add_de(struct super_block *s, struct dnode *d, unsigned char *name,
162 unsigned namelen, secno down_ptr)
163{
164 struct hpfs_dirent *de;
165 struct hpfs_dirent *de_end = dnode_end_de(d);
166 unsigned d_size = de_size(namelen, down_ptr);
167 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
168 int c = hpfs_compare_names(s, name, namelen, de->name, de->namelen, de->last);
169 if (!c) {
170 hpfs_error(s, "name (%c,%d) already exists in dnode %08x", *name, namelen, d->self);
171 return NULL;
172 }
173 if (c < 0) break;
174 }
175 memmove((char *)de + d_size, de, (char *)de_end - (char *)de);
176 memset(de, 0, d_size);
177 if (down_ptr) {
178 *(int *)((char *)de + d_size - 4) = down_ptr;
179 de->down = 1;
180 }
181 de->length = d_size;
182 if (down_ptr) de->down = 1;
183 de->not_8x3 = hpfs_is_name_long(name, namelen);
184 de->namelen = namelen;
185 memcpy(de->name, name, namelen);
186 d->first_free += d_size;
187 return de;
188}
189
190/* Delete dirent and don't care about its subtree */
191
192static void hpfs_delete_de(struct super_block *s, struct dnode *d,
193 struct hpfs_dirent *de)
194{
195 if (de->last) {
196 hpfs_error(s, "attempt to delete last dirent in dnode %08x", d->self);
197 return;
198 }
199 d->first_free -= de->length;
200 memmove(de, de_next_de(de), d->first_free + (char *)d - (char *)de);
201}
202
203static void fix_up_ptrs(struct super_block *s, struct dnode *d)
204{
205 struct hpfs_dirent *de;
206 struct hpfs_dirent *de_end = dnode_end_de(d);
207 dnode_secno dno = d->self;
208 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de))
209 if (de->down) {
210 struct quad_buffer_head qbh;
211 struct dnode *dd;
212 if ((dd = hpfs_map_dnode(s, de_down_pointer(de), &qbh))) {
213 if (dd->up != dno || dd->root_dnode) {
214 dd->up = dno;
215 dd->root_dnode = 0;
216 hpfs_mark_4buffers_dirty(&qbh);
217 }
218 hpfs_brelse4(&qbh);
219 }
220 }
221}
222
223/* Add an entry to dnode and do dnode splitting if required */
224
225static int hpfs_add_to_dnode(struct inode *i, dnode_secno dno,
226 unsigned char *name, unsigned namelen,
227 struct hpfs_dirent *new_de, dnode_secno down_ptr)
228{
229 struct quad_buffer_head qbh, qbh1, qbh2;
230 struct dnode *d, *ad, *rd, *nd = NULL;
231 dnode_secno adno, rdno;
232 struct hpfs_dirent *de;
233 struct hpfs_dirent nde;
234 char *nname;
235 int h;
236 int pos;
237 struct buffer_head *bh;
238 struct fnode *fnode;
239 int c1, c2 = 0;
240 if (!(nname = kmalloc(256, GFP_NOFS))) {
241 printk("HPFS: out of memory, can't add to dnode\n");
242 return 1;
243 }
244 go_up:
245 if (namelen >= 256) {
246 hpfs_error(i->i_sb, "hpfs_add_to_dnode: namelen == %d", namelen);
247 if (nd) kfree(nd);
248 kfree(nname);
249 return 1;
250 }
251 if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) {
252 if (nd) kfree(nd);
253 kfree(nname);
254 return 1;
255 }
256 go_up_a:
257 if (hpfs_sb(i->i_sb)->sb_chk)
258 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_to_dnode")) {
259 hpfs_brelse4(&qbh);
260 if (nd) kfree(nd);
261 kfree(nname);
262 return 1;
263 }
264 if (d->first_free + de_size(namelen, down_ptr) <= 2048) {
265 loff_t t;
266 copy_de(de=hpfs_add_de(i->i_sb, d, name, namelen, down_ptr), new_de);
267 t = get_pos(d, de);
268 for_all_poss(i, hpfs_pos_ins, t, 1);
269 for_all_poss(i, hpfs_pos_subst, 4, t);
270 for_all_poss(i, hpfs_pos_subst, 5, t + 1);
271 hpfs_mark_4buffers_dirty(&qbh);
272 hpfs_brelse4(&qbh);
273 if (nd) kfree(nd);
274 kfree(nname);
275 return 0;
276 }
277 if (!nd) if (!(nd = kmalloc(0x924, GFP_NOFS))) {
278 /* 0x924 is a max size of dnode after adding a dirent with
279 max name length. We alloc this only once. There must
280 not be any error while splitting dnodes, otherwise the
281 whole directory, not only file we're adding, would
282 be lost. */
283 printk("HPFS: out of memory for dnode splitting\n");
284 hpfs_brelse4(&qbh);
285 kfree(nname);
286 return 1;
287 }
288 memcpy(nd, d, d->first_free);
289 copy_de(de = hpfs_add_de(i->i_sb, nd, name, namelen, down_ptr), new_de);
290 for_all_poss(i, hpfs_pos_ins, get_pos(nd, de), 1);
291 h = ((char *)dnode_last_de(nd) - (char *)nd) / 2 + 10;
292 if (!(ad = hpfs_alloc_dnode(i->i_sb, d->up, &adno, &qbh1, 0))) {
293 hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
294 hpfs_brelse4(&qbh);
295 kfree(nd);
296 kfree(nname);
297 return 1;
298 }
299 i->i_size += 2048;
300 i->i_blocks += 4;
301 pos = 1;
302 for (de = dnode_first_de(nd); (char *)de_next_de(de) - (char *)nd < h; de = de_next_de(de)) {
303 copy_de(hpfs_add_de(i->i_sb, ad, de->name, de->namelen, de->down ? de_down_pointer(de) : 0), de);
304 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | pos, ((loff_t)adno << 4) | pos);
305 pos++;
306 }
307 copy_de(new_de = &nde, de);
308 memcpy(name = nname, de->name, namelen = de->namelen);
309 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | pos, 4);
310 down_ptr = adno;
311 set_last_pointer(i->i_sb, ad, de->down ? de_down_pointer(de) : 0);
312 de = de_next_de(de);
313 memmove((char *)nd + 20, de, nd->first_free + (char *)nd - (char *)de);
314 nd->first_free -= (char *)de - (char *)nd - 20;
315 memcpy(d, nd, nd->first_free);
316 for_all_poss(i, hpfs_pos_del, (loff_t)dno << 4, pos);
317 fix_up_ptrs(i->i_sb, ad);
318 if (!d->root_dnode) {
319 dno = ad->up = d->up;
320 hpfs_mark_4buffers_dirty(&qbh);
321 hpfs_brelse4(&qbh);
322 hpfs_mark_4buffers_dirty(&qbh1);
323 hpfs_brelse4(&qbh1);
324 goto go_up;
325 }
326 if (!(rd = hpfs_alloc_dnode(i->i_sb, d->up, &rdno, &qbh2, 0))) {
327 hpfs_error(i->i_sb, "unable to alloc dnode - dnode tree will be corrupted");
328 hpfs_brelse4(&qbh);
329 hpfs_brelse4(&qbh1);
330 kfree(nd);
331 kfree(nname);
332 return 1;
333 }
334 i->i_size += 2048;
335 i->i_blocks += 4;
336 rd->root_dnode = 1;
337 rd->up = d->up;
338 if (!(fnode = hpfs_map_fnode(i->i_sb, d->up, &bh))) {
339 hpfs_free_dnode(i->i_sb, rdno);
340 hpfs_brelse4(&qbh);
341 hpfs_brelse4(&qbh1);
342 hpfs_brelse4(&qbh2);
343 kfree(nd);
344 kfree(nname);
345 return 1;
346 }
347 fnode->u.external[0].disk_secno = rdno;
348 mark_buffer_dirty(bh);
349 brelse(bh);
350 d->up = ad->up = hpfs_i(i)->i_dno = rdno;
351 d->root_dnode = ad->root_dnode = 0;
352 hpfs_mark_4buffers_dirty(&qbh);
353 hpfs_brelse4(&qbh);
354 hpfs_mark_4buffers_dirty(&qbh1);
355 hpfs_brelse4(&qbh1);
356 qbh = qbh2;
357 set_last_pointer(i->i_sb, rd, dno);
358 dno = rdno;
359 d = rd;
360 goto go_up_a;
361}
362
363/*
364 * Add an entry to directory btree.
365 * I hate such crazy directory structure.
366 * It's easy to read but terrible to write.
367 * I wrote this directory code 4 times.
368 * I hope, now it's finally bug-free.
369 */
370
371int hpfs_add_dirent(struct inode *i, unsigned char *name, unsigned namelen,
372 struct hpfs_dirent *new_de, int cdepth)
373{
374 struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
375 struct dnode *d;
376 struct hpfs_dirent *de, *de_end;
377 struct quad_buffer_head qbh;
378 dnode_secno dno;
379 int c;
380 int c1, c2 = 0;
381 dno = hpfs_inode->i_dno;
382 down:
383 if (hpfs_sb(i->i_sb)->sb_chk)
384 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "hpfs_add_dirent")) return 1;
385 if (!(d = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 1;
386 de_end = dnode_end_de(d);
387 for (de = dnode_first_de(d); de < de_end; de = de_next_de(de)) {
388 if (!(c = hpfs_compare_names(i->i_sb, name, namelen, de->name, de->namelen, de->last))) {
389 hpfs_brelse4(&qbh);
390 return -1;
391 }
392 if (c < 0) {
393 if (de->down) {
394 dno = de_down_pointer(de);
395 hpfs_brelse4(&qbh);
396 goto down;
397 }
398 break;
399 }
400 }
401 hpfs_brelse4(&qbh);
402 if (!cdepth) hpfs_lock_creation(i->i_sb);
403 if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_ADD)) {
404 c = 1;
405 goto ret;
406 }
407 i->i_version++;
408 c = hpfs_add_to_dnode(i, dno, name, namelen, new_de, 0);
409 ret:
410 if (!cdepth) hpfs_unlock_creation(i->i_sb);
411 return c;
412}
413
414/*
415 * Find dirent with higher name in 'from' subtree and move it to 'to' dnode.
416 * Return the dnode we moved from (to be checked later if it's empty)
417 */
418
419static secno move_to_top(struct inode *i, dnode_secno from, dnode_secno to)
420{
421 dnode_secno dno, ddno;
422 dnode_secno chk_up = to;
423 struct dnode *dnode;
424 struct quad_buffer_head qbh;
425 struct hpfs_dirent *de, *nde;
426 int a;
427 loff_t t;
428 int c1, c2 = 0;
429 dno = from;
430 while (1) {
431 if (hpfs_sb(i->i_sb)->sb_chk)
432 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "move_to_top"))
433 return 0;
434 if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return 0;
435 if (hpfs_sb(i->i_sb)->sb_chk) {
436 if (dnode->up != chk_up) {
437 hpfs_error(i->i_sb, "move_to_top: up pointer from %08x should be %08x, is %08x",
438 dno, chk_up, dnode->up);
439 hpfs_brelse4(&qbh);
440 return 0;
441 }
442 chk_up = dno;
443 }
444 if (!(de = dnode_last_de(dnode))) {
445 hpfs_error(i->i_sb, "move_to_top: dnode %08x has no last de", dno);
446 hpfs_brelse4(&qbh);
447 return 0;
448 }
449 if (!de->down) break;
450 dno = de_down_pointer(de);
451 hpfs_brelse4(&qbh);
452 }
453 while (!(de = dnode_pre_last_de(dnode))) {
454 dnode_secno up = dnode->up;
455 hpfs_brelse4(&qbh);
456 hpfs_free_dnode(i->i_sb, dno);
457 i->i_size -= 2048;
458 i->i_blocks -= 4;
459 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, 5);
460 if (up == to) return to;
461 if (!(dnode = hpfs_map_dnode(i->i_sb, up, &qbh))) return 0;
462 if (dnode->root_dnode) {
463 hpfs_error(i->i_sb, "move_to_top: got to root_dnode while moving from %08x to %08x", from, to);
464 hpfs_brelse4(&qbh);
465 return 0;
466 }
467 de = dnode_last_de(dnode);
468 if (!de || !de->down) {
469 hpfs_error(i->i_sb, "move_to_top: dnode %08x doesn't point down to %08x", up, dno);
470 hpfs_brelse4(&qbh);
471 return 0;
472 }
473 dnode->first_free -= 4;
474 de->length -= 4;
475 de->down = 0;
476 hpfs_mark_4buffers_dirty(&qbh);
477 dno = up;
478 }
479 t = get_pos(dnode, de);
480 for_all_poss(i, hpfs_pos_subst, t, 4);
481 for_all_poss(i, hpfs_pos_subst, t + 1, 5);
482 if (!(nde = kmalloc(de->length, GFP_NOFS))) {
483 hpfs_error(i->i_sb, "out of memory for dirent - directory will be corrupted");
484 hpfs_brelse4(&qbh);
485 return 0;
486 }
487 memcpy(nde, de, de->length);
488 ddno = de->down ? de_down_pointer(de) : 0;
489 hpfs_delete_de(i->i_sb, dnode, de);
490 set_last_pointer(i->i_sb, dnode, ddno);
491 hpfs_mark_4buffers_dirty(&qbh);
492 hpfs_brelse4(&qbh);
493 a = hpfs_add_to_dnode(i, to, nde->name, nde->namelen, nde, from);
494 kfree(nde);
495 if (a) return 0;
496 return dno;
497}
498
499/*
500 * Check if a dnode is empty and delete it from the tree
501 * (chkdsk doesn't like empty dnodes)
502 */
503
504static void delete_empty_dnode(struct inode *i, dnode_secno dno)
505{
506 struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
507 struct quad_buffer_head qbh;
508 struct dnode *dnode;
509 dnode_secno down, up, ndown;
510 int p;
511 struct hpfs_dirent *de;
512 int c1, c2 = 0;
513 try_it_again:
514 if (hpfs_stop_cycles(i->i_sb, dno, &c1, &c2, "delete_empty_dnode")) return;
515 if (!(dnode = hpfs_map_dnode(i->i_sb, dno, &qbh))) return;
516 if (dnode->first_free > 56) goto end;
517 if (dnode->first_free == 52 || dnode->first_free == 56) {
518 struct hpfs_dirent *de_end;
519 int root = dnode->root_dnode;
520 up = dnode->up;
521 de = dnode_first_de(dnode);
522 down = de->down ? de_down_pointer(de) : 0;
523 if (hpfs_sb(i->i_sb)->sb_chk) if (root && !down) {
524 hpfs_error(i->i_sb, "delete_empty_dnode: root dnode %08x is empty", dno);
525 goto end;
526 }
527 hpfs_brelse4(&qbh);
528 hpfs_free_dnode(i->i_sb, dno);
529 i->i_size -= 2048;
530 i->i_blocks -= 4;
531 if (root) {
532 struct fnode *fnode;
533 struct buffer_head *bh;
534 struct dnode *d1;
535 struct quad_buffer_head qbh1;
536 if (hpfs_sb(i->i_sb)->sb_chk) if (up != i->i_ino) {
537 hpfs_error(i->i_sb, "bad pointer to fnode, dnode %08x, pointing to %08x, should be %08x", dno, up, i->i_ino);
538 return;
539 }
540 if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
541 d1->up = up;
542 d1->root_dnode = 1;
543 hpfs_mark_4buffers_dirty(&qbh1);
544 hpfs_brelse4(&qbh1);
545 }
546 if ((fnode = hpfs_map_fnode(i->i_sb, up, &bh))) {
547 fnode->u.external[0].disk_secno = down;
548 mark_buffer_dirty(bh);
549 brelse(bh);
550 }
551 hpfs_inode->i_dno = down;
552 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, (loff_t) 12);
553 return;
554 }
555 if (!(dnode = hpfs_map_dnode(i->i_sb, up, &qbh))) return;
556 p = 1;
557 de_end = dnode_end_de(dnode);
558 for (de = dnode_first_de(dnode); de < de_end; de = de_next_de(de), p++)
559 if (de->down) if (de_down_pointer(de) == dno) goto fnd;
560 hpfs_error(i->i_sb, "delete_empty_dnode: pointer to dnode %08x not found in dnode %08x", dno, up);
561 goto end;
562 fnd:
563 for_all_poss(i, hpfs_pos_subst, ((loff_t)dno << 4) | 1, ((loff_t)up << 4) | p);
564 if (!down) {
565 de->down = 0;
566 de->length -= 4;
567 dnode->first_free -= 4;
568 memmove(de_next_de(de), (char *)de_next_de(de) + 4,
569 (char *)dnode + dnode->first_free - (char *)de_next_de(de));
570 } else {
571 struct dnode *d1;
572 struct quad_buffer_head qbh1;
573 *(dnode_secno *) ((void *) de + de->length - 4) = down;
574 if ((d1 = hpfs_map_dnode(i->i_sb, down, &qbh1))) {
575 d1->up = up;
576 hpfs_mark_4buffers_dirty(&qbh1);
577 hpfs_brelse4(&qbh1);
578 }
579 }
580 } else {
581 hpfs_error(i->i_sb, "delete_empty_dnode: dnode %08x, first_free == %03x", dno, dnode->first_free);
582 goto end;
583 }
584
585 if (!de->last) {
586 struct hpfs_dirent *de_next = de_next_de(de);
587 struct hpfs_dirent *de_cp;
588 struct dnode *d1;
589 struct quad_buffer_head qbh1;
590 if (!de_next->down) goto endm;
591 ndown = de_down_pointer(de_next);
592 if (!(de_cp = kmalloc(de->length, GFP_NOFS))) {
593 printk("HPFS: out of memory for dtree balancing\n");
594 goto endm;
595 }
596 memcpy(de_cp, de, de->length);
597 hpfs_delete_de(i->i_sb, dnode, de);
598 hpfs_mark_4buffers_dirty(&qbh);
599 hpfs_brelse4(&qbh);
600 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, 4);
601 for_all_poss(i, hpfs_pos_del, ((loff_t)up << 4) | p, 1);
602 if (de_cp->down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de_cp), &qbh1))) {
603 d1->up = ndown;
604 hpfs_mark_4buffers_dirty(&qbh1);
605 hpfs_brelse4(&qbh1);
606 }
607 hpfs_add_to_dnode(i, ndown, de_cp->name, de_cp->namelen, de_cp, de_cp->down ? de_down_pointer(de_cp) : 0);
608 /*printk("UP-TO-DNODE: %08x (ndown = %08x, down = %08x, dno = %08x)\n", up, ndown, down, dno);*/
609 dno = up;
610 kfree(de_cp);
611 goto try_it_again;
612 } else {
613 struct hpfs_dirent *de_prev = dnode_pre_last_de(dnode);
614 struct hpfs_dirent *de_cp;
615 struct dnode *d1;
616 struct quad_buffer_head qbh1;
617 dnode_secno dlp;
618 if (!de_prev) {
619 hpfs_error(i->i_sb, "delete_empty_dnode: empty dnode %08x", up);
620 hpfs_mark_4buffers_dirty(&qbh);
621 hpfs_brelse4(&qbh);
622 dno = up;
623 goto try_it_again;
624 }
625 if (!de_prev->down) goto endm;
626 ndown = de_down_pointer(de_prev);
627 if ((d1 = hpfs_map_dnode(i->i_sb, ndown, &qbh1))) {
628 struct hpfs_dirent *del = dnode_last_de(d1);
629 dlp = del->down ? de_down_pointer(del) : 0;
630 if (!dlp && down) {
631 if (d1->first_free > 2044) {
632 if (hpfs_sb(i->i_sb)->sb_chk >= 2) {
633 printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
634 printk("HPFS: warning: terminating balancing operation\n");
635 }
636 hpfs_brelse4(&qbh1);
637 goto endm;
638 }
639 if (hpfs_sb(i->i_sb)->sb_chk >= 2) {
640 printk("HPFS: warning: unbalanced dnode tree, see hpfs.txt 4 more info\n");
641 printk("HPFS: warning: goin'on\n");
642 }
643 del->length += 4;
644 del->down = 1;
645 d1->first_free += 4;
646 }
647 if (dlp && !down) {
648 del->length -= 4;
649 del->down = 0;
650 d1->first_free -= 4;
651 } else if (down)
652 *(dnode_secno *) ((void *) del + del->length - 4) = down;
653 } else goto endm;
654 if (!(de_cp = kmalloc(de_prev->length, GFP_NOFS))) {
655 printk("HPFS: out of memory for dtree balancing\n");
656 hpfs_brelse4(&qbh1);
657 goto endm;
658 }
659 hpfs_mark_4buffers_dirty(&qbh1);
660 hpfs_brelse4(&qbh1);
661 memcpy(de_cp, de_prev, de_prev->length);
662 hpfs_delete_de(i->i_sb, dnode, de_prev);
663 if (!de_prev->down) {
664 de_prev->length += 4;
665 de_prev->down = 1;
666 dnode->first_free += 4;
667 }
668 *(dnode_secno *) ((void *) de_prev + de_prev->length - 4) = ndown;
669 hpfs_mark_4buffers_dirty(&qbh);
670 hpfs_brelse4(&qbh);
671 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | (p - 1), 4);
672 for_all_poss(i, hpfs_pos_subst, ((loff_t)up << 4) | p, ((loff_t)up << 4) | (p - 1));
673 if (down) if ((d1 = hpfs_map_dnode(i->i_sb, de_down_pointer(de), &qbh1))) {
674 d1->up = ndown;
675 hpfs_mark_4buffers_dirty(&qbh1);
676 hpfs_brelse4(&qbh1);
677 }
678 hpfs_add_to_dnode(i, ndown, de_cp->name, de_cp->namelen, de_cp, dlp);
679 dno = up;
680 kfree(de_cp);
681 goto try_it_again;
682 }
683 endm:
684 hpfs_mark_4buffers_dirty(&qbh);
685 end:
686 hpfs_brelse4(&qbh);
687}
688
689
690/* Delete dirent from directory */
691
692int hpfs_remove_dirent(struct inode *i, dnode_secno dno, struct hpfs_dirent *de,
693 struct quad_buffer_head *qbh, int depth)
694{
695 struct dnode *dnode = qbh->data;
696 dnode_secno down = 0;
697 int lock = 0;
698 loff_t t;
699 if (de->first || de->last) {
700 hpfs_error(i->i_sb, "hpfs_remove_dirent: attempt to delete first or last dirent in dnode %08x", dno);
701 hpfs_brelse4(qbh);
702 return 1;
703 }
704 if (de->down) down = de_down_pointer(de);
705 if (depth && (de->down || (de == dnode_first_de(dnode) && de_next_de(de)->last))) {
706 lock = 1;
707 hpfs_lock_creation(i->i_sb);
708 if (hpfs_check_free_dnodes(i->i_sb, FREE_DNODES_DEL)) {
709 hpfs_brelse4(qbh);
710 hpfs_unlock_creation(i->i_sb);
711 return 2;
712 }
713 }
714 i->i_version++;
715 for_all_poss(i, hpfs_pos_del, (t = get_pos(dnode, de)) + 1, 1);
716 hpfs_delete_de(i->i_sb, dnode, de);
717 hpfs_mark_4buffers_dirty(qbh);
718 hpfs_brelse4(qbh);
719 if (down) {
720 dnode_secno a = move_to_top(i, down, dno);
721 for_all_poss(i, hpfs_pos_subst, 5, t);
722 if (a) delete_empty_dnode(i, a);
723 if (lock) hpfs_unlock_creation(i->i_sb);
724 return !a;
725 }
726 delete_empty_dnode(i, dno);
727 if (lock) hpfs_unlock_creation(i->i_sb);
728 return 0;
729}
730
731void hpfs_count_dnodes(struct super_block *s, dnode_secno dno, int *n_dnodes,
732 int *n_subdirs, int *n_items)
733{
734 struct dnode *dnode;
735 struct quad_buffer_head qbh;
736 struct hpfs_dirent *de;
737 dnode_secno ptr, odno = 0;
738 int c1, c2 = 0;
739 int d1, d2 = 0;
740 go_down:
741 if (n_dnodes) (*n_dnodes)++;
742 if (hpfs_sb(s)->sb_chk)
743 if (hpfs_stop_cycles(s, dno, &c1, &c2, "hpfs_count_dnodes #1")) return;
744 ptr = 0;
745 go_up:
746 if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return;
747 if (hpfs_sb(s)->sb_chk) if (odno && odno != -1 && dnode->up != odno)
748 hpfs_error(s, "hpfs_count_dnodes: bad up pointer; dnode %08x, down %08x points to %08x", odno, dno, dnode->up);
749 de = dnode_first_de(dnode);
750 if (ptr) while(1) {
751 if (de->down) if (de_down_pointer(de) == ptr) goto process_de;
752 if (de->last) {
753 hpfs_brelse4(&qbh);
754 hpfs_error(s, "hpfs_count_dnodes: pointer to dnode %08x not found in dnode %08x, got here from %08x",
755 ptr, dno, odno);
756 return;
757 }
758 de = de_next_de(de);
759 }
760 next_de:
761 if (de->down) {
762 odno = dno;
763 dno = de_down_pointer(de);
764 hpfs_brelse4(&qbh);
765 goto go_down;
766 }
767 process_de:
768 if (!de->first && !de->last && de->directory && n_subdirs) (*n_subdirs)++;
769 if (!de->first && !de->last && n_items) (*n_items)++;
770 if ((de = de_next_de(de)) < dnode_end_de(dnode)) goto next_de;
771 ptr = dno;
772 dno = dnode->up;
773 if (dnode->root_dnode) {
774 hpfs_brelse4(&qbh);
775 return;
776 }
777 hpfs_brelse4(&qbh);
778 if (hpfs_sb(s)->sb_chk)
779 if (hpfs_stop_cycles(s, ptr, &d1, &d2, "hpfs_count_dnodes #2")) return;
780 odno = -1;
781 goto go_up;
782}
783
784static struct hpfs_dirent *map_nth_dirent(struct super_block *s, dnode_secno dno, int n,
785 struct quad_buffer_head *qbh, struct dnode **dn)
786{
787 int i;
788 struct hpfs_dirent *de, *de_end;
789 struct dnode *dnode;
790 dnode = hpfs_map_dnode(s, dno, qbh);
791 if (!dnode) return NULL;
792 if (dn) *dn=dnode;
793 de = dnode_first_de(dnode);
794 de_end = dnode_end_de(dnode);
795 for (i = 1; de < de_end; i++, de = de_next_de(de)) {
796 if (i == n) {
797 return de;
798 }
799 if (de->last) break;
800 }
801 hpfs_brelse4(qbh);
802 hpfs_error(s, "map_nth_dirent: n too high; dnode = %08x, requested %08x", dno, n);
803 return NULL;
804}
805
806dnode_secno hpfs_de_as_down_as_possible(struct super_block *s, dnode_secno dno)
807{
808 struct quad_buffer_head qbh;
809 dnode_secno d = dno;
810 dnode_secno up = 0;
811 struct hpfs_dirent *de;
812 int c1, c2 = 0;
813
814 again:
815 if (hpfs_sb(s)->sb_chk)
816 if (hpfs_stop_cycles(s, d, &c1, &c2, "hpfs_de_as_down_as_possible"))
817 return d;
818 if (!(de = map_nth_dirent(s, d, 1, &qbh, NULL))) return dno;
819 if (hpfs_sb(s)->sb_chk)
820 if (up && ((struct dnode *)qbh.data)->up != up)
821 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);
822 if (!de->down) {
823 hpfs_brelse4(&qbh);
824 return d;
825 }
826 up = d;
827 d = de_down_pointer(de);
828 hpfs_brelse4(&qbh);
829 goto again;
830}
831
832struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
833 struct quad_buffer_head *qbh)
834{
835 loff_t pos;
836 unsigned c;
837 dnode_secno dno;
838 struct hpfs_dirent *de, *d;
839 struct hpfs_dirent *up_de;
840 struct hpfs_dirent *end_up_de;
841 struct dnode *dnode;
842 struct dnode *up_dnode;
843 struct quad_buffer_head qbh0;
844
845 pos = *posp;
846 dno = pos >> 6 << 2;
847 pos &= 077;
848 if (!(de = map_nth_dirent(inode->i_sb, dno, pos, qbh, &dnode)))
849 goto bail;
850
851 /* Going to the next dirent */
852 if ((d = de_next_de(de)) < dnode_end_de(dnode)) {
853 if (!(++*posp & 077)) {
854 hpfs_error(inode->i_sb, "map_pos_dirent: pos crossed dnode boundary; pos = %08x", *posp);
855 goto bail;
856 }
857 /* We're going down the tree */
858 if (d->down) {
859 *posp = ((loff_t) hpfs_de_as_down_as_possible(inode->i_sb, de_down_pointer(d)) << 4) + 1;
860 }
861
862 return de;
863 }
864
865 /* Going up */
866 if (dnode->root_dnode) goto bail;
867
868 if (!(up_dnode = hpfs_map_dnode(inode->i_sb, dnode->up, &qbh0)))
869 goto bail;
870
871 end_up_de = dnode_end_de(up_dnode);
872 c = 0;
873 for (up_de = dnode_first_de(up_dnode); up_de < end_up_de;
874 up_de = de_next_de(up_de)) {
875 if (!(++c & 077)) hpfs_error(inode->i_sb,
876 "map_pos_dirent: pos crossed dnode boundary; dnode = %08x", dnode->up);
877 if (up_de->down && de_down_pointer(up_de) == dno) {
878 *posp = ((loff_t) dnode->up << 4) + c;
879 hpfs_brelse4(&qbh0);
880 return de;
881 }
882 }
883
884 hpfs_error(inode->i_sb, "map_pos_dirent: pointer to dnode %08x not found in parent dnode %08x",
885 dno, dnode->up);
886 hpfs_brelse4(&qbh0);
887
888 bail:
889 *posp = 12;
890 return de;
891}
892
893/* Find a dirent in tree */
894
895struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno, char *name, unsigned len,
896 dnode_secno *dd, struct quad_buffer_head *qbh)
897{
898 struct dnode *dnode;
899 struct hpfs_dirent *de;
900 struct hpfs_dirent *de_end;
901 int c1, c2 = 0;
902
903 if (!S_ISDIR(inode->i_mode)) hpfs_error(inode->i_sb, "map_dirent: not a directory\n");
904 again:
905 if (hpfs_sb(inode->i_sb)->sb_chk)
906 if (hpfs_stop_cycles(inode->i_sb, dno, &c1, &c2, "map_dirent")) return NULL;
907 if (!(dnode = hpfs_map_dnode(inode->i_sb, dno, qbh))) return NULL;
908
909 de_end = dnode_end_de(dnode);
910 for (de = dnode_first_de(dnode); de < de_end; de = de_next_de(de)) {
911 int t = hpfs_compare_names(inode->i_sb, name, len, de->name, de->namelen, de->last);
912 if (!t) {
913 if (dd) *dd = dno;
914 return de;
915 }
916 if (t < 0) {
917 if (de->down) {
918 dno = de_down_pointer(de);
919 hpfs_brelse4(qbh);
920 goto again;
921 }
922 break;
923 }
924 }
925 hpfs_brelse4(qbh);
926 return NULL;
927}
928
929/*
930 * Remove empty directory. In normal cases it is only one dnode with two
931 * entries, but we must handle also such obscure cases when it's a tree
932 * of empty dnodes.
933 */
934
935void hpfs_remove_dtree(struct super_block *s, dnode_secno dno)
936{
937 struct quad_buffer_head qbh;
938 struct dnode *dnode;
939 struct hpfs_dirent *de;
940 dnode_secno d1, d2, rdno = dno;
941 while (1) {
942 if (!(dnode = hpfs_map_dnode(s, dno, &qbh))) return;
943 de = dnode_first_de(dnode);
944 if (de->last) {
945 if (de->down) d1 = de_down_pointer(de);
946 else goto error;
947 hpfs_brelse4(&qbh);
948 hpfs_free_dnode(s, dno);
949 dno = d1;
950 } else break;
951 }
952 if (!de->first) goto error;
953 d1 = de->down ? de_down_pointer(de) : 0;
954 de = de_next_de(de);
955 if (!de->last) goto error;
956 d2 = de->down ? de_down_pointer(de) : 0;
957 hpfs_brelse4(&qbh);
958 hpfs_free_dnode(s, dno);
959 do {
960 while (d1) {
961 if (!(dnode = hpfs_map_dnode(s, dno = d1, &qbh))) return;
962 de = dnode_first_de(dnode);
963 if (!de->last) goto error;
964 d1 = de->down ? de_down_pointer(de) : 0;
965 hpfs_brelse4(&qbh);
966 hpfs_free_dnode(s, dno);
967 }
968 d1 = d2;
969 d2 = 0;
970 } while (d1);
971 return;
972 error:
973 hpfs_brelse4(&qbh);
974 hpfs_free_dnode(s, dno);
975 hpfs_error(s, "directory %08x is corrupted or not empty", rdno);
976}
977
978/*
979 * Find dirent for specified fnode. Use truncated 15-char name in fnode as
980 * a help for searching.
981 */
982
983struct hpfs_dirent *map_fnode_dirent(struct super_block *s, fnode_secno fno,
984 struct fnode *f, struct quad_buffer_head *qbh)
985{
986 char *name1;
987 char *name2;
988 int name1len, name2len;
989 struct dnode *d;
990 dnode_secno dno, downd;
991 struct fnode *upf;
992 struct buffer_head *bh;
993 struct hpfs_dirent *de, *de_end;
994 int c;
995 int c1, c2 = 0;
996 int d1, d2 = 0;
997 name1 = f->name;
998 if (!(name2 = kmalloc(256, GFP_NOFS))) {
999 printk("HPFS: out of memory, can't map dirent\n");
1000 return NULL;
1001 }
1002 if (f->len <= 15)
1003 memcpy(name2, name1, name1len = name2len = f->len);
1004 else {
1005 memcpy(name2, name1, 15);
1006 memset(name2 + 15, 0xff, 256 - 15);
1007 /*name2[15] = 0xff;*/
1008 name1len = 15; name2len = 256;
1009 }
1010 if (!(upf = hpfs_map_fnode(s, f->up, &bh))) {
1011 kfree(name2);
1012 return NULL;
1013 }
1014 if (!upf->dirflag) {
1015 brelse(bh);
1016 hpfs_error(s, "fnode %08x has non-directory parent %08x", fno, f->up);
1017 kfree(name2);
1018 return NULL;
1019 }
1020 dno = upf->u.external[0].disk_secno;
1021 brelse(bh);
1022 go_down:
1023 downd = 0;
1024 go_up:
1025 if (!(d = hpfs_map_dnode(s, dno, qbh))) {
1026 kfree(name2);
1027 return NULL;
1028 }
1029 de_end = dnode_end_de(d);
1030 de = dnode_first_de(d);
1031 if (downd) {
1032 while (de < de_end) {
1033 if (de->down) if (de_down_pointer(de) == downd) goto f;
1034 de = de_next_de(de);
1035 }
1036 hpfs_error(s, "pointer to dnode %08x not found in dnode %08x", downd, dno);
1037 hpfs_brelse4(qbh);
1038 kfree(name2);
1039 return NULL;
1040 }
1041 next_de:
1042 if (de->fnode == fno) {
1043 kfree(name2);
1044 return de;
1045 }
1046 c = hpfs_compare_names(s, name1, name1len, de->name, de->namelen, de->last);
1047 if (c < 0 && de->down) {
1048 dno = de_down_pointer(de);
1049 hpfs_brelse4(qbh);
1050 if (hpfs_sb(s)->sb_chk)
1051 if (hpfs_stop_cycles(s, dno, &c1, &c2, "map_fnode_dirent #1")) {
1052 kfree(name2);
1053 return NULL;
1054 }
1055 goto go_down;
1056 }
1057 f:
1058 if (de->fnode == fno) {
1059 kfree(name2);
1060 return de;
1061 }
1062 c = hpfs_compare_names(s, name2, name2len, de->name, de->namelen, de->last);
1063 if (c < 0 && !de->last) goto not_found;
1064 if ((de = de_next_de(de)) < de_end) goto next_de;
1065 if (d->root_dnode) goto not_found;
1066 downd = dno;
1067 dno = d->up;
1068 hpfs_brelse4(qbh);
1069 if (hpfs_sb(s)->sb_chk)
1070 if (hpfs_stop_cycles(s, downd, &d1, &d2, "map_fnode_dirent #2")) {
1071 kfree(name2);
1072 return NULL;
1073 }
1074 goto go_up;
1075 not_found:
1076 hpfs_brelse4(qbh);
1077 hpfs_error(s, "dirent for fnode %08x not found", fno);
1078 kfree(name2);
1079 return NULL;
1080}
diff --git a/fs/hpfs/ea.c b/fs/hpfs/ea.c
new file mode 100644
index 000000000000..66339dc030e4
--- /dev/null
+++ b/fs/hpfs/ea.c
@@ -0,0 +1,363 @@
1/*
2 * linux/fs/hpfs/ea.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * handling extended attributes
7 */
8
9#include "hpfs_fn.h"
10
11/* Remove external extended attributes. ano specifies whether a is a
12 direct sector where eas starts or an anode */
13
14void hpfs_ea_ext_remove(struct super_block *s, secno a, int ano, unsigned len)
15{
16 unsigned pos = 0;
17 while (pos < len) {
18 char ex[4 + 255 + 1 + 8];
19 struct extended_attribute *ea = (struct extended_attribute *)ex;
20 if (pos + 4 > len) {
21 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
22 ano ? "anode" : "sectors", a, len);
23 return;
24 }
25 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
26 if (ea->indirect) {
27 if (ea->valuelen != 8) {
28 hpfs_error(s, "ea->indirect set while ea->valuelen!=8, %s %08x, pos %08x",
29 ano ? "anode" : "sectors", a, pos);
30 return;
31 }
32 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 9, ex+4))
33 return;
34 hpfs_ea_remove(s, ea_sec(ea), ea->anode, ea_len(ea));
35 }
36 pos += ea->namelen + ea->valuelen + 5;
37 }
38 if (!ano) hpfs_free_sectors(s, a, (len+511) >> 9);
39 else {
40 struct buffer_head *bh;
41 struct anode *anode;
42 if ((anode = hpfs_map_anode(s, a, &bh))) {
43 hpfs_remove_btree(s, &anode->btree);
44 brelse(bh);
45 hpfs_free_sectors(s, a, 1);
46 }
47 }
48}
49
50static char *get_indirect_ea(struct super_block *s, int ano, secno a, int size)
51{
52 char *ret;
53 if (!(ret = kmalloc(size + 1, GFP_NOFS))) {
54 printk("HPFS: out of memory for EA\n");
55 return NULL;
56 }
57 if (hpfs_ea_read(s, a, ano, 0, size, ret)) {
58 kfree(ret);
59 return NULL;
60 }
61 ret[size] = 0;
62 return ret;
63}
64
65static void set_indirect_ea(struct super_block *s, int ano, secno a, char *data,
66 int size)
67{
68 hpfs_ea_write(s, a, ano, 0, size, data);
69}
70
71/* Read an extended attribute named 'key' into the provided buffer */
72
73int hpfs_read_ea(struct super_block *s, struct fnode *fnode, char *key,
74 char *buf, int size)
75{
76 unsigned pos;
77 int ano, len;
78 secno a;
79 struct extended_attribute *ea;
80 struct extended_attribute *ea_end = fnode_end_ea(fnode);
81 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
82 if (!strcmp(ea->name, key)) {
83 if (ea->indirect)
84 goto indirect;
85 if (ea->valuelen >= size)
86 return -EINVAL;
87 memcpy(buf, ea_data(ea), ea->valuelen);
88 buf[ea->valuelen] = 0;
89 return 0;
90 }
91 a = fnode->ea_secno;
92 len = fnode->ea_size_l;
93 ano = fnode->ea_anode;
94 pos = 0;
95 while (pos < len) {
96 char ex[4 + 255 + 1 + 8];
97 ea = (struct extended_attribute *)ex;
98 if (pos + 4 > len) {
99 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
100 ano ? "anode" : "sectors", a, len);
101 return -EIO;
102 }
103 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return -EIO;
104 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
105 return -EIO;
106 if (!strcmp(ea->name, key)) {
107 if (ea->indirect)
108 goto indirect;
109 if (ea->valuelen >= size)
110 return -EINVAL;
111 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, buf))
112 return -EIO;
113 buf[ea->valuelen] = 0;
114 return 0;
115 }
116 pos += ea->namelen + ea->valuelen + 5;
117 }
118 return -ENOENT;
119indirect:
120 if (ea_len(ea) >= size)
121 return -EINVAL;
122 if (hpfs_ea_read(s, ea_sec(ea), ea->anode, 0, ea_len(ea), buf))
123 return -EIO;
124 buf[ea_len(ea)] = 0;
125 return 0;
126}
127
128/* Read an extended attribute named 'key' */
129char *hpfs_get_ea(struct super_block *s, struct fnode *fnode, char *key, int *size)
130{
131 char *ret;
132 unsigned pos;
133 int ano, len;
134 secno a;
135 struct extended_attribute *ea;
136 struct extended_attribute *ea_end = fnode_end_ea(fnode);
137 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
138 if (!strcmp(ea->name, key)) {
139 if (ea->indirect)
140 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
141 if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) {
142 printk("HPFS: out of memory for EA\n");
143 return NULL;
144 }
145 memcpy(ret, ea_data(ea), ea->valuelen);
146 ret[ea->valuelen] = 0;
147 return ret;
148 }
149 a = fnode->ea_secno;
150 len = fnode->ea_size_l;
151 ano = fnode->ea_anode;
152 pos = 0;
153 while (pos < len) {
154 char ex[4 + 255 + 1 + 8];
155 ea = (struct extended_attribute *)ex;
156 if (pos + 4 > len) {
157 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
158 ano ? "anode" : "sectors", a, len);
159 return NULL;
160 }
161 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return NULL;
162 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
163 return NULL;
164 if (!strcmp(ea->name, key)) {
165 if (ea->indirect)
166 return get_indirect_ea(s, ea->anode, ea_sec(ea), *size = ea_len(ea));
167 if (!(ret = kmalloc((*size = ea->valuelen) + 1, GFP_NOFS))) {
168 printk("HPFS: out of memory for EA\n");
169 return NULL;
170 }
171 if (hpfs_ea_read(s, a, ano, pos + 4 + ea->namelen + 1, ea->valuelen, ret)) {
172 kfree(ret);
173 return NULL;
174 }
175 ret[ea->valuelen] = 0;
176 return ret;
177 }
178 pos += ea->namelen + ea->valuelen + 5;
179 }
180 return NULL;
181}
182
183/*
184 * Update or create extended attribute 'key' with value 'data'. Note that
185 * when this ea exists, it MUST have the same size as size of data.
186 * This driver can't change sizes of eas ('cause I just don't need it).
187 */
188
189void hpfs_set_ea(struct inode *inode, struct fnode *fnode, char *key, char *data, int size)
190{
191 fnode_secno fno = inode->i_ino;
192 struct super_block *s = inode->i_sb;
193 unsigned pos;
194 int ano, len;
195 secno a;
196 unsigned char h[4];
197 struct extended_attribute *ea;
198 struct extended_attribute *ea_end = fnode_end_ea(fnode);
199 for (ea = fnode_ea(fnode); ea < ea_end; ea = next_ea(ea))
200 if (!strcmp(ea->name, key)) {
201 if (ea->indirect) {
202 if (ea_len(ea) == size)
203 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
204 } else if (ea->valuelen == size) {
205 memcpy(ea_data(ea), data, size);
206 }
207 return;
208 }
209 a = fnode->ea_secno;
210 len = fnode->ea_size_l;
211 ano = fnode->ea_anode;
212 pos = 0;
213 while (pos < len) {
214 char ex[4 + 255 + 1 + 8];
215 ea = (struct extended_attribute *)ex;
216 if (pos + 4 > len) {
217 hpfs_error(s, "EAs don't end correctly, %s %08x, len %08x",
218 ano ? "anode" : "sectors", a, len);
219 return;
220 }
221 if (hpfs_ea_read(s, a, ano, pos, 4, ex)) return;
222 if (hpfs_ea_read(s, a, ano, pos + 4, ea->namelen + 1 + (ea->indirect ? 8 : 0), ex + 4))
223 return;
224 if (!strcmp(ea->name, key)) {
225 if (ea->indirect) {
226 if (ea_len(ea) == size)
227 set_indirect_ea(s, ea->anode, ea_sec(ea), data, size);
228 }
229 else {
230 if (ea->valuelen == size)
231 hpfs_ea_write(s, a, ano, pos + 4 + ea->namelen + 1, size, data);
232 }
233 return;
234 }
235 pos += ea->namelen + ea->valuelen + 5;
236 }
237 if (!fnode->ea_offs) {
238 /*if (fnode->ea_size_s) {
239 hpfs_error(s, "fnode %08x: ea_size_s == %03x, ea_offs == 0",
240 inode->i_ino, fnode->ea_size_s);
241 return;
242 }*/
243 fnode->ea_offs = 0xc4;
244 }
245 if (fnode->ea_offs < 0xc4 || fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200) {
246 hpfs_error(s, "fnode %08x: ea_offs == %03x, ea_size_s == %03x",
247 inode->i_ino, fnode->ea_offs, fnode->ea_size_s);
248 return;
249 }
250 if ((fnode->ea_size_s || !fnode->ea_size_l) &&
251 fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s + strlen(key) + size + 5 <= 0x200) {
252 ea = fnode_end_ea(fnode);
253 *(char *)ea = 0;
254 ea->namelen = strlen(key);
255 ea->valuelen = size;
256 strcpy(ea->name, key);
257 memcpy(ea_data(ea), data, size);
258 fnode->ea_size_s += strlen(key) + size + 5;
259 goto ret;
260 }
261 /* Most the code here is 99.9993422% unused. I hope there are no bugs.
262 But what .. HPFS.IFS has also bugs in ea management. */
263 if (fnode->ea_size_s && !fnode->ea_size_l) {
264 secno n;
265 struct buffer_head *bh;
266 char *data;
267 if (!(n = hpfs_alloc_sector(s, fno, 1, 0, 1))) return;
268 if (!(data = hpfs_get_sector(s, n, &bh))) {
269 hpfs_free_sectors(s, n, 1);
270 return;
271 }
272 memcpy(data, fnode_ea(fnode), fnode->ea_size_s);
273 fnode->ea_size_l = fnode->ea_size_s;
274 fnode->ea_size_s = 0;
275 fnode->ea_secno = n;
276 fnode->ea_anode = 0;
277 mark_buffer_dirty(bh);
278 brelse(bh);
279 }
280 pos = fnode->ea_size_l + 5 + strlen(key) + size;
281 len = (fnode->ea_size_l + 511) >> 9;
282 if (pos >= 30000) goto bail;
283 while (((pos + 511) >> 9) > len) {
284 if (!len) {
285 if (!(fnode->ea_secno = hpfs_alloc_sector(s, fno, 1, 0, 1)))
286 goto bail;
287 fnode->ea_anode = 0;
288 len++;
289 } else if (!fnode->ea_anode) {
290 if (hpfs_alloc_if_possible(s, fnode->ea_secno + len)) {
291 len++;
292 } else {
293 /* Aargh... don't know how to create ea anodes :-( */
294 /*struct buffer_head *bh;
295 struct anode *anode;
296 anode_secno a_s;
297 if (!(anode = hpfs_alloc_anode(s, fno, &a_s, &bh)))
298 goto bail;
299 anode->up = fno;
300 anode->btree.fnode_parent = 1;
301 anode->btree.n_free_nodes--;
302 anode->btree.n_used_nodes++;
303 anode->btree.first_free += 12;
304 anode->u.external[0].disk_secno = fnode->ea_secno;
305 anode->u.external[0].file_secno = 0;
306 anode->u.external[0].length = len;
307 mark_buffer_dirty(bh);
308 brelse(bh);
309 fnode->ea_anode = 1;
310 fnode->ea_secno = a_s;*/
311 secno new_sec;
312 int i;
313 if (!(new_sec = hpfs_alloc_sector(s, fno, 1, 1 - ((pos + 511) >> 9), 1)))
314 goto bail;
315 for (i = 0; i < len; i++) {
316 struct buffer_head *bh1, *bh2;
317 void *b1, *b2;
318 if (!(b1 = hpfs_map_sector(s, fnode->ea_secno + i, &bh1, len - i - 1))) {
319 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
320 goto bail;
321 }
322 if (!(b2 = hpfs_get_sector(s, new_sec + i, &bh2))) {
323 brelse(bh1);
324 hpfs_free_sectors(s, new_sec, (pos + 511) >> 9);
325 goto bail;
326 }
327 memcpy(b2, b1, 512);
328 brelse(bh1);
329 mark_buffer_dirty(bh2);
330 brelse(bh2);
331 }
332 hpfs_free_sectors(s, fnode->ea_secno, len);
333 fnode->ea_secno = new_sec;
334 len = (pos + 511) >> 9;
335 }
336 }
337 if (fnode->ea_anode) {
338 if (hpfs_add_sector_to_btree(s, fnode->ea_secno,
339 0, len) != -1) {
340 len++;
341 } else {
342 goto bail;
343 }
344 }
345 }
346 h[0] = 0;
347 h[1] = strlen(key);
348 h[2] = size & 0xff;
349 h[3] = size >> 8;
350 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l, 4, h)) goto bail;
351 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 4, h[1] + 1, key)) goto bail;
352 if (hpfs_ea_write(s, fnode->ea_secno, fnode->ea_anode, fnode->ea_size_l + 5 + h[1], size, data)) goto bail;
353 fnode->ea_size_l = pos;
354 ret:
355 hpfs_i(inode)->i_ea_size += 5 + strlen(key) + size;
356 return;
357 bail:
358 if (fnode->ea_secno)
359 if (fnode->ea_anode) hpfs_truncate_btree(s, fnode->ea_secno, 1, (fnode->ea_size_l + 511) >> 9);
360 else hpfs_free_sectors(s, fnode->ea_secno + ((fnode->ea_size_l + 511) >> 9), len - ((fnode->ea_size_l + 511) >> 9));
361 else fnode->ea_secno = fnode->ea_size_l = 0;
362}
363
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
new file mode 100644
index 000000000000..ab144dabd870
--- /dev/null
+++ b/fs/hpfs/file.c
@@ -0,0 +1,140 @@
1/*
2 * linux/fs/hpfs/file.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * file VFS functions
7 */
8
9#include "hpfs_fn.h"
10
11#define BLOCKS(size) (((size) + 511) >> 9)
12
13static int hpfs_file_release(struct inode *inode, struct file *file)
14{
15 lock_kernel();
16 hpfs_write_if_changed(inode);
17 unlock_kernel();
18 return 0;
19}
20
21int hpfs_file_fsync(struct file *file, struct dentry *dentry, int datasync)
22{
23 /*return file_fsync(file, dentry);*/
24 return 0; /* Don't fsync :-) */
25}
26
27/*
28 * generic_file_read often calls bmap with non-existing sector,
29 * so we must ignore such errors.
30 */
31
32static secno hpfs_bmap(struct inode *inode, unsigned file_secno)
33{
34 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
35 unsigned n, disk_secno;
36 struct fnode *fnode;
37 struct buffer_head *bh;
38 if (BLOCKS(hpfs_i(inode)->mmu_private) <= file_secno) return 0;
39 n = file_secno - hpfs_inode->i_file_sec;
40 if (n < hpfs_inode->i_n_secs) return hpfs_inode->i_disk_sec + n;
41 if (!(fnode = hpfs_map_fnode(inode->i_sb, inode->i_ino, &bh))) return 0;
42 disk_secno = hpfs_bplus_lookup(inode->i_sb, inode, &fnode->btree, file_secno, bh);
43 if (disk_secno == -1) return 0;
44 if (hpfs_chk_sectors(inode->i_sb, disk_secno, 1, "bmap")) return 0;
45 return disk_secno;
46}
47
48static void hpfs_truncate(struct inode *i)
49{
50 if (IS_IMMUTABLE(i)) return /*-EPERM*/;
51 lock_kernel();
52 hpfs_i(i)->i_n_secs = 0;
53 i->i_blocks = 1 + ((i->i_size + 511) >> 9);
54 hpfs_i(i)->mmu_private = i->i_size;
55 hpfs_truncate_btree(i->i_sb, i->i_ino, 1, ((i->i_size + 511) >> 9));
56 hpfs_write_inode(i);
57 hpfs_i(i)->i_n_secs = 0;
58 unlock_kernel();
59}
60
61static int hpfs_get_block(struct inode *inode, sector_t iblock, struct buffer_head *bh_result, int create)
62{
63 secno s;
64 s = hpfs_bmap(inode, iblock);
65 if (s) {
66 map_bh(bh_result, inode->i_sb, s);
67 return 0;
68 }
69 if (!create) return 0;
70 if (iblock<<9 != hpfs_i(inode)->mmu_private) {
71 BUG();
72 return -EIO;
73 }
74 if ((s = hpfs_add_sector_to_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1)) == -1) {
75 hpfs_truncate_btree(inode->i_sb, inode->i_ino, 1, inode->i_blocks - 1);
76 return -ENOSPC;
77 }
78 inode->i_blocks++;
79 hpfs_i(inode)->mmu_private += 512;
80 set_buffer_new(bh_result);
81 map_bh(bh_result, inode->i_sb, s);
82 return 0;
83}
84
85static int hpfs_writepage(struct page *page, struct writeback_control *wbc)
86{
87 return block_write_full_page(page,hpfs_get_block, wbc);
88}
89static int hpfs_readpage(struct file *file, struct page *page)
90{
91 return block_read_full_page(page,hpfs_get_block);
92}
93static int hpfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
94{
95 return cont_prepare_write(page,from,to,hpfs_get_block,
96 &hpfs_i(page->mapping->host)->mmu_private);
97}
98static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
99{
100 return generic_block_bmap(mapping,block,hpfs_get_block);
101}
102struct address_space_operations hpfs_aops = {
103 .readpage = hpfs_readpage,
104 .writepage = hpfs_writepage,
105 .sync_page = block_sync_page,
106 .prepare_write = hpfs_prepare_write,
107 .commit_write = generic_commit_write,
108 .bmap = _hpfs_bmap
109};
110
111static ssize_t hpfs_file_write(struct file *file, const char __user *buf,
112 size_t count, loff_t *ppos)
113{
114 ssize_t retval;
115
116 retval = generic_file_write(file, buf, count, ppos);
117 if (retval > 0) {
118 struct inode *inode = file->f_dentry->d_inode;
119 inode->i_mtime = CURRENT_TIME_SEC;
120 hpfs_i(inode)->i_dirty = 1;
121 }
122 return retval;
123}
124
125struct file_operations hpfs_file_ops =
126{
127 .llseek = generic_file_llseek,
128 .read = generic_file_read,
129 .write = hpfs_file_write,
130 .mmap = generic_file_mmap,
131 .release = hpfs_file_release,
132 .fsync = hpfs_file_fsync,
133 .sendfile = generic_file_sendfile,
134};
135
136struct inode_operations hpfs_file_iops =
137{
138 .truncate = hpfs_truncate,
139 .setattr = hpfs_notify_change,
140};
diff --git a/fs/hpfs/hpfs.h b/fs/hpfs/hpfs.h
new file mode 100644
index 000000000000..0e84c73cd9c4
--- /dev/null
+++ b/fs/hpfs/hpfs.h
@@ -0,0 +1,493 @@
1/*
2 * linux/fs/hpfs/hpfs.h
3 *
4 * HPFS structures by Chris Smith, 1993
5 *
6 * a little bit modified by Mikulas Patocka, 1998-1999
7 */
8
9/* The paper
10
11 Duncan, Roy
12 Design goals and implementation of the new High Performance File System
13 Microsoft Systems Journal Sept 1989 v4 n5 p1(13)
14
15 describes what HPFS looked like when it was new, and it is the source
16 of most of the information given here. The rest is conjecture.
17
18 For definitive information on the Duncan paper, see it, not this file.
19 For definitive information on HPFS, ask somebody else -- this is guesswork.
20 There are certain to be many mistakes. */
21
22/* Notation */
23
24typedef unsigned secno; /* sector number, partition relative */
25
26typedef secno dnode_secno; /* sector number of a dnode */
27typedef secno fnode_secno; /* sector number of an fnode */
28typedef secno anode_secno; /* sector number of an anode */
29
30typedef u32 time32_t; /* 32-bit time_t type */
31
32/* sector 0 */
33
34/* The boot block is very like a FAT boot block, except that the
35 29h signature byte is 28h instead, and the ID string is "HPFS". */
36
37#define BB_MAGIC 0xaa55
38
39struct hpfs_boot_block
40{
41 unsigned char jmp[3];
42 unsigned char oem_id[8];
43 unsigned char bytes_per_sector[2]; /* 512 */
44 unsigned char sectors_per_cluster;
45 unsigned char n_reserved_sectors[2];
46 unsigned char n_fats;
47 unsigned char n_rootdir_entries[2];
48 unsigned char n_sectors_s[2];
49 unsigned char media_byte;
50 unsigned short sectors_per_fat;
51 unsigned short sectors_per_track;
52 unsigned short heads_per_cyl;
53 unsigned int n_hidden_sectors;
54 unsigned int n_sectors_l; /* size of partition */
55 unsigned char drive_number;
56 unsigned char mbz;
57 unsigned char sig_28h; /* 28h */
58 unsigned char vol_serno[4];
59 unsigned char vol_label[11];
60 unsigned char sig_hpfs[8]; /* "HPFS " */
61 unsigned char pad[448];
62 unsigned short magic; /* aa55 */
63};
64
65
66/* sector 16 */
67
68/* The super block has the pointer to the root directory. */
69
70#define SB_MAGIC 0xf995e849
71
72struct hpfs_super_block
73{
74 unsigned magic; /* f995 e849 */
75 unsigned magic1; /* fa53 e9c5, more magic? */
76 /*unsigned huh202;*/ /* ?? 202 = N. of B. in 1.00390625 S.*/
77 char version; /* version of a filesystem usually 2 */
78 char funcversion; /* functional version - oldest version
79 of filesystem that can understand
80 this disk */
81 unsigned short int zero; /* 0 */
82 fnode_secno root; /* fnode of root directory */
83 secno n_sectors; /* size of filesystem */
84 unsigned n_badblocks; /* number of bad blocks */
85 secno bitmaps; /* pointers to free space bit maps */
86 unsigned zero1; /* 0 */
87 secno badblocks; /* bad block list */
88 unsigned zero3; /* 0 */
89 time32_t last_chkdsk; /* date last checked, 0 if never */
90 /*unsigned zero4;*/ /* 0 */
91 time32_t last_optimize; /* date last optimized, 0 if never */
92 secno n_dir_band; /* number of sectors in dir band */
93 secno dir_band_start; /* first sector in dir band */
94 secno dir_band_end; /* last sector in dir band */
95 secno dir_band_bitmap; /* free space map, 1 dnode per bit */
96 char volume_name[32]; /* not used */
97 secno user_id_table; /* 8 preallocated sectors - user id */
98 unsigned zero6[103]; /* 0 */
99};
100
101
102/* sector 17 */
103
104/* The spare block has pointers to spare sectors. */
105
106#define SP_MAGIC 0xf9911849
107
108struct hpfs_spare_block
109{
110 unsigned magic; /* f991 1849 */
111 unsigned magic1; /* fa52 29c5, more magic? */
112
113 unsigned dirty: 1; /* 0 clean, 1 "improperly stopped" */
114 /*unsigned flag1234: 4;*/ /* unknown flags */
115 unsigned sparedir_used: 1; /* spare dirblks used */
116 unsigned hotfixes_used: 1; /* hotfixes used */
117 unsigned bad_sector: 1; /* bad sector, corrupted disk (???) */
118 unsigned bad_bitmap: 1; /* bad bitmap */
119 unsigned fast: 1; /* partition was fast formatted */
120 unsigned old_wrote: 1; /* old version wrote to partion */
121 unsigned old_wrote_1: 1; /* old version wrote to partion (?) */
122 unsigned install_dasd_limits: 1; /* HPFS386 flags */
123 unsigned resynch_dasd_limits: 1;
124 unsigned dasd_limits_operational: 1;
125 unsigned multimedia_active: 1;
126 unsigned dce_acls_active: 1;
127 unsigned dasd_limits_dirty: 1;
128 unsigned flag67: 2;
129 unsigned char mm_contlgulty;
130 unsigned char unused;
131
132 secno hotfix_map; /* info about remapped bad sectors */
133 unsigned n_spares_used; /* number of hotfixes */
134 unsigned n_spares; /* number of spares in hotfix map */
135 unsigned n_dnode_spares_free; /* spare dnodes unused */
136 unsigned n_dnode_spares; /* length of spare_dnodes[] list,
137 follows in this block*/
138 secno code_page_dir; /* code page directory block */
139 unsigned n_code_pages; /* number of code pages */
140 /*unsigned large_numbers[2];*/ /* ?? */
141 unsigned super_crc; /* on HPFS386 and LAN Server this is
142 checksum of superblock, on normal
143 OS/2 unused */
144 unsigned spare_crc; /* on HPFS386 checksum of spareblock */
145 unsigned zero1[15]; /* unused */
146 dnode_secno spare_dnodes[100]; /* emergency free dnode list */
147 unsigned zero2[1]; /* room for more? */
148};
149
150/* The bad block list is 4 sectors long. The first word must be zero,
151 the remaining words give n_badblocks bad block numbers.
152 I bet you can see it coming... */
153
154#define BAD_MAGIC 0
155
156/* The hotfix map is 4 sectors long. It looks like
157
158 secno from[n_spares];
159 secno to[n_spares];
160
161 The to[] list is initialized to point to n_spares preallocated empty
162 sectors. The from[] list contains the sector numbers of bad blocks
163 which have been remapped to corresponding sectors in the to[] list.
164 n_spares_used gives the length of the from[] list. */
165
166
167/* Sectors 18 and 19 are preallocated and unused.
168 Maybe they're spares for 16 and 17, but simple substitution fails. */
169
170
171/* The code page info pointed to by the spare block consists of an index
172 block and blocks containing uppercasing tables. I don't know what
173 these are for (CHKDSK, maybe?) -- OS/2 does not seem to use them
174 itself. Linux doesn't use them either. */
175
176/* block pointed to by spareblock->code_page_dir */
177
178#define CP_DIR_MAGIC 0x494521f7
179
180struct code_page_directory
181{
182 unsigned magic; /* 4945 21f7 */
183 unsigned n_code_pages; /* number of pointers following */
184 unsigned zero1[2];
185 struct {
186 unsigned short ix; /* index */
187 unsigned short code_page_number; /* code page number */
188 unsigned bounds; /* matches corresponding word
189 in data block */
190 secno code_page_data; /* sector number of a code_page_data
191 containing c.p. array */
192 unsigned short index; /* index in c.p. array in that sector*/
193 unsigned short unknown; /* some unknown value; usually 0;
194 2 in Japanese version */
195 } array[31]; /* unknown length */
196};
197
198/* blocks pointed to by code_page_directory */
199
200#define CP_DATA_MAGIC 0x894521f7
201
202struct code_page_data
203{
204 unsigned magic; /* 8945 21f7 */
205 unsigned n_used; /* # elements used in c_p_data[] */
206 unsigned bounds[3]; /* looks a bit like
207 (beg1,end1), (beg2,end2)
208 one byte each */
209 unsigned short offs[3]; /* offsets from start of sector
210 to start of c_p_data[ix] */
211 struct {
212 unsigned short ix; /* index */
213 unsigned short code_page_number; /* code page number */
214 unsigned short unknown; /* the same as in cp directory */
215 unsigned char map[128]; /* upcase table for chars 80..ff */
216 unsigned short zero2;
217 } code_page[3];
218 unsigned char incognita[78];
219};
220
221
222/* Free space bitmaps are 4 sectors long, which is 16384 bits.
223 16384 sectors is 8 meg, and each 8 meg band has a 4-sector bitmap.
224 Bit order in the maps is little-endian. 0 means taken, 1 means free.
225
226 Bit map sectors are marked allocated in the bit maps, and so are sectors
227 off the end of the partition.
228
229 Band 0 is sectors 0-3fff, its map is in sectors 18-1b.
230 Band 1 is 4000-7fff, its map is in 7ffc-7fff.
231 Band 2 is 8000-ffff, its map is in 8000-8003.
232 The remaining bands have maps in their first (even) or last (odd) 4 sectors
233 -- if the last, partial, band is odd its map is in its last 4 sectors.
234
235 The bitmap locations are given in a table pointed to by the super block.
236 No doubt they aren't constrained to be at 18, 7ffc, 8000, ...; that is
237 just where they usually are.
238
239 The "directory band" is a bunch of sectors preallocated for dnodes.
240 It has a 4-sector free space bitmap of its own. Each bit in the map
241 corresponds to one 4-sector dnode, bit 0 of the map corresponding to
242 the first 4 sectors of the directory band. The entire band is marked
243 allocated in the main bitmap. The super block gives the locations
244 of the directory band and its bitmap. ("band" doesn't mean it is
245 8 meg long; it isn't.) */
246
247
248/* dnode: directory. 4 sectors long */
249
250/* A directory is a tree of dnodes. The fnode for a directory
251 contains one pointer, to the root dnode of the tree. The fnode
252 never moves, the dnodes do the B-tree thing, splitting and merging
253 as files are added and removed. */
254
255#define DNODE_MAGIC 0x77e40aae
256
257struct dnode {
258 unsigned magic; /* 77e4 0aae */
259 unsigned first_free; /* offset from start of dnode to
260 first free dir entry */
261 unsigned root_dnode:1; /* Is it root dnode? */
262 unsigned increment_me:31; /* some kind of activity counter?
263 Neither HPFS.IFS nor CHKDSK cares
264 if you change this word */
265 secno up; /* (root dnode) directory's fnode
266 (nonroot) parent dnode */
267 dnode_secno self; /* pointer to this dnode */
268 unsigned char dirent[2028]; /* one or more dirents */
269};
270
271struct hpfs_dirent {
272 unsigned short length; /* offset to next dirent */
273 unsigned first: 1; /* set on phony ^A^A (".") entry */
274 unsigned has_acl: 1;
275 unsigned down: 1; /* down pointer present (after name) */
276 unsigned last: 1; /* set on phony \377 entry */
277 unsigned has_ea: 1; /* entry has EA */
278 unsigned has_xtd_perm: 1; /* has extended perm list (???) */
279 unsigned has_explicit_acl: 1;
280 unsigned has_needea: 1; /* ?? some EA has NEEDEA set
281 I have no idea why this is
282 interesting in a dir entry */
283 unsigned read_only: 1; /* dos attrib */
284 unsigned hidden: 1; /* dos attrib */
285 unsigned system: 1; /* dos attrib */
286 unsigned flag11: 1; /* would be volume label dos attrib */
287 unsigned directory: 1; /* dos attrib */
288 unsigned archive: 1; /* dos attrib */
289 unsigned not_8x3: 1; /* name is not 8.3 */
290 unsigned flag15: 1;
291 fnode_secno fnode; /* fnode giving allocation info */
292 time32_t write_date; /* mtime */
293 unsigned file_size; /* file length, bytes */
294 time32_t read_date; /* atime */
295 time32_t creation_date; /* ctime */
296 unsigned ea_size; /* total EA length, bytes */
297 unsigned char no_of_acls : 3; /* number of ACL's */
298 unsigned char reserver : 5;
299 unsigned char ix; /* code page index (of filename), see
300 struct code_page_data */
301 unsigned char namelen, name[1]; /* file name */
302 /* dnode_secno down; btree down pointer, if present,
303 follows name on next word boundary, or maybe it
304 precedes next dirent, which is on a word boundary. */
305};
306
307
308/* B+ tree: allocation info in fnodes and anodes */
309
310/* dnodes point to fnodes which are responsible for listing the sectors
311 assigned to the file. This is done with trees of (length,address)
312 pairs. (Actually triples, of (length, file-address, disk-address)
313 which can represent holes. Find out if HPFS does that.)
314 At any rate, fnodes contain a small tree; if subtrees are needed
315 they occupy essentially a full block in anodes. A leaf-level tree node
316 has 3-word entries giving sector runs, a non-leaf node has 2-word
317 entries giving subtree pointers. A flag in the header says which. */
318
319struct bplus_leaf_node
320{
321 unsigned file_secno; /* first file sector in extent */
322 unsigned length; /* length, sectors */
323 secno disk_secno; /* first corresponding disk sector */
324};
325
326struct bplus_internal_node
327{
328 unsigned file_secno; /* subtree maps sectors < this */
329 anode_secno down; /* pointer to subtree */
330};
331
332struct bplus_header
333{
334 unsigned hbff: 1; /* high bit of first free entry offset */
335 unsigned flag1: 1;
336 unsigned flag2: 1;
337 unsigned flag3: 1;
338 unsigned flag4: 1;
339 unsigned fnode_parent: 1; /* ? we're pointed to by an fnode,
340 the data btree or some ea or the
341 main ea bootage pointer ea_secno */
342 /* also can get set in fnodes, which
343 may be a chkdsk glitch or may mean
344 this bit is irrelevant in fnodes,
345 or this interpretation is all wet */
346 unsigned binary_search: 1; /* suggest binary search (unused) */
347 unsigned internal: 1; /* 1 -> (internal) tree of anodes
348 0 -> (leaf) list of extents */
349 unsigned char fill[3];
350 unsigned char n_free_nodes; /* free nodes in following array */
351 unsigned char n_used_nodes; /* used nodes in following array */
352 unsigned short first_free; /* offset from start of header to
353 first free node in array */
354 union {
355 struct bplus_internal_node internal[0]; /* (internal) 2-word entries giving
356 subtree pointers */
357 struct bplus_leaf_node external[0]; /* (external) 3-word entries giving
358 sector runs */
359 } u;
360};
361
362/* fnode: root of allocation b+ tree, and EA's */
363
364/* Every file and every directory has one fnode, pointed to by the directory
365 entry and pointing to the file's sectors or directory's root dnode. EA's
366 are also stored here, and there are said to be ACL's somewhere here too. */
367
368#define FNODE_MAGIC 0xf7e40aae
369
370struct fnode
371{
372 unsigned magic; /* f7e4 0aae */
373 unsigned zero1[2]; /* read history */
374 unsigned char len, name[15]; /* true length, truncated name */
375 fnode_secno up; /* pointer to file's directory fnode */
376 /*unsigned zero2[3];*/
377 secno acl_size_l;
378 secno acl_secno;
379 unsigned short acl_size_s;
380 char acl_anode;
381 char zero2; /* history bit count */
382 unsigned ea_size_l; /* length of disk-resident ea's */
383 secno ea_secno; /* first sector of disk-resident ea's*/
384 unsigned short ea_size_s; /* length of fnode-resident ea's */
385
386 unsigned flag0: 1;
387 unsigned ea_anode: 1; /* 1 -> ea_secno is an anode */
388 unsigned flag2: 1;
389 unsigned flag3: 1;
390 unsigned flag4: 1;
391 unsigned flag5: 1;
392 unsigned flag6: 1;
393 unsigned flag7: 1;
394 unsigned dirflag: 1; /* 1 -> directory. first & only extent
395 points to dnode. */
396 unsigned flag9: 1;
397 unsigned flag10: 1;
398 unsigned flag11: 1;
399 unsigned flag12: 1;
400 unsigned flag13: 1;
401 unsigned flag14: 1;
402 unsigned flag15: 1;
403
404 struct bplus_header btree; /* b+ tree, 8 extents or 12 subtrees */
405 union {
406 struct bplus_leaf_node external[8];
407 struct bplus_internal_node internal[12];
408 } u;
409
410 unsigned file_size; /* file length, bytes */
411 unsigned n_needea; /* number of EA's with NEEDEA set */
412 char user_id[16]; /* unused */
413 unsigned short ea_offs; /* offset from start of fnode
414 to first fnode-resident ea */
415 char dasd_limit_treshhold;
416 char dasd_limit_delta;
417 unsigned dasd_limit;
418 unsigned dasd_usage;
419 /*unsigned zero5[2];*/
420 unsigned char ea[316]; /* zero or more EA's, packed together
421 with no alignment padding.
422 (Do not use this name, get here
423 via fnode + ea_offs. I think.) */
424};
425
426
427/* anode: 99.44% pure allocation tree */
428
429#define ANODE_MAGIC 0x37e40aae
430
431struct anode
432{
433 unsigned magic; /* 37e4 0aae */
434 anode_secno self; /* pointer to this anode */
435 secno up; /* parent anode or fnode */
436
437 struct bplus_header btree; /* b+tree, 40 extents or 60 subtrees */
438 union {
439 struct bplus_leaf_node external[40];
440 struct bplus_internal_node internal[60];
441 } u;
442
443 unsigned fill[3]; /* unused */
444};
445
446
447/* extended attributes.
448
449 A file's EA info is stored as a list of (name,value) pairs. It is
450 usually in the fnode, but (if it's large) it is moved to a single
451 sector run outside the fnode, or to multiple runs with an anode tree
452 that points to them.
453
454 The value of a single EA is stored along with the name, or (if large)
455 it is moved to a single sector run, or multiple runs pointed to by an
456 anode tree, pointed to by the value field of the (name,value) pair.
457
458 Flags in the EA tell whether the value is immediate, in a single sector
459 run, or in multiple runs. Flags in the fnode tell whether the EA list
460 is immediate, in a single run, or in multiple runs. */
461
462struct extended_attribute
463{
464 unsigned indirect: 1; /* 1 -> value gives sector number
465 where real value starts */
466 unsigned anode: 1; /* 1 -> sector is an anode
467 that points to fragmented value */
468 unsigned flag2: 1;
469 unsigned flag3: 1;
470 unsigned flag4: 1;
471 unsigned flag5: 1;
472 unsigned flag6: 1;
473 unsigned needea: 1; /* required ea */
474 unsigned char namelen; /* length of name, bytes */
475 unsigned short valuelen; /* length of value, bytes */
476 unsigned char name[0];
477 /*
478 unsigned char name[namelen]; ascii attrib name
479 unsigned char nul; terminating '\0', not counted
480 unsigned char value[valuelen]; value, arbitrary
481 if this.indirect, valuelen is 8 and the value is
482 unsigned length; real length of value, bytes
483 secno secno; sector address where it starts
484 if this.anode, the above sector number is the root of an anode tree
485 which points to the value.
486 */
487};
488
489/*
490 Local Variables:
491 comment-column: 40
492 End:
493*/
diff --git a/fs/hpfs/hpfs_fn.h b/fs/hpfs/hpfs_fn.h
new file mode 100644
index 000000000000..6628c3b352cb
--- /dev/null
+++ b/fs/hpfs/hpfs_fn.h
@@ -0,0 +1,338 @@
1/*
2 * linux/fs/hpfs/hpfs_fn.h
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * function headers
7 */
8
9//#define DBG
10//#define DEBUG_LOCKS
11
12#include <linux/pagemap.h>
13#include <linux/buffer_head.h>
14#include <linux/hpfs_fs.h>
15#include <linux/slab.h>
16#include <linux/smp_lock.h>
17
18#include "hpfs.h"
19
20#define EIOERROR EIO
21#define EFSERROR EPERM
22#define EMEMERROR ENOMEM
23
24#define ANODE_ALLOC_FWD 512
25#define FNODE_ALLOC_FWD 0
26#define ALLOC_FWD_MIN 16
27#define ALLOC_FWD_MAX 128
28#define ALLOC_M 1
29#define FNODE_RD_AHEAD 16
30#define ANODE_RD_AHEAD 16
31#define DNODE_RD_AHEAD 4
32
33#define FREE_DNODES_ADD 58
34#define FREE_DNODES_DEL 29
35
36#define CHKCOND(x,y) if (!(x)) printk y
37
38#ifdef DBG
39#define PRINTK(x) printk x
40#else
41#undef PRINTK
42#define PRINTK(x)
43#endif
44
45struct hpfs_inode_info {
46 loff_t mmu_private;
47 ino_t i_parent_dir; /* (directories) gives fnode of parent dir */
48 unsigned i_dno; /* (directories) root dnode */
49 unsigned i_dpos; /* (directories) temp for readdir */
50 unsigned i_dsubdno; /* (directories) temp for readdir */
51 unsigned i_file_sec; /* (files) minimalist cache of alloc info */
52 unsigned i_disk_sec; /* (files) minimalist cache of alloc info */
53 unsigned i_n_secs; /* (files) minimalist cache of alloc info */
54 unsigned i_ea_size; /* size of extended attributes */
55 unsigned i_conv : 2; /* (files) crlf->newline hackery */
56 unsigned i_ea_mode : 1; /* file's permission is stored in ea */
57 unsigned i_ea_uid : 1; /* file's uid is stored in ea */
58 unsigned i_ea_gid : 1; /* file's gid is stored in ea */
59 unsigned i_dirty : 1;
60 struct semaphore i_sem;
61 struct semaphore i_parent;
62 loff_t **i_rddir_off;
63 struct inode vfs_inode;
64};
65
66struct hpfs_sb_info {
67 ino_t sb_root; /* inode number of root dir */
68 unsigned sb_fs_size; /* file system size, sectors */
69 unsigned sb_bitmaps; /* sector number of bitmap list */
70 unsigned sb_dirband_start; /* directory band start sector */
71 unsigned sb_dirband_size; /* directory band size, dnodes */
72 unsigned sb_dmap; /* sector number of dnode bit map */
73 unsigned sb_n_free; /* free blocks for statfs, or -1 */
74 unsigned sb_n_free_dnodes; /* free dnodes for statfs, or -1 */
75 uid_t sb_uid; /* uid from mount options */
76 gid_t sb_gid; /* gid from mount options */
77 umode_t sb_mode; /* mode from mount options */
78 unsigned sb_conv : 2; /* crlf->newline hackery */
79 unsigned sb_eas : 2; /* eas: 0-ignore, 1-ro, 2-rw */
80 unsigned sb_err : 2; /* on errs: 0-cont, 1-ro, 2-panic */
81 unsigned sb_chk : 2; /* checks: 0-no, 1-normal, 2-strict */
82 unsigned sb_lowercase : 1; /* downcase filenames hackery */
83 unsigned sb_was_error : 1; /* there was an error, set dirty flag */
84 unsigned sb_chkdsk : 2; /* chkdsk: 0-no, 1-on errs, 2-allways */
85 unsigned char *sb_cp_table; /* code page tables: */
86 /* 128 bytes uppercasing table & */
87 /* 128 bytes lowercasing table */
88 unsigned *sb_bmp_dir; /* main bitmap directory */
89 unsigned sb_c_bitmap; /* current bitmap */
90 unsigned sb_max_fwd_alloc; /* max forwad allocation */
91 struct semaphore hpfs_creation_de; /* when creating dirents, nobody else
92 can alloc blocks */
93 /*unsigned sb_mounting : 1;*/
94 int sb_timeshift;
95};
96
97/*
98 * conv= options
99 */
100
101#define CONV_BINARY 0 /* no conversion */
102#define CONV_TEXT 1 /* crlf->newline */
103#define CONV_AUTO 2 /* decide based on file contents */
104
105/* Four 512-byte buffers and the 2k block obtained by concatenating them */
106
107struct quad_buffer_head {
108 struct buffer_head *bh[4];
109 void *data;
110};
111
112/* The b-tree down pointer from a dir entry */
113
114static inline dnode_secno de_down_pointer (struct hpfs_dirent *de)
115{
116 CHKCOND(de->down,("HPFS: de_down_pointer: !de->down\n"));
117 return *(dnode_secno *) ((void *) de + de->length - 4);
118}
119
120/* The first dir entry in a dnode */
121
122static inline struct hpfs_dirent *dnode_first_de (struct dnode *dnode)
123{
124 return (void *) dnode->dirent;
125}
126
127/* The end+1 of the dir entries */
128
129static inline struct hpfs_dirent *dnode_end_de (struct dnode *dnode)
130{
131 CHKCOND(dnode->first_free>=0x14 && dnode->first_free<=0xa00,("HPFS: dnode_end_de: dnode->first_free = %d\n",(int)dnode->first_free));
132 return (void *) dnode + dnode->first_free;
133}
134
135/* The dir entry after dir entry de */
136
137static inline struct hpfs_dirent *de_next_de (struct hpfs_dirent *de)
138{
139 CHKCOND(de->length>=0x20 && de->length<0x800,("HPFS: de_next_de: de->length = %d\n",(int)de->length));
140 return (void *) de + de->length;
141}
142
143static inline struct extended_attribute *fnode_ea(struct fnode *fnode)
144{
145 return (struct extended_attribute *)((char *)fnode + fnode->ea_offs + fnode->acl_size_s);
146}
147
148static inline struct extended_attribute *fnode_end_ea(struct fnode *fnode)
149{
150 return (struct extended_attribute *)((char *)fnode + fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s);
151}
152
153static inline struct extended_attribute *next_ea(struct extended_attribute *ea)
154{
155 return (struct extended_attribute *)((char *)ea + 5 + ea->namelen + ea->valuelen);
156}
157
158static inline secno ea_sec(struct extended_attribute *ea)
159{
160 return *(secno *)((char *)ea + 9 + ea->namelen);
161}
162
163static inline secno ea_len(struct extended_attribute *ea)
164{
165 return *(secno *)((char *)ea + 5 + ea->namelen);
166}
167
168static inline char *ea_data(struct extended_attribute *ea)
169{
170 return (char *)((char *)ea + 5 + ea->namelen);
171}
172
173static inline unsigned de_size(int namelen, secno down_ptr)
174{
175 return ((0x1f + namelen + 3) & ~3) + (down_ptr ? 4 : 0);
176}
177
178static inline void copy_de(struct hpfs_dirent *dst, struct hpfs_dirent *src)
179{
180 int a;
181 int n;
182 if (!dst || !src) return;
183 a = dst->down;
184 n = dst->not_8x3;
185 memcpy((char *)dst + 2, (char *)src + 2, 28);
186 dst->down = a;
187 dst->not_8x3 = n;
188}
189
190static inline unsigned tstbits(unsigned *bmp, unsigned b, unsigned n)
191{
192 int i;
193 if ((b >= 0x4000) || (b + n - 1 >= 0x4000)) return n;
194 if (!((bmp[(b & 0x3fff) >> 5] >> (b & 0x1f)) & 1)) return 1;
195 for (i = 1; i < n; i++)
196 if (/*b+i < 0x4000 &&*/ !((bmp[((b+i) & 0x3fff) >> 5] >> ((b+i) & 0x1f)) & 1))
197 return i + 1;
198 return 0;
199}
200
201/* alloc.c */
202
203int hpfs_chk_sectors(struct super_block *, secno, int, char *);
204secno hpfs_alloc_sector(struct super_block *, secno, unsigned, int, int);
205int hpfs_alloc_if_possible(struct super_block *, secno);
206void hpfs_free_sectors(struct super_block *, secno, unsigned);
207int hpfs_check_free_dnodes(struct super_block *, int);
208void hpfs_free_dnode(struct super_block *, secno);
209struct dnode *hpfs_alloc_dnode(struct super_block *, secno, dnode_secno *, struct quad_buffer_head *, int);
210struct fnode *hpfs_alloc_fnode(struct super_block *, secno, fnode_secno *, struct buffer_head **);
211struct anode *hpfs_alloc_anode(struct super_block *, secno, anode_secno *, struct buffer_head **);
212
213/* anode.c */
214
215secno hpfs_bplus_lookup(struct super_block *, struct inode *, struct bplus_header *, unsigned, struct buffer_head *);
216secno hpfs_add_sector_to_btree(struct super_block *, secno, int, unsigned);
217void hpfs_remove_btree(struct super_block *, struct bplus_header *);
218int hpfs_ea_read(struct super_block *, secno, int, unsigned, unsigned, char *);
219int hpfs_ea_write(struct super_block *, secno, int, unsigned, unsigned, char *);
220void hpfs_ea_remove(struct super_block *, secno, int, unsigned);
221void hpfs_truncate_btree(struct super_block *, secno, int, unsigned);
222void hpfs_remove_fnode(struct super_block *, fnode_secno fno);
223
224/* buffer.c */
225
226void hpfs_lock_creation(struct super_block *);
227void hpfs_unlock_creation(struct super_block *);
228void *hpfs_map_sector(struct super_block *, unsigned, struct buffer_head **, int);
229void *hpfs_get_sector(struct super_block *, unsigned, struct buffer_head **);
230void *hpfs_map_4sectors(struct super_block *, unsigned, struct quad_buffer_head *, int);
231void *hpfs_get_4sectors(struct super_block *, unsigned, struct quad_buffer_head *);
232void hpfs_brelse4(struct quad_buffer_head *);
233void hpfs_mark_4buffers_dirty(struct quad_buffer_head *);
234
235/* dentry.c */
236
237void hpfs_set_dentry_operations(struct dentry *);
238
239/* dir.c */
240
241struct dentry *hpfs_lookup(struct inode *, struct dentry *, struct nameidata *);
242extern struct file_operations hpfs_dir_ops;
243
244/* dnode.c */
245
246void hpfs_add_pos(struct inode *, loff_t *);
247void hpfs_del_pos(struct inode *, loff_t *);
248struct hpfs_dirent *hpfs_add_de(struct super_block *, struct dnode *, unsigned char *, unsigned, secno);
249int hpfs_add_dirent(struct inode *, unsigned char *, unsigned, struct hpfs_dirent *, int);
250int hpfs_remove_dirent(struct inode *, dnode_secno, struct hpfs_dirent *, struct quad_buffer_head *, int);
251void hpfs_count_dnodes(struct super_block *, dnode_secno, int *, int *, int *);
252dnode_secno hpfs_de_as_down_as_possible(struct super_block *, dnode_secno dno);
253struct hpfs_dirent *map_pos_dirent(struct inode *, loff_t *, struct quad_buffer_head *);
254struct hpfs_dirent *map_dirent(struct inode *, dnode_secno, char *, unsigned, dnode_secno *, struct quad_buffer_head *);
255void hpfs_remove_dtree(struct super_block *, dnode_secno);
256struct hpfs_dirent *map_fnode_dirent(struct super_block *, fnode_secno, struct fnode *, struct quad_buffer_head *);
257
258/* ea.c */
259
260void hpfs_ea_ext_remove(struct super_block *, secno, int, unsigned);
261int hpfs_read_ea(struct super_block *, struct fnode *, char *, char *, int);
262char *hpfs_get_ea(struct super_block *, struct fnode *, char *, int *);
263void hpfs_set_ea(struct inode *, struct fnode *, char *, char *, int);
264
265/* file.c */
266
267int hpfs_file_fsync(struct file *, struct dentry *, int);
268extern struct file_operations hpfs_file_ops;
269extern struct inode_operations hpfs_file_iops;
270extern struct address_space_operations hpfs_aops;
271
272/* inode.c */
273
274void hpfs_init_inode(struct inode *);
275void hpfs_read_inode(struct inode *);
276void hpfs_write_inode(struct inode *);
277void hpfs_write_inode_nolock(struct inode *);
278int hpfs_notify_change(struct dentry *, struct iattr *);
279void hpfs_write_if_changed(struct inode *);
280void hpfs_delete_inode(struct inode *);
281
282/* map.c */
283
284unsigned *hpfs_map_dnode_bitmap(struct super_block *, struct quad_buffer_head *);
285unsigned *hpfs_map_bitmap(struct super_block *, unsigned, struct quad_buffer_head *, char *);
286char *hpfs_load_code_page(struct super_block *, secno);
287secno *hpfs_load_bitmap_directory(struct super_block *, secno bmp);
288struct fnode *hpfs_map_fnode(struct super_block *s, ino_t, struct buffer_head **);
289struct anode *hpfs_map_anode(struct super_block *s, anode_secno, struct buffer_head **);
290struct dnode *hpfs_map_dnode(struct super_block *s, dnode_secno, struct quad_buffer_head *);
291dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino);
292
293/* name.c */
294
295unsigned char hpfs_upcase(unsigned char *, unsigned char);
296int hpfs_chk_name(unsigned char *, unsigned *);
297char *hpfs_translate_name(struct super_block *, unsigned char *, unsigned, int, int);
298int hpfs_compare_names(struct super_block *, unsigned char *, unsigned, unsigned char *, unsigned, int);
299int hpfs_is_name_long(unsigned char *, unsigned);
300void hpfs_adjust_length(unsigned char *, unsigned *);
301void hpfs_decide_conv(struct inode *, unsigned char *, unsigned);
302
303/* namei.c */
304
305extern struct inode_operations hpfs_dir_iops;
306extern struct address_space_operations hpfs_symlink_aops;
307
308static inline struct hpfs_inode_info *hpfs_i(struct inode *inode)
309{
310 return list_entry(inode, struct hpfs_inode_info, vfs_inode);
311}
312
313static inline struct hpfs_sb_info *hpfs_sb(struct super_block *sb)
314{
315 return sb->s_fs_info;
316}
317
318/* super.c */
319
320void hpfs_error(struct super_block *, char *, ...);
321int hpfs_stop_cycles(struct super_block *, int, int *, int *, char *);
322unsigned hpfs_count_one_bitmap(struct super_block *, secno);
323
324/*
325 * local time (HPFS) to GMT (Unix)
326 */
327
328static inline time_t local_to_gmt(struct super_block *s, time32_t t)
329{
330 extern struct timezone sys_tz;
331 return t + sys_tz.tz_minuteswest * 60 + hpfs_sb(s)->sb_timeshift;
332}
333
334static inline time32_t gmt_to_local(struct super_block *s, time_t t)
335{
336 extern struct timezone sys_tz;
337 return t - sys_tz.tz_minuteswest * 60 - hpfs_sb(s)->sb_timeshift;
338}
diff --git a/fs/hpfs/inode.c b/fs/hpfs/inode.c
new file mode 100644
index 000000000000..38b1741fa539
--- /dev/null
+++ b/fs/hpfs/inode.c
@@ -0,0 +1,291 @@
1/*
2 * linux/fs/hpfs/inode.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * inode VFS functions
7 */
8
9#include "hpfs_fn.h"
10
11void hpfs_init_inode(struct inode *i)
12{
13 struct super_block *sb = i->i_sb;
14 struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
15
16 i->i_uid = hpfs_sb(sb)->sb_uid;
17 i->i_gid = hpfs_sb(sb)->sb_gid;
18 i->i_mode = hpfs_sb(sb)->sb_mode;
19 hpfs_inode->i_conv = hpfs_sb(sb)->sb_conv;
20 i->i_blksize = 512;
21 i->i_size = -1;
22 i->i_blocks = -1;
23
24 hpfs_inode->i_dno = 0;
25 hpfs_inode->i_n_secs = 0;
26 hpfs_inode->i_file_sec = 0;
27 hpfs_inode->i_disk_sec = 0;
28 hpfs_inode->i_dpos = 0;
29 hpfs_inode->i_dsubdno = 0;
30 hpfs_inode->i_ea_mode = 0;
31 hpfs_inode->i_ea_uid = 0;
32 hpfs_inode->i_ea_gid = 0;
33 hpfs_inode->i_ea_size = 0;
34
35 hpfs_inode->i_rddir_off = NULL;
36 hpfs_inode->i_dirty = 0;
37
38 i->i_ctime.tv_sec = i->i_ctime.tv_nsec = 0;
39 i->i_mtime.tv_sec = i->i_mtime.tv_nsec = 0;
40 i->i_atime.tv_sec = i->i_atime.tv_nsec = 0;
41}
42
43void hpfs_read_inode(struct inode *i)
44{
45 struct buffer_head *bh;
46 struct fnode *fnode;
47 struct super_block *sb = i->i_sb;
48 struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
49 unsigned char *ea;
50 int ea_size;
51
52 if (!(fnode = hpfs_map_fnode(sb, i->i_ino, &bh))) {
53 /*i->i_mode |= S_IFREG;
54 i->i_mode &= ~0111;
55 i->i_op = &hpfs_file_iops;
56 i->i_fop = &hpfs_file_ops;
57 i->i_nlink = 0;*/
58 make_bad_inode(i);
59 return;
60 }
61 if (hpfs_sb(i->i_sb)->sb_eas) {
62 if ((ea = hpfs_get_ea(i->i_sb, fnode, "UID", &ea_size))) {
63 if (ea_size == 2) {
64 i->i_uid = le16_to_cpu(*(u16*)ea);
65 hpfs_inode->i_ea_uid = 1;
66 }
67 kfree(ea);
68 }
69 if ((ea = hpfs_get_ea(i->i_sb, fnode, "GID", &ea_size))) {
70 if (ea_size == 2) {
71 i->i_gid = le16_to_cpu(*(u16*)ea);
72 hpfs_inode->i_ea_gid = 1;
73 }
74 kfree(ea);
75 }
76 if ((ea = hpfs_get_ea(i->i_sb, fnode, "SYMLINK", &ea_size))) {
77 kfree(ea);
78 i->i_mode = S_IFLNK | 0777;
79 i->i_op = &page_symlink_inode_operations;
80 i->i_data.a_ops = &hpfs_symlink_aops;
81 i->i_nlink = 1;
82 i->i_size = ea_size;
83 i->i_blocks = 1;
84 brelse(bh);
85 return;
86 }
87 if ((ea = hpfs_get_ea(i->i_sb, fnode, "MODE", &ea_size))) {
88 int rdev = 0;
89 umode_t mode = hpfs_sb(sb)->sb_mode;
90 if (ea_size == 2) {
91 mode = le16_to_cpu(*(u16*)ea);
92 hpfs_inode->i_ea_mode = 1;
93 }
94 kfree(ea);
95 i->i_mode = mode;
96 if (S_ISBLK(mode) || S_ISCHR(mode)) {
97 if ((ea = hpfs_get_ea(i->i_sb, fnode, "DEV", &ea_size))) {
98 if (ea_size == 4)
99 rdev = le32_to_cpu(*(u32*)ea);
100 kfree(ea);
101 }
102 }
103 if (S_ISBLK(mode) || S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
104 brelse(bh);
105 i->i_nlink = 1;
106 i->i_size = 0;
107 i->i_blocks = 1;
108 init_special_inode(i, mode,
109 new_decode_dev(rdev));
110 return;
111 }
112 }
113 }
114 if (fnode->dirflag) {
115 unsigned n_dnodes, n_subdirs;
116 i->i_mode |= S_IFDIR;
117 i->i_op = &hpfs_dir_iops;
118 i->i_fop = &hpfs_dir_ops;
119 hpfs_inode->i_parent_dir = fnode->up;
120 hpfs_inode->i_dno = fnode->u.external[0].disk_secno;
121 if (hpfs_sb(sb)->sb_chk >= 2) {
122 struct buffer_head *bh0;
123 if (hpfs_map_fnode(sb, hpfs_inode->i_parent_dir, &bh0)) brelse(bh0);
124 }
125 n_dnodes = 0; n_subdirs = 0;
126 hpfs_count_dnodes(i->i_sb, hpfs_inode->i_dno, &n_dnodes, &n_subdirs, NULL);
127 i->i_blocks = 4 * n_dnodes;
128 i->i_size = 2048 * n_dnodes;
129 i->i_nlink = 2 + n_subdirs;
130 } else {
131 i->i_mode |= S_IFREG;
132 if (!hpfs_inode->i_ea_mode) i->i_mode &= ~0111;
133 i->i_op = &hpfs_file_iops;
134 i->i_fop = &hpfs_file_ops;
135 i->i_nlink = 1;
136 i->i_size = fnode->file_size;
137 i->i_blocks = ((i->i_size + 511) >> 9) + 1;
138 i->i_data.a_ops = &hpfs_aops;
139 hpfs_i(i)->mmu_private = i->i_size;
140 }
141 brelse(bh);
142}
143
144static void hpfs_write_inode_ea(struct inode *i, struct fnode *fnode)
145{
146 struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
147 /*if (fnode->acl_size_l || fnode->acl_size_s) {
148 Some unknown structures like ACL may be in fnode,
149 we'd better not overwrite them
150 hpfs_error(i->i_sb, "fnode %08x has some unknown HPFS386 stuctures", i->i_ino);
151 } else*/ if (hpfs_sb(i->i_sb)->sb_eas >= 2) {
152 u32 ea;
153 if ((i->i_uid != hpfs_sb(i->i_sb)->sb_uid) || hpfs_inode->i_ea_uid) {
154 ea = cpu_to_le32(i->i_uid);
155 hpfs_set_ea(i, fnode, "UID", (char*)&ea, 2);
156 hpfs_inode->i_ea_uid = 1;
157 }
158 if ((i->i_gid != hpfs_sb(i->i_sb)->sb_gid) || hpfs_inode->i_ea_gid) {
159 ea = cpu_to_le32(i->i_gid);
160 hpfs_set_ea(i, fnode, "GID", (char *)&ea, 2);
161 hpfs_inode->i_ea_gid = 1;
162 }
163 if (!S_ISLNK(i->i_mode))
164 if ((i->i_mode != ((hpfs_sb(i->i_sb)->sb_mode & ~(S_ISDIR(i->i_mode) ? 0 : 0111))
165 | (S_ISDIR(i->i_mode) ? S_IFDIR : S_IFREG))
166 && i->i_mode != ((hpfs_sb(i->i_sb)->sb_mode & ~(S_ISDIR(i->i_mode) ? 0222 : 0333))
167 | (S_ISDIR(i->i_mode) ? S_IFDIR : S_IFREG))) || hpfs_inode->i_ea_mode) {
168 ea = cpu_to_le32(i->i_mode);
169 hpfs_set_ea(i, fnode, "MODE", (char *)&ea, 2);
170 hpfs_inode->i_ea_mode = 1;
171 }
172 if (S_ISBLK(i->i_mode) || S_ISCHR(i->i_mode)) {
173 ea = cpu_to_le32(new_encode_dev(i->i_rdev));
174 hpfs_set_ea(i, fnode, "DEV", (char *)&ea, 4);
175 }
176 }
177}
178
179void hpfs_write_inode(struct inode *i)
180{
181 struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
182 struct inode *parent;
183 if (i->i_ino == hpfs_sb(i->i_sb)->sb_root) return;
184 if (hpfs_inode->i_rddir_off && !atomic_read(&i->i_count)) {
185 if (*hpfs_inode->i_rddir_off) printk("HPFS: write_inode: some position still there\n");
186 kfree(hpfs_inode->i_rddir_off);
187 hpfs_inode->i_rddir_off = NULL;
188 }
189 down(&hpfs_inode->i_parent);
190 if (!i->i_nlink) {
191 up(&hpfs_inode->i_parent);
192 return;
193 }
194 parent = iget_locked(i->i_sb, hpfs_inode->i_parent_dir);
195 if (parent) {
196 hpfs_inode->i_dirty = 0;
197 if (parent->i_state & I_NEW) {
198 hpfs_init_inode(parent);
199 hpfs_read_inode(parent);
200 unlock_new_inode(parent);
201 }
202 down(&hpfs_inode->i_sem);
203 hpfs_write_inode_nolock(i);
204 up(&hpfs_inode->i_sem);
205 iput(parent);
206 } else {
207 mark_inode_dirty(i);
208 }
209 up(&hpfs_inode->i_parent);
210}
211
212void hpfs_write_inode_nolock(struct inode *i)
213{
214 struct hpfs_inode_info *hpfs_inode = hpfs_i(i);
215 struct buffer_head *bh;
216 struct fnode *fnode;
217 struct quad_buffer_head qbh;
218 struct hpfs_dirent *de;
219 if (i->i_ino == hpfs_sb(i->i_sb)->sb_root) return;
220 if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) return;
221 if (i->i_ino != hpfs_sb(i->i_sb)->sb_root && i->i_nlink) {
222 if (!(de = map_fnode_dirent(i->i_sb, i->i_ino, fnode, &qbh))) {
223 brelse(bh);
224 return;
225 }
226 } else de = NULL;
227 if (S_ISREG(i->i_mode)) {
228 fnode->file_size = i->i_size;
229 if (de) de->file_size = i->i_size;
230 } else if (S_ISDIR(i->i_mode)) {
231 fnode->file_size = 0;
232 if (de) de->file_size = 0;
233 }
234 hpfs_write_inode_ea(i, fnode);
235 if (de) {
236 de->write_date = gmt_to_local(i->i_sb, i->i_mtime.tv_sec);
237 de->read_date = gmt_to_local(i->i_sb, i->i_atime.tv_sec);
238 de->creation_date = gmt_to_local(i->i_sb, i->i_ctime.tv_sec);
239 de->read_only = !(i->i_mode & 0222);
240 de->ea_size = hpfs_inode->i_ea_size;
241 hpfs_mark_4buffers_dirty(&qbh);
242 hpfs_brelse4(&qbh);
243 }
244 if (S_ISDIR(i->i_mode)) {
245 if ((de = map_dirent(i, hpfs_inode->i_dno, "\001\001", 2, NULL, &qbh))) {
246 de->write_date = gmt_to_local(i->i_sb, i->i_mtime.tv_sec);
247 de->read_date = gmt_to_local(i->i_sb, i->i_atime.tv_sec);
248 de->creation_date = gmt_to_local(i->i_sb, i->i_ctime.tv_sec);
249 de->read_only = !(i->i_mode & 0222);
250 de->ea_size = /*hpfs_inode->i_ea_size*/0;
251 de->file_size = 0;
252 hpfs_mark_4buffers_dirty(&qbh);
253 hpfs_brelse4(&qbh);
254 } else hpfs_error(i->i_sb, "directory %08x doesn't have '.' entry", i->i_ino);
255 }
256 mark_buffer_dirty(bh);
257 brelse(bh);
258}
259
260int hpfs_notify_change(struct dentry *dentry, struct iattr *attr)
261{
262 struct inode *inode = dentry->d_inode;
263 int error=0;
264 lock_kernel();
265 if ( ((attr->ia_valid & ATTR_SIZE) && attr->ia_size > inode->i_size) ||
266 (hpfs_sb(inode->i_sb)->sb_root == inode->i_ino) ) {
267 error = -EINVAL;
268 } else if ((error = inode_change_ok(inode, attr))) {
269 } else if ((error = inode_setattr(inode, attr))) {
270 } else {
271 hpfs_write_inode(inode);
272 }
273 unlock_kernel();
274 return error;
275}
276
277void hpfs_write_if_changed(struct inode *inode)
278{
279 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
280
281 if (hpfs_inode->i_dirty)
282 hpfs_write_inode(inode);
283}
284
285void hpfs_delete_inode(struct inode *inode)
286{
287 lock_kernel();
288 hpfs_remove_fnode(inode->i_sb, inode->i_ino);
289 unlock_kernel();
290 clear_inode(inode);
291}
diff --git a/fs/hpfs/map.c b/fs/hpfs/map.c
new file mode 100644
index 000000000000..0fecdac22e4e
--- /dev/null
+++ b/fs/hpfs/map.c
@@ -0,0 +1,275 @@
1/*
2 * linux/fs/hpfs/map.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * mapping structures to memory with some minimal checks
7 */
8
9#include "hpfs_fn.h"
10
11unsigned *hpfs_map_dnode_bitmap(struct super_block *s, struct quad_buffer_head *qbh)
12{
13 return hpfs_map_4sectors(s, hpfs_sb(s)->sb_dmap, qbh, 0);
14}
15
16unsigned int *hpfs_map_bitmap(struct super_block *s, unsigned bmp_block,
17 struct quad_buffer_head *qbh, char *id)
18{
19 secno sec;
20 if (hpfs_sb(s)->sb_chk) if (bmp_block * 16384 > hpfs_sb(s)->sb_fs_size) {
21 hpfs_error(s, "hpfs_map_bitmap called with bad parameter: %08x at %s", bmp_block, id);
22 return NULL;
23 }
24 sec = hpfs_sb(s)->sb_bmp_dir[bmp_block];
25 if (!sec || sec > hpfs_sb(s)->sb_fs_size-4) {
26 hpfs_error(s, "invalid bitmap block pointer %08x -> %08x at %s", bmp_block, sec, id);
27 return NULL;
28 }
29 return hpfs_map_4sectors(s, sec, qbh, 4);
30}
31
32/*
33 * Load first code page into kernel memory, return pointer to 256-byte array,
34 * first 128 bytes are uppercasing table for chars 128-255, next 128 bytes are
35 * lowercasing table
36 */
37
38char *hpfs_load_code_page(struct super_block *s, secno cps)
39{
40 struct buffer_head *bh;
41 secno cpds;
42 unsigned cpi;
43 unsigned char *ptr;
44 unsigned char *cp_table;
45 int i;
46 struct code_page_data *cpd;
47 struct code_page_directory *cp = hpfs_map_sector(s, cps, &bh, 0);
48 if (!cp) return NULL;
49 if (cp->magic != CP_DIR_MAGIC) {
50 printk("HPFS: Code page directory magic doesn't match (magic = %08x)\n", cp->magic);
51 brelse(bh);
52 return NULL;
53 }
54 if (!cp->n_code_pages) {
55 printk("HPFS: n_code_pages == 0\n");
56 brelse(bh);
57 return NULL;
58 }
59 cpds = cp->array[0].code_page_data;
60 cpi = cp->array[0].index;
61 brelse(bh);
62
63 if (cpi >= 3) {
64 printk("HPFS: Code page index out of array\n");
65 return NULL;
66 }
67
68 if (!(cpd = hpfs_map_sector(s, cpds, &bh, 0))) return NULL;
69 if ((unsigned)cpd->offs[cpi] > 0x178) {
70 printk("HPFS: Code page index out of sector\n");
71 brelse(bh);
72 return NULL;
73 }
74 ptr = (char *)cpd + cpd->offs[cpi] + 6;
75 if (!(cp_table = kmalloc(256, GFP_KERNEL))) {
76 printk("HPFS: out of memory for code page table\n");
77 brelse(bh);
78 return NULL;
79 }
80 memcpy(cp_table, ptr, 128);
81 brelse(bh);
82
83 /* Try to build lowercasing table from uppercasing one */
84
85 for (i=128; i<256; i++) cp_table[i]=i;
86 for (i=128; i<256; i++) if (cp_table[i-128]!=i && cp_table[i-128]>=128)
87 cp_table[cp_table[i-128]] = i;
88
89 return cp_table;
90}
91
92secno *hpfs_load_bitmap_directory(struct super_block *s, secno bmp)
93{
94 struct buffer_head *bh;
95 int n = (hpfs_sb(s)->sb_fs_size + 0x200000 - 1) >> 21;
96 int i;
97 secno *b;
98 if (!(b = kmalloc(n * 512, GFP_KERNEL))) {
99 printk("HPFS: can't allocate memory for bitmap directory\n");
100 return NULL;
101 }
102 for (i=0;i<n;i++) {
103 secno *d = hpfs_map_sector(s, bmp+i, &bh, n - i - 1);
104 if (!d) {
105 kfree(b);
106 return NULL;
107 }
108 memcpy((char *)b + 512 * i, d, 512);
109 brelse(bh);
110 }
111 return b;
112}
113
114/*
115 * Load fnode to memory
116 */
117
118struct fnode *hpfs_map_fnode(struct super_block *s, ino_t ino, struct buffer_head **bhp)
119{
120 struct fnode *fnode;
121 if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, ino, 1, "fnode")) {
122 return NULL;
123 }
124 if ((fnode = hpfs_map_sector(s, ino, bhp, FNODE_RD_AHEAD))) {
125 if (hpfs_sb(s)->sb_chk) {
126 struct extended_attribute *ea;
127 struct extended_attribute *ea_end;
128 if (fnode->magic != FNODE_MAGIC) {
129 hpfs_error(s, "bad magic on fnode %08x", ino);
130 goto bail;
131 }
132 if (!fnode->dirflag) {
133 if ((unsigned)fnode->btree.n_used_nodes + (unsigned)fnode->btree.n_free_nodes !=
134 (fnode->btree.internal ? 12 : 8)) {
135 hpfs_error(s, "bad number of nodes in fnode %08x", ino);
136 goto bail;
137 }
138 if (fnode->btree.first_free !=
139 8 + fnode->btree.n_used_nodes * (fnode->btree.internal ? 8 : 12)) {
140 hpfs_error(s, "bad first_free pointer in fnode %08x", ino);
141 goto bail;
142 }
143 }
144 if (fnode->ea_size_s && ((signed int)fnode->ea_offs < 0xc4 ||
145 (signed int)fnode->ea_offs + fnode->acl_size_s + fnode->ea_size_s > 0x200)) {
146 hpfs_error(s, "bad EA info in fnode %08x: ea_offs == %04x ea_size_s == %04x",
147 ino, fnode->ea_offs, fnode->ea_size_s);
148 goto bail;
149 }
150 ea = fnode_ea(fnode);
151 ea_end = fnode_end_ea(fnode);
152 while (ea != ea_end) {
153 if (ea > ea_end) {
154 hpfs_error(s, "bad EA in fnode %08x", ino);
155 goto bail;
156 }
157 ea = next_ea(ea);
158 }
159 }
160 }
161 return fnode;
162 bail:
163 brelse(*bhp);
164 return NULL;
165}
166
167struct anode *hpfs_map_anode(struct super_block *s, anode_secno ano, struct buffer_head **bhp)
168{
169 struct anode *anode;
170 if (hpfs_sb(s)->sb_chk) if (hpfs_chk_sectors(s, ano, 1, "anode")) return NULL;
171 if ((anode = hpfs_map_sector(s, ano, bhp, ANODE_RD_AHEAD)))
172 if (hpfs_sb(s)->sb_chk) {
173 if (anode->magic != ANODE_MAGIC || anode->self != ano) {
174 hpfs_error(s, "bad magic on anode %08x", ano);
175 goto bail;
176 }
177 if ((unsigned)anode->btree.n_used_nodes + (unsigned)anode->btree.n_free_nodes !=
178 (anode->btree.internal ? 60 : 40)) {
179 hpfs_error(s, "bad number of nodes in anode %08x", ano);
180 goto bail;
181 }
182 if (anode->btree.first_free !=
183 8 + anode->btree.n_used_nodes * (anode->btree.internal ? 8 : 12)) {
184 hpfs_error(s, "bad first_free pointer in anode %08x", ano);
185 goto bail;
186 }
187 }
188 return anode;
189 bail:
190 brelse(*bhp);
191 return NULL;
192}
193
194/*
195 * Load dnode to memory and do some checks
196 */
197
198struct dnode *hpfs_map_dnode(struct super_block *s, unsigned secno,
199 struct quad_buffer_head *qbh)
200{
201 struct dnode *dnode;
202 if (hpfs_sb(s)->sb_chk) {
203 if (hpfs_chk_sectors(s, secno, 4, "dnode")) return NULL;
204 if (secno & 3) {
205 hpfs_error(s, "dnode %08x not byte-aligned", secno);
206 return NULL;
207 }
208 }
209 if ((dnode = hpfs_map_4sectors(s, secno, qbh, DNODE_RD_AHEAD)))
210 if (hpfs_sb(s)->sb_chk) {
211 unsigned p, pp = 0;
212 unsigned char *d = (char *)dnode;
213 int b = 0;
214 if (dnode->magic != DNODE_MAGIC) {
215 hpfs_error(s, "bad magic on dnode %08x", secno);
216 goto bail;
217 }
218 if (dnode->self != secno)
219 hpfs_error(s, "bad self pointer on dnode %08x self = %08x", secno, dnode->self);
220 /* Check dirents - bad dirents would cause infinite
221 loops or shooting to memory */
222 if (dnode->first_free > 2048/* || dnode->first_free < 84*/) {
223 hpfs_error(s, "dnode %08x has first_free == %08x", secno, dnode->first_free);
224 goto bail;
225 }
226 for (p = 20; p < dnode->first_free; p += d[p] + (d[p+1] << 8)) {
227 struct hpfs_dirent *de = (struct hpfs_dirent *)((char *)dnode + p);
228 if (de->length > 292 || (de->length < 32) || (de->length & 3) || p + de->length > 2048) {
229 hpfs_error(s, "bad dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
230 goto bail;
231 }
232 if (((31 + de->namelen + de->down*4 + 3) & ~3) != de->length) {
233 if (((31 + de->namelen + de->down*4 + 3) & ~3) < de->length && s->s_flags & MS_RDONLY) goto ok;
234 hpfs_error(s, "namelen does not match dirent size in dnode %08x, dirent %03x, last %03x", secno, p, pp);
235 goto bail;
236 }
237 ok:
238 if (hpfs_sb(s)->sb_chk >= 2) b |= 1 << de->down;
239 if (de->down) if (de_down_pointer(de) < 0x10) {
240 hpfs_error(s, "bad down pointer in dnode %08x, dirent %03x, last %03x", secno, p, pp);
241 goto bail;
242 }
243 pp = p;
244
245 }
246 if (p != dnode->first_free) {
247 hpfs_error(s, "size on last dirent does not match first_free; dnode %08x", secno);
248 goto bail;
249 }
250 if (d[pp + 30] != 1 || d[pp + 31] != 255) {
251 hpfs_error(s, "dnode %08x does not end with \\377 entry", secno);
252 goto bail;
253 }
254 if (b == 3) printk("HPFS: warning: unbalanced dnode tree, dnode %08x; see hpfs.txt 4 more info\n", secno);
255 }
256 return dnode;
257 bail:
258 hpfs_brelse4(qbh);
259 return NULL;
260}
261
262dnode_secno hpfs_fnode_dno(struct super_block *s, ino_t ino)
263{
264 struct buffer_head *bh;
265 struct fnode *fnode;
266 dnode_secno dno;
267
268 fnode = hpfs_map_fnode(s, ino, &bh);
269 if (!fnode)
270 return 0;
271
272 dno = fnode->u.external[0].disk_secno;
273 brelse(bh);
274 return dno;
275}
diff --git a/fs/hpfs/name.c b/fs/hpfs/name.c
new file mode 100644
index 000000000000..1f4a964384eb
--- /dev/null
+++ b/fs/hpfs/name.c
@@ -0,0 +1,144 @@
1/*
2 * linux/fs/hpfs/name.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * operations with filenames
7 */
8
9#include "hpfs_fn.h"
10
11static char *text_postfix[]={
12".ASM", ".BAS", ".BAT", ".C", ".CC", ".CFG", ".CMD", ".CON", ".CPP", ".DEF",
13".DOC", ".DPR", ".ERX", ".H", ".HPP", ".HTM", ".HTML", ".JAVA", ".LOG", ".PAS",
14".RC", ".TEX", ".TXT", ".Y", ""};
15
16static char *text_prefix[]={
17"AUTOEXEC.", "CHANGES", "COPYING", "CONFIG.", "CREDITS", "FAQ", "FILE_ID.DIZ",
18"MAKEFILE", "READ.ME", "README", "TERMCAP", ""};
19
20void hpfs_decide_conv(struct inode *inode, unsigned char *name, unsigned len)
21{
22 struct hpfs_inode_info *hpfs_inode = hpfs_i(inode);
23 int i;
24 if (hpfs_inode->i_conv != CONV_AUTO) return;
25 for (i = 0; *text_postfix[i]; i++) {
26 int l = strlen(text_postfix[i]);
27 if (l <= len)
28 if (!hpfs_compare_names(inode->i_sb, text_postfix[i], l, name + len - l, l, 0))
29 goto text;
30 }
31 for (i = 0; *text_prefix[i]; i++) {
32 int l = strlen(text_prefix[i]);
33 if (l <= len)
34 if (!hpfs_compare_names(inode->i_sb, text_prefix[i], l, name, l, 0))
35 goto text;
36 }
37 hpfs_inode->i_conv = CONV_BINARY;
38 return;
39 text:
40 hpfs_inode->i_conv = CONV_TEXT;
41 return;
42}
43
44static inline int not_allowed_char(unsigned char c)
45{
46 return c<' ' || c=='"' || c=='*' || c=='/' || c==':' || c=='<' ||
47 c=='>' || c=='?' || c=='\\' || c=='|';
48}
49
50static inline int no_dos_char(unsigned char c)
51{ /* Characters that are allowed in HPFS but not in DOS */
52 return c=='+' || c==',' || c==';' || c=='=' || c=='[' || c==']';
53}
54
55static inline unsigned char upcase(unsigned char *dir, unsigned char a)
56{
57 if (a<128 || a==255) return a>='a' && a<='z' ? a - 0x20 : a;
58 if (!dir) return a;
59 return dir[a-128];
60}
61
62unsigned char hpfs_upcase(unsigned char *dir, unsigned char a)
63{
64 return upcase(dir, a);
65}
66
67static inline unsigned char locase(unsigned char *dir, unsigned char a)
68{
69 if (a<128 || a==255) return a>='A' && a<='Z' ? a + 0x20 : a;
70 if (!dir) return a;
71 return dir[a];
72}
73
74int hpfs_chk_name(unsigned char *name, unsigned *len)
75{
76 int i;
77 if (*len > 254) return -ENAMETOOLONG;
78 hpfs_adjust_length(name, len);
79 if (!*len) return -EINVAL;
80 for (i = 0; i < *len; i++) if (not_allowed_char(name[i])) return -EINVAL;
81 if (*len == 1) if (name[0] == '.') return -EINVAL;
82 if (*len == 2) if (name[0] == '.' && name[1] == '.') return -EINVAL;
83 return 0;
84}
85
86char *hpfs_translate_name(struct super_block *s, unsigned char *from,
87 unsigned len, int lc, int lng)
88{
89 char *to;
90 int i;
91 if (hpfs_sb(s)->sb_chk >= 2) if (hpfs_is_name_long(from, len) != lng) {
92 printk("HPFS: Long name flag mismatch - name ");
93 for (i=0; i<len; i++) printk("%c", from[i]);
94 printk(" misidentified as %s.\n", lng ? "short" : "long");
95 printk("HPFS: It's nothing serious. It could happen because of bug in OS/2.\nHPFS: Set checks=normal to disable this message.\n");
96 }
97 if (!lc) return from;
98 if (!(to = kmalloc(len, GFP_KERNEL))) {
99 printk("HPFS: can't allocate memory for name conversion buffer\n");
100 return from;
101 }
102 for (i = 0; i < len; i++) to[i] = locase(hpfs_sb(s)->sb_cp_table,from[i]);
103 return to;
104}
105
106int hpfs_compare_names(struct super_block *s, unsigned char *n1, unsigned l1,
107 unsigned char *n2, unsigned l2, int last)
108{
109 unsigned l = l1 < l2 ? l1 : l2;
110 unsigned i;
111 if (last) return -1;
112 for (i = 0; i < l; i++) {
113 unsigned char c1 = upcase(hpfs_sb(s)->sb_cp_table,n1[i]);
114 unsigned char c2 = upcase(hpfs_sb(s)->sb_cp_table,n2[i]);
115 if (c1 < c2) return -1;
116 if (c1 > c2) return 1;
117 }
118 if (l1 < l2) return -1;
119 if (l1 > l2) return 1;
120 return 0;
121}
122
123int hpfs_is_name_long(unsigned char *name, unsigned len)
124{
125 int i,j;
126 for (i = 0; i < len && name[i] != '.'; i++)
127 if (no_dos_char(name[i])) return 1;
128 if (!i || i > 8) return 1;
129 if (i == len) return 0;
130 for (j = i + 1; j < len; j++)
131 if (name[j] == '.' || no_dos_char(name[i])) return 1;
132 return j - i > 4;
133}
134
135/* OS/2 clears dots and spaces at the end of file name, so we have to */
136
137void hpfs_adjust_length(unsigned char *name, unsigned *len)
138{
139 if (!*len) return;
140 if (*len == 1 && name[0] == '.') return;
141 if (*len == 2 && name[0] == '.' && name[1] == '.') return;
142 while (*len && (name[*len - 1] == '.' || name[*len - 1] == ' '))
143 (*len)--;
144}
diff --git a/fs/hpfs/namei.c b/fs/hpfs/namei.c
new file mode 100644
index 000000000000..8ff8fc433fc1
--- /dev/null
+++ b/fs/hpfs/namei.c
@@ -0,0 +1,673 @@
1/*
2 * linux/fs/hpfs/namei.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * adding & removing files & directories
7 */
8
9#include "hpfs_fn.h"
10
11static int hpfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
12{
13 const char *name = dentry->d_name.name;
14 unsigned len = dentry->d_name.len;
15 struct quad_buffer_head qbh0;
16 struct buffer_head *bh;
17 struct hpfs_dirent *de;
18 struct fnode *fnode;
19 struct dnode *dnode;
20 struct inode *result;
21 fnode_secno fno;
22 dnode_secno dno;
23 int r;
24 struct hpfs_dirent dee;
25 int err;
26 if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
27 lock_kernel();
28 err = -ENOSPC;
29 fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
30 if (!fnode)
31 goto bail;
32 dnode = hpfs_alloc_dnode(dir->i_sb, fno, &dno, &qbh0, 1);
33 if (!dnode)
34 goto bail1;
35 memset(&dee, 0, sizeof dee);
36 dee.directory = 1;
37 if (!(mode & 0222)) dee.read_only = 1;
38 /*dee.archive = 0;*/
39 dee.hidden = name[0] == '.';
40 dee.fnode = fno;
41 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds());
42 result = new_inode(dir->i_sb);
43 if (!result)
44 goto bail2;
45 hpfs_init_inode(result);
46 result->i_ino = fno;
47 hpfs_i(result)->i_parent_dir = dir->i_ino;
48 hpfs_i(result)->i_dno = dno;
49 result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date);
50 result->i_ctime.tv_nsec = 0;
51 result->i_mtime.tv_nsec = 0;
52 result->i_atime.tv_nsec = 0;
53 hpfs_i(result)->i_ea_size = 0;
54 result->i_mode |= S_IFDIR;
55 result->i_op = &hpfs_dir_iops;
56 result->i_fop = &hpfs_dir_ops;
57 result->i_blocks = 4;
58 result->i_size = 2048;
59 result->i_nlink = 2;
60 if (dee.read_only)
61 result->i_mode &= ~0222;
62
63 down(&hpfs_i(dir)->i_sem);
64 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
65 if (r == 1)
66 goto bail3;
67 if (r == -1) {
68 err = -EEXIST;
69 goto bail3;
70 }
71 fnode->len = len;
72 memcpy(fnode->name, name, len > 15 ? 15 : len);
73 fnode->up = dir->i_ino;
74 fnode->dirflag = 1;
75 fnode->btree.n_free_nodes = 7;
76 fnode->btree.n_used_nodes = 1;
77 fnode->btree.first_free = 0x14;
78 fnode->u.external[0].disk_secno = dno;
79 fnode->u.external[0].file_secno = -1;
80 dnode->root_dnode = 1;
81 dnode->up = fno;
82 de = hpfs_add_de(dir->i_sb, dnode, "\001\001", 2, 0);
83 de->creation_date = de->write_date = de->read_date = gmt_to_local(dir->i_sb, get_seconds());
84 if (!(mode & 0222)) de->read_only = 1;
85 de->first = de->directory = 1;
86 /*de->hidden = de->system = 0;*/
87 de->fnode = fno;
88 mark_buffer_dirty(bh);
89 brelse(bh);
90 hpfs_mark_4buffers_dirty(&qbh0);
91 hpfs_brelse4(&qbh0);
92 dir->i_nlink++;
93 insert_inode_hash(result);
94
95 if (result->i_uid != current->fsuid ||
96 result->i_gid != current->fsgid ||
97 result->i_mode != (mode | S_IFDIR)) {
98 result->i_uid = current->fsuid;
99 result->i_gid = current->fsgid;
100 result->i_mode = mode | S_IFDIR;
101 hpfs_write_inode_nolock(result);
102 }
103 d_instantiate(dentry, result);
104 up(&hpfs_i(dir)->i_sem);
105 unlock_kernel();
106 return 0;
107bail3:
108 up(&hpfs_i(dir)->i_sem);
109 iput(result);
110bail2:
111 hpfs_brelse4(&qbh0);
112 hpfs_free_dnode(dir->i_sb, dno);
113bail1:
114 brelse(bh);
115 hpfs_free_sectors(dir->i_sb, fno, 1);
116bail:
117 unlock_kernel();
118 return err;
119}
120
121static int hpfs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
122{
123 const char *name = dentry->d_name.name;
124 unsigned len = dentry->d_name.len;
125 struct inode *result = NULL;
126 struct buffer_head *bh;
127 struct fnode *fnode;
128 fnode_secno fno;
129 int r;
130 struct hpfs_dirent dee;
131 int err;
132 if ((err = hpfs_chk_name((char *)name, &len)))
133 return err==-ENOENT ? -EINVAL : err;
134 lock_kernel();
135 err = -ENOSPC;
136 fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
137 if (!fnode)
138 goto bail;
139 memset(&dee, 0, sizeof dee);
140 if (!(mode & 0222)) dee.read_only = 1;
141 dee.archive = 1;
142 dee.hidden = name[0] == '.';
143 dee.fnode = fno;
144 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds());
145
146 result = new_inode(dir->i_sb);
147 if (!result)
148 goto bail1;
149
150 hpfs_init_inode(result);
151 result->i_ino = fno;
152 result->i_mode |= S_IFREG;
153 result->i_mode &= ~0111;
154 result->i_op = &hpfs_file_iops;
155 result->i_fop = &hpfs_file_ops;
156 result->i_nlink = 1;
157 hpfs_decide_conv(result, (char *)name, len);
158 hpfs_i(result)->i_parent_dir = dir->i_ino;
159 result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date);
160 result->i_ctime.tv_nsec = 0;
161 result->i_mtime.tv_nsec = 0;
162 result->i_atime.tv_nsec = 0;
163 hpfs_i(result)->i_ea_size = 0;
164 if (dee.read_only)
165 result->i_mode &= ~0222;
166 result->i_blocks = 1;
167 result->i_size = 0;
168 result->i_data.a_ops = &hpfs_aops;
169 hpfs_i(result)->mmu_private = 0;
170
171 down(&hpfs_i(dir)->i_sem);
172 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
173 if (r == 1)
174 goto bail2;
175 if (r == -1) {
176 err = -EEXIST;
177 goto bail2;
178 }
179 fnode->len = len;
180 memcpy(fnode->name, name, len > 15 ? 15 : len);
181 fnode->up = dir->i_ino;
182 mark_buffer_dirty(bh);
183 brelse(bh);
184
185 insert_inode_hash(result);
186
187 if (result->i_uid != current->fsuid ||
188 result->i_gid != current->fsgid ||
189 result->i_mode != (mode | S_IFREG)) {
190 result->i_uid = current->fsuid;
191 result->i_gid = current->fsgid;
192 result->i_mode = mode | S_IFREG;
193 hpfs_write_inode_nolock(result);
194 }
195 d_instantiate(dentry, result);
196 up(&hpfs_i(dir)->i_sem);
197 unlock_kernel();
198 return 0;
199
200bail2:
201 up(&hpfs_i(dir)->i_sem);
202 iput(result);
203bail1:
204 brelse(bh);
205 hpfs_free_sectors(dir->i_sb, fno, 1);
206bail:
207 unlock_kernel();
208 return err;
209}
210
211static int hpfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
212{
213 const char *name = dentry->d_name.name;
214 unsigned len = dentry->d_name.len;
215 struct buffer_head *bh;
216 struct fnode *fnode;
217 fnode_secno fno;
218 int r;
219 struct hpfs_dirent dee;
220 struct inode *result = NULL;
221 int err;
222 if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
223 if (hpfs_sb(dir->i_sb)->sb_eas < 2) return -EPERM;
224 if (!new_valid_dev(rdev))
225 return -EINVAL;
226 lock_kernel();
227 err = -ENOSPC;
228 fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
229 if (!fnode)
230 goto bail;
231 memset(&dee, 0, sizeof dee);
232 if (!(mode & 0222)) dee.read_only = 1;
233 dee.archive = 1;
234 dee.hidden = name[0] == '.';
235 dee.fnode = fno;
236 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds());
237
238 result = new_inode(dir->i_sb);
239 if (!result)
240 goto bail1;
241
242 hpfs_init_inode(result);
243 result->i_ino = fno;
244 hpfs_i(result)->i_parent_dir = dir->i_ino;
245 result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date);
246 result->i_ctime.tv_nsec = 0;
247 result->i_mtime.tv_nsec = 0;
248 result->i_atime.tv_nsec = 0;
249 hpfs_i(result)->i_ea_size = 0;
250 result->i_uid = current->fsuid;
251 result->i_gid = current->fsgid;
252 result->i_nlink = 1;
253 result->i_size = 0;
254 result->i_blocks = 1;
255 init_special_inode(result, mode, rdev);
256
257 down(&hpfs_i(dir)->i_sem);
258 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
259 if (r == 1)
260 goto bail2;
261 if (r == -1) {
262 err = -EEXIST;
263 goto bail2;
264 }
265 fnode->len = len;
266 memcpy(fnode->name, name, len > 15 ? 15 : len);
267 fnode->up = dir->i_ino;
268 mark_buffer_dirty(bh);
269
270 insert_inode_hash(result);
271
272 hpfs_write_inode_nolock(result);
273 d_instantiate(dentry, result);
274 up(&hpfs_i(dir)->i_sem);
275 brelse(bh);
276 unlock_kernel();
277 return 0;
278bail2:
279 up(&hpfs_i(dir)->i_sem);
280 iput(result);
281bail1:
282 brelse(bh);
283 hpfs_free_sectors(dir->i_sb, fno, 1);
284bail:
285 unlock_kernel();
286 return err;
287}
288
289static int hpfs_symlink(struct inode *dir, struct dentry *dentry, const char *symlink)
290{
291 const char *name = dentry->d_name.name;
292 unsigned len = dentry->d_name.len;
293 struct buffer_head *bh;
294 struct fnode *fnode;
295 fnode_secno fno;
296 int r;
297 struct hpfs_dirent dee;
298 struct inode *result;
299 int err;
300 if ((err = hpfs_chk_name((char *)name, &len))) return err==-ENOENT ? -EINVAL : err;
301 lock_kernel();
302 if (hpfs_sb(dir->i_sb)->sb_eas < 2) {
303 unlock_kernel();
304 return -EPERM;
305 }
306 err = -ENOSPC;
307 fnode = hpfs_alloc_fnode(dir->i_sb, hpfs_i(dir)->i_dno, &fno, &bh);
308 if (!fnode)
309 goto bail;
310 memset(&dee, 0, sizeof dee);
311 dee.archive = 1;
312 dee.hidden = name[0] == '.';
313 dee.fnode = fno;
314 dee.creation_date = dee.write_date = dee.read_date = gmt_to_local(dir->i_sb, get_seconds());
315
316 result = new_inode(dir->i_sb);
317 if (!result)
318 goto bail1;
319 result->i_ino = fno;
320 hpfs_init_inode(result);
321 hpfs_i(result)->i_parent_dir = dir->i_ino;
322 result->i_ctime.tv_sec = result->i_mtime.tv_sec = result->i_atime.tv_sec = local_to_gmt(dir->i_sb, dee.creation_date);
323 result->i_ctime.tv_nsec = 0;
324 result->i_mtime.tv_nsec = 0;
325 result->i_atime.tv_nsec = 0;
326 hpfs_i(result)->i_ea_size = 0;
327 result->i_mode = S_IFLNK | 0777;
328 result->i_uid = current->fsuid;
329 result->i_gid = current->fsgid;
330 result->i_blocks = 1;
331 result->i_nlink = 1;
332 result->i_size = strlen(symlink);
333 result->i_op = &page_symlink_inode_operations;
334 result->i_data.a_ops = &hpfs_symlink_aops;
335
336 down(&hpfs_i(dir)->i_sem);
337 r = hpfs_add_dirent(dir, (char *)name, len, &dee, 0);
338 if (r == 1)
339 goto bail2;
340 if (r == -1) {
341 err = -EEXIST;
342 goto bail2;
343 }
344 fnode->len = len;
345 memcpy(fnode->name, name, len > 15 ? 15 : len);
346 fnode->up = dir->i_ino;
347 hpfs_set_ea(result, fnode, "SYMLINK", (char *)symlink, strlen(symlink));
348 mark_buffer_dirty(bh);
349 brelse(bh);
350
351 insert_inode_hash(result);
352
353 hpfs_write_inode_nolock(result);
354 d_instantiate(dentry, result);
355 up(&hpfs_i(dir)->i_sem);
356 unlock_kernel();
357 return 0;
358bail2:
359 up(&hpfs_i(dir)->i_sem);
360 iput(result);
361bail1:
362 brelse(bh);
363 hpfs_free_sectors(dir->i_sb, fno, 1);
364bail:
365 unlock_kernel();
366 return err;
367}
368
369static int hpfs_unlink(struct inode *dir, struct dentry *dentry)
370{
371 const char *name = dentry->d_name.name;
372 unsigned len = dentry->d_name.len;
373 struct quad_buffer_head qbh;
374 struct hpfs_dirent *de;
375 struct inode *inode = dentry->d_inode;
376 dnode_secno dno;
377 fnode_secno fno;
378 int r;
379 int rep = 0;
380 int err;
381
382 lock_kernel();
383 hpfs_adjust_length((char *)name, &len);
384again:
385 down(&hpfs_i(inode)->i_parent);
386 down(&hpfs_i(dir)->i_sem);
387 err = -ENOENT;
388 de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh);
389 if (!de)
390 goto out;
391
392 err = -EPERM;
393 if (de->first)
394 goto out1;
395
396 err = -EISDIR;
397 if (de->directory)
398 goto out1;
399
400 fno = de->fnode;
401 r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
402 switch (r) {
403 case 1:
404 hpfs_error(dir->i_sb, "there was error when removing dirent");
405 err = -EFSERROR;
406 break;
407 case 2: /* no space for deleting, try to truncate file */
408
409 err = -ENOSPC;
410 if (rep++)
411 break;
412
413 up(&hpfs_i(dir)->i_sem);
414 up(&hpfs_i(inode)->i_parent);
415 d_drop(dentry);
416 spin_lock(&dentry->d_lock);
417 if (atomic_read(&dentry->d_count) > 1 ||
418 permission(inode, MAY_WRITE, NULL) ||
419 !S_ISREG(inode->i_mode) ||
420 get_write_access(inode)) {
421 spin_unlock(&dentry->d_lock);
422 d_rehash(dentry);
423 } else {
424 struct iattr newattrs;
425 spin_unlock(&dentry->d_lock);
426 /*printk("HPFS: truncating file before delete.\n");*/
427 newattrs.ia_size = 0;
428 newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME;
429 err = notify_change(dentry, &newattrs);
430 put_write_access(inode);
431 if (!err)
432 goto again;
433 }
434 unlock_kernel();
435 return -ENOSPC;
436 default:
437 inode->i_nlink--;
438 err = 0;
439 }
440 goto out;
441
442out1:
443 hpfs_brelse4(&qbh);
444out:
445 up(&hpfs_i(dir)->i_sem);
446 up(&hpfs_i(inode)->i_parent);
447 unlock_kernel();
448 return err;
449}
450
451static int hpfs_rmdir(struct inode *dir, struct dentry *dentry)
452{
453 const char *name = dentry->d_name.name;
454 unsigned len = dentry->d_name.len;
455 struct quad_buffer_head qbh;
456 struct hpfs_dirent *de;
457 struct inode *inode = dentry->d_inode;
458 dnode_secno dno;
459 fnode_secno fno;
460 int n_items = 0;
461 int err;
462 int r;
463
464 hpfs_adjust_length((char *)name, &len);
465 lock_kernel();
466 down(&hpfs_i(inode)->i_parent);
467 down(&hpfs_i(dir)->i_sem);
468 err = -ENOENT;
469 de = map_dirent(dir, hpfs_i(dir)->i_dno, (char *)name, len, &dno, &qbh);
470 if (!de)
471 goto out;
472
473 err = -EPERM;
474 if (de->first)
475 goto out1;
476
477 err = -ENOTDIR;
478 if (!de->directory)
479 goto out1;
480
481 hpfs_count_dnodes(dir->i_sb, hpfs_i(inode)->i_dno, NULL, NULL, &n_items);
482 err = -ENOTEMPTY;
483 if (n_items)
484 goto out1;
485
486 fno = de->fnode;
487 r = hpfs_remove_dirent(dir, dno, de, &qbh, 1);
488 switch (r) {
489 case 1:
490 hpfs_error(dir->i_sb, "there was error when removing dirent");
491 err = -EFSERROR;
492 break;
493 case 2:
494 err = -ENOSPC;
495 break;
496 default:
497 dir->i_nlink--;
498 inode->i_nlink = 0;
499 err = 0;
500 }
501 goto out;
502out1:
503 hpfs_brelse4(&qbh);
504out:
505 up(&hpfs_i(dir)->i_sem);
506 up(&hpfs_i(inode)->i_parent);
507 unlock_kernel();
508 return err;
509}
510
511static int hpfs_symlink_readpage(struct file *file, struct page *page)
512{
513 char *link = kmap(page);
514 struct inode *i = page->mapping->host;
515 struct fnode *fnode;
516 struct buffer_head *bh;
517 int err;
518
519 err = -EIO;
520 lock_kernel();
521 if (!(fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh)))
522 goto fail;
523 err = hpfs_read_ea(i->i_sb, fnode, "SYMLINK", link, PAGE_SIZE);
524 brelse(bh);
525 if (err)
526 goto fail;
527 unlock_kernel();
528 SetPageUptodate(page);
529 kunmap(page);
530 unlock_page(page);
531 return 0;
532
533fail:
534 unlock_kernel();
535 SetPageError(page);
536 kunmap(page);
537 unlock_page(page);
538 return err;
539}
540
541struct address_space_operations hpfs_symlink_aops = {
542 .readpage = hpfs_symlink_readpage
543};
544
545static int hpfs_rename(struct inode *old_dir, struct dentry *old_dentry,
546 struct inode *new_dir, struct dentry *new_dentry)
547{
548 char *old_name = (char *)old_dentry->d_name.name;
549 int old_len = old_dentry->d_name.len;
550 char *new_name = (char *)new_dentry->d_name.name;
551 int new_len = new_dentry->d_name.len;
552 struct inode *i = old_dentry->d_inode;
553 struct inode *new_inode = new_dentry->d_inode;
554 struct quad_buffer_head qbh, qbh1;
555 struct hpfs_dirent *dep, *nde;
556 struct hpfs_dirent de;
557 dnode_secno dno;
558 int r;
559 struct buffer_head *bh;
560 struct fnode *fnode;
561 int err;
562 if ((err = hpfs_chk_name((char *)new_name, &new_len))) return err;
563 err = 0;
564 hpfs_adjust_length((char *)old_name, &old_len);
565
566 lock_kernel();
567 /* order doesn't matter, due to VFS exclusion */
568 down(&hpfs_i(i)->i_parent);
569 if (new_inode)
570 down(&hpfs_i(new_inode)->i_parent);
571 down(&hpfs_i(old_dir)->i_sem);
572 if (new_dir != old_dir)
573 down(&hpfs_i(new_dir)->i_sem);
574
575 /* Erm? Moving over the empty non-busy directory is perfectly legal */
576 if (new_inode && S_ISDIR(new_inode->i_mode)) {
577 err = -EINVAL;
578 goto end1;
579 }
580
581 if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, (char *)old_name, old_len, &dno, &qbh))) {
582 hpfs_error(i->i_sb, "lookup succeeded but map dirent failed");
583 err = -ENOENT;
584 goto end1;
585 }
586 copy_de(&de, dep);
587 de.hidden = new_name[0] == '.';
588
589 if (new_inode) {
590 int r;
591 if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 1)) != 2) {
592 if ((nde = map_dirent(new_dir, hpfs_i(new_dir)->i_dno, (char *)new_name, new_len, NULL, &qbh1))) {
593 new_inode->i_nlink = 0;
594 copy_de(nde, &de);
595 memcpy(nde->name, new_name, new_len);
596 hpfs_mark_4buffers_dirty(&qbh1);
597 hpfs_brelse4(&qbh1);
598 goto end;
599 }
600 hpfs_error(new_dir->i_sb, "hpfs_rename: could not find dirent");
601 err = -EFSERROR;
602 goto end1;
603 }
604 err = r == 2 ? -ENOSPC : r == 1 ? -EFSERROR : 0;
605 goto end1;
606 }
607
608 if (new_dir == old_dir) hpfs_brelse4(&qbh);
609
610 hpfs_lock_creation(i->i_sb);
611 if ((r = hpfs_add_dirent(new_dir, new_name, new_len, &de, 1))) {
612 hpfs_unlock_creation(i->i_sb);
613 if (r == -1) hpfs_error(new_dir->i_sb, "hpfs_rename: dirent already exists!");
614 err = r == 1 ? -ENOSPC : -EFSERROR;
615 if (new_dir != old_dir) hpfs_brelse4(&qbh);
616 goto end1;
617 }
618
619 if (new_dir == old_dir)
620 if (!(dep = map_dirent(old_dir, hpfs_i(old_dir)->i_dno, (char *)old_name, old_len, &dno, &qbh))) {
621 hpfs_unlock_creation(i->i_sb);
622 hpfs_error(i->i_sb, "lookup succeeded but map dirent failed at #2");
623 err = -ENOENT;
624 goto end1;
625 }
626
627 if ((r = hpfs_remove_dirent(old_dir, dno, dep, &qbh, 0))) {
628 hpfs_unlock_creation(i->i_sb);
629 hpfs_error(i->i_sb, "hpfs_rename: could not remove dirent");
630 err = r == 2 ? -ENOSPC : -EFSERROR;
631 goto end1;
632 }
633 hpfs_unlock_creation(i->i_sb);
634
635 end:
636 hpfs_i(i)->i_parent_dir = new_dir->i_ino;
637 if (S_ISDIR(i->i_mode)) {
638 new_dir->i_nlink++;
639 old_dir->i_nlink--;
640 }
641 if ((fnode = hpfs_map_fnode(i->i_sb, i->i_ino, &bh))) {
642 fnode->up = new_dir->i_ino;
643 fnode->len = new_len;
644 memcpy(fnode->name, new_name, new_len>15?15:new_len);
645 if (new_len < 15) memset(&fnode->name[new_len], 0, 15 - new_len);
646 mark_buffer_dirty(bh);
647 brelse(bh);
648 }
649 hpfs_i(i)->i_conv = hpfs_sb(i->i_sb)->sb_conv;
650 hpfs_decide_conv(i, (char *)new_name, new_len);
651end1:
652 if (old_dir != new_dir)
653 up(&hpfs_i(new_dir)->i_sem);
654 up(&hpfs_i(old_dir)->i_sem);
655 up(&hpfs_i(i)->i_parent);
656 if (new_inode)
657 up(&hpfs_i(new_inode)->i_parent);
658 unlock_kernel();
659 return err;
660}
661
662struct inode_operations hpfs_dir_iops =
663{
664 .create = hpfs_create,
665 .lookup = hpfs_lookup,
666 .unlink = hpfs_unlink,
667 .symlink = hpfs_symlink,
668 .mkdir = hpfs_mkdir,
669 .rmdir = hpfs_rmdir,
670 .mknod = hpfs_mknod,
671 .rename = hpfs_rename,
672 .setattr = hpfs_notify_change,
673};
diff --git a/fs/hpfs/super.c b/fs/hpfs/super.c
new file mode 100644
index 000000000000..8eefa6366db7
--- /dev/null
+++ b/fs/hpfs/super.c
@@ -0,0 +1,701 @@
1/*
2 * linux/fs/hpfs/super.c
3 *
4 * Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
5 *
6 * mounting, unmounting, error handling
7 */
8
9#include "hpfs_fn.h"
10#include <linux/module.h>
11#include <linux/parser.h>
12#include <linux/init.h>
13#include <linux/statfs.h>
14
15/* Mark the filesystem dirty, so that chkdsk checks it when os/2 booted */
16
17static void mark_dirty(struct super_block *s)
18{
19 if (hpfs_sb(s)->sb_chkdsk && !(s->s_flags & MS_RDONLY)) {
20 struct buffer_head *bh;
21 struct hpfs_spare_block *sb;
22 if ((sb = hpfs_map_sector(s, 17, &bh, 0))) {
23 sb->dirty = 1;
24 sb->old_wrote = 0;
25 mark_buffer_dirty(bh);
26 brelse(bh);
27 }
28 }
29}
30
31/* Mark the filesystem clean (mark it dirty for chkdsk if chkdsk==2 or if there
32 were errors) */
33
34static void unmark_dirty(struct super_block *s)
35{
36 struct buffer_head *bh;
37 struct hpfs_spare_block *sb;
38 if (s->s_flags & MS_RDONLY) return;
39 if ((sb = hpfs_map_sector(s, 17, &bh, 0))) {
40 sb->dirty = hpfs_sb(s)->sb_chkdsk > 1 - hpfs_sb(s)->sb_was_error;
41 sb->old_wrote = hpfs_sb(s)->sb_chkdsk >= 2 && !hpfs_sb(s)->sb_was_error;
42 mark_buffer_dirty(bh);
43 brelse(bh);
44 }
45}
46
47/* Filesystem error... */
48
49#define ERR_BUF_SIZE 1024
50
51void hpfs_error(struct super_block *s, char *m,...)
52{
53 char *buf;
54 va_list l;
55 va_start(l, m);
56 if (!(buf = kmalloc(ERR_BUF_SIZE, GFP_KERNEL)))
57 printk("HPFS: No memory for error message '%s'\n",m);
58 else if (vsprintf(buf, m, l) >= ERR_BUF_SIZE)
59 printk("HPFS: Grrrr... Kernel memory corrupted ... going on, but it'll crash very soon :-(\n");
60 printk("HPFS: filesystem error: ");
61 if (buf) printk("%s", buf);
62 else printk("%s\n",m);
63 if (!hpfs_sb(s)->sb_was_error) {
64 if (hpfs_sb(s)->sb_err == 2) {
65 printk("; crashing the system because you wanted it\n");
66 mark_dirty(s);
67 panic("HPFS panic");
68 } else if (hpfs_sb(s)->sb_err == 1) {
69 if (s->s_flags & MS_RDONLY) printk("; already mounted read-only\n");
70 else {
71 printk("; remounting read-only\n");
72 mark_dirty(s);
73 s->s_flags |= MS_RDONLY;
74 }
75 } else if (s->s_flags & MS_RDONLY) printk("; going on - but anything won't be destroyed because it's read-only\n");
76 else printk("; corrupted filesystem mounted read/write - your computer will explode within 20 seconds ... but you wanted it so!\n");
77 } else printk("\n");
78 if (buf) kfree(buf);
79 hpfs_sb(s)->sb_was_error = 1;
80}
81
82/*
83 * A little trick to detect cycles in many hpfs structures and don't let the
84 * kernel crash on corrupted filesystem. When first called, set c2 to 0.
85 *
86 * BTW. chkdsk doesn't detect cycles correctly. When I had 2 lost directories
87 * nested each in other, chkdsk locked up happilly.
88 */
89
90int hpfs_stop_cycles(struct super_block *s, int key, int *c1, int *c2,
91 char *msg)
92{
93 if (*c2 && *c1 == key) {
94 hpfs_error(s, "cycle detected on key %08x in %s", key, msg);
95 return 1;
96 }
97 (*c2)++;
98 if (!((*c2 - 1) & *c2)) *c1 = key;
99 return 0;
100}
101
102static void hpfs_put_super(struct super_block *s)
103{
104 struct hpfs_sb_info *sbi = hpfs_sb(s);
105 if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
106 if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
107 unmark_dirty(s);
108 s->s_fs_info = NULL;
109 kfree(sbi);
110}
111
112unsigned hpfs_count_one_bitmap(struct super_block *s, secno secno)
113{
114 struct quad_buffer_head qbh;
115 unsigned *bits;
116 unsigned i, count;
117 if (!(bits = hpfs_map_4sectors(s, secno, &qbh, 4))) return 0;
118 count = 0;
119 for (i = 0; i < 2048 / sizeof(unsigned); i++) {
120 unsigned b;
121 if (!bits[i]) continue;
122 for (b = bits[i]; b; b>>=1) count += b & 1;
123 }
124 hpfs_brelse4(&qbh);
125 return count;
126}
127
128static unsigned count_bitmaps(struct super_block *s)
129{
130 unsigned n, count, n_bands;
131 n_bands = (hpfs_sb(s)->sb_fs_size + 0x3fff) >> 14;
132 count = 0;
133 for (n = 0; n < n_bands; n++)
134 count += hpfs_count_one_bitmap(s, hpfs_sb(s)->sb_bmp_dir[n]);
135 return count;
136}
137
138static int hpfs_statfs(struct super_block *s, struct kstatfs *buf)
139{
140 struct hpfs_sb_info *sbi = hpfs_sb(s);
141 lock_kernel();
142
143 /*if (sbi->sb_n_free == -1) {*/
144 sbi->sb_n_free = count_bitmaps(s);
145 sbi->sb_n_free_dnodes = hpfs_count_one_bitmap(s, sbi->sb_dmap);
146 /*}*/
147 buf->f_type = s->s_magic;
148 buf->f_bsize = 512;
149 buf->f_blocks = sbi->sb_fs_size;
150 buf->f_bfree = sbi->sb_n_free;
151 buf->f_bavail = sbi->sb_n_free;
152 buf->f_files = sbi->sb_dirband_size / 4;
153 buf->f_ffree = sbi->sb_n_free_dnodes;
154 buf->f_namelen = 254;
155
156 unlock_kernel();
157
158 return 0;
159}
160
161static kmem_cache_t * hpfs_inode_cachep;
162
163static struct inode *hpfs_alloc_inode(struct super_block *sb)
164{
165 struct hpfs_inode_info *ei;
166 ei = (struct hpfs_inode_info *)kmem_cache_alloc(hpfs_inode_cachep, SLAB_NOFS);
167 if (!ei)
168 return NULL;
169 ei->vfs_inode.i_version = 1;
170 return &ei->vfs_inode;
171}
172
173static void hpfs_destroy_inode(struct inode *inode)
174{
175 kmem_cache_free(hpfs_inode_cachep, hpfs_i(inode));
176}
177
178static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
179{
180 struct hpfs_inode_info *ei = (struct hpfs_inode_info *) foo;
181
182 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
183 SLAB_CTOR_CONSTRUCTOR) {
184 init_MUTEX(&ei->i_sem);
185 init_MUTEX(&ei->i_parent);
186 inode_init_once(&ei->vfs_inode);
187 }
188}
189
190static int init_inodecache(void)
191{
192 hpfs_inode_cachep = kmem_cache_create("hpfs_inode_cache",
193 sizeof(struct hpfs_inode_info),
194 0, SLAB_RECLAIM_ACCOUNT,
195 init_once, NULL);
196 if (hpfs_inode_cachep == NULL)
197 return -ENOMEM;
198 return 0;
199}
200
201static void destroy_inodecache(void)
202{
203 if (kmem_cache_destroy(hpfs_inode_cachep))
204 printk(KERN_INFO "hpfs_inode_cache: not all structures were freed\n");
205}
206
207/*
208 * A tiny parser for option strings, stolen from dosfs.
209 * Stolen again from read-only hpfs.
210 * And updated for table-driven option parsing.
211 */
212
213enum {
214 Opt_help, Opt_uid, Opt_gid, Opt_umask, Opt_case_lower, Opt_case_asis,
215 Opt_conv_binary, Opt_conv_text, Opt_conv_auto,
216 Opt_check_none, Opt_check_normal, Opt_check_strict,
217 Opt_err_cont, Opt_err_ro, Opt_err_panic,
218 Opt_eas_no, Opt_eas_ro, Opt_eas_rw,
219 Opt_chkdsk_no, Opt_chkdsk_errors, Opt_chkdsk_always,
220 Opt_timeshift, Opt_err,
221};
222
223static match_table_t tokens = {
224 {Opt_help, "help"},
225 {Opt_uid, "uid=%u"},
226 {Opt_gid, "gid=%u"},
227 {Opt_umask, "umask=%o"},
228 {Opt_case_lower, "case=lower"},
229 {Opt_case_asis, "case=asis"},
230 {Opt_conv_binary, "conv=binary"},
231 {Opt_conv_text, "conv=text"},
232 {Opt_conv_auto, "conv=auto"},
233 {Opt_check_none, "check=none"},
234 {Opt_check_normal, "check=normal"},
235 {Opt_check_strict, "check=strict"},
236 {Opt_err_cont, "errors=continue"},
237 {Opt_err_ro, "errors=remount-ro"},
238 {Opt_err_panic, "errors=panic"},
239 {Opt_eas_no, "eas=no"},
240 {Opt_eas_ro, "eas=ro"},
241 {Opt_eas_rw, "eas=rw"},
242 {Opt_chkdsk_no, "chkdsk=no"},
243 {Opt_chkdsk_errors, "chkdsk=errors"},
244 {Opt_chkdsk_always, "chkdsk=always"},
245 {Opt_timeshift, "timeshift=%d"},
246 {Opt_err, NULL},
247};
248
249static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
250 int *lowercase, int *conv, int *eas, int *chk, int *errs,
251 int *chkdsk, int *timeshift)
252{
253 char *p;
254 int option;
255
256 if (!opts)
257 return 1;
258
259 /*printk("Parsing opts: '%s'\n",opts);*/
260
261 while ((p = strsep(&opts, ",")) != NULL) {
262 substring_t args[MAX_OPT_ARGS];
263 int token;
264 if (!*p)
265 continue;
266
267 token = match_token(p, tokens, args);
268 switch (token) {
269 case Opt_help:
270 return 2;
271 case Opt_uid:
272 if (match_int(args, &option))
273 return 0;
274 *uid = option;
275 break;
276 case Opt_gid:
277 if (match_int(args, &option))
278 return 0;
279 *gid = option;
280 break;
281 case Opt_umask:
282 if (match_octal(args, &option))
283 return 0;
284 *umask = option;
285 break;
286 case Opt_case_lower:
287 *lowercase = 1;
288 break;
289 case Opt_case_asis:
290 *lowercase = 0;
291 break;
292 case Opt_conv_binary:
293 *conv = CONV_BINARY;
294 break;
295 case Opt_conv_text:
296 *conv = CONV_TEXT;
297 break;
298 case Opt_conv_auto:
299 *conv = CONV_AUTO;
300 break;
301 case Opt_check_none:
302 *chk = 0;
303 break;
304 case Opt_check_normal:
305 *chk = 1;
306 break;
307 case Opt_check_strict:
308 *chk = 2;
309 break;
310 case Opt_err_cont:
311 *errs = 0;
312 break;
313 case Opt_err_ro:
314 *errs = 1;
315 break;
316 case Opt_err_panic:
317 *errs = 2;
318 break;
319 case Opt_eas_no:
320 *eas = 0;
321 break;
322 case Opt_eas_ro:
323 *eas = 1;
324 break;
325 case Opt_eas_rw:
326 *eas = 2;
327 break;
328 case Opt_chkdsk_no:
329 *chkdsk = 0;
330 break;
331 case Opt_chkdsk_errors:
332 *chkdsk = 1;
333 break;
334 case Opt_chkdsk_always:
335 *chkdsk = 2;
336 break;
337 case Opt_timeshift:
338 {
339 int m = 1;
340 char *rhs = args[0].from;
341 if (!rhs || !*rhs)
342 return 0;
343 if (*rhs == '-') m = -1;
344 if (*rhs == '+' || *rhs == '-') rhs++;
345 *timeshift = simple_strtoul(rhs, &rhs, 0) * m;
346 if (*rhs)
347 return 0;
348 break;
349 }
350 default:
351 return 0;
352 }
353 }
354 return 1;
355}
356
357static inline void hpfs_help(void)
358{
359 printk("\n\
360HPFS filesystem options:\n\
361 help do not mount and display this text\n\
362 uid=xxx set uid of files that don't have uid specified in eas\n\
363 gid=xxx set gid of files that don't have gid specified in eas\n\
364 umask=xxx set mode of files that don't have mode specified in eas\n\
365 case=lower lowercase all files\n\
366 case=asis do not lowercase files (default)\n\
367 conv=binary do not convert CR/LF -> LF (default)\n\
368 conv=auto convert only files with known text extensions\n\
369 conv=text convert all files\n\
370 check=none no fs checks - kernel may crash on corrupted filesystem\n\
371 check=normal do some checks - it should not crash (default)\n\
372 check=strict do extra time-consuming checks, used for debugging\n\
373 errors=continue continue on errors\n\
374 errors=remount-ro remount read-only if errors found (default)\n\
375 errors=panic panic on errors\n\
376 chkdsk=no do not mark fs for chkdsking even if there were errors\n\
377 chkdsk=errors mark fs dirty if errors found (default)\n\
378 chkdsk=always always mark fs dirty - used for debugging\n\
379 eas=no ignore extended attributes\n\
380 eas=ro read but do not write extended attributes\n\
381 eas=rw r/w eas => enables chmod, chown, mknod, ln -s (default)\n\
382 timeshift=nnn add nnn seconds to file times\n\
383\n");
384}
385
386static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
387{
388 uid_t uid;
389 gid_t gid;
390 umode_t umask;
391 int lowercase, conv, eas, chk, errs, chkdsk, timeshift;
392 int o;
393 struct hpfs_sb_info *sbi = hpfs_sb(s);
394
395 *flags |= MS_NOATIME;
396
397 uid = sbi->sb_uid; gid = sbi->sb_gid;
398 umask = 0777 & ~sbi->sb_mode;
399 lowercase = sbi->sb_lowercase; conv = sbi->sb_conv;
400 eas = sbi->sb_eas; chk = sbi->sb_chk; chkdsk = sbi->sb_chkdsk;
401 errs = sbi->sb_err; timeshift = sbi->sb_timeshift;
402
403 if (!(o = parse_opts(data, &uid, &gid, &umask, &lowercase, &conv,
404 &eas, &chk, &errs, &chkdsk, &timeshift))) {
405 printk("HPFS: bad mount options.\n");
406 return 1;
407 }
408 if (o == 2) {
409 hpfs_help();
410 return 1;
411 }
412 if (timeshift != sbi->sb_timeshift) {
413 printk("HPFS: timeshift can't be changed using remount.\n");
414 return 1;
415 }
416
417 unmark_dirty(s);
418
419 sbi->sb_uid = uid; sbi->sb_gid = gid;
420 sbi->sb_mode = 0777 & ~umask;
421 sbi->sb_lowercase = lowercase; sbi->sb_conv = conv;
422 sbi->sb_eas = eas; sbi->sb_chk = chk; sbi->sb_chkdsk = chkdsk;
423 sbi->sb_err = errs; sbi->sb_timeshift = timeshift;
424
425 if (!(*flags & MS_RDONLY)) mark_dirty(s);
426
427 return 0;
428}
429
430/* Super operations */
431
432static struct super_operations hpfs_sops =
433{
434 .alloc_inode = hpfs_alloc_inode,
435 .destroy_inode = hpfs_destroy_inode,
436 .delete_inode = hpfs_delete_inode,
437 .put_super = hpfs_put_super,
438 .statfs = hpfs_statfs,
439 .remount_fs = hpfs_remount_fs,
440};
441
442static int hpfs_fill_super(struct super_block *s, void *options, int silent)
443{
444 struct buffer_head *bh0, *bh1, *bh2;
445 struct hpfs_boot_block *bootblock;
446 struct hpfs_super_block *superblock;
447 struct hpfs_spare_block *spareblock;
448 struct hpfs_sb_info *sbi;
449 struct inode *root;
450
451 uid_t uid;
452 gid_t gid;
453 umode_t umask;
454 int lowercase, conv, eas, chk, errs, chkdsk, timeshift;
455
456 dnode_secno root_dno;
457 struct hpfs_dirent *de = NULL;
458 struct quad_buffer_head qbh;
459
460 int o;
461
462 sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
463 if (!sbi)
464 return -ENOMEM;
465 s->s_fs_info = sbi;
466 memset(sbi, 0, sizeof(*sbi));
467
468 sbi->sb_bmp_dir = NULL;
469 sbi->sb_cp_table = NULL;
470
471 init_MUTEX(&sbi->hpfs_creation_de);
472
473 uid = current->uid;
474 gid = current->gid;
475 umask = current->fs->umask;
476 lowercase = 0;
477 conv = CONV_BINARY;
478 eas = 2;
479 chk = 1;
480 errs = 1;
481 chkdsk = 1;
482 timeshift = 0;
483
484 if (!(o = parse_opts(options, &uid, &gid, &umask, &lowercase, &conv,
485 &eas, &chk, &errs, &chkdsk, &timeshift))) {
486 printk("HPFS: bad mount options.\n");
487 goto bail0;
488 }
489 if (o==2) {
490 hpfs_help();
491 goto bail0;
492 }
493
494 /*sbi->sb_mounting = 1;*/
495 sb_set_blocksize(s, 512);
496 sbi->sb_fs_size = -1;
497 if (!(bootblock = hpfs_map_sector(s, 0, &bh0, 0))) goto bail1;
498 if (!(superblock = hpfs_map_sector(s, 16, &bh1, 1))) goto bail2;
499 if (!(spareblock = hpfs_map_sector(s, 17, &bh2, 0))) goto bail3;
500
501 /* Check magics */
502 if (/*bootblock->magic != BB_MAGIC
503 ||*/ superblock->magic != SB_MAGIC
504 || spareblock->magic != SP_MAGIC) {
505 if (!silent) printk("HPFS: Bad magic ... probably not HPFS\n");
506 goto bail4;
507 }
508
509 /* Check version */
510 if (!(s->s_flags & MS_RDONLY) &&
511 superblock->funcversion != 2 && superblock->funcversion != 3) {
512 printk("HPFS: Bad version %d,%d. Mount readonly to go around\n",
513 (int)superblock->version, (int)superblock->funcversion);
514 printk("HPFS: please try recent version of HPFS driver at http://artax.karlin.mff.cuni.cz/~mikulas/vyplody/hpfs/index-e.cgi and if it still can't understand this format, contact author - mikulas@artax.karlin.mff.cuni.cz\n");
515 goto bail4;
516 }
517
518 s->s_flags |= MS_NOATIME;
519
520 /* Fill superblock stuff */
521 s->s_magic = HPFS_SUPER_MAGIC;
522 s->s_op = &hpfs_sops;
523
524 sbi->sb_root = superblock->root;
525 sbi->sb_fs_size = superblock->n_sectors;
526 sbi->sb_bitmaps = superblock->bitmaps;
527 sbi->sb_dirband_start = superblock->dir_band_start;
528 sbi->sb_dirband_size = superblock->n_dir_band;
529 sbi->sb_dmap = superblock->dir_band_bitmap;
530 sbi->sb_uid = uid;
531 sbi->sb_gid = gid;
532 sbi->sb_mode = 0777 & ~umask;
533 sbi->sb_n_free = -1;
534 sbi->sb_n_free_dnodes = -1;
535 sbi->sb_lowercase = lowercase;
536 sbi->sb_conv = conv;
537 sbi->sb_eas = eas;
538 sbi->sb_chk = chk;
539 sbi->sb_chkdsk = chkdsk;
540 sbi->sb_err = errs;
541 sbi->sb_timeshift = timeshift;
542 sbi->sb_was_error = 0;
543 sbi->sb_cp_table = NULL;
544 sbi->sb_c_bitmap = -1;
545 sbi->sb_max_fwd_alloc = 0xffffff;
546
547 /* Load bitmap directory */
548 if (!(sbi->sb_bmp_dir = hpfs_load_bitmap_directory(s, superblock->bitmaps)))
549 goto bail4;
550
551 /* Check for general fs errors*/
552 if (spareblock->dirty && !spareblock->old_wrote) {
553 if (errs == 2) {
554 printk("HPFS: Improperly stopped, not mounted\n");
555 goto bail4;
556 }
557 hpfs_error(s, "improperly stopped");
558 }
559
560 if (!(s->s_flags & MS_RDONLY)) {
561 spareblock->dirty = 1;
562 spareblock->old_wrote = 0;
563 mark_buffer_dirty(bh2);
564 }
565
566 if (spareblock->hotfixes_used || spareblock->n_spares_used) {
567 if (errs >= 2) {
568 printk("HPFS: Hotfixes not supported here, try chkdsk\n");
569 mark_dirty(s);
570 goto bail4;
571 }
572 hpfs_error(s, "hotfixes not supported here, try chkdsk");
573 if (errs == 0) printk("HPFS: Proceeding, but your filesystem will be probably corrupted by this driver...\n");
574 else printk("HPFS: This driver may read bad files or crash when operating on disk with hotfixes.\n");
575 }
576 if (spareblock->n_dnode_spares != spareblock->n_dnode_spares_free) {
577 if (errs >= 2) {
578 printk("HPFS: Spare dnodes used, try chkdsk\n");
579 mark_dirty(s);
580 goto bail4;
581 }
582 hpfs_error(s, "warning: spare dnodes used, try chkdsk");
583 if (errs == 0) printk("HPFS: Proceeding, but your filesystem could be corrupted if you delete files or directories\n");
584 }
585 if (chk) {
586 unsigned a;
587 if (superblock->dir_band_end - superblock->dir_band_start + 1 != superblock->n_dir_band ||
588 superblock->dir_band_end < superblock->dir_band_start || superblock->n_dir_band > 0x4000) {
589 hpfs_error(s, "dir band size mismatch: dir_band_start==%08x, dir_band_end==%08x, n_dir_band==%08x",
590 superblock->dir_band_start, superblock->dir_band_end, superblock->n_dir_band);
591 goto bail4;
592 }
593 a = sbi->sb_dirband_size;
594 sbi->sb_dirband_size = 0;
595 if (hpfs_chk_sectors(s, superblock->dir_band_start, superblock->n_dir_band, "dir_band") ||
596 hpfs_chk_sectors(s, superblock->dir_band_bitmap, 4, "dir_band_bitmap") ||
597 hpfs_chk_sectors(s, superblock->bitmaps, 4, "bitmaps")) {
598 mark_dirty(s);
599 goto bail4;
600 }
601 sbi->sb_dirband_size = a;
602 } else printk("HPFS: You really don't want any checks? You are crazy...\n");
603
604 /* Load code page table */
605 if (spareblock->n_code_pages)
606 if (!(sbi->sb_cp_table = hpfs_load_code_page(s, spareblock->code_page_dir)))
607 printk("HPFS: Warning: code page support is disabled\n");
608
609 brelse(bh2);
610 brelse(bh1);
611 brelse(bh0);
612
613 root = iget_locked(s, sbi->sb_root);
614 if (!root)
615 goto bail0;
616 hpfs_init_inode(root);
617 hpfs_read_inode(root);
618 unlock_new_inode(root);
619 s->s_root = d_alloc_root(root);
620 if (!s->s_root) {
621 iput(root);
622 goto bail0;
623 }
624 hpfs_set_dentry_operations(s->s_root);
625
626 /*
627 * find the root directory's . pointer & finish filling in the inode
628 */
629
630 root_dno = hpfs_fnode_dno(s, sbi->sb_root);
631 if (root_dno)
632 de = map_dirent(root, root_dno, "\001\001", 2, NULL, &qbh);
633 if (!de)
634 hpfs_error(s, "unable to find root dir");
635 else {
636 root->i_atime.tv_sec = local_to_gmt(s, de->read_date);
637 root->i_atime.tv_nsec = 0;
638 root->i_mtime.tv_sec = local_to_gmt(s, de->write_date);
639 root->i_mtime.tv_nsec = 0;
640 root->i_ctime.tv_sec = local_to_gmt(s, de->creation_date);
641 root->i_ctime.tv_nsec = 0;
642 hpfs_i(root)->i_ea_size = de->ea_size;
643 hpfs_i(root)->i_parent_dir = root->i_ino;
644 if (root->i_size == -1)
645 root->i_size = 2048;
646 if (root->i_blocks == -1)
647 root->i_blocks = 5;
648 hpfs_brelse4(&qbh);
649 }
650 return 0;
651
652bail4: brelse(bh2);
653bail3: brelse(bh1);
654bail2: brelse(bh0);
655bail1:
656bail0:
657 if (sbi->sb_bmp_dir) kfree(sbi->sb_bmp_dir);
658 if (sbi->sb_cp_table) kfree(sbi->sb_cp_table);
659 s->s_fs_info = NULL;
660 kfree(sbi);
661 return -EINVAL;
662}
663
664static struct super_block *hpfs_get_sb(struct file_system_type *fs_type,
665 int flags, const char *dev_name, void *data)
666{
667 return get_sb_bdev(fs_type, flags, dev_name, data, hpfs_fill_super);
668}
669
670static struct file_system_type hpfs_fs_type = {
671 .owner = THIS_MODULE,
672 .name = "hpfs",
673 .get_sb = hpfs_get_sb,
674 .kill_sb = kill_block_super,
675 .fs_flags = FS_REQUIRES_DEV,
676};
677
678static int __init init_hpfs_fs(void)
679{
680 int err = init_inodecache();
681 if (err)
682 goto out1;
683 err = register_filesystem(&hpfs_fs_type);
684 if (err)
685 goto out;
686 return 0;
687out:
688 destroy_inodecache();
689out1:
690 return err;
691}
692
693static void __exit exit_hpfs_fs(void)
694{
695 unregister_filesystem(&hpfs_fs_type);
696 destroy_inodecache();
697}
698
699module_init(init_hpfs_fs)
700module_exit(exit_hpfs_fs)
701MODULE_LICENSE("GPL");