OpenCores
URL https://opencores.org/ocsvn/or1k_old/or1k_old/trunk

Subversion Repositories or1k_old

[/] [or1k_old/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [hpfs/] [hpfs_fs.c] - Blame information for rev 1782

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 *  linux/fs/hpfs/hpfs_fs.c
3
 *  read-only HPFS
4
 *  version 1.0
5
 *
6
 *  Chris Smith 1993
7
 *
8
 *  Sources & references:
9
 *   Duncan, _Design ... of HPFS_, MSJ 4(5)   (C) 1989 Microsoft Corp
10
 *   linux/fs/minix  Copyright (C) 1991, 1992, 1993  Linus Torvalds
11
 *   linux/fs/msdos  Written 1992, 1993 by Werner Almesberger
12
 *   linux/fs/isofs  Copyright (C) 1991  Eric Youngdale
13
 */
14
 
15
#include <linux/module.h>
16
 
17
#include <linux/fs.h>
18
#include <linux/hpfs_fs.h>
19
#include <linux/errno.h>
20
#include <linux/malloc.h>
21
#include <linux/kernel.h>
22
#include <linux/sched.h>
23
#include <linux/locks.h>
24
#include <linux/stat.h>
25
#include <linux/string.h>
26
#include <asm/bitops.h>
27
#include <asm/segment.h>
28
 
29
#include "hpfs.h"
30
#include "hpfs_caps.h"
31
 
32
/*
33
 * HPFS is a mixture of 512-byte blocks and 2048-byte blocks.  The 2k blocks
34
 * are used for directories and bitmaps.  For bmap to work, we must run the
35
 * file system with 512-byte blocks.  The 2k blocks are assembled in buffers
36
 * obtained from kmalloc.
37
 *
38
 * For a file's i-number we use the sector number of its fnode, coded.
39
 * (Directory ino's are even, file ino's are odd, and ino >> 1 is the
40
 * sector address of the fnode.  This is a hack to allow lookup() to
41
 * tell read_inode() whether it is necessary to read the fnode.)
42
 *
43
 * The map_xxx routines all read something into a buffer and return a
44
 * pointer somewhere in the buffer.  The caller must do the brelse.
45
 * The other routines are balanced.
46
 *
47
 * For details on the data structures see hpfs.h and the Duncan paper.
48
 *
49
 * Overview
50
 *
51
 * [ The names of these data structures, except fnode, are not Microsoft's
52
 * or IBM's.  I don't know what names they use.  The semantics described
53
 * here are those of this implementation, and any coincidence between it
54
 * and real HPFS is to be hoped for but not guaranteed by me, and
55
 * certainly not guaranteed by MS or IBM.  Who know nothing about this. ]
56
 *
57
 * [ Also, the following will make little sense if you haven't read the
58
 * Duncan paper, which is excellent. ]
59
 *
60
 * HPFS is a tree.  There are 3 kinds of nodes.  A directory is a tree
61
 * of dnodes, and a file's allocation info is a tree of sector runs
62
 * stored in fnodes and anodes.
63
 *
64
 * The top pointer is in the super block, it points to the fnode of the
65
 * root directory.
66
 *
67
 * The root directory -- all directories -- gives file names, dates &c,
68
 * and fnode addresses.  If the directory fits in one dnode, that's it,
69
 * otherwise the top dnode points to other dnodes, forming a tree.  A
70
 * dnode tree (one directory) might look like
71
 *
72
 *     ((a b c) d (e f g) h (i j) k l (m n o p))
73
 *
74
 * The subtrees appear between the files.  Each dir entry contains, along
75
 * with the name and fnode, a dnode pointer to the subtree that precedes it
76
 * (if there is one; a flag tells that).  The first entry in every directory
77
 * is ^A^A, the "." entry for the directory itself.  The last entry in every
78
 * dnode is \377, a fake entry whose only valid fields are the bit marking
79
 * it last and the down pointer to the subtree preceding it, if any.
80
 *
81
 * The "value" field of directory entries is an fnode address.  The fnode
82
 * tells where the sectors of the file are.  The fnode for a subdirectory
83
 * contains one pointer, to the root dnode of the subdirectory.  The fnode
84
 * for a data file contains, in effect, a tiny anode.  (Most of the space
85
 * in fnodes is for extended attributes.)
86
 *
87
 * anodes and the anode part of fnodes are trees of extents.  An extent
88
 * is a (length, disk address) pair, labeled with the file address being
89
 * mapped.  E.g.,
90
 *
91
 *     (0: 3@1000  3: 1@2000  4: 2@10)
92
 *
93
 * means the file:disk sector map (0:1000 1:1001 2:1002 3:2000 4:10 5:11).
94
 *
95
 * There is space for 8 file:len@disk triples in an fnode, or for 40 in an
96
 * anode.  If this is insufficient, subtrees are used, as in
97
 *
98
 *  (6: (0: 3@1000  3: 1@2000  4: 2@10)  12: (6: 3@8000  9: 1@9000  10: 2@20))
99
 *
100
 * The label on a subtree is the first address *after* that tree.  The
101
 * subtrees are always anodes.  The label:subtree pairs require only
102
 * two words each, so non-leaf subtrees have a different format; there
103
 * is room for 12 label:subtree pairs in an fnode, or 60 in an anode.
104
 *
105
 * Within a directory, each dnode contains a pointer up to its parent
106
 * dnode.  The root dnode points up to the directory's fnode.
107
 *
108
 * Each fnode contains a pointer to the directory that contains it
109
 * (to the fnode of the directory).  So this pointer in a directory
110
 * fnode is "..".
111
 *
112
 * On the disk, dnodes are all together in the center of the partition,
113
 * and HPFS even manages to put all the dnodes for a single directory
114
 * together, generally.  fnodes are out with the data.  anodes are seldom
115
 * seen -- in fact noncontiguous files are seldom seen.  I think this is
116
 * partly the open() call that lets programs specify the length of an
117
 * output file when they know it, and partly because HPFS.IFS really is
118
 * very good at resisting fragmentation.
119
 */
120
 
121
/* notation */
122
 
123
#define little_ushort(x) (*(unsigned short *) &(x))
124
typedef void nonconst;
125
 
126
/* super block ops */
127
 
128
static void hpfs_read_inode(struct inode *);
129
static void hpfs_put_super(struct super_block *);
130
static void hpfs_statfs(struct super_block *, struct statfs *, int);
131
static int hpfs_remount_fs(struct super_block *, int *, char *);
132
 
133
static const struct super_operations hpfs_sops =
134
{
135
        hpfs_read_inode,                /* read_inode */
136
        NULL,                           /* notify_change */
137
        NULL,                           /* write_inode */
138
        NULL,                           /* put_inode */
139
        hpfs_put_super,                 /* put_super */
140
        NULL,                           /* write_super */
141
        hpfs_statfs,                    /* statfs */
142
        hpfs_remount_fs,                /* remount_fs */
143
};
144
 
145
/* file ops */
146
 
147
static int hpfs_file_read(struct inode *, struct file *, char *, int);
148
static secno hpfs_bmap(struct inode *, unsigned);
149
 
150
static const struct file_operations hpfs_file_ops =
151
{
152
        NULL,                           /* lseek - default */
153
        hpfs_file_read,                 /* read */
154
        NULL,                           /* write */
155
        NULL,                           /* readdir - bad */
156
        NULL,                           /* select - default */
157
        NULL,                           /* ioctl - default */
158
        generic_file_mmap,              /* mmap */
159
        NULL,                           /* no special open is needed */
160
        NULL,                           /* release */
161
        file_fsync,                     /* fsync */
162
};
163
 
164
static const struct inode_operations hpfs_file_iops =
165
{
166
        (nonconst *) & hpfs_file_ops,   /* default file operations */
167
        NULL,                           /* create */
168
        NULL,                           /* lookup */
169
        NULL,                           /* link */
170
        NULL,                           /* unlink */
171
        NULL,                           /* symlink */
172
        NULL,                           /* mkdir */
173
        NULL,                           /* rmdir */
174
        NULL,                           /* mknod */
175
        NULL,                           /* rename */
176
        NULL,                           /* readlink */
177
        NULL,                           /* follow_link */
178
        generic_readpage,               /* readpage */
179
        NULL,                           /* writepage */
180
        (int (*)(struct inode *, int))
181
        &hpfs_bmap,                     /* bmap */
182
        NULL,                           /* truncate */
183
        NULL,                           /* permission */
184
};
185
 
186
/* directory ops */
187
 
188
static int hpfs_dir_read(struct inode *inode, struct file *filp,
189
                         char *buf, int count);
190
static int hpfs_readdir(struct inode *inode, struct file *filp,
191
                        void *dirent, filldir_t filldir);
192
static int hpfs_lookup(struct inode *, const char *, int, struct inode **);
193
 
194
static const struct file_operations hpfs_dir_ops =
195
{
196
        NULL,                           /* lseek - default */
197
        hpfs_dir_read,                  /* read */
198
        NULL,                           /* write - bad */
199
        hpfs_readdir,                   /* readdir */
200
        NULL,                           /* select - default */
201
        NULL,                           /* ioctl - default */
202
        NULL,                           /* mmap */
203
        NULL,                           /* no special open code */
204
        NULL,                           /* no special release code */
205
        file_fsync,                     /* fsync */
206
};
207
 
208
static const struct inode_operations hpfs_dir_iops =
209
{
210
        (nonconst *) & hpfs_dir_ops,    /* default directory file ops */
211
        NULL,                           /* create */
212
        hpfs_lookup,                    /* lookup */
213
        NULL,                           /* link */
214
        NULL,                           /* unlink */
215
        NULL,                           /* symlink */
216
        NULL,                           /* mkdir */
217
        NULL,                           /* rmdir */
218
        NULL,                           /* mknod */
219
        NULL,                           /* rename */
220
        NULL,                           /* readlink */
221
        NULL,                           /* follow_link */
222
        NULL,                           /* readpage */
223
        NULL,                           /* writepage */
224
        NULL,                           /* bmap */
225
        NULL,                           /* truncate */
226
        NULL,                           /* permission */
227
};
228
 
229
/* Four 512-byte buffers and the 2k block obtained by concatenating them */
230
 
231
struct quad_buffer_head {
232
        struct buffer_head *bh[4];
233
        void *data;
234
};
235
 
236
/* forwards */
237
 
238
static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
239
                      int *lowercase, int *conv, int *nocheck);
