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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [minix/] [inode.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 *  Modified for 680x0 by Andreas Schwab
10
 */
11
 
12
#include <linux/module.h>
13
 
14
#include <linux/fs.h>
15
#include <linux/minix_fs.h>
16
#include <linux/slab.h>
17
#include <linux/locks.h>
18
#include <linux/init.h>
19
#include <linux/smp_lock.h>
20
#include <linux/highuid.h>
21
#include <linux/blkdev.h>
22
 
23
static void minix_read_inode(struct inode * inode);
24
static void minix_write_inode(struct inode * inode, int wait);
25
static int minix_statfs(struct super_block *sb, struct statfs *buf);
26
static int minix_remount (struct super_block * sb, int * flags, char * data);
27
 
28
static void minix_delete_inode(struct inode *inode)
29
{
30
        lock_kernel();
31
 
32
        inode->i_size = 0;
33
        minix_truncate(inode);
34
        minix_free_inode(inode);
35
 
36
        unlock_kernel();
37
}
38
 
39
static void minix_commit_super(struct super_block * sb)
40
{
41
        mark_buffer_dirty(sb->u.minix_sb.s_sbh);
42
        sb->s_dirt = 0;
43
}
44
 
45
static void minix_write_super(struct super_block * sb)
46
{
47
        struct minix_super_block * ms;
48
 
49
        if (!(sb->s_flags & MS_RDONLY)) {
50
                ms = sb->u.minix_sb.s_ms;
51
 
52
                if (ms->s_state & MINIX_VALID_FS)
53
                        ms->s_state &= ~MINIX_VALID_FS;
54
                minix_commit_super(sb);
55
        }
56
        sb->s_dirt = 0;
57
}
58
 
59
 
60
static void minix_put_super(struct super_block *sb)
61
{
62
        int i;
63
 
64
        if (!(sb->s_flags & MS_RDONLY)) {
65
                sb->u.minix_sb.s_ms->s_state = sb->u.minix_sb.s_mount_state;
66
                mark_buffer_dirty(sb->u.minix_sb.s_sbh);
67
        }
68
        for (i = 0; i < sb->u.minix_sb.s_imap_blocks; i++)
69
                brelse(sb->u.minix_sb.s_imap[i]);
70
        for (i = 0; i < sb->u.minix_sb.s_zmap_blocks; i++)
71
                brelse(sb->u.minix_sb.s_zmap[i]);
72
        brelse (sb->u.minix_sb.s_sbh);
73
        kfree(sb->u.minix_sb.s_imap);
74
 
75
        return;
76
}
77
 
78
static struct super_operations minix_sops = {
79
        read_inode:     minix_read_inode,
80
        write_inode:    minix_write_inode,
81
        delete_inode:   minix_delete_inode,
82
        put_super:      minix_put_super,
83
        write_super:    minix_write_super,
84
        statfs:         minix_statfs,
85
        remount_fs:     minix_remount,
86
};
87
 
88
static int minix_remount (struct super_block * sb, int * flags, char * data)
89
{
90
        struct minix_super_block * ms;
91
 
92
        ms = sb->u.minix_sb.s_ms;
93
        if ((*flags & MS_RDONLY) == (sb->s_flags & MS_RDONLY))
94
                return 0;
95
        if (*flags & MS_RDONLY) {
96
                if (ms->s_state & MINIX_VALID_FS ||
97
                    !(sb->u.minix_sb.s_mount_state & MINIX_VALID_FS))
98
                        return 0;
99
                /* Mounting a rw partition read-only. */
100
                ms->s_state = sb->u.minix_sb.s_mount_state;
101
                mark_buffer_dirty(sb->u.minix_sb.s_sbh);
102
                sb->s_dirt = 1;
103
                minix_commit_super(sb);
104
        }
105
        else {
106
                /* Mount a partition which is read-only, read-write. */
107
                sb->u.minix_sb.s_mount_state = ms->s_state;
108
                ms->s_state &= ~MINIX_VALID_FS;
109
                mark_buffer_dirty(sb->u.minix_sb.s_sbh);
110
                sb->s_dirt = 1;
111
 
112
                if (!(sb->u.minix_sb.s_mount_state & MINIX_VALID_FS))
113
                        printk ("MINIX-fs warning: remounting unchecked fs, "
114
                                "running fsck is recommended.\n");
115
                else if ((sb->u.minix_sb.s_mount_state & MINIX_ERROR_FS))
116
                        printk ("MINIX-fs warning: remounting fs with errors, "
117
                                "running fsck is recommended.\n");
118
        }
119
        return 0;
120
}
121
 
122
static struct super_block *minix_read_super(struct super_block *s, void *data,
123
                                     int silent)
124
{
125
        struct buffer_head *bh;
126
        struct buffer_head **map;
127
        struct minix_super_block *ms;
128
        int i, block;
129
        kdev_t dev = s->s_dev;
130
        struct inode *root_inode;
131
        unsigned int hblock;
132
        struct minix_sb_info *sbi = &s->u.minix_sb;
133
 
134
        /* N.B. These should be compile-time tests.
135
           Unfortunately that is impossible. */
136
        if (32 != sizeof (struct minix_inode))
137
                panic("bad V1 i-node size");
138
        if (64 != sizeof(struct minix2_inode))
139
                panic("bad V2 i-node size");
140
 
141
        hblock = get_hardsect_size(dev);
142
        if (hblock > BLOCK_SIZE)
143
                goto out_bad_hblock;
144
 
145
        set_blocksize(dev, BLOCK_SIZE);
146
        s->s_blocksize = BLOCK_SIZE;
147
        s->s_blocksize_bits = BLOCK_SIZE_BITS;
148
        if (!(bh = sb_bread(s, 1)))
149
                goto out_bad_sb;
150
 
151
        ms = (struct minix_super_block *) bh->b_data;
152
        sbi->s_ms = ms;
153
        sbi->s_sbh = bh;
154
        sbi->s_mount_state = ms->s_state;
155
        sbi->s_ninodes = ms->s_ninodes;
156
        sbi->s_nzones = ms->s_nzones;
157
        sbi->s_imap_blocks = ms->s_imap_blocks;
158
        sbi->s_zmap_blocks = ms->s_zmap_blocks;
159
        sbi->s_firstdatazone = ms->s_firstdatazone;
160
        sbi->s_log_zone_size = ms->s_log_zone_size;
161
        sbi->s_max_size = ms->s_max_size;
162
        s->s_magic = ms->s_magic;
163
        if (s->s_magic == MINIX_SUPER_MAGIC) {
164
                sbi->s_version = MINIX_V1;
165
                sbi->s_dirsize = 16;
166
                sbi->s_namelen = 14;
167
                sbi->s_link_max = MINIX_LINK_MAX;
168
        } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
169
                sbi->s_version = MINIX_V1;
170
                sbi->s_dirsize = 32;
171
                sbi->s_namelen = 30;
172
                sbi->s_link_max = MINIX_LINK_MAX;
173
        } else if (s->s_magic == MINIX2_SUPER_MAGIC) {
174
                sbi->s_version = MINIX_V2;
175
                sbi->s_nzones = ms->s_zones;
176
                sbi->s_dirsize = 16;
177
                sbi->s_namelen = 14;
178
                sbi->s_link_max = MINIX2_LINK_MAX;
179
        } else if (s->s_magic == MINIX2_SUPER_MAGIC2) {
180
                sbi->s_version = MINIX_V2;
181
                sbi->s_nzones = ms->s_zones;
182
                sbi->s_dirsize = 32;
183
                sbi->s_namelen = 30;
184
                sbi->s_link_max = MINIX2_LINK_MAX;
185
        } else
186
                goto out_no_fs;
187
 
188
        /*
189
         * Allocate the buffer map to keep the superblock small.
190
         */
191
        i = (sbi->s_imap_blocks + sbi->s_zmap_blocks) * sizeof(bh);
192
        map = kmalloc(i, GFP_KERNEL);
193
        if (!map)
194
                goto out_no_map;
195
        memset(map, 0, i);
196
        sbi->s_imap = &map[0];
197
        sbi->s_zmap = &map[sbi->s_imap_blocks];
198
 
199
        block=2;
200
        for (i=0 ; i < sbi->s_imap_blocks ; i++) {
201
                if (!(sbi->s_imap[i]=sb_bread(s, block)))
202
                        goto out_no_bitmap;
203
                block++;
204
        }
205
        for (i=0 ; i < sbi->s_zmap_blocks ; i++) {
206
                if (!(sbi->s_zmap[i]=sb_bread(s, block)))
207
                        goto out_no_bitmap;
208
                block++;
209
        }
210
 
211
        minix_set_bit(0,sbi->s_imap[0]->b_data);
212
        minix_set_bit(0,sbi->s_zmap[0]->b_data);
213
 
214
        /* set up enough so that it can read an inode */
215
        s->s_op = &minix_sops;
216
        root_inode = iget(s, MINIX_ROOT_INO);
217
        if (!root_inode || is_bad_inode(root_inode))
218
                goto out_no_root;
219
 
220
        s->s_root = d_alloc_root(root_inode);
221
        if (!s->s_root)
222
                goto out_iput;
223
 
224
        if (!NO_TRUNCATE)
225
                s->s_root->d_op = &minix_dentry_operations;
226
 
227
        if (!(s->s_flags & MS_RDONLY)) {
228
                ms->s_state &= ~MINIX_VALID_FS;
229
                mark_buffer_dirty(bh);
230
                s->s_dirt = 1;
231
        }
232
        if (!(sbi->s_mount_state & MINIX_VALID_FS))
233
                printk ("MINIX-fs: mounting unchecked file system, "
234
                        "running fsck is recommended.\n");
235
        else if (sbi->s_mount_state & MINIX_ERROR_FS)
236
                printk ("MINIX-fs: mounting file system with errors, "
237
                        "running fsck is recommended.\n");
238
        return s;
239
 
240
out_iput:
241
        iput(root_inode);
242
        goto out_freemap;
243
 
244
out_no_root:
245
        if (!silent)
246
                printk("MINIX-fs: get root inode failed\n");
247
        goto out_freemap;
248
 
249
out_no_bitmap:
250
        printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
251
    out_freemap:
252
        for (i = 0; i < sbi->s_imap_blocks; i++)
253
                brelse(sbi->s_imap[i]);
254
        for (i = 0; i < sbi->s_zmap_blocks; i++)
255
                brelse(sbi->s_zmap[i]);
256
        kfree(sbi->s_imap);
257
        goto out_release;
258
 
259
out_no_map:
260
        if (!silent)
261
                printk ("MINIX-fs: can't allocate map\n");
262
        goto out_release;
263
 
264
out_no_fs:
265
        if (!silent)
266
                printk("VFS: Can't find a Minix or Minix V2 filesystem on device "
267
                       "%s.\n", kdevname(dev));
268
    out_release:
269
        brelse(bh);
270
        goto out;
271
 
272
out_bad_hblock:
273
        printk("MINIX-fs: blocksize too small for device.\n");
274
        goto out;
275
 
276
out_bad_sb:
277
        printk("MINIX-fs: unable to read superblock\n");
278
 out:
279
        return NULL;
280
}
281
 
