summaryrefslogtreecommitdiffstats
path: root/fs/efs/super.c
diff options
context:
space:
mode:
authorAl Smith <Al.Smith@aeschi.ch.eu.org>1999-03-31 11:28:49 +0000
committerAl Smith <Al.Smith@aeschi.ch.eu.org>1999-03-31 11:28:49 +0000
commit4cd9a486c8091de019dadee71cb80d4b53d8bd6d (patch)
treeb32d3745ed7b46cc861cd607a33426581c7bb26c /fs/efs/super.c
parent04a4c145e0293e7cd55c5c844eda08b1611e78a6 (diff)
Updated efs support to revision 0.97.
Diffstat (limited to 'fs/efs/super.c')
-rw-r--r--fs/efs/super.c106
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;
}