240
static int check_warn(int not_ok,
241
                      const char *p1, const char *p2, const char *p3);
242
static int zerop(void *addr, unsigned len);
243
static void count_dnodes(struct inode *inode, dnode_secno dno,
244
                         unsigned *n_dnodes, unsigned *n_subdirs);
245
static unsigned count_bitmap(struct super_block *s);
246
static unsigned count_one_bitmap(kdev_t dev, secno secno);
247
static secno bplus_lookup(struct inode *inode, struct bplus_header *b,
248
                          secno file_secno, struct buffer_head **bhp);
249
static struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno,
250
                                    const unsigned char *name, unsigned len,
251
                                      struct quad_buffer_head *qbh);
252
static struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
253
                                          struct quad_buffer_head *qbh);
254
static dnode_secno dir_subdno(struct inode *inode, unsigned pos);
255
static struct hpfs_dirent *map_nth_dirent(kdev_t dev, dnode_secno dno,
256
                                          int n,
257
                                          struct quad_buffer_head *qbh);
258
static unsigned choose_conv(unsigned char *p, unsigned len);
259
static unsigned convcpy_tofs(unsigned char *out, unsigned char *in,
260
                             unsigned len);
261
static dnode_secno fnode_dno(kdev_t dev, ino_t ino);
262
static struct fnode *map_fnode(kdev_t dev, ino_t ino,
263
                               struct buffer_head **bhp);
264
static struct anode *map_anode(kdev_t dev, unsigned secno,
265
                               struct buffer_head **bhp);
266
static struct dnode *map_dnode(kdev_t dev, unsigned secno,
267
                               struct quad_buffer_head *qbh);
268
static void *map_sector(kdev_t dev, unsigned secno, struct buffer_head **bhp);
269
static void *map_4sectors(kdev_t dev, unsigned secno,
270
                          struct quad_buffer_head *qbh);
271
static void brelse4(struct quad_buffer_head *qbh);
272
 
273
/*
274
 * make inode number for a file
275
 */
276
 
277
static inline ino_t file_ino(fnode_secno secno)
278
{
279
        return secno << 1 | 1;
280
}
281
 
282
/*
283
 * make inode number for a directory
284
 */
285
 
286
static inline ino_t dir_ino(fnode_secno secno)
287
{
288
        return secno << 1;
289
}
290
 
291
/*
292
 * get fnode address from an inode number
293
 */
294
 
295
static inline fnode_secno ino_secno(ino_t ino)
296
{
297
        return ino >> 1;
298
}
299
 
300
/*
301
 * test for directory's inode number
302
 */
303
 
304
static inline int ino_is_dir(ino_t ino)
305
{
306
        return (ino & 1) == 0;
307
}
308
 
309
/*
310
 * conv= options
311
 */
312
 
313
#define CONV_BINARY 0                   /* no conversion */
314
#define CONV_TEXT 1                     /* crlf->newline */
315
#define CONV_AUTO 2                     /* decide based on file contents */
316
 
317
/*
318
 * local time (HPFS) to GMT (Unix)
319
 */
320
 
321
static inline time_t local_to_gmt(time_t t)
322
{
323
        extern struct timezone sys_tz;
324
        return t + sys_tz.tz_minuteswest * 60;
325
}
326
 
327
/* super block ops */
328
 
329
/*
330
 * mount.  This gets one thing, the root directory inode.  It does a
331
 * bunch of guessed-at consistency checks.
332
 */
333
 
334
struct super_block *hpfs_read_super(struct super_block *s,
335
                                    void *options, int silent)