282
static int minix_statfs(struct super_block *sb, struct statfs *buf)
283
{
284
        buf->f_type = sb->s_magic;
285
        buf->f_bsize = sb->s_blocksize;
286
        buf->f_blocks = (sb->u.minix_sb.s_nzones - sb->u.minix_sb.s_firstdatazone) << sb->u.minix_sb.s_log_zone_size;
287
        buf->f_bfree = minix_count_free_blocks(sb);
288
        buf->f_bavail = buf->f_bfree;
289
        buf->f_files = sb->u.minix_sb.s_ninodes;
290
        buf->f_ffree = minix_count_free_inodes(sb);
291
        buf->f_namelen = sb->u.minix_sb.s_namelen;
292
        return 0;
293
}
294
 
295
static int minix_get_block(struct inode *inode, long block,
296
                    struct buffer_head *bh_result, int create)
297
{
298
        if (INODE_VERSION(inode) == MINIX_V1)
299
                return V1_minix_get_block(inode, block, bh_result, create);
300
        else
301
                return V2_minix_get_block(inode, block, bh_result, create);
302
}
303
 
304
static int minix_writepage(struct page *page)
305
{
306
        return block_write_full_page(page,minix_get_block);
307
}
308
static int minix_readpage(struct file *file, struct page *page)
309
{
310
        return block_read_full_page(page,minix_get_block);
311
}
312
static int minix_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to)
313
{
314
        return block_prepare_write(page,from,to,minix_get_block);
315
}
316
static int minix_bmap(struct address_space *mapping, long block)
317
{
318
        return generic_block_bmap(mapping,block,minix_get_block);
319
}
320
static struct address_space_operations minix_aops = {
321
        readpage: minix_readpage,
322
        writepage: minix_writepage,
323
        sync_page: block_sync_page,
324
        prepare_write: minix_prepare_write,
325
        commit_write: generic_commit_write,
326
        bmap: minix_bmap
327
};
328
 
329
void minix_set_inode(struct inode *inode, dev_t rdev)
330
{
331
        if (S_ISREG(inode->i_mode)) {
332
                inode->i_op = &minix_file_inode_operations;
333
                inode->i_fop = &minix_file_operations;
334
                inode->i_mapping->a_ops = &minix_aops;
335
        } else if (S_ISDIR(inode->i_mode)) {
336
                inode->i_op = &minix_dir_inode_operations;
337
                inode->i_fop = &minix_dir_operations;
338
                inode->i_mapping->a_ops = &minix_aops;
339
        } else if (S_ISLNK(inode->i_mode)) {
340
                inode->i_op = &page_symlink_inode_operations;
341
                inode->i_mapping->a_ops = &minix_aops;
342
        } else
343
                init_special_inode(inode, inode->i_mode, rdev);
344
}
345
 
346
/*
347
 * The minix V1 function to read an inode.
348
 */
349
static void V1_minix_read_inode(struct inode * inode)
350
{
351
        struct buffer_head * bh;
352
        struct minix_inode * raw_inode;
353
        int i;
354
 
355
        raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
356
        if (!raw_inode) {
357
                make_bad_inode(inode);
358
                return;
359
        }
360
        inode->i_mode = raw_inode->i_mode;
361
        inode->i_uid = (uid_t)raw_inode->i_uid;
362
        inode->i_gid = (gid_t)raw_inode->i_gid;
363
        inode->i_nlink = raw_inode->i_nlinks;
364
        inode->i_size = raw_inode->i_size;
365
        inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
366
        inode->i_blocks = inode->i_blksize = 0;
367
        for (i = 0; i < 9; i++)
368
                inode->u.minix_i.u.i1_data[i] = raw_inode->i_zone[i];
369
        minix_set_inode(inode, raw_inode->i_zone[0]);
370
        brelse(bh);
371
}
372
 
373
/*
374
 * The minix V2 function to read an inode.
375
 */
376
static void V2_minix_read_inode(struct inode * inode)
377
{
378
        struct buffer_head * bh;
379
        struct minix2_inode * raw_inode;
380
        int i;
381
 
382
        raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
383
        if (!raw_inode) {
384
                make_bad_inode(inode);
385
                return;
386
        }
387
        inode->i_mode = raw_inode->i_mode;
388
        inode->i_uid = (uid_t)raw_inode->i_uid;
389
        inode->i_gid = (gid_t)raw_inode->i_gid;
390
        inode->i_nlink = raw_inode->i_nlinks;
391
        inode->i_size = raw_inode->i_size;
392
        inode->i_mtime = raw_inode->i_mtime;
393
        inode->i_atime = raw_inode->i_atime;
394
        inode->i_ctime = raw_inode->i_ctime;
395
        inode->i_blocks = inode->i_blksize = 0;
396
        for (i = 0; i < 10; i++)
397
                inode->u.minix_i.u.i2_data[i] = raw_inode->i_zone[i];
398
        minix_set_inode(inode, raw_inode->i_zone[0]);
399
        brelse(bh);
400
}
401
 
402
/*
403
 * The global function to read an inode.
404
 */
405
static void minix_read_inode(struct inode * inode)
406
{
407
        if (INODE_VERSION(inode) == MINIX_V1)
408
                V1_minix_read_inode(inode);
409
        else
410
                V2_minix_read_inode(inode);
411
}
412
 
413
/*
414
 * The minix V1 function to synchronize an inode.
415
 */
416
static struct buffer_head * V1_minix_update_inode(struct inode * inode)
417
{
418
        struct buffer_head * bh;
419
        struct minix_inode * raw_inode;
420
        int i;
421
 
422
        raw_inode = minix_V1_raw_inode(inode->i_sb, inode->i_ino, &bh);
423
        if (!raw_inode)
424
                return 0;
425
        raw_inode->i_mode = inode->i_mode;
426
        raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
427
        raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
428
        raw_inode->i_nlinks = inode->i_nlink;
429
        raw_inode->i_size = inode->i_size;
430
        raw_inode->i_time = inode->i_mtime;
431
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
432
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
433
        else for (i = 0; i < 9; i++)
434
                raw_inode->i_zone[i] = inode->u.minix_i.u.i1_data[i];
435
        mark_buffer_dirty(bh);
436
        return bh;
437
}
438
 
439
/*
440
 * The minix V2 function to synchronize an inode.
441
 */
442
static struct buffer_head * V2_minix_update_inode(struct inode * inode)
443
{
444
        struct buffer_head * bh;
445
        struct minix2_inode * raw_inode;
446
        int i;
447
 
448
        raw_inode = minix_V2_raw_inode(inode->i_sb, inode->i_ino, &bh);
449
        if (!raw_inode)
450
                return 0;
451
        raw_inode->i_mode = inode->i_mode;
452
        raw_inode->i_uid = fs_high2lowuid(inode->i_uid);
453
        raw_inode->i_gid = fs_high2lowgid(inode->i_gid);
454
        raw_inode->i_nlinks = inode->i_nlink;
455
        raw_inode->i_size = inode->i_size;
456
        raw_inode->i_mtime = inode->i_mtime;
457
        raw_inode->i_atime = inode->i_atime;
458
        raw_inode->i_ctime = inode->i_ctime;
459
        if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
460
                raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
461
        else for (i = 0; i < 10; i++)
462
                raw_inode->i_zone[i] = inode->u.minix_i.u.i2_data[i];
463
        mark_buffer_dirty(bh);
464
        return bh;
465
}
466
 
467
static struct buffer_head *minix_update_inode(struct inode *inode)
468
{
469
        if (INODE_VERSION(inode) == MINIX_V1)
470
                return V1_minix_update_inode(inode);
471
        else
472
                return V2_minix_update_inode(inode);
473
}
474
 
475
static void minix_write_inode(struct inode * inode, int wait)
476
{
477
        struct buffer_head *bh;
478
 
479
        lock_kernel();
480
        bh = minix_update_inode(inode);
481
        unlock_kernel();
482
        brelse(bh);
483
}
484
 
485
int minix_sync_inode(struct inode * inode)
486
{
487
        int err = 0;
488
        struct buffer_head *bh;
489
 
490
        bh = minix_update_inode(inode);
491
        if (bh && buffer_dirty(bh))
492
        {
493
                ll_rw_block(WRITE, 1, &bh);
494
                wait_on_buffer(bh);
495
                if (buffer_req(bh) && !buffer_uptodate(bh))
496
                {
497
                        printk ("IO error syncing minix inode ["
498
                                "%s:%08lx]\n",
499
                                kdevname(inode->i_dev), inode->i_ino);
500
                        err = -1;
501
                }
502
        }
503
        else if (!bh)
504
                err = -1;
505
        brelse (bh);
506
        return err;
507
}
508
 
509
/*
510
 * The function that is called for file truncation.
511
 */
512
void minix_truncate(struct inode * inode)
513
{
514
        if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode)))
515
                return;
516
        if (INODE_VERSION(inode) == MINIX_V1)
517
                V1_minix_truncate(inode);
518
        else
519
                V2_minix_truncate(inode);
520
}
521
 
522
static DECLARE_FSTYPE_DEV(minix_fs_type,"minix",minix_read_super);
523
 
524
static int __init init_minix_fs(void)
525
{
526
        return register_filesystem(&minix_fs_type);
527
}
528
 
529
static void __exit exit_minix_fs(void)
530
{
531
        unregister_filesystem(&minix_fs_type);
532
}
533
 
534
EXPORT_NO_SYMBOLS;
535
 
536
module_init(init_minix_fs)
537
module_exit(exit_minix_fs)
538
MODULE_LICENSE("GPL");
539
 

powered by: WebSVN 2.1.0

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