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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [fs/] [minix/] [inode.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1628 jcastillo
/*
2
 *  linux/fs/minix/inode.c
3
 *
4
 *  Copyright (C) 1991, 1992  Linus Torvalds
5
 *
6
 *  Copyright (C) 1996  Gertjan van Wingerde    (gertjan@cs.vu.nl)
7
 *      Minix V2 fs support.
8
 */
9
 
10
#include <linux/module.h>
11
 
12
#include <linux/sched.h>
13
#include <linux/minix_fs.h>
14
#include <linux/kernel.h>
15
#include <linux/mm.h>
16
#include <linux/string.h>
17
#include <linux/stat.h>
18
#include <linux/locks.h>
19
 
20
#include <asm/system.h>
21
#include <asm/segment.h>
22
#include <asm/bitops.h>
23
 
24
void minix_put_inode(struct inode *inode)
25
{
26
        if (inode->i_nlink)
27
                return;
28
        inode->i_size = 0;
29
        minix_truncate(inode);
30
        minix_free_inode(inode);
31
}
32
 
33
static void minix_commit_super (struct super_block * sb,
34
                               struct minix_super_block * ms)
35
{
36
        mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1);
37
        sb->s_dirt = 0;
38
}
39
 
40
void minix_write_super (struct super_block * sb)
41
{
42
        struct minix_super_block * ms;
43
 
44
        if (!(sb->s_flags & MS_RDONLY)) {
45
                ms = sb->u.minix_sb.s_ms;
46
 
47
                if (ms->s_state & MINIX_VALID_FS)
48
                        ms->s_state &= ~MINIX_VALID_FS;
49
                minix_commit_super (sb, ms);
50
        }
51
        sb->s_dirt = 0;
52
}
53
 
54
 
55
void minix_put_super(struct super_block *sb)
56
{
57
        int i;
58
 
59
        lock_super(sb);
60
        if (!(sb->s_flags & MS_RDONLY)) {
61
                sb->u.minix_sb.s_ms->s_state = sb->u.minix_sb.s_mount_state;
62
                mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1);
63
        }
64
        sb->s_dev = 0;
65
        for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
66
                brelse(sb->u.minix_sb.s_imap[i]);
67
        for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
68
                brelse(sb->u.minix_sb.s_zmap[i]);
69
        brelse (sb->u.minix_sb.s_sbh);
70
        unlock_super(sb);
71
        MOD_DEC_USE_COUNT;
72
        return;
73
}
74
 
75
static struct super_operations minix_sops = {
76
        minix_read_inode,
77
        NULL,
78
        minix_write_inode,
79
        minix_put_inode,
80
        minix_put_super,
81
        minix_write_super,
82
        minix_statfs,
83
        minix_remount
84
};
85
 
86
int minix_remount (struct super_block * sb, int * flags, char * data)
87
{
88
        struct minix_super_block * ms;
89
 
90
        ms = sb->u.minix_sb.s_ms;
91
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
92
                return 0;
93
        if (*flags & MS_RDONLY) {
94
                if (ms->s_state & MINIX_VALID_FS ||
95
                    !(sb->u.minix_sb.s_mount_state & MINIX_VALID_FS))
96
                        return 0;
97
                /* Mounting a rw partition read-only. */
98
                ms->s_state = sb->u.minix_sb.s_mount_state;
99
                mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1);
100
                sb->s_dirt = 1;
101
                minix_commit_super (sb, ms);
102
        }
103
        else {
104
                /* Mount a partition which is read-only, read-write. */
105
                sb->u.minix_sb.s_mount_state = ms->s_state;
106
                ms->s_state &= ~MINIX_VALID_FS;
107
                mark_buffer_dirty(sb->u.minix_sb.s_sbh, 1);
108
                sb->s_dirt = 1;
109
 
110
                if (!(sb->u.minix_sb.s_mount_state & MINIX_VALID_FS))
111
                        printk ("MINIX-fs warning: remounting unchecked fs, "
112
                                "running fsck is recommended.\n");
113
                else if ((sb->u.minix_sb.s_mount_state & MINIX_ERROR_FS))
114
                        printk ("MINIX-fs warning: remounting fs with errors, "
115
                                "running fsck is recommended.\n");
116
        }
117
        return 0;
118
}
119
 