336
{
337
        struct hpfs_boot_block *bootblock;
338
        struct hpfs_super_block *superblock;
339
        struct hpfs_spare_block *spareblock;
340
        struct hpfs_dirent *de;
341
        struct buffer_head *bh0, *bh1, *bh2;
342
        struct quad_buffer_head qbh;
343
        dnode_secno root_dno;
344
        kdev_t dev;
345
        uid_t uid;
346
        gid_t gid;
347
        umode_t umask;
348
        int lowercase;
349
        int conv;
350
        int dubious;
351
        int nocheck;
352
 
353
        MOD_INC_USE_COUNT;
354
 
355
        /*
356
         * Get the mount options
357
         */
358
 
359
        if (!parse_opts(options, &uid, &gid, &umask, &lowercase, &conv,
360
                                 &nocheck)) {
361
                printk("HPFS: syntax error in mount options.  Not mounted.\n");
362
                s->s_dev = 0;
363
                MOD_DEC_USE_COUNT;
364
                return 0;
365
        }
366
 
367
        /*
368
         * Fill in the super block struct
369
         */
370
 
371
        lock_super(s);
372
        dev = s->s_dev;
373
        set_blocksize(dev, 512);
374
 
375
        /*
376
         * fetch sectors 0, 16, 17
377
         */
378
 
379
        bootblock = map_sector(dev, 0, &bh0);
380
        if (!bootblock)
381
                goto bail;
382
 
383
        superblock = map_sector(dev, 16, &bh1);
384
        if (!superblock)
385
                goto bail0;
386
 
387
        spareblock = map_sector(dev, 17, &bh2);
388
        if (!spareblock)
389
                goto bail1;
390
 
391
        /*
392
         * Check that this fs looks enough like a known one that we can find
393
         * and read the root directory.
394
         */
395
 
396
        if (bootblock->magic != 0xaa55
397
            || superblock->magic != SB_MAGIC
398
            || spareblock->magic != SP_MAGIC
399
            || bootblock->sig_28h != 0x28
400
            || memcmp(&bootblock->sig_hpfs, "HPFS    ", 8)
401
            || little_ushort(bootblock->bytes_per_sector) != 512) {
402
                printk("HPFS: hpfs_read_super: Not HPFS\n");
403
                goto bail2;
404
        }
405
 
406
        /*
407
         * Check for inconsistencies -- possibly wrong guesses here, possibly
408
         * filesystem problems.
409
         */
410
 
411
        dubious = 0;
412
 
413
        dubious |= check_warn(spareblock->dirty != 0,
414
                       "`Improperly stopped'", "flag is set", "run CHKDSK");
415
        dubious |= check_warn(spareblock->n_spares_used != 0,
416
                              "Spare blocks", "may be in use", "run CHKDSK");
417
 
418
        /*
419
         * Above errors mean we could get wrong answers if we proceed,
420
         * so don't
421
         */
422
 
423
        if (dubious && !nocheck)
424
                goto bail2;
425
 
426
        dubious |= check_warn((spareblock->n_dnode_spares !=
427
                               spareblock->n_dnode_spares_free),
428
                              "Spare dnodes", "may be in use", "run CHKDSK");
429
        dubious |= check_warn(superblock->zero1 != 0,
430
                              "#1", "unknown word nonzero", "investigate");
431
        dubious |= check_warn(superblock->zero3 != 0,
432
                              "#3", "unknown word nonzero", "investigate");
433
        dubious |= check_warn(superblock->zero4 != 0,
434
                              "#4", "unknown word nonzero", "investigate");
435
        dubious |= check_warn(!zerop(superblock->zero5,
436
                                     sizeof superblock->zero5),
437
                              "#5", "unknown word nonzero", "investigate");
438
        dubious |= check_warn(!zerop(superblock->zero6,
439
                                     sizeof superblock->zero6),
440
                              "#6", "unknown word nonzero", "investigate");
441
 
442
        if (dubious)
443
                printk("HPFS: Proceeding, but operation may be unreliable\n");
444
 
445
        /*
446
         * set fs read only
447
         */
448
 
449
        s->s_flags |= MS_RDONLY;
450
 
451
        /*
452
         * fill in standard stuff
453
         */
454
 
455
        s->s_magic = HPFS_SUPER_MAGIC;
456
        s->s_blocksize = 512;
457
        s->s_blocksize_bits = 9;
458
        s->s_op = (struct super_operations *) &hpfs_sops;
459
 
460
        /*
461
         * fill in hpfs stuff
462
         */
463
 
464
        s->s_hpfs_root = dir_ino(superblock->root);
465
        s->s_hpfs_fs_size = superblock->n_sectors;
466
        s->s_hpfs_dirband_size = superblock->n_dir_band / 4;
467
        s->s_hpfs_dmap = superblock->dir_band_bitmap;
468
        s->s_hpfs_bitmaps = superblock->bitmaps;
469
        s->s_hpfs_uid = uid;
470
        s->s_hpfs_gid = gid;
471
        s->s_hpfs_mode = 0777 & ~umask;
472
        s->s_hpfs_n_free = -1;
473
        s->s_hpfs_n_free_dnodes = -1;
474
        s->s_hpfs_lowercase = lowercase;
475
        s->s_hpfs_conv = conv;
476
 
477
        /*
478
         * done with the low blocks
479
         */
480
 
481
        brelse(bh2);
482
        brelse(bh1);
483
        brelse(bh0);
484
 
485
        /*
486
         * all set.  try it out.
487
         */
488
 
489
        s->s_mounted = iget(s, s->s_hpfs_root);
490
        unlock_super(s);
491
 
492
        if (!s->s_mounted) {
493
                printk("HPFS: hpfs_read_super: inode get failed\n");
494
                s->s_dev = 0;
495
                MOD_DEC_USE_COUNT;
496
                return 0;
497
        }
498
 
499
        /*
500
         * find the root directory's . pointer & finish filling in the inode
501
         */
502
 
503
        root_dno = fnode_dno(dev, s->s_hpfs_root);
504
        if (root_dno)
505
                de = map_dirent(s->s_mounted, root_dno, "\001\001", 2, &qbh);
506
        if (!root_dno || !de) {
507
                printk("HPFS: "
508
                       "hpfs_read_super: root dir isn't in the root dir\n");
509
                s->s_dev = 0;
510
                MOD_DEC_USE_COUNT;
511
                return 0;
512
        }
513
 
514
        s->s_mounted->i_atime = local_to_gmt(de->read_date);
515
        s->s_mounted->i_mtime = local_to_gmt(de->write_date);
516
        s->s_mounted->i_ctime = local_to_gmt(de->creation_date);
517
 
518
        brelse4(&qbh);
519
        return s;
520
 
521
 bail2:
522
        brelse(bh2);
523
 bail1:
524
        brelse(bh1);
525
 bail0:
526
        brelse(bh0);
527
 bail:
528
        s->s_dev = 0;
529
        unlock_super(s);
530
        MOD_DEC_USE_COUNT;
531
        return 0;
532
}
533
 
534
static int check_warn(int not_ok,
535
                      const char *p1, const char *p2, const char *p3)
536
{
537
        if (not_ok)
538
                printk("HPFS: %s %s. Please %s\n", p1, p2, p3);
539
        return not_ok;
540
}
541
 
542
static int zerop(void *addr, unsigned len)
543
{
544
        unsigned char *p = addr;
545
        return p[0] == 0 && memcmp(p, p + 1, len - 1) == 0;
546
}
547
 
548
/*
549
 * A tiny parser for option strings, stolen from dosfs.
550
 */
551
 
552
static int parse_opts(char *opts, uid_t *uid, gid_t *gid, umode_t *umask,
553
                      int *lowercase, int *conv, int *nocheck)
554
{
555
        char *p, *rhs;
556
 
557
        *uid = current->uid;
558
        *gid = current->gid;
559
        *umask = current->fs->umask;
560
        *lowercase = 1;
561
        *conv = CONV_BINARY;
562
        *nocheck = 0;
563
 
564
        if (!opts)
565
                return 1;
566
 
567
        for (p = strtok(opts, ","); p != 0; p = strtok(0, ",")) {
568
                if ((rhs = strchr(p, '=')) != 0)
569
                        *rhs++ = '\0';
570
                if (!strcmp(p, "uid")) {
571
                        if (!rhs || !*rhs)
572
                                return 0;
573
                        *uid = simple_strtoul(rhs, &rhs, 0);
574
                        if (*rhs)
575
                                return 0;
576
                }
577
                else if (!strcmp(p, "gid")) {
578
                        if (!rhs || !*rhs)
579
                                return 0;
580
                        *gid = simple_strtoul(rhs, &rhs, 0);
581
                        if (*rhs)
582
                                return 0;
583
                }
584
                else if (!strcmp(p, "umask")) {
585
                        if (!rhs || !*rhs)
586
                                return 0;
587
                        *umask = simple_strtoul(rhs, &rhs, 8);
588
                        if (*rhs)
589
                                return 0;
590
                }
591
                else if (!strcmp(p, "case")) {
592
                        if (!strcmp(rhs, "lower"))
593
                                *lowercase = 1;
594
                        else if (!strcmp(rhs, "asis"))
595
                                *lowercase = 0;
596
                        else
597
                                return 0;
598
                }
599
                else if (!strcmp(p, "conv")) {
600
                        if (!strcmp(rhs, "binary"))
601
                                *conv = CONV_BINARY;
602
                        else if (!strcmp(rhs, "text"))
603
                                *conv = CONV_TEXT;
604
                        else if (!strcmp(rhs, "auto"))
605
                                *conv = CONV_AUTO;
606
                        else
607
                                return 0;
608
                }
609
                else if (!strcmp(p,"nocheck"))
610
                        *nocheck=1;
611
                else
612
                        return 1;
613
        }
614
 
615
        return 1;
616
}
617
 
618
/*
619
 * read_inode.  This is called with exclusive access to a new inode that
620
 * has only (i_dev,i_ino) set.  It is responsible for filling in the rest.
621
 * We leave the dates blank, to be filled in from the dir entry.
622
 *
623
 * NOTE that there must be no sleeping from the return in this routine
624
 * until lookup() finishes filling in the inode, otherwise the partly
625
 * completed inode would be visible during the sleep.
626
 *
627
 * It is done in this strange and sinful way because the alternative
628
 * is to read the fnode, find the dir pointer in it, read that fnode
629
 * to get the dnode pointer, search through that whole directory for
630
 * the ino we're reading, and get the dates.  It works that way, but
631
 * ls sounds like fsck.
632
 */
633
 
634
static void hpfs_read_inode(struct inode *inode)
635
{
636
        struct super_block *s = inode->i_sb;
637
 
638
        /* be ready to bail out */
639
 
640
        inode->i_op = 0;
641
        inode->i_mode = 0;
642
 
643
        if (inode->i_ino == 0
644
            || ino_secno(inode->i_ino) >= inode->i_sb->s_hpfs_fs_size) {
645
                printk("HPFS: read_inode: bad ino\n");
646
                return;
647
        }
648
 
649
        /*
650
         * canned stuff
651
         */
652
 
653
        inode->i_uid = s->s_hpfs_uid;
654
        inode->i_gid = s->s_hpfs_gid;
655
        inode->i_mode = s->s_hpfs_mode;
656
        inode->i_hpfs_conv = s->s_hpfs_conv;
657
 
658
        inode->i_hpfs_dno = 0;
659
        inode->i_hpfs_n_secs = 0;
660
        inode->i_hpfs_file_sec = 0;
661
        inode->i_hpfs_disk_sec = 0;
662
        inode->i_hpfs_dpos = 0;
663
        inode->i_hpfs_dsubdno = 0;
664
 
665
        /*
666
         * figure out whether we are looking at a directory or a file
667
         */
668
 
669
        if (ino_is_dir(inode->i_ino))
670
                inode->i_mode |= S_IFDIR;
671
        else {
672
                inode->i_mode |= S_IFREG;
673
                inode->i_mode &= ~0111;
674
        }
675
 
676
        /*
677
         * these fields must be filled in from the dir entry, which we don't
678
         * have but lookup does.  It will fill them in before letting the
679
         * inode out of its grasp.
680
         */
681
 
682
        inode->i_atime = 0;
683
        inode->i_mtime = 0;
684
        inode->i_ctime = 0;
685
        inode->i_size = 0;
686
 
687
        /*
688
         * fill in the rest
689
         */
690
 
691
        if (S_ISREG(inode->i_mode)) {
692
 
693
                inode->i_op = (struct inode_operations *) &hpfs_file_iops;
694
                inode->i_nlink = 1;
695
                inode->i_blksize = 512;
696
 
697
        }
698
        else {
699
                unsigned n_dnodes, n_subdirs;
700
                struct buffer_head *bh0;
701
                struct fnode *fnode = map_fnode(inode->i_dev,
702
                                                inode->i_ino, &bh0);
703
 
704
                if (!fnode) {
705
                        printk("HPFS: read_inode: no fnode\n");
706
                        inode->i_mode = 0;
707
                        return;
708
                }
709
 
710
                inode->i_hpfs_parent_dir = dir_ino(fnode->up);
711
                inode->i_hpfs_dno = fnode->u.external[0].disk_secno;
712
 
713
                brelse(bh0);
714
 
715
                n_dnodes = n_subdirs = 0;
716
                count_dnodes(inode, inode->i_hpfs_dno, &n_dnodes, &n_subdirs);
717
 
718
                inode->i_op = (struct inode_operations *) &hpfs_dir_iops;
719
                inode->i_blksize = 512; /* 2048 here confuses ls & du & ... */
720
                inode->i_blocks = 4 * n_dnodes;
721
                inode->i_size = 512 * inode->i_blocks;
722
                inode->i_nlink = 2 + n_subdirs;
723
        }
724
}
725
 
726
/*
727
 * unmount.
728
 */
729
 
730
static void hpfs_put_super(struct super_block *s)
731
{
732
        lock_super(s);
733
        s->s_dev = 0;
734
        unlock_super(s);
735
        MOD_DEC_USE_COUNT;
736
}
737
 
738
/*
739
 * statfs.  For free inode counts we report the count of dnodes in the
740
 * directory band -- not exactly right but pretty analogous.
741
 */
742
 
743
static void hpfs_statfs(struct super_block *s, struct statfs *buf, int bufsiz)
744
{
745
        struct statfs tmp;
746
 
747
        /*
748
         * count the bits in the bitmaps, unless we already have
749
         */
750
        if (s->s_hpfs_n_free == -1) {
751
                s->s_hpfs_n_free = count_bitmap(s);
752
                s->s_hpfs_n_free_dnodes =
753
                    count_one_bitmap(s->s_dev, s->s_hpfs_dmap);
754
        }
755
 
756
        /*
757
         * fill in the user statfs struct
758
         */
759
        tmp.f_type = s->s_magic;
760
        tmp.f_bsize = 512;
761
        tmp.f_blocks = s->s_hpfs_fs_size;
762
        tmp.f_bfree = s->s_hpfs_n_free;
763
        tmp.f_bavail = s->s_hpfs_n_free;
764
        tmp.f_files = s->s_hpfs_dirband_size;
765
        tmp.f_ffree = s->s_hpfs_n_free_dnodes;
766
        tmp.f_namelen = 254;
767
        memcpy_tofs(buf, &tmp, bufsiz);
768
}
769
 
770
/*
771
 * remount.  Don't let read only be turned off.
772
 */
773
 
774
static int hpfs_remount_fs(struct super_block *s, int *flags, char *data)
775
{
776
        if (!(*flags & MS_RDONLY))
777
                return -EINVAL;
778
        return 0;
779
}
780
 
781
/*
782
 * count the dnodes in a directory, and the subdirs.
783
 */
784
 
785
static void count_dnodes(struct inode *inode, dnode_secno dno,
786
                         unsigned *n_dnodes, unsigned *n_subdirs)
787
{
788
        struct quad_buffer_head qbh;
789
        struct dnode *dnode;
790
        struct hpfs_dirent *de;
791
        struct hpfs_dirent *de_end;
792
 
793
        dnode = map_dnode(inode->i_dev, dno, &qbh);
794
        if (!dnode)
795
                return;
796
        de = dnode_first_de(dnode);
797
        de_end = dnode_end_de(dnode);
798
 
799
        (*n_dnodes)++;
800
 
801
        for (; de < de_end; de = de_next_de(de)) {
802
                if (de->down)
803
                        count_dnodes(inode, de_down_pointer(de),
804
                                     n_dnodes, n_subdirs);
805
                if (de->directory && !de->first)
806
                        (*n_subdirs)++;
807
                if (de->last || de->length == 0)
808
                        break;
809
        }
810
 
811
        brelse4(&qbh);
812
}
813
 
814
/*
815
 * count the bits in the free space bit maps
816
 */
817
 
818
static unsigned count_bitmap(struct super_block *s)
819
{
820
        unsigned n, count, n_bands;
821
        secno *bitmaps;
822
        struct quad_buffer_head qbh;
823
 
824
        /*
825
         * there is one bit map for each 16384 sectors
826
         */
827
        n_bands = (s->s_hpfs_fs_size + 0x3fff) >> 14;
828
 
829
        /*
830
         * their locations are given in an array pointed to by the super
831
         * block
832
         */
833
        bitmaps = map_4sectors(s->s_dev, s->s_hpfs_bitmaps, &qbh);
834
        if (!bitmaps)
835
                return 0;
836
 
837
        count = 0;
838
 
839
        /*
840
         * map each one and count the free sectors
841
         */
842
        for (n = 0; n < n_bands; n++)
843
                if (bitmaps[n] == 0)
844
                        printk("HPFS: bit map pointer missing\n");
845
                else
846
                        count += count_one_bitmap(s->s_dev, bitmaps[n]);
847
 
848
        brelse4(&qbh);
849
        return count;
850
}
851
 
852
/*
853
 * Read in one bit map, count the bits, return the count.
854
 */
855
 
856
static unsigned count_one_bitmap(kdev_t dev, secno secno)
857
{
858
        struct quad_buffer_head qbh;
859
        char *bits;
860
        unsigned i, count;
861
 
862
        bits = map_4sectors(dev, secno, &qbh);
863
        if (!bits)
864
                return 0;
865
 
866
        count = 0;
867
 
868
        for (i = 0; i < 8 * 2048; i++)
869
                count += (test_bit(i, bits) != 0);
870
        brelse4(&qbh);
871
 
872
        return count;
873
}
874
 
875
/* file ops */
876
 
877
/*
878
 * read.  Read the bytes, put them in buf, return the count.
879
 */
880
 
881
static int hpfs_file_read(struct inode *inode, struct file *filp,
882
                          char *buf, int count)
883
{
884
        unsigned q, r, n, n0;
885
        struct buffer_head *bh;
886
        char *block;
887
        char *start;
888
 
889
        if (inode == 0 || !S_ISREG(inode->i_mode))
890
                return -EINVAL;
891
 
892
        /*
893
         * truncate count at EOF
894
         */
895
        if (count > inode->i_size - (off_t) filp->f_pos)
896
                count = inode->i_size - filp->f_pos;
897
 
898
        start = buf;
899
        while (count > 0) {
900
                /*
901
                 * get file sector number, offset in sector, length to end of
902
                 * sector
903
                 */
904
                q = filp->f_pos >> 9;
905
                r = filp->f_pos & 511;
906
                n = 512 - r;
907
 
908
                /*
909
                 * get length to copy to user buffer
910
                 */
911
                if (n > count)
912
                        n = count;
913
 
914
                /*
915
                 * read the sector, copy to user
916
                 */
917
                block = map_sector(inode->i_dev, hpfs_bmap(inode, q), &bh);
918
                if (!block)
919
                        return -EIO;
920
 
921
                /*
922
                 * but first decide if it has \r\n, if the mount option said
923
                 * to do that
924
                 */
925
                if (inode->i_hpfs_conv == CONV_AUTO)
926
                        inode->i_hpfs_conv = choose_conv(block + r, n);
927
 
928
                if (inode->i_hpfs_conv == CONV_BINARY) {
929
                        /*
930
                         * regular copy, output length is same as input
931
                         * length
932
                         */
933
                        memcpy_tofs(buf, block + r, n);
934
                        n0 = n;
935
                }
936
                else {
937
                        /*
938
                         * squeeze out \r, output length varies
939
                         */
940
                        n0 = convcpy_tofs(buf, block + r, n);
941
                        if (count > inode->i_size - (off_t) filp->f_pos - n + n0)
942
                                count = inode->i_size - filp->f_pos - n + n0;
943
                }
944
 
945
                brelse(bh);
946
 
947
                /*
948
                 * advance input n bytes, output n0 bytes
949
                 */
950
                filp->f_pos += n;
951
                buf += n0;
952
                count -= n0;
953
        }
954
 
955
        return buf - start;
956
}
957
 
958
/*
959
 * This routine implements conv=auto.  Return CONV_BINARY or CONV_TEXT.
960
 */
961
 
962
static unsigned choose_conv(unsigned char *p, unsigned len)
963
{
964
        unsigned tvote, bvote;
965
        unsigned c;
966
 
967
        tvote = bvote = 0;
968
 
969
        while (len--) {
970
                c = *p++;
971
                if (c < ' ')
972
                        if (c == '\r' && len && *p == '\n')
973
                                tvote += 10;
974
                        else if (c == '\t' || c == '\n');
975
                        else
976
                                bvote += 5;
977
                else if (c < '\177')
978
                        tvote++;
979
                else
980
                        bvote += 5;
981
        }
982
 
983
        if (tvote > bvote)
984
                return CONV_TEXT;
985
        else
986
                return CONV_BINARY;
987
}
988
 
989
/*
990
 * This routine implements conv=text.  :s/crlf/nl/
991
 */
992
 
993
static unsigned convcpy_tofs(unsigned char *out, unsigned char *in,
994
                             unsigned len)
995
{
996
        unsigned char *start = out;
997
 
998
        while (len--) {
999
                unsigned c = *in++;
1000
                if (c == '\r' && (len == 0 || *in == '\n'));
1001
                else
1002
                        put_user(c, out++);
1003
        }
1004
 
1005
        return out - start;
1006
}
1007
 
1008
/*
1009
 * Return the disk sector number containing a file sector.
1010
 */
1011
 
1012
static secno hpfs_bmap(struct inode *inode, unsigned file_secno)
1013
{
1014
        unsigned n, disk_secno;
1015
        struct fnode *fnode;
1016
        struct buffer_head *bh;
1017
 
1018
        /*
1019
         * There is one sector run cached in the inode. See if the sector is
1020
         * in it.
1021
         */
1022
 
1023
        n = file_secno - inode->i_hpfs_file_sec;
1024
        if (n < inode->i_hpfs_n_secs)
1025
                return inode->i_hpfs_disk_sec + n;
1026
 
1027
        /*
1028
         * No, read the fnode and go find the sector.
1029
         */
1030
 
1031
        else {
1032
                fnode = map_fnode(inode->i_dev, inode->i_ino, &bh);
1033
                if (!fnode)
1034
                        return 0;
1035
                disk_secno = bplus_lookup(inode, &fnode->btree,
1036
                                          file_secno, &bh);
1037
                brelse(bh);
1038
                return disk_secno;
1039
        }
1040
}
1041
 
1042
/*
1043
 * Search allocation tree *b for the given file sector number and return
1044
 * the disk sector number.  Buffer *bhp has the tree in it, and can be
1045
 * reused for subtrees when access to *b is no longer needed.
1046
 * *bhp is busy on entry and exit.
1047
 */
1048
 
1049
static secno bplus_lookup(struct inode *inode, struct bplus_header *b,
1050
                          secno file_secno, struct buffer_head **bhp)
1051
{
1052
        int i;
1053
 
1054
        /*
1055
         * A leaf-level tree gives a list of sector runs.  Find the one
1056
         * containing the file sector we want, cache the map info in the
1057
         * inode for later, and return the corresponding disk sector.
1058
         */
1059
 
1060
        if (!b->internal) {
1061
                struct bplus_leaf_node *n = b->u.external;
1062
                for (i = 0; i < b->n_used_nodes; i++) {
1063
                        unsigned t = file_secno - n[i].file_secno;
1064
                        if (t < n[i].length) {
1065
                                inode->i_hpfs_file_sec = n[i].file_secno;
1066
                                inode->i_hpfs_disk_sec = n[i].disk_secno;
1067
                                inode->i_hpfs_n_secs = n[i].length;
1068
                                return n[i].disk_secno + t;
1069
                        }
1070
                }
1071
        }
1072
 
1073
        /*
1074
         * A non-leaf tree gives a list of subtrees.  Find the one containing
1075
         * the file sector we want, read it in, and recurse to search it.
1076
         */
1077
 
1078
        else {
1079
                struct bplus_internal_node *n = b->u.internal;
1080
                for (i = 0; i < b->n_used_nodes; i++) {
1081
                        if (file_secno < n[i].file_secno) {
1082
                                struct anode *anode;
1083
                                anode_secno ano = n[i].down;
1084
                                brelse(*bhp);
1085
                                anode = map_anode(inode->i_dev, ano, bhp);
1086
                                if (!anode)
1087
                                        break;
1088
                                return bplus_lookup(inode, &anode->btree,
1089
                                                    file_secno, bhp);
1090
                        }
1091
                }
1092
        }
1093
 
1094
        /*
1095
         * If we get here there was a hole in the file.  As far as I know we
1096
         * never do get here, but falling off the end would be indelicate. So
1097
         * return a pointer to a handy all-zero sector.  This is not a
1098
         * reasonable way to handle files with holes if they really do
1099
         * happen.
1100
         */
1101
 
1102
        printk("HPFS: bplus_lookup: sector not found\n");
1103
        return 15;
1104
}
1105
 
1106
/* directory ops */
1107
 
1108
/*
1109
 * lookup.  Search the specified directory for the specified name, set
1110
 * *result to the corresponding inode.
1111
 *
1112
 * lookup uses the inode number to tell read_inode whether it is reading
1113
 * the inode of a directory or a file -- file ino's are odd, directory
1114
 * ino's are even.  read_inode avoids i/o for file inodes; everything
1115
 * needed is up here in the directory.  (And file fnodes are out in
1116
 * the boondocks.)
1117
 */
1118
 
1119
static int hpfs_lookup(struct inode *dir, const char *name, int len,
1120
                       struct inode **result)
1121
{
1122
        struct quad_buffer_head qbh;
1123
        struct hpfs_dirent *de;
1124
        struct inode *inode;
1125
        ino_t ino;
1126
 
1127
        /* In case of madness */
1128
 
1129
        *result = 0;
1130
        if (dir == 0)
1131
                return -ENOENT;
1132
        if (!S_ISDIR(dir->i_mode))
1133
                goto bail;
1134
 
1135
        /*
1136
         * Read in the directory entry. "." is there under the name ^A^A .
1137
         * Always read the dir even for . and .. in case we need the dates.
1138
         */
1139
 
1140
        if (name[0] == '.' && len == 1)
1141
                de = map_dirent(dir, dir->i_hpfs_dno, "\001\001", 2, &qbh);
1142
        else if (name[0] == '.' && name[1] == '.' && len == 2)
1143
                de = map_dirent(dir,
1144
                                fnode_dno(dir->i_dev, dir->i_hpfs_parent_dir),
1145
                                "\001\001", 2, &qbh);
1146
        else
1147
                de = map_dirent(dir, dir->i_hpfs_dno, name, len, &qbh);
1148
 
1149
        /*
1150
         * This is not really a bailout, just means file not found.
1151
         */
1152
 
1153
        if (!de)
1154
                goto bail;
1155
 
1156
        /*
1157
         * Get inode number, what we're after.
1158
         */
1159
 
1160
        if (de->directory)
1161
                ino = dir_ino(de->fnode);
1162
        else
1163
                ino = file_ino(de->fnode);
1164
 
1165
        /*
1166
         * Go find or make an inode.
1167
         */
1168
 
1169
        if (!(inode = iget(dir->i_sb, ino)))
1170
                goto bail1;
1171
 
1172
        /*
1173
         * Fill in the info from the directory if this is a newly created
1174
         * inode.
1175
         */
1176
 
1177
        if (!inode->i_atime) {
1178
                inode->i_atime = local_to_gmt(de->read_date);
1179
                inode->i_mtime = local_to_gmt(de->write_date);
1180
                inode->i_ctime = local_to_gmt(de->creation_date);
1181
                if (de->read_only)
1182
                        inode->i_mode &= ~0222;
1183
                if (!de->directory) {
1184
                        inode->i_size = de->file_size;
1185
                        /*
1186
                         * i_blocks should count the fnode and any anodes.
1187
                         * We count 1 for the fnode and don't bother about
1188
                         * anodes -- the disk heads are on the directory band
1189
                         * and we want them to stay there.
1190
                         */
1191
                        inode->i_blocks = 1 + ((inode->i_size + 511) >> 9);
1192
                }
1193
        }
1194
 
1195
        brelse4(&qbh);
1196
 
1197
        /*
1198
         * Made it.
1199
         */
1200
 
1201
        *result = inode;
1202
        iput(dir);
1203
        return 0;
1204
 
1205
        /*
1206
         * Didn't.
1207
         */
1208
 bail1:
1209
        brelse4(&qbh);
1210
 bail:
1211
        iput(dir);
1212
        return -ENOENT;
1213
}
1214
 
1215
/*
1216
 * Compare two counted strings ignoring case.
1217
 * HPFS directory order sorts letters as if they're upper case.
1218
 */
1219
 
1220
static inline int memcasecmp(const unsigned char *s1, const unsigned char *s2,
1221
                             unsigned n)
1222
{
1223
        int t;
1224
 
1225
        if (n != 0)
1226
                do {
1227
                        unsigned c1 = linux_char_to_upper_linux (*s1++);
1228
                        unsigned c2 = hpfs_char_to_upper_linux (*s2++);
1229
                        if ((t = c1 - c2) != 0)
1230
                                return t;
1231
                } while (--n != 0);
1232
 
1233
        return 0;
1234
}
1235
 
1236
/*
1237
 * Search a directory for the given name, return a pointer to its dir entry
1238
 * and a pointer to the buffer containing it.
1239
 */
1240
 
1241
static struct hpfs_dirent *map_dirent(struct inode *inode, dnode_secno dno,
1242
                                      const unsigned char *name, unsigned len,
1243
                                      struct quad_buffer_head *qbh)
1244
{
1245
        struct dnode *dnode;
1246
        struct hpfs_dirent *de;
1247
        struct hpfs_dirent *de_end;
1248
        int t, l;
1249
 
1250
        /*
1251
         * read the dnode at the root of our subtree
1252
         */
1253
        dnode = map_dnode(inode->i_dev, dno, qbh);
1254
        if (!dnode)
1255
                return 0;
1256
 
1257
        /*
1258
         * get pointers to start and end+1 of dir entries
1259
         */
1260
        de = dnode_first_de(dnode);
1261
        de_end = dnode_end_de(dnode);
1262
 
1263
        /*
1264
         * look through the entries for the name we're after
1265
         */
1266
        for ( ; de < de_end; de = de_next_de(de)) {
1267
 
1268
                /*
1269
                 * compare names
1270
                 */
1271
                l = len < de->namelen ? len : de->namelen;
1272
                t = memcasecmp(name, de->name, l);
1273
 
1274
                /*
1275
                 * initial substring matches, compare lengths
1276
                 */
1277
                if (t == 0) {
1278
                        t = len - de->namelen;
1279
                        /* bingo */
1280
                        if (t == 0)
1281
                                return de;
1282
                }
1283
 
1284
                /*
1285
                 * wanted name .lt. dir name => not present.
1286
                 */
1287
                if (t < 0) {
1288
                        /*
1289
                         * if there is a subtree, search it.
1290
                         */
1291
                        if (de->down) {
1292
                                dnode_secno sub_dno = de_down_pointer(de);
1293
                                brelse4(qbh);
1294
                                return map_dirent(inode, sub_dno,
1295
                                                  name, len, qbh);
1296
                        }
1297
                        else
1298
                                break;
1299
                }
1300
 
1301
                /*
1302
                 * de->last is set on the last name in the dnode (it's always
1303
                 * a "\377" pseudo entry).  de->length == 0 means we're about
1304
                 * to infinite loop. This test does nothing in a well-formed
1305
                 * dnode.
1306
                 */
1307
                if (de->last || de->length == 0)
1308
                        break;
1309
        }
1310
 
1311
        /*
1312
         * name not found.
1313
         */
1314
        brelse4(qbh);
1315
        return 0;
1316
}
1317
 
1318
/*
1319
 * readdir.  Return exactly 1 dirent.  (I tried and tried, but currently
1320
 * the interface with libc just does not permit more than 1.  If it gets
1321
 * fixed, throw this out and just walk the tree and write records into
1322
 * the user buffer.)
1323
 *
1324
 * [ we now can handle multiple dirents, although the current libc doesn't
1325
 *   use that. The way hpfs does this is pretty strange, as we need to do
1326
 *   the name translation etc before calling "filldir()". This is untested,
1327
 *   as I don't have any hpfs partitions to test against.   Linus ]
1328
 *
1329
 * We keep track of our position in the dnode tree with a sort of
1330
 * dewey-decimal record of subtree locations.  Like so:
1331
 *
1332
 *   (1 (1.1 1.2 1.3) 2 3 (3.1 (3.1.1 3.1.2) 3.2 3.3 (3.3.1)) 4)
1333
 *
1334
 * Subtrees appear after their file, out of lexical order,
1335
 * which would be before their file.  It's easier.
1336
 *
1337
 * A directory can't hold more than 56 files, so 6 bits are used for
1338
 * position numbers.  If the tree is so deep that the position encoding
1339
 * doesn't fit, I'm sure something absolutely fascinating happens.
1340
 *
1341
 * The actual sequence of f_pos values is
1342
 *     0 => .   -1 => ..   1 1.1 ... 8.9 9 => files  -2 => eof
1343
 *
1344
 * The directory inode caches one position-to-dnode correspondence so
1345
 * we won't have to repeatedly scan the top levels of the tree.
1346
 */
1347
 
1348
/*
1349
 * Translate the given name: Blam it to lowercase if the mount option said to.
1350
 */
1351
 
1352
static void translate_hpfs_name(const unsigned char * from, int len, char * to, int lowercase)
1353
{
1354
        while (len > 0) {
1355
                unsigned t = *from;
1356
                len--;
1357
                if (lowercase)
1358
                        t = hpfs_char_to_lower_linux (t);
1359
                else
1360
                        t = hpfs_char_to_linux (t);
1361
                *to = t;
1362
                from++;
1363
                to++;
1364
        }
1365
}
1366
 
1367
static int hpfs_readdir(struct inode *inode, struct file *filp, void * dirent,
1368
        filldir_t filldir)
1369
{
1370
        struct quad_buffer_head qbh;
1371
        struct hpfs_dirent *de;
1372
        int namelen, lc;
1373
        ino_t ino;
1374
        char * tempname;
1375
        long old_pos;
1376
 
1377
        if (inode == 0
1378
            || inode->i_sb == 0
1379
            || !S_ISDIR(inode->i_mode))
1380
                return -EBADF;
1381
 
1382
        tempname = (char *) __get_free_page(GFP_KERNEL);
1383
        if (!tempname)
1384
                return -ENOMEM;
1385
 
1386
        lc = inode->i_sb->s_hpfs_lowercase;
1387
        switch ((long) filp->f_pos) {
1388
        case -2:
1389
                break;
1390
 
1391
        case 0:
1392
                if (filldir(dirent, ".", 1, filp->f_pos, inode->i_ino) < 0)
1393
                        break;
1394
                filp->f_pos = -1;
1395
                /* fall through */
1396
 
1397
        case -1:
1398
                if (filldir(dirent, "..", 2, filp->f_pos, inode->i_hpfs_parent_dir) < 0)
1399
                        break;
1400
                filp->f_pos = 1;
1401
                /* fall through */
1402
 
1403
        default:
1404
                for (;;) {
1405
                        old_pos = filp->f_pos;
1406
                        de = map_pos_dirent(inode, &filp->f_pos, &qbh);
1407
                        if (!de) {
1408
                                filp->f_pos = -2;
1409
                                break;
1410
                        }
1411
                        namelen = de->namelen;
1412
                        translate_hpfs_name(de->name, namelen, tempname, lc);
1413
                        if (de->directory)
1414
                                ino = dir_ino(de->fnode);
1415
                        else
1416
                                ino = file_ino(de->fnode);
1417
                        brelse4(&qbh);
1418
                        if (filldir(dirent, tempname, namelen, old_pos, ino) < 0) {
1419
                                filp->f_pos = old_pos;
1420
                                break;
1421
                        }
1422
                }
1423
        }
1424
        free_page((unsigned long) tempname);
1425
        return 0;
1426
}
1427
 
1428
/*
1429
 * Map the dir entry at subtree coordinates given by *posp, and
1430
 * increment *posp to point to the following dir entry.
1431
 */
1432
 
1433
static struct hpfs_dirent *map_pos_dirent(struct inode *inode, loff_t *posp,
1434
                                          struct quad_buffer_head *qbh)
1435
{
1436
        unsigned pos, q, r;
1437
        dnode_secno dno;
1438
        struct hpfs_dirent *de;
1439
 
1440
        /*
1441
         * Get the position code and split off the rightmost index r
1442
         */
1443
 
1444
        pos = *posp;
1445
        q = pos >> 6;
1446
        r = pos & 077;
1447
 
1448
        /*
1449
         * Get the sector address of the dnode
1450
         * pointed to by the leading part q
1451
         */
1452
 
1453
        dno = dir_subdno(inode, q);
1454
        if (!dno)
1455
                return 0;
1456
 
1457
        /*
1458
         * Get the entry at index r in dnode q
1459
         */
1460
 
1461
        de = map_nth_dirent(inode->i_dev, dno, r, qbh);
1462
 
1463
        /*
1464
         * If none, we're out of files in this dnode.  Ascend.
1465
         */
1466
 
1467
        if (!de) {
1468
                if (q == 0)
1469
                        return 0;
1470
                *posp = q + 1;
1471
                return map_pos_dirent(inode, posp, qbh);
1472
        }
1473
 
1474
        /*
1475
         * If a subtree is here, descend.
1476
         */
1477
 
1478
        if (de->down)
1479
                *posp = pos << 6 | 1;
1480
        else
1481
                *posp = pos + 1;
1482
 
1483
        /*
1484
         * Don't return the ^A^A and \377 entries.
1485
         */
1486
 
1487
        if (de->first || de->last) {
1488
                brelse4(qbh);
1489
                return map_pos_dirent(inode, posp, qbh);
1490
        }
1491
        else
1492
                return de;
1493
}
1494
 
1495
/*
1496
 * Return the address of the dnode with subtree coordinates given by pos.
1497
 */
1498
 
1499
static dnode_secno dir_subdno(struct inode *inode, unsigned pos)
1500
{
1501
        struct hpfs_dirent *de;
1502
        struct quad_buffer_head qbh;
1503
 
1504
        /*
1505
         * 0 is the root dnode
1506
         */
1507
 
1508
        if (pos == 0)
1509
                return inode->i_hpfs_dno;
1510
 
1511
        /*
1512
         * we have one pos->dnode translation cached in the inode
1513
         */
1514
 
1515
        else if (pos == inode->i_hpfs_dpos)
1516
                return inode->i_hpfs_dsubdno;
1517
 
1518
        /*
1519
         * otherwise go look
1520
         */
1521
 
1522
        else {
1523
                unsigned q = pos >> 6;
1524
                unsigned r = pos & 077;
1525
                dnode_secno dno;
1526
 
1527
                /*
1528
                 * dnode at position q
1529
                 */
1530
                dno = dir_subdno(inode, q);
1531
                if (dno == 0)
1532
                        return 0;
1533
 
1534
                /*
1535
                 * entry at index r
1536
                 */
1537
                de = map_nth_dirent(inode->i_dev, dno, r, &qbh);
1538
                if (!de || !de->down)
1539
                        return 0;
1540
 
1541
                /*
1542
                 * get the dnode down pointer
1543
                 */
1544
                dno = de_down_pointer(de);
1545
                brelse4(&qbh);
1546
 
1547
                /*
1548
                 * cache it for next time
1549
                 */
1550
                inode->i_hpfs_dpos = pos;
1551
                inode->i_hpfs_dsubdno = dno;
1552
                return dno;
1553
        }
1554
}
1555
 
1556
/*
1557
 * Return the dir entry at index n in dnode dno, or 0 if there isn't one
1558
 */
1559
 
1560
static struct hpfs_dirent *map_nth_dirent(kdev_t dev, dnode_secno dno,
1561
                                          int n,
1562
                                          struct quad_buffer_head *qbh)
1563
{
1564
        int i;
1565
        struct hpfs_dirent *de, *de_end;
1566
        struct dnode *dnode = map_dnode(dev, dno, qbh);
1567
 
1568
        de = dnode_first_de(dnode);
1569
        de_end = dnode_end_de(dnode);
1570
 
1571
        for (i = 1; de < de_end; i++, de = de_next_de(de)) {
1572
                if (i == n)
1573
                        return de;
1574
                if (de->last || de->length == 0)
1575
                        break;
1576
        }
1577
 
1578
        brelse4(qbh);
1579
        return 0;
1580
}
1581
 
1582
static int hpfs_dir_read(struct inode *inode, struct file *filp,
1583
                         char *buf, int count)
1584
{
1585
        return -EISDIR;
1586
}
1587
 
1588
/* Return the dnode pointer in a directory fnode */
1589
 
1590
static dnode_secno fnode_dno(kdev_t dev, ino_t ino)
1591
{
1592
        struct buffer_head *bh;
1593
        struct fnode *fnode;
1594
        dnode_secno dno;
1595
 
1596
        fnode = map_fnode(dev, ino, &bh);
1597
        if (!fnode)
1598
                return 0;
1599
 
1600
        dno = fnode->u.external[0].disk_secno;
1601
        brelse(bh);
1602
        return dno;
1603
}
1604
 
1605
/* Map an fnode into a buffer and return pointers to it and to the buffer. */
1606
 
1607
static struct fnode *map_fnode(kdev_t dev, ino_t ino, struct buffer_head **bhp)
1608
{
1609
        struct fnode *fnode;
1610
 
1611
        if (ino == 0) {
1612
                printk("HPFS: missing fnode\n");
1613
                return 0;
1614
        }
1615
 
1616
        fnode = map_sector(dev, ino_secno(ino), bhp);
1617
        if (fnode)
1618
                if (fnode->magic != FNODE_MAGIC) {
1619
                        printk("HPFS: map_fnode: bad fnode pointer\n");
1620
                        brelse(*bhp);
1621
                        return 0;
1622
                }
1623
        return fnode;
1624
}
1625
 
1626
/* Map an anode into a buffer and return pointers to it and to the buffer. */
1627
 
1628
static struct anode *map_anode(kdev_t dev, unsigned secno,
1629
                               struct buffer_head **bhp)
1630
{
1631
        struct anode *anode;
1632
 
1633
        if (secno == 0) {
1634
                printk("HPFS: missing anode\n");
1635
                return 0;
1636
        }
1637
 
1638
        anode = map_sector(dev, secno, bhp);
1639
        if (anode)
1640
                if (anode->magic != ANODE_MAGIC || anode->self != secno) {
1641
                        printk("HPFS: map_anode: bad anode pointer\n");
1642
                        brelse(*bhp);
1643
                        return 0;
1644
                }
1645
        return anode;
1646
}
1647
 
1648
/* Map a dnode into a buffer and return pointers to it and to the buffer. */
1649
 
1650
static struct dnode *map_dnode(kdev_t dev, unsigned secno,
1651
                               struct quad_buffer_head *qbh)
1652
{
1653
        struct dnode *dnode;
1654
 
1655
        if (secno == 0) {
1656
                printk("HPFS: missing dnode\n");
1657
                return 0;
1658
        }
1659
 
1660
        dnode = map_4sectors(dev, secno, qbh);
1661
        if (dnode)
1662
                if (dnode->magic != DNODE_MAGIC || dnode->self != secno) {
1663
                        printk("HPFS: map_dnode: bad dnode pointer\n");
1664
                        brelse4(qbh);
1665
                        return 0;
1666
                }
1667
        return dnode;
1668
}
1669
 
1670
/* Map a sector into a buffer and return pointers to it and to the buffer. */
1671
 
1672
static void *map_sector(kdev_t dev, unsigned secno, struct buffer_head **bhp)
1673
{
1674
        struct buffer_head *bh;
1675
 
1676
        if ((*bhp = bh = bread(dev, secno, 512)) != 0)
1677
                return bh->b_data;
1678
        else {
1679
                printk("HPFS: map_sector: read error\n");
1680
                return 0;
1681
        }
1682
}
1683
 
1684
/* Map 4 sectors into a 4buffer and return pointers to it and to the buffer. */
1685
 
1686
static void *map_4sectors(kdev_t dev, unsigned secno,
1687
                          struct quad_buffer_head *qbh)
1688
{
1689
        struct buffer_head *bh;
1690
        char *data;
1691
 
1692
        if (secno & 3) {
1693
                printk("HPFS: map_4sectors: unaligned read\n");
1694
                return 0;
1695
        }
1696
 
1697
        qbh->data = data = kmalloc(2048, GFP_KERNEL);
1698
        if (!data)
1699
                goto bail;
1700
 
1701
        qbh->bh[0] = bh = breada(dev, secno, 512, 0, UINT_MAX);
1702
        if (!bh)
1703
                goto bail0;
1704
        memcpy(data, bh->b_data, 512);
1705
 
1706
        qbh->bh[1] = bh = bread(dev, secno + 1, 512);
1707
        if (!bh)
1708
                goto bail1;
1709
        memcpy(data + 512, bh->b_data, 512);
1710
 
1711
        qbh->bh[2] = bh = bread(dev, secno + 2, 512);
1712
        if (!bh)
1713
                goto bail2;
1714
        memcpy(data + 2 * 512, bh->b_data, 512);
1715
 
1716
        qbh->bh[3] = bh = bread(dev, secno + 3, 512);
1717
        if (!bh)
1718
                goto bail3;
1719
        memcpy(data + 3 * 512, bh->b_data, 512);
1720
 
1721
        return data;
1722
 
1723
 bail3:
1724
        brelse(qbh->bh[2]);
1725
 bail2:
1726
        brelse(qbh->bh[1]);
1727
 bail1:
1728
        brelse(qbh->bh[0]);
1729
 bail0:
1730
        kfree_s(data, 2048);
1731
 bail:
1732
        printk("HPFS: map_4sectors: read error\n");
1733
        return 0;
1734
}
1735
 
1736
/* Deallocate a 4-buffer block */
1737
 
1738
static void brelse4(struct quad_buffer_head *qbh)
1739
{
1740
        brelse(qbh->bh[3]);
1741
        brelse(qbh->bh[2]);
1742
        brelse(qbh->bh[1]);
1743
        brelse(qbh->bh[0]);
1744
        kfree_s(qbh->data, 2048);
1745
}
1746
 
1747
static struct file_system_type hpfs_fs_type = {
1748
        hpfs_read_super, "hpfs", 1, NULL
1749
};
1750
 
1751
int init_hpfs_fs(void)
1752
{
1753
        return register_filesystem(&hpfs_fs_type);
1754
}
1755
 
1756
#ifdef MODULE
1757
int init_module(void)
1758
{
1759
        int status;
1760
 
1761
        if ((status = init_hpfs_fs()) == 0)
1762
                register_symtab(0);
1763
        return status;
1764
}
1765
 
1766
void cleanup_module(void)
1767
{
1768
        unregister_filesystem(&hpfs_fs_type);
1769
}
1770
 
1771
#endif
1772
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.