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

Subversion Repositories or1k

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
2
 * super.c
3
 *
4
 * Copyright (c) 1999 Al Smith
5
 *
6
 * Portions derived from work (c) 1995,1996 Christian Vogelgsang.
7
 */
8
 
9
#include <linux/init.h>
10
#include <linux/module.h>
11
#include <linux/locks.h>
12
#include <linux/efs_fs.h>
13
#include <linux/efs_vh.h>
14
#include <linux/efs_fs_sb.h>
15
 
16
static DECLARE_FSTYPE_DEV(efs_fs_type, "efs", efs_read_super);
17
 
18
static struct super_operations efs_superblock_operations = {
19
        read_inode:     efs_read_inode,
20
        statfs:         efs_statfs,
21
};
22
 
23
static int __init init_efs_fs(void) {
24
        printk("EFS: "EFS_VERSION" - http://aeschi.ch.eu.org/efs/\n");
25
        return register_filesystem(&efs_fs_type);
26
}
27
 
28
static void __exit exit_efs_fs(void) {
29
        unregister_filesystem(&efs_fs_type);
30
}
31
 
32
EXPORT_NO_SYMBOLS;
33
 
34
module_init(init_efs_fs)
35
module_exit(exit_efs_fs)
36
 
37
static efs_block_t efs_validate_vh(struct volume_header *vh) {
38
        int             i;
39
        unsigned int    cs, csum, *ui;
40
        efs_block_t     sblock = 0; /* shuts up gcc */
41
        struct pt_types *pt_entry;
42
        int             pt_type, slice = -1;
43
 
44
        if (be32_to_cpu(vh->vh_magic) != VHMAGIC) {
45
                /*
46
                 * assume that we're dealing with a partition and allow
47
                 * read_super() to try and detect a valid superblock
48
                 * on the next block.
49
                 */
50
                return 0;
51
        }
52
 
53
        ui = ((unsigned int *) (vh + 1)) - 1;
54
        for(csum = 0; ui >= ((unsigned int *) vh);) {
55
                cs = *ui--;
56
                csum += be32_to_cpu(cs);
57
        }
58
        if (csum) {
59
                printk(KERN_INFO "EFS: SGI disklabel: checksum bad, label corrupted\n");
60
                return 0;
61
        }
62
 
63
#ifdef DEBUG
64
        printk(KERN_DEBUG "EFS: bf: \"%16s\"\n", vh->vh_bootfile);
65
 
66
        for(i = 0; i < NVDIR; i++) {
67
                int     j;
68
                char    name[VDNAMESIZE+1];
69
 
70
                for(j = 0; j < VDNAMESIZE; j++) {
71
                        name[j] = vh->vh_vd[i].vd_name[j];
72
                }
73
                name[j] = (char) 0;
74
 
75
                if (name[0]) {
76
                        printk(KERN_DEBUG "EFS: vh: %8s block: 0x%08x size: 0x%08x\n",
77
                                name,
78
                                (int) be32_to_cpu(vh->vh_vd[i].vd_lbn),
79
                                (int) be32_to_cpu(vh->vh_vd[i].vd_nbytes));
80
                }
81
        }
82
#endif
83
 
84
        for(i = 0; i < NPARTAB; i++) {
85
                pt_type = (int) be32_to_cpu(vh->vh_pt[i].pt_type);
86
                for(pt_entry = sgi_pt_types; pt_entry->pt_name; pt_entry++) {
87
                        if (pt_type == pt_entry->pt_type) break;
88
                }
89
#ifdef DEBUG
90
                if (be32_to_cpu(vh->vh_pt[i].pt_nblks)) {
91
                        printk(KERN_DEBUG "EFS: pt %2d: start: %08d size: %08d type: 0x%02x (%s)\n",
92
                                i,
93
                                (int) be32_to_cpu(vh->vh_pt[i].pt_firstlbn),
94
                                (int) be32_to_cpu(vh->vh_pt[i].pt_nblks),
95
                                pt_type,
96
                                (pt_entry->pt_name) ? pt_entry->pt_name : "unknown");
97
                }
98
#endif
99
                if (IS_EFS(pt_type)) {
100
                        sblock = be32_to_cpu(vh->vh_pt[i].pt_firstlbn);
101
                        slice = i;
102
                }
103
        }
104
 
105
        if (slice == -1) {
106
                printk(KERN_NOTICE "EFS: partition table contained no EFS partitions\n");
107
#ifdef DEBUG
108
        } else {
109
                printk(KERN_INFO "EFS: using slice %d (type %s, offset 0x%x)\n",
110
                        slice,
111
                        (pt_entry->pt_name) ? pt_entry->pt_name : "unknown",
112
                        sblock);
113
#endif
114
        }
115
        return(sblock);
116
}
117
 
118
static int efs_validate_super(struct efs_sb_info *sb, struct efs_super *super) {
119
 
120
        if (!IS_EFS_MAGIC(be32_to_cpu(super->fs_magic))) return -1;
121
 
122
        sb->fs_magic     = be32_to_cpu(super->fs_magic);
123
        sb->total_blocks = be32_to_cpu(super->fs_size);
124
        sb->first_block  = be32_to_cpu(super->fs_firstcg);
125
        sb->group_size   = be32_to_cpu(super->fs_cgfsize);
126
        sb->data_free    = be32_to_cpu(super->fs_tfree);
127
        sb->inode_free   = be32_to_cpu(super->fs_tinode);
128
        sb->inode_blocks = be16_to_cpu(super->fs_cgisize);
129
        sb->total_groups = be16_to_cpu(super->fs_ncg);
130
 
131
        return 0;
132
}
133
 
134
struct super_block *efs_read_super(struct super_block *s, void *d, int silent) {
135
        kdev_t dev = s->s_dev;
136
        struct efs_sb_info *sb;
137
        struct buffer_head *bh;
138
 
139
        sb = SUPER_INFO(s);
140
 
141
        s->s_magic              = EFS_SUPER_MAGIC;
142
        s->s_blocksize          = EFS_BLOCKSIZE;
143
        s->s_blocksize_bits     = EFS_BLOCKSIZE_BITS;
144
 
145
        if( set_blocksize(dev, EFS_BLOCKSIZE) < 0)
146
        {
147
                printk(KERN_ERR "EFS: device does not support %d byte blocks\n",
148
                        EFS_BLOCKSIZE);
149
                goto out_no_fs_ul;
150
        }
151
 
152
        /* read the vh (volume header) block */
153
        bh = sb_bread(s, 0);
154
 
155
        if (!bh) {
156
                printk(KERN_ERR "EFS: cannot read volume header\n");
157
                goto out_no_fs_ul;
158
        }
159
 
160
        /*
161
         * if this returns zero then we didn't find any partition table.
162
         * this isn't (yet) an error - just assume for the moment that
163
         * the device is valid and go on to search for a superblock.
164
         */
165
        sb->fs_start = efs_validate_vh((struct volume_header *) bh->b_data);
166
        brelse(bh);
167
 
168
        if (sb->fs_start == -1) {
169
                goto out_no_fs_ul;
170
        }
171
 
172
        bh = sb_bread(s, sb->fs_start + EFS_SUPER);
173
        if (!bh) {
174
                printk(KERN_ERR "EFS: cannot read superblock\n");
175
                goto out_no_fs_ul;
176
        }
177
 
178
        if (efs_validate_super(sb, (struct efs_super *) bh->b_data)) {
179
#ifdef DEBUG
180
                printk(KERN_WARNING "EFS: invalid superblock at block %u\n", sb->fs_start + EFS_SUPER);
181
#endif
182
                brelse(bh);
183
                goto out_no_fs_ul;
184
        }
185
        brelse(bh);
186
 
187
        if (!(s->s_flags & MS_RDONLY)) {
188
#ifdef DEBUG
189
                printk(KERN_INFO "EFS: forcing read-only mode\n");
190
#endif
191
                s->s_flags |= MS_RDONLY;
192
        }
193
        s->s_op   = &efs_superblock_operations;
194
        s->s_root = d_alloc_root(iget(s, EFS_ROOTINODE));
195
 
196
        if (!(s->s_root)) {
197
                printk(KERN_ERR "EFS: get root inode failed\n");
198
                goto out_no_fs;
199
        }
200
 
201
        return(s);
202
 
203
out_no_fs_ul:
204
out_no_fs:
205
        return(NULL);
206
}
207
 
208
int efs_statfs(struct super_block *s, struct statfs *buf) {
209
        struct efs_sb_info *sb = SUPER_INFO(s);
210
 
211
        buf->f_type    = EFS_SUPER_MAGIC;       /* efs magic number */
212
        buf->f_bsize   = EFS_BLOCKSIZE;         /* blocksize */
213
        buf->f_blocks  = sb->total_groups *     /* total data blocks */
214
                        (sb->group_size - sb->inode_blocks);
215
        buf->f_bfree   = sb->data_free;         /* free data blocks */
216
        buf->f_bavail  = sb->data_free;         /* free blocks for non-root */
217
        buf->f_files   = sb->total_groups *     /* total inodes */
218
                        sb->inode_blocks *
219
                        (EFS_BLOCKSIZE / sizeof(struct efs_dinode));
220
        buf->f_ffree   = sb->inode_free;        /* free inodes */
221
        buf->f_fsid.val[0] = (sb->fs_magic >> 16) & 0xffff; /* fs ID */
222
        buf->f_fsid.val[1] =  sb->fs_magic        & 0xffff; /* fs ID */
223
        buf->f_namelen = EFS_MAXNAMELEN;        /* max filename length */
224
 
225
        return 0;
226
}
227
 

powered by: WebSVN 2.1.0

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