diff options
author | Al Smith <Al.Smith@aeschi.ch.eu.org> | 1999-03-31 11:28:49 +0000 |
---|---|---|
committer | Al Smith <Al.Smith@aeschi.ch.eu.org> | 1999-03-31 11:28:49 +0000 |
commit | 4cd9a486c8091de019dadee71cb80d4b53d8bd6d (patch) | |
tree | b32d3745ed7b46cc861cd607a33426581c7bb26c /fs/efs/super.c | |
parent | 04a4c145e0293e7cd55c5c844eda08b1611e78a6 (diff) |
Updated efs support to revision 0.97.
Diffstat (limited to 'fs/efs/super.c')
-rw-r--r-- | fs/efs/super.c | 106 |
1 files changed, 59 insertions, 47 deletions
diff --git a/fs/efs/super.c b/fs/efs/super.c index f897a2ebb..2bc259d51 100644 --- a/fs/efs/super.c +++ b/fs/efs/super.c @@ -7,7 +7,11 @@ */ #include <linux/module.h> -#include <linux/efs.h> +#include <linux/init.h> + +#include <linux/efs_fs.h> +#include <linux/efs_vh.h> +#include <linux/efs_fs_sb.h> void efs_read_inode(struct inode *); void efs_put_super(struct super_block *); @@ -33,22 +37,36 @@ static struct super_operations efs_superblock_operations = { NULL /* remount */ }; -int init_module(void) { +__initfunc(int init_efs_fs(void)) { + printk(cprt); + printk(" - http://aeschi.ch.eu.org/efs/\n"); return register_filesystem(&efs_fs_type); } +#ifdef MODULE +EXPORT_NO_SYMBOLS; + +int init_module(void) { + return init_efs_fs(); +} + void cleanup_module(void) { unregister_filesystem(&efs_fs_type); } +#endif -static long efs_validate_vh(struct volume_header *vh, int slice) { +static long efs_validate_vh(struct volume_header *vh) { int i, j; - int32_t sblock = 0; - int type; + int32_t sblock = -1; + int type, slice = -1; char name[VDNAMESIZE+1]; if (be32_to_cpu(vh->vh_magic) != VHMAGIC) { - printk("EFS: invalid volume descriptor\n"); + /* + * assume that we're dealing with a partition and allow + * read_super() to try and detect a valid superblock + * on the next block. + */ return 0; } @@ -64,7 +82,7 @@ static long efs_validate_vh(struct volume_header *vh, int slice) { #ifdef DEBUG if (name[0]) { - printk("EFS: vh: 0x%8s block: 0x%08x size: 0x%08x\n", + printk("EFS: vh: %8s block: 0x%08x size: 0x%08x\n", name, (int) be32_to_cpu(vh->vh_vd[i].vd_lbn), (int) be32_to_cpu(vh->vh_vd[i].vd_nbytes)); @@ -80,25 +98,21 @@ static long efs_validate_vh(struct volume_header *vh, int slice) { (int) be32_to_cpu(vh->vh_pt[i].pt_nblks), type); #endif - if (slice == i && (type == 5 || type == 7)) { + if (type == 5 || type == 7) { sblock = be32_to_cpu(vh->vh_pt[i].pt_firstlbn); - } else if (slice == -1 && sblock == 0) { - if (type == 5 || type == 7) { - sblock = be32_to_cpu(vh->vh_pt[i].pt_firstlbn); - slice = i; - } + slice = i; } } - if (sblock) { - printk("EFS: using slice %d (offset 0x%x)\n", slice, sblock); - } else if (slice != -1) { - printk("EFS: no efs filesystem found on slice %d\n", slice); + if (sblock < 0) { + printk("EFS: found valid partition table but no EFS partitions\n"); + } else { + printk("EFS: using CD slice %d (offset 0x%x)\n", slice, sblock); } return(sblock); } -static int efs_validate_super(struct efs_spb *sb, struct efs *super) { +static int efs_validate_super(struct efs_sb_info *sb, struct efs_super *super) { if (!IS_EFS_MAGIC(be32_to_cpu(super->fs_magic))) return -1; @@ -106,6 +120,8 @@ static int efs_validate_super(struct efs_spb *sb, struct efs *super) { sb->total_blocks = be32_to_cpu(super->fs_size); sb->first_block = be32_to_cpu(super->fs_firstcg); sb->group_size = be32_to_cpu(super->fs_cgfsize); + sb->data_free = be32_to_cpu(super->fs_tfree); + sb->inode_free = be32_to_cpu(super->fs_tinode); sb->inode_blocks = be16_to_cpu(super->fs_cgisize); sb->total_groups = be16_to_cpu(super->fs_ncg); @@ -113,27 +129,16 @@ static int efs_validate_super(struct efs_spb *sb, struct efs *super) { } struct super_block *efs_read_super(struct super_block *s, void *d, int verbose) { - int slice = -1; kdev_t dev = s->s_dev; struct inode *root_inode; - struct efs_spb *spb; + struct efs_sb_info *spb; struct buffer_head *bh; - if (d) { - /* parse mount option */ - if (!strncmp(d, "slice=", 6)) { - slice = simple_strtoul(d+6, NULL, 10); - } else if (strcmp(d, "")) { - printk("EFS: invalid mount option\n"); - return(NULL); - } - } - MOD_INC_USE_COUNT; lock_super(s); /* approx 230 bytes available in this union */ - spb = (struct efs_spb *) &(s->u.generic_sbp); + spb = (struct efs_sb_info *) &(s->u.generic_sbp); set_blocksize(dev, EFS_BLOCKSIZE); @@ -145,11 +150,15 @@ struct super_block *efs_read_super(struct super_block *s, void *d, int verbose) goto out_no_fs_ul; } - spb->fs_start = efs_validate_vh((struct volume_header *) bh->b_data, slice); + /* + * if this returns zero then we didn't find any partition table. + * this isn't (yet) an error - just assume for the moment that + * the device is valid and go on to search for a superblock. + */ + spb->fs_start = efs_validate_vh((struct volume_header *) bh->b_data); brelse(bh); - if(!spb->fs_start) { - printk("EFS: invalid volume descriptor\n"); + if (spb->fs_start < 0) { goto out_no_fs_ul; } @@ -159,7 +168,7 @@ struct super_block *efs_read_super(struct super_block *s, void *d, int verbose) goto out_no_fs_ul; } - if (efs_validate_super(spb, (struct efs *) bh->b_data)) { + if (efs_validate_super(spb, (struct efs_super *) bh->b_data)) { printk("EFS: invalid superblock\n"); brelse(bh); goto out_no_fs_ul; @@ -214,18 +223,21 @@ void efs_put_super(struct super_block *s) { int efs_statfs(struct super_block *s, struct statfs *buf, int bufsiz) { struct statfs tmp; - struct efs_spb *sbp = (struct efs_spb *)&s->u.generic_sbp; - - tmp.f_type = EFS_SUPER_MAGIC; - tmp.f_bsize = EFS_BLOCKSIZE; - tmp.f_blocks = sbp->total_blocks; - tmp.f_bfree = 0; - tmp.f_bavail = 0; - tmp.f_files = 0; /* ? */ - tmp.f_ffree = 0; - tmp.f_fsid.val[0] = (sbp->fs_magic >> 16) & 0xffff; - tmp.f_fsid.val[1] = sbp->fs_magic & 0xffff; - tmp.f_namelen = EFS_MAXNAMELEN; + struct efs_sb_info *sbp = (struct efs_sb_info *)&s->u.generic_sbp; + + tmp.f_type = EFS_SUPER_MAGIC; /* efs magic number */ + tmp.f_bsize = EFS_BLOCKSIZE; /* blocksize */ + tmp.f_blocks = sbp->total_groups * /* total data blocks */ + (sbp->group_size - sbp->inode_blocks); + tmp.f_bfree = sbp->data_free; /* free data blocks */ + tmp.f_bavail = sbp->data_free; /* free blocks for non-root */ + tmp.f_files = sbp->total_groups * /* total inodes */ + sbp->inode_blocks * + (EFS_BLOCKSIZE / sizeof(struct efs_dinode)); + tmp.f_ffree = sbp->inode_free; /* free inodes */ + tmp.f_fsid.val[0] = (sbp->fs_magic >> 16) & 0xffff; /* fs ID */ + tmp.f_fsid.val[1] = sbp->fs_magic & 0xffff; /* fs ID */ + tmp.f_namelen = EFS_MAXNAMELEN; /* max filename length */ return copy_to_user(buf, &tmp, bufsiz) ? -EFAULT : 0; } |