120
/*
121
 * Check the root directory of the filesystem to make sure
122
 * it really _is_ a minix filesystem, and to check the size
123
 * of the directory entry.
124
 */
125
static const char * minix_checkroot(struct super_block *s)
126
{
127
        struct inode * dir;
128
        struct buffer_head *bh;
129
        struct minix_dir_entry *de;
130
        const char * errmsg;
131
        int dirsize;
132
 
133
        dir = s->s_mounted;
134
        if (!S_ISDIR(dir->i_mode))
135
                return "root directory is not a directory";
136
 
137
        bh = minix_bread(dir, 0, 0);
138
        if (!bh)
139
                return "unable to read root directory";
140
 
141
        de = (struct minix_dir_entry *) bh->b_data;
142
        errmsg = "bad root directory '.' entry";
143
        dirsize = BLOCK_SIZE;
144
        if (de->inode == MINIX_ROOT_INO && strcmp(de->name, ".") == 0) {
145
                errmsg = "bad root directory '..' entry";
146
                dirsize = 8;
147
        }
148
 
149
        while ((dirsize <<= 1) < BLOCK_SIZE) {
150
                de = (struct minix_dir_entry *) (bh->b_data + dirsize);
151
                if (de->inode != MINIX_ROOT_INO)
152
                        continue;
153
                if (strcmp(de->name, ".."))
154
                        continue;
155
                s->u.minix_sb.s_dirsize = dirsize;
156
                s->u.minix_sb.s_namelen = dirsize - 2;
157
                errmsg = NULL;
158
                break;
159
        }
160
        brelse(bh);
161
        return errmsg;
162
}
163
 
164
struct super_block *minix_read_super(struct super_block *s,void *data,
165
                                     int silent)
166
{
167
        struct buffer_head *bh;
168
        struct minix_super_block *ms;
169
        int i, block;
170
        kdev_t dev = s->s_dev;
171
        const char * errmsg;
172
 
173
        if (32 != sizeof (struct minix_inode))
174
                panic("bad V1 i-node size");
175
        if (64 != sizeof(struct minix2_inode))
176
                panic("bad V2 i-node size");
177
        MOD_INC_USE_COUNT;
178
        lock_super(s);
179
        set_blocksize(dev, BLOCK_SIZE);
180
        if (!(bh = bread(dev,1,BLOCK_SIZE))) {
181
                s->s_dev = 0;
182
                unlock_super(s);
183
                printk("MINIX-fs: unable to read superblock\n");
184
                MOD_DEC_USE_COUNT;
185
                return NULL;
186
        }
187
        ms = (struct minix_super_block *) bh->b_data;
188
        s->u.minix_sb.s_ms = ms;
189
        s->u.minix_sb.s_sbh = bh;
190
        s->u.minix_sb.s_mount_state = ms->s_state;
191
        s->s_blocksize = 1024;
192
        s->s_blocksize_bits = 10;
193
        s->u.minix_sb.s_ninodes = ms->s_ninodes;
194
        s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
195
        s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
196
        s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
197
        s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
198
        s->u.minix_sb.s_max_size = ms->s_max_size;
199
        s->s_magic = ms->s_magic;
200
        if (s->s_magic == MINIX_SUPER_MAGIC) {
201
                s->u.minix_sb.s_version = MINIX_V1;
202
                s->u.minix_sb.s_nzones = ms->s_nzones;
203
                s->u.minix_sb.s_dirsize = 16;
204
                s->u.minix_sb.s_namelen = 14;
205
        } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
206
                s->u.minix_sb.s_version = MINIX_V1;
207
                s->u.minix_sb.s_nzones = ms->s_nzones;
208
                s->u.minix_sb.s_dirsize = 32;
209
                s->u.minix_sb.s_namelen = 30;
210
        } else if (s->s_magic == MINIX2_SUPER_MAGIC) {
211
                s->u.minix_sb.s_version = MINIX_V2;
212
                s->u.minix_sb.s_nzones = ms->s_zones;
213
                s->u.minix_sb.s_dirsize = 16;
214
                s->u.minix_sb.s_namelen = 14;
215
        } else if (s->s_magic == MINIX2_SUPER_MAGIC2) {
216
                s->u.minix_sb.s_version = MINIX_V2;
217
                s->u.minix_sb.s_nzones = ms->s_zones;
218
                s->u.minix_sb.s_dirsize = 32;
219
                s->u.minix_sb.s_namelen = 30;
220
        } else {
221
                s->s_dev = 0;
222
                unlock_super(s);
223
                brelse(bh);
224
                if (!silent)
225
                        printk("VFS: Can't find a minix or minix V2 filesystem on dev "
226
                               "%s.\n", kdevname(dev));
227
                MOD_DEC_USE_COUNT;
228
                return NULL;
229
        }
230
        for (i=0;i < MINIX_I_MAP_SLOTS;i++)
231
                s->u.minix_sb.s_imap[i] = NULL;
232
        for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
233
                s->u.minix_sb.s_zmap[i] = NULL;
234
        if (s->u.minix_sb.s_zmap_blocks > MINIX_Z_MAP_SLOTS) {
235
                s->s_dev = 0;
236
                unlock_super (s);
237
                brelse (bh);
238
                if (!silent)
239
                        printk ("MINIX-fs: filesystem too big\n");
240
                MOD_DEC_USE_COUNT;
241
                return NULL;
242
        }
243
        block=2;
244
        for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
245
                if ((s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
246
                        block++;
247
                else
248
                        break;
249
        for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
250
                if ((s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
251
                        block++;
252
                else
253
                        break;
254
        if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
255
                for(i=0;i<MINIX_I_MAP_SLOTS;i++)
256
                        brelse(s->u.minix_sb.s_imap[i]);
257
                for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
258
                        brelse(s->u.minix_sb.s_zmap[i]);
259
                s->s_dev = 0;
260
                unlock_super(s);
261
                brelse(bh);
262
                printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
263
                MOD_DEC_USE_COUNT;
264
                return NULL;
265
        }
266
        set_bit(0,s->u.minix_sb.s_imap[0]->b_data);
267
        set_bit(0,s->u.minix_sb.s_zmap[0]->b_data);
268
        unlock_super(s);
269
        /* set up enough so that it can read an inode */
270
        s->s_dev = dev;
271
        s->s_op = &minix_sops;
272
        s->s_mounted = iget(s,MINIX_ROOT_INO);
273
        if (!s->s_mounted) {
274
                s->s_dev = 0;
275
                brelse(bh);
276
                if (!silent)
277
                        printk("MINIX-fs: get root inode failed\n");
278
                MOD_DEC_USE_COUNT;
279
                return NULL;
280
        }
281
 
282
        errmsg = minix_checkroot(s);
283
        if (errmsg) {
284
                if (!silent)
285
                        printk("MINIX-fs: %s\n", errmsg);
286
                iput (s->s_mounted);
287
                s->s_dev = 0;
288
                brelse (bh);
289
                MOD_DEC_USE_COUNT;
290
                return NULL;
291
        }
292
 
293
        if (!(s->s_flags & MS_RDONLY)) {
294
                ms->s_state &= ~MINIX_VALID_FS;
295
                mark_buffer_dirty(bh, 1);
296
                s->s_dirt = 1;
297
        }
298
        if (!(s->u.minix_sb.s_mount_state & MINIX_VALID_FS))
299
                printk ("MINIX-fs: mounting unchecked file system, "
300
                        "running fsck is recommended.\n");
301
        else if (s->u.minix_sb.s_mount_state & MINIX_ERROR_FS)
302
                printk ("MINIX-fs: mounting file system with errors, "
303
                        "running fsck is recommended.\n");
304
        return s;
305
}
306
 
307
void minix_statfs(struct super_block *sb, struct statfs *buf, int bufsiz)
308
{
309
        struct statfs tmp;
310
 
311
        tmp.f_type = sb->s_magic;
312
        tmp.f_bsize = sb->s_blocksize;
313
        tmp.f_blocks = (sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone) << sb->u.minix_sb.s_log_zone_size;
314
        tmp.f_bfree = minix_count_free_blocks(sb);
315
        tmp.f_bavail = tmp.f_bfree;
316
        tmp.f_files = sb->u.minix_sb.s_ninodes;
317
        tmp.f_ffree = minix_count_free_inodes(sb);
318
        tmp.f_namelen = sb->u.minix_sb.s_namelen;
319
        memcpy_tofs(buf, &tmp, bufsiz);
320
}
321
 
322
/*
323
 * The minix V1 fs bmap functions.
324
 */
325
#define V1_inode_bmap(inode,nr) (((unsigned short *)(inode)->u.minix_i.u.i1_data)[(nr)])
326
 
327
static int V1_block_bmap(struct buffer_head * bh, int nr)
328
{
329
        int tmp;
330
 
331
        if (!bh)
332
                return 0;
333
        tmp = ((unsigned short *) bh->b_data)[nr];
334
        brelse(bh);
335
        return tmp;
336
}
337
 
338
static int V1_minix_bmap(struct inode * inode,int block)
339
{
340
        int i;
341
 
342
        if (block<0) {
343
                printk("minix_bmap: block<0");
344
                return 0;
345
        }
346
        if (block >= (inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)) {
347
                printk("minix_bmap: block>big");
348
                return 0;
349
        }
350
        if (block < 7)
351
                return V1_inode_bmap(inode,block);
352
        block -= 7;
353
        if (block < 512) {
354
                i = V1_inode_bmap(inode,7);
355
                if (!i)
356
                        return 0;
357
                return V1_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
358
        }
359
        block -= 512;
360
        i = V1_inode_bmap(inode,8);
361
        if (!i)
362
                return 0;
363
        i = V1_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
364
        if (!i)
365
                return 0;
366
        return V1_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
367
}
368
 
369
/*
370
 * The minix V2 fs bmap functions.
371
 */
372
#define V2_inode_bmap(inode,nr) (((unsigned long  *)(inode)->u.minix_i.u.i2_data)[(nr)])
373
static int V2_block_bmap(struct buffer_head * bh, int nr)
374
{
375
        int tmp;
376
 
377
        if (!bh)
378
                return 0;
379
        tmp = ((unsigned long *) bh->b_data)[nr];
380
        brelse(bh);
381
        return tmp;
382
}
383
 
384
static int V2_minix_bmap(struct inode * inode,int block)
385
{
386
        int i;
387
 
388
        if (block<0) {
389
                printk("minix_bmap: block<0");
390
                return 0;
391
        }
392
        if (block >= (inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE)) {
393
                printk("minix_bmap: block>big");
394
                return 0;
395
        }
396
        if (block < 7)
397
                return V2_inode_bmap(inode,block);
398
        block -= 7;
399
        if (block < 256) {
400
                i = V2_inode_bmap(inode,7);
401
                if (!i)
402
                        return 0;
403
                return V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
404
        }
405
        block -= 256;
406
        if (block < 256*256) {
407
                i = V2_inode_bmap(inode,8);
408
                if (!i)
409
                        return 0;
410
                i = V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block >> 8);
411
                if (!i)
412
                        return 0;
413
                return V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
414
        }
415
        block -= 256*256;
416
        i = V2_inode_bmap(inode,9);
417
        if (!i)
418
                return 0;
419
        i = V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block >> 16);
420
        if (!i)
421
                return 0;
422
        i = V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block >> 8) & 255);
423
        if (!i)
424
                return 0;
425
        return V2_block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
426
}
427
 
428
/*
429
 * The global minix fs bmap function.
430
 */
431
int minix_bmap(struct inode * inode,int block)
432
{
433
        if (INODE_VERSION(inode) == MINIX_V1)
434
                return V1_minix_bmap(inode, block);
435
        else
436
                return V2_minix_bmap(inode, block);
437
}
438
 
439
/*
440
 * The minix V1 fs getblk functions.
441
 */
442
static struct buffer_head * V1_inode_getblk(struct inode * inode, int nr,
443
                                            int create)
444
{
445
        int tmp;
446
        unsigned short *p;
447
        struct buffer_head * result;
448
 
449
        p = inode->u.minix_i.u.i1_data + nr;
450
repeat:
451
        tmp = *p;
452
        if (tmp) {
453
                result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
454
                if (tmp == *p)
455
                        return result;
456
                brelse(result);
457
                goto repeat;
458
        }
459
        if (!create)
460
                return NULL;
461
        tmp = minix_new_block(inode->i_sb);
462
        if (!tmp)
463
                return NULL;
464
        result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
465
        if (*p) {
466
                minix_free_block(inode->i_sb,tmp);
467
                brelse(result);
468
                goto repeat;
469
        }
470
        *p = tmp;
471
        inode->i_ctime = CURRENT_TIME;
472
        inode->i_dirt = 1;
473
        return result;
474
}
475
 
476
static struct buffer_head * V1_block_getblk(struct inode * inode,
477
        struct buffer_head * bh, int nr, int create)
478
{
479
        int tmp;
480
        unsigned short *p;
481
        struct buffer_head * result;
482
 
483
        if (!bh)
484
                return NULL;
485
        if (!buffer_uptodate(bh)) {
486
                ll_rw_block(READ, 1, &bh);
487
                wait_on_buffer(bh);
488
                if (!buffer_uptodate(bh)) {
489
                        brelse(bh);
490
                        return NULL;
491
                }
492
        }
493
        p = nr + (unsigned short *) bh->b_data;
494
repeat:
495
        tmp = *p;
496
        if (tmp) {
497
                result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
498
                if (tmp == *p) {
499
                        brelse(bh);
500
                        return result;
501
                }
502
                brelse(result);
503
                goto repeat;
504
        }
505
        if (!create) {
506
                brelse(bh);
507
                return NULL;
508
        }
509
        tmp = minix_new_block(inode->i_sb);
510
        if (!tmp) {
511
                brelse(bh);
512
                return NULL;
513
        }
514
        result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
515
        if (*p) {
516
                minix_free_block(inode->i_sb,tmp);
517
                brelse(result);
518
                goto repeat;
519
        }
520
        *p = tmp;
521
        mark_buffer_dirty(bh, 1);
522
        brelse(bh);
523
        return result;
524
}
525
 
526
static struct buffer_head * V1_minix_getblk(struct inode * inode, int block,
527
                                            int create)
528
{
529
        struct buffer_head * bh;
530
 
531
        if (block<0) {
532
                printk("minix_getblk: block<0");
533
                return NULL;
534
        }
535
        if (block >= inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE) {
536
                printk("minix_getblk: block>big");
537
                return NULL;
538
        }
539
        if (block < 7)
540
                return V1_inode_getblk(inode,block,create);
541
        block -= 7;
542
        if (block < 512) {
543
                bh = V1_inode_getblk(inode,7,create);
544
                return V1_block_getblk(inode, bh, block, create);
545
        }
546
        block -= 512;
547
        bh = V1_inode_getblk(inode,8,create);
548
        bh = V1_block_getblk(inode, bh, (block>>9) & 511, create);
549
        return V1_block_getblk(inode, bh, block & 511, create);
550
}
551
 
552
/*
553
 * The minix V2 fs getblk functions.
554
 */
555
static struct buffer_head * V2_inode_getblk(struct inode * inode, int nr,
556
                                            int create)
557
{
558
        int tmp;
559
        unsigned long *p;
560
        struct buffer_head * result;
561
 
562
        p = (unsigned long *) inode->u.minix_i.u.i2_data + nr;
563
repeat:
564
        tmp = *p;
565
        if (tmp) {
566
                result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
567
                if (tmp == *p)
568
                        return result;
569
                brelse(result);
570
                goto repeat;
571
        }
572
        if (!create)
573
                return NULL;
574
        tmp = minix_new_block(inode->i_sb);
575
        if (!tmp)
576
                return NULL;
577
        result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
578
        if (*p) {
579
                minix_free_block(inode->i_sb,tmp);
580
                brelse(result);
581
                goto repeat;
582
        }
583
        *p = tmp;
584
        inode->i_ctime = CURRENT_TIME;
585
        inode->i_dirt = 1;
586
        return result;
587
}
588
 
589
static struct buffer_head * V2_block_getblk(struct inode * inode,
590
        struct buffer_head * bh, int nr, int create)
591
{
592
        int tmp;
593
        unsigned long *p;
594
        struct buffer_head * result;
595
 
596
        if (!bh)
597
                return NULL;
598
        if (!buffer_uptodate(bh)) {
599
                ll_rw_block(READ, 1, &bh);
600
                wait_on_buffer(bh);
601
                if (!buffer_uptodate(bh)) {
602
                        brelse(bh);
603
                        return NULL;
604
                }
605
        }
606
        p = nr + (unsigned long *) bh->b_data;
607
repeat:
608
        tmp = *p;
609
        if (tmp) {
610
                result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
611
                if (tmp == *p) {
612
                        brelse(bh);
613
                        return result;
614
                }
615
                brelse(result);
616
                goto repeat;
617
        }
618
        if (!create) {
619
                brelse(bh);
620
                return NULL;
621
        }
622
        tmp = minix_new_block(inode->i_sb);
623
        if (!tmp) {
624
                brelse(bh);
625
                return NULL;
626
        }
627
        result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
628
        if (*p) {
629
                minix_free_block(inode->i_sb,tmp);
630
                brelse(result);
631
                goto repeat;
632
        }
633
        *p = tmp;
634
        mark_buffer_dirty(bh, 1);
635
        brelse(bh);
636
        return result;
637
}
638
 
639
static struct buffer_head * V2_minix_getblk(struct inode * inode, int block,
640
                                            int create)
641
{
642
        struct buffer_head * bh;
643
 
644
        if (block<0) {
645
                printk("minix_getblk: block<0");
646
                return NULL;
647
        }
648
        if (block >= inode->i_sb->u.minix_sb.s_max_size/BLOCK_SIZE) {
649
                printk("minix_getblk: block>big");
650
                return NULL;
651
        }
652
        if (block < 7)
653
                return V2_inode_getblk(inode,block,create);
654
        block -= 7;
655
        if (block < 256) {
656
                bh = V2_inode_getblk(inode,7,create);
657
                return V2_block_getblk(inode, bh, block, create);
658
        }
659
        block -= 256;
660
        if (block < 256*256) {
661
                bh = V2_inode_getblk(inode,8,create);
662
                bh = V2_block_getblk(inode, bh, (block>>8) & 255, create);
663
                return V2_block_getblk(inode, bh, block & 255, create);
664
        }
665
        block -= 256*256;
666
        bh = V2_inode_getblk(inode,9,create);
667
        bh = V2_block_getblk(inode, bh, (block >> 16) & 255, create);
668
        bh = V2_block_getblk(inode, bh, (block >> 8) & 255, create);
669
        return V2_block_getblk(inode, bh, block & 255, create);
670
}
671
 
672
/*
673
 * the global minix fs getblk function.
674
 */
675
struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
676
{
677
        if (INODE_VERSION(inode) == MINIX_V1)
678
                return V1_minix_getblk(inode,block,create);
679
        else
680
                return V2_minix_getblk(inode,block,create);
681
}
682
 
683
struct buffer_head * minix_bread(struct inode * inode, int block, int create)
684
{
685
        struct buffer_head * bh;
686
 
687
        bh = minix_getblk(inode,block,create);
688
        if (!bh || buffer_uptodate(bh))
689
                return bh;
690
        ll_rw_block(READ, 1, &bh);
691
        wait_on_buffer(bh);
692
        if (buffer_uptodate(bh))
693
                return bh;
694
        brelse(bh);
695
        return NULL;
696
}
697
 
698
/*
699
 * The minix V1 function to read an inode.
700
 */
701
static void V1_minix_read_inode(struct inode * inode)
702
{
703
        struct buffer_head * bh;
704
        struct minix_inode * raw_inode;
705
        int block, ino;
706
 
707
        ino = inode->i_ino;
708
        inode->i_op = NULL;
709
        inode->i_mode = 0;
710
        if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
711
                printk("Bad inode number on dev %s"
712
                       ": %d is out of range\n",
713
                        kdevname(inode->i_dev), ino);
714
                return;
715
        }
716
        block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
717
                    inode->i_sb->u.minix_sb.s_zmap_blocks +
718
                    (ino-1)/MINIX_INODES_PER_BLOCK;
719
        if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
720
                printk("Major problem: unable to read inode from dev "
721
                       "%s\n", kdevname(inode->i_dev));
722
                return;
723
        }
724
        raw_inode = ((struct minix_inode *) bh->b_data) +
725
                    (ino-1)%MINIX_INODES_PER_BLOCK;
726
        inode->i_mode = raw_inode->i_mode;
727
        inode->i_uid = raw_inode->i_uid;
728
        inode->i_gid = raw_inode->i_gid;
729
        inode->i_nlink = raw_inode->i_nlinks;
730
        inode->i_size = raw_inode->i_size;
731
        inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
732
        inode->i_blocks = inode->i_blksize = 0;
733
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
734
                inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]);
735
        else for (block = 0; block < 9; block++)
736
                inode->u.minix_i.u.i1_data[block] = raw_inode->i_zone[block];
737
        brelse(bh);
738
        if (S_ISREG(inode->i_mode))
739
                inode->i_op = &minix_file_inode_operations;
740
        else if (S_ISDIR(inode->i_mode))
741
                inode->i_op = &minix_dir_inode_operations;
742
        else if (S_ISLNK(inode->i_mode))
743
                inode->i_op = &minix_symlink_inode_operations;
744
        else if (S_ISCHR(inode->i_mode))
745
                inode->i_op = &chrdev_inode_operations;
746
        else if (S_ISBLK(inode->i_mode))
747
                inode->i_op = &blkdev_inode_operations;
748
        else if (S_ISFIFO(inode->i_mode))
749
                init_fifo(inode);
750
}
751
 
752
/*
753
 * The minix V2 function to read an inode.
754
 */
755
static void V2_minix_read_inode(struct inode * inode)
756
{
757
        struct buffer_head * bh;
758
        struct minix2_inode * raw_inode;
759
        int block, ino;
760
 
761
        ino = inode->i_ino;
762
        inode->i_op = NULL;
763
        inode->i_mode = 0;
764
        if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
765
                printk("Bad inode number on dev %s"
766
                       ": %d is out of range\n",
767
                        kdevname(inode->i_dev), ino);
768
                return;
769
        }
770
        block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
771
                    inode->i_sb->u.minix_sb.s_zmap_blocks +
772
                    (ino-1)/MINIX2_INODES_PER_BLOCK;
773
        if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
774
                printk("Major problem: unable to read inode from dev "
775
                       "%s\n", kdevname(inode->i_dev));
776
                return;
777
        }
778
        raw_inode = ((struct minix2_inode *) bh->b_data) +
779
                    (ino-1)%MINIX2_INODES_PER_BLOCK;
780
        inode->i_mode = raw_inode->i_mode;
781
        inode->i_uid = raw_inode->i_uid;
782
        inode->i_gid = raw_inode->i_gid;
783
        inode->i_nlink = raw_inode->i_nlinks;
784
        inode->i_size = raw_inode->i_size;
785
        inode->i_mtime = raw_inode->i_mtime;
786
        inode->i_atime = raw_inode->i_atime;
787
        inode->i_ctime = raw_inode->i_ctime;
788
        inode->i_blocks = inode->i_blksize = 0;
789
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
790
                inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]);
791
        else for (block = 0; block < 10; block++)
792
                inode->u.minix_i.u.i2_data[block] = raw_inode->i_zone[block];
793
        brelse(bh);
794
        if (S_ISREG(inode->i_mode))
795
                inode->i_op = &minix_file_inode_operations;
796
        else if (S_ISDIR(inode->i_mode))
797
                inode->i_op = &minix_dir_inode_operations;
798
        else if (S_ISLNK(inode->i_mode))
799
                inode->i_op = &minix_symlink_inode_operations;
800
        else if (S_ISCHR(inode->i_mode))
801
                inode->i_op = &chrdev_inode_operations;
802
        else if (S_ISBLK(inode->i_mode))
803
                inode->i_op = &blkdev_inode_operations;
804
        else if (S_ISFIFO(inode->i_mode))
805
                init_fifo(inode);
806
}
807
 
808
/*
809
 * The global function to read an inode.
810
 */
811
void minix_read_inode(struct inode * inode)
812
{
813
        if (INODE_VERSION(inode) == MINIX_V1)
814
                V1_minix_read_inode(inode);
815
        else
816
                V2_minix_read_inode(inode);
817
}
818
 
819
/*
820
 * The minix V1 function to synchronize an inode.
821
 */
822
static struct buffer_head * V1_minix_update_inode(struct inode * inode)
823
{
824
        struct buffer_head * bh;
825
        struct minix_inode * raw_inode;
826
        int ino, block;
827
 
828
        ino = inode->i_ino;
829
        if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
830
                printk("Bad inode number on dev %s"
831
                       ": %d is out of range\n",
832
                        kdevname(inode->i_dev), ino);
833
                inode->i_dirt = 0;
834
                return 0;
835
        }
836
        block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
837
                (ino-1)/MINIX_INODES_PER_BLOCK;
838
        if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
839
                printk("unable to read i-node block\n");
840
                inode->i_dirt = 0;
841
                return 0;
842
        }
843
        raw_inode = ((struct minix_inode *)bh->b_data) +
844
                (ino-1)%MINIX_INODES_PER_BLOCK;
845
        raw_inode->i_mode = inode->i_mode;
846
        raw_inode->i_uid = inode->i_uid;
847
        raw_inode->i_gid = inode->i_gid;
848
        raw_inode->i_nlinks = inode->i_nlink;
849
        raw_inode->i_size = inode->i_size;
850
        raw_inode->i_time = inode->i_mtime;
851
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
852
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
853
        else for (block = 0; block < 9; block++)
854
                raw_inode->i_zone[block] = inode->u.minix_i.u.i1_data[block];
855
        inode->i_dirt=0;
856
        mark_buffer_dirty(bh, 1);
857
        return bh;
858
}
859
 
860
/*
861
 * The minix V2 function to synchronize an inode.
862
 */
863
static struct buffer_head * V2_minix_update_inode(struct inode * inode)
864
{
865
        struct buffer_head * bh;
866
        struct minix2_inode * raw_inode;
867
        int ino, block;
868
 
869
        ino = inode->i_ino;
870
        if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
871
                printk("Bad inode number on dev %s"
872
                       ": %d is out of range\n",
873
                        kdevname(inode->i_dev), ino);
874
                inode->i_dirt = 0;
875
                return 0;
876
        }
877
        block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
878
                (ino-1)/MINIX2_INODES_PER_BLOCK;
879
        if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
880
                printk("unable to read i-node block\n");
881
                inode->i_dirt = 0;
882
                return 0;
883
        }
884
        raw_inode = ((struct minix2_inode *)bh->b_data) +
885
                (ino-1)%MINIX2_INODES_PER_BLOCK;
886
        raw_inode->i_mode = inode->i_mode;
887
        raw_inode->i_uid = inode->i_uid;
888
        raw_inode->i_gid = inode->i_gid;
889
        raw_inode->i_nlinks = inode->i_nlink;
890
        raw_inode->i_size = inode->i_size;
891
        raw_inode->i_mtime = inode->i_mtime;
892
        raw_inode->i_atime = inode->i_atime;
893
        raw_inode->i_ctime = inode->i_ctime;
894
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
895
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
896
        else for (block = 0; block < 10; block++)
897
                raw_inode->i_zone[block] = inode->u.minix_i.u.i2_data[block];
898
        inode->i_dirt=0;
899
        mark_buffer_dirty(bh, 1);
900
        return bh;
901
}
902
 
903
struct buffer_head *minix_update_inode(struct inode *inode)
904
{
905
        if (INODE_VERSION(inode) == MINIX_V1)
906
                return V1_minix_update_inode(inode);
907
        else
908
                return V2_minix_update_inode(inode);
909
}
910
 
911
void minix_write_inode(struct inode * inode)
912
{
913
        struct buffer_head *bh;
914
 
915
        bh = minix_update_inode(inode);
916
        brelse(bh);
917
}
918
 
919
int minix_sync_inode(struct inode * inode)
920
{
921
        int err = 0;
922
        struct buffer_head *bh;
923
 
924
        bh = minix_update_inode(inode);
925
        if (bh && buffer_dirty(bh))
926
        {
927
                ll_rw_block(WRITE, 1, &bh);
928
                wait_on_buffer(bh);
929
                if (buffer_req(bh) && !buffer_uptodate(bh))
930
                {
931
                        printk ("IO error syncing minix inode ["
932
                                "%s:%08lx]\n",
933
                                kdevname(inode->i_dev), inode->i_ino);
934
                        err = -1;
935
                }
936
        }
937
        else if (!bh)
938
                err = -1;
939
        brelse (bh);
940
        return err;
941
}
942
 
943
static struct file_system_type minix_fs_type = {
944
        minix_read_super, "minix", 1, NULL
945
};
946
 
947
int init_minix_fs(void)
948
{
949
        return register_filesystem(&minix_fs_type);
950
}
951
 
952
#ifdef MODULE
953
int init_module(void)
954
{
955
        int status;
956
 
957
        if ((status = init_minix_fs()) == 0)
958
                register_symtab(0);
959
        return status;
960
}
961
 
962
void cleanup_module(void)
963
{
964
        unregister_filesystem(&minix_fs_type);
965
}
966
 
967
#endif

powered by: WebSVN 2.1.0

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