From: Adrian M. <zx8...@us...> - 2002-11-10 00:52:05
|
Update of /cvsroot/linuxdc/linux-sh-dc/fs/vmufs In directory usw-pr-cvs1:/tmp/cvs-serv22516/fs/vmufs Modified Files: Tag: linux-sh-dc-2_4-branch vmufs.h super.c inode.c Log Message: Moving vmufs towards device independence Index: vmufs.h =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmufs/Attic/vmufs.h,v retrieving revision 1.1.2.2 retrieving revision 1.1.2.3 diff -u -d -r1.1.2.2 -r1.1.2.3 --- vmufs.h 3 Nov 2002 04:34:28 -0000 1.1.2.2 +++ vmufs.h 10 Nov 2002 00:52:00 -0000 1.1.2.3 @@ -12,15 +12,14 @@ extern struct file_operations vmufs_file_operations; /* Memory card details */ -typedef struct memcard_s { - long partitions; - long blocklen; - long writecnt; - long readcnt; - long removable; +struct memcard { + long sb_bnum; + long fat_bnum; + long fat_len; + long dir_bnum; + long dir_len; long numblocks; - struct mtd_info *mtd; -} memcard_t; +}; struct vmufs_file_info { struct vmufs_file_info *prev; @@ -36,11 +35,4 @@ }; -int int_from_bcd(__u8 bcd); - - -#ifndef MTD_BLOCK_MAJOR -#define MTD_BLOCK_MAJOR 31 -#endif - -#define ROOT_BLOCK 255 +inline int int_from_bcd(__u8 bcd); Index: super.c =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmufs/Attic/super.c,v retrieving revision 1.1.2.11 retrieving revision 1.1.2.12 diff -u -d -r1.1.2.11 -r1.1.2.12 --- super.c 8 Nov 2002 19:41:26 -0000 1.1.2.11 +++ super.c 10 Nov 2002 00:52:00 -0000 1.1.2.12 @@ -48,11 +48,13 @@ void vmufs_read_inode(struct inode *in) { struct super_block *sb = in->i_sb; + struct memcard *vmudetails = + ((struct memcard *) sb->u.generic_sbp); + long superblock_bno = vmudetails->sb_bnum; int century, year, month, day, hour, minute, second; - if (in->i_ino == 255) { + if (in->i_ino == superblock_bno) { struct buffer_head *bh = sb_bread(sb, in->i_ino); - century = int_from_bcd((bh->b_data)[0x30]); year = int_from_bcd((bh->b_data)[0x31]); month = int_from_bcd((bh->b_data)[0x32]); @@ -85,11 +87,11 @@ in->i_version = ++event; brelse(bh); } else { - int blck_read = 253; + int blck_read = vmudetails->dir_bnum; struct buffer_head *bh = bread(sb->s_dev, blck_read, 512); int y; - if (in->i_ino > 199) { + if (in->i_ino > (vmudetails->dir_len * 0x10)) { /* Not here */ brelse(bh); return; @@ -105,8 +107,9 @@ in->i_mode |= S_IFREG; /* Scan through the directory to find the matching file */ - for (y = 0; y < 200; y++) { - if ((y / 0x10) > (253 - blck_read)) { + for (y = 0; y < (vmudetails->dir_len * 0x10); y++) { + if ((y / 0x10) > + (vmudetails->dir_bnum - blck_read)) { brelse(bh); blck_read--; bh = bread(sb->s_dev, blck_read, 512); @@ -116,7 +119,7 @@ break; } - if (y >= 200) { + if (y >= (vmudetails->dir_len * 0x10)) { brelse(bh); /* TO DO: error return required */ return; @@ -169,80 +172,105 @@ void vmufs_put_super(struct super_block *sb) { sb->s_dev = 0; + struct memcard *vmudetails = (struct memcard *) (sb->u.generic_sbp); + kfree(vmudetails); } static int vmufs_statfs(struct super_block *sb, struct statfs *buf) { - struct mtd_info *mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); - struct maple_driver_data *d = - (struct maple_driver_data *) (mtd->priv); - memcard_t *memcard = (memcard_t *) (d->private_data); buf->f_type = 0x55555555; - buf->f_bsize = mtd->erasesize; - buf->f_bfree = memcard->numblocks; + buf->f_bsize = 512; + buf->f_bfree = 256; /* TO DO: Fix */ buf->f_bavail = 0; buf->f_ffree = 0; buf->f_namelen = 12; - put_mtd_device(mtd); + return 0; } static struct super_operations vmufs_super_operations = { - read_inode: vmufs_read_inode, - put_super: vmufs_put_super, - statfs: vmufs_statfs, + read_inode:vmufs_read_inode, + put_super:vmufs_put_super, + statfs:vmufs_statfs, }; +static int check_sb_format(struct buffer_head *bh) +{ + __u32 s_magic = 0x55555555; + + if (!((((__u32 *) bh->b_data)[0] == s_magic) + && (((__u32 *) bh->b_data)[1] == s_magic) + && (((__u32 *) bh->b_data)[2] == s_magic) + && (s_magic == ((__u32 *) bh->b_data)[3]))) + return 0; + else + return 1; +} + + + static struct super_block *vmufs_read_super(struct super_block *sb, void *data, int silent) { - struct mtd_info *mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); - struct maple_driver_data *d = - (struct maple_driver_data *) (mtd->priv); - memcard_t *memcard = (memcard_t *) (d->private_data); + + /*Search for the superblock - assuming likely sizes are 256, 128, 512 and 1024 blocks */ + struct buffer_head *bh; + int z; + /* Have to try lowest number first to avoid oops */ + for (z = 128; z < 1024; z = z * 2) { + + bh = bread(sb->s_dev, z - 1, 512); + + if (check_sb_format(bh)) + break; + brelse(bh); + if (z == 1024) { /* failed */ + printk(KERN_ERR + "vmufs: attempted to mount non vmufs medium as vmufs\n"); + return NULL; + } + } + + /* Store this data in the super block */ + struct memcard *vmudata = + kmalloc(sizeof(struct memcard), GFP_KERNEL); + vmudata->numblocks = z; + vmudata->sb_bnum = z - 1; + vmudata->fat_bnum = z - 2; + if (z < 512) + vmudata->fat_len = 1; + else if (z == 512) + vmudata->fat_len = 2; + else + vmudata->fat_len = 4; + vmudata->dir_bnum = vmudata->fat_bnum - vmudata->fat_len; + if (z == 128) + vmudata->dir_len = 7; + else + vmudata->dir_len = 13 * (z / 256); + sb->u.generic_sbp = vmudata; + struct inode *root_i; int erasesize, log_2 = 0; - /* Read off the details of this device */ - if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) { - printk(KERN_ERR - "vmufs: attempt to mount non-MTD device %s\n " - "as vmu filesystem", kdevname(sb->s_dev)); - return NULL; - } - sb->s_blocksize = mtd->erasesize; - erasesize = mtd->erasesize; + + sb->s_blocksize = 512; + erasesize = 512; while ((erasesize /= 2) != 0) log_2++; /* thanks to MR Brown */ sb->s_blocksize_bits = log_2; - sb->s_magic = 0x55555555; /* Nearest thing vmu has */ + sb->s_magic = 0x55555555; sb->s_op = &vmufs_super_operations; - put_mtd_device(mtd); - - bh = sb_bread(sb, memcard->numblocks - 1); - - /* Check a formatted vmu */ - if (!((((__u32 *) bh->b_data)[0] == sb->s_magic) - && (((__u32 *) bh->b_data)[1] == sb->s_magic) - && (((__u32 *) bh->b_data)[2] == sb->s_magic) - && (sb->s_magic == ((__u32 *) bh->b_data)[3]))) { - printk - ("Attempted to mount non-vmufs filesystem as vmufs\n"); - brelse(bh); - return NULL; - } - brelse(bh); - - root_i = iget(sb, memcard->numblocks - 1); + root_i = iget(sb, vmudata->sb_bnum); if (!root_i) { printk("VMUFS: get root inode failed\n"); @@ -270,8 +298,8 @@ } module_init(init_vmufs_fs) -module_exit(exit_vmufs_fs) + module_exit(exit_vmufs_fs) -MODULE_DESCRIPTION("Filesystem for Sega Dreamcast VMU"); + MODULE_DESCRIPTION("Filesystem for Sega Dreamcast VMU"); MODULE_AUTHOR("Adrian McMenamin"); MODULE_LICENSE("GPL"); Index: inode.c =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmufs/Attic/inode.c,v retrieving revision 1.1.2.13 retrieving revision 1.1.2.14 diff -u -d -r1.1.2.13 -r1.1.2.14 --- inode.c 8 Nov 2002 19:41:26 -0000 1.1.2.13 +++ inode.c 10 Nov 2002 00:52:00 -0000 1.1.2.14 @@ -22,7 +22,10 @@ struct dentry *vmufs_inode_lookup(struct inode *in, struct dentry *dent) { struct super_block *sb = in->i_sb; - int blck_read = 253; + void *sbp = sb->u.generic_sbp; + struct memcard *vmudetails = (struct memcard *) sbp; + + long blck_read = vmudetails->dir_bnum; struct buffer_head *bh = bread(sb->s_dev, blck_read, 512); struct vmufs_file_info *first_one = NULL; struct vmufs_file_info *last_one = NULL; @@ -32,7 +35,8 @@ struct vmufs_file_info *saved_file = kmalloc(sizeof(struct vmufs_file_info), GFP_KERNEL); saved_file->prev = last_one; - saved_file->ftype = ((__u8 *) bh->b_data)[0 + fno * 0x20]; + saved_file->ftype = + ((__u8 *) bh->b_data)[(fno % 0x10) * 0x20]; if (saved_file->ftype == 0) { /* no file */ if (last_one) @@ -54,7 +58,7 @@ fno++; - if ((fno / 0x10) > (253 - blck_read)) { + if ((fno / 0x10) > (vmudetails->dir_bnum - blck_read)) { brelse(bh); blck_read--; bh = bread(sb->s_dev, blck_read, 512); @@ -113,8 +117,13 @@ struct dentry *dentry = filp->f_dentry; struct inode *inode = dentry->d_inode; struct super_block *sb = inode->i_sb; - struct buffer_head *bh = bread(sb->s_dev, 253, 512); - int blck_read = 253; /* Traverse through all blocks of VMU directory */ + struct memcard *vmudetails = + ((struct memcard *) sb->u.generic_sbp); + + + int blck_read = vmudetails->dir_bnum; /* Traverse through all blocks of VMU directory */ + struct buffer_head *bh = bread(sb->s_dev, blck_read, 512); + int i = filp->f_pos; switch ((unsigned int) filp->f_pos) { @@ -134,16 +143,16 @@ } /* wander through the Directory and find files */ - if (i > 200) { + if ((i - 2) > (vmudetails->dir_len * 0x10)) { brelse(bh); - return -1; /* Cannot be more than 200 */ + return -1; } struct vmufs_file_info *saved_file = kmalloc(sizeof(struct vmufs_file_info), GFP_KERNEL); do { - if ((i - 2) / 0x10 > (253 - blck_read)) { /* move to next block in directory */ + if ((i - 2) / 0x10 > (vmudetails->dir_bnum - blck_read)) { /* move to next block in directory */ brelse(bh); blck_read--; bh = bread(sb->s_dev, blck_read, 512); @@ -181,10 +190,10 @@ } struct file_operations vmufs_file_dir_operations = { - owner: THIS_MODULE, - read: generic_read_dir, - readdir: vmufs_readdir, - fsync: file_fsync, + owner:THIS_MODULE, + read:generic_read_dir, + readdir:vmufs_readdir, + fsync:file_fsync, }; ssize_t vmufs_file_read(struct file *file, char *buf, size_t count, @@ -199,6 +208,9 @@ struct buffer_head *bh_fat; long file_len = in->i_size; char *readbuf; + struct super_block *sb = in->i_sb; + struct memcard *vmudetails = + ((struct memcard *) sb->u.generic_sbp); if (*ppos > file_len) return -EINVAL; @@ -209,11 +221,10 @@ if (blcks_to_read == 0) return 0; readbuf = kmalloc(count, GFP_KERNEL); - - /* Trverse through FAT to read the blocks in */ + /* Traverse through FAT to read the blocks in */ x = 0; next_block = in->i_ino; - bh_fat = bread(in->i_sb->s_dev, 254, blksize); + bh_fat = bread(in->i_sb->s_dev, vmudetails->fat_bnum, blksize); /*Walk through to where we are */ if (blkoffset > 0) { do { @@ -242,7 +253,7 @@ } struct file_operations vmufs_file_operations = { - read: vmufs_file_read, + read:vmufs_file_read, }; struct inode_operations vmufs_file_inode_operations = { |