From: Adrian M. <zx8...@us...> - 2002-11-20 22:53:04
|
Update of /cvsroot/linuxdc/linux-sh-dc/fs/vmufs In directory sc8-pr-cvs1:/tmp/cvs-serv9230/fs/vmufs Modified Files: Tag: linux-sh-dc-2_4-branch super.c inode.c Log Message: vmufs write support - EXPERIMENTAL Index: super.c =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmufs/Attic/super.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 --- super.c 13 Nov 2002 23:19:41 -0000 1.1.2.13 +++ super.c 20 Nov 2002 22:53:00 -0000 1.1.2.14 @@ -127,13 +127,19 @@ } /* identified the correct directory entry */ - century = int_from_bcd((bh->b_data)[0x10 + (y % 0x10) * 0x20]); - year = int_from_bcd((bh->b_data)[0x11 + (y % 0x10) * 0x20]); - month = int_from_bcd((bh->b_data)[0x12 + (y % 0x10) * 0x20]); + century = + int_from_bcd((bh->b_data)[0x10 + (y % 0x10) * 0x20]); + year = + int_from_bcd((bh->b_data)[0x11 + (y % 0x10) * 0x20]); + month = + int_from_bcd((bh->b_data)[0x12 + (y % 0x10) * 0x20]); day = int_from_bcd((bh->b_data)[0x13 + (y % 0x10) * 0x20]); - hour = int_from_bcd((bh->b_data)[0x14 + (y % 0x10) * 0x20]); - minute = int_from_bcd((bh->b_data)[0x15 + (y % 0x10) * 0x20]); - second = int_from_bcd((bh->b_data)[0x16 + (y % 0x10) * 0x20]); + hour = + int_from_bcd((bh->b_data)[0x14 + (y % 0x10) * 0x20]); + minute = + int_from_bcd((bh->b_data)[0x15 + (y % 0x10) * 0x20]); + second = + int_from_bcd((bh->b_data)[0x16 + (y % 0x10) * 0x20]); in->i_ctime = in->i_mtime = mktime(century * 100 + year, month, day, hour, minute, @@ -191,9 +197,103 @@ return 0; } -static struct super_operations vmufs_super_operations = { - read_inode:vmufs_read_inode, - put_super:vmufs_put_super, +static void vmufs_delete_inode(struct inode *in) +{ + /* Delete inode by marking space as free in FAT + * no need to waste time and effort by actually + * wiping underlying data on media */ + struct buffer_head *bh, *bh_old; + struct super_block *sb; + struct memcard *vmudetails; + int z, y, x, blck_read; + __u16 nextblock, fatdata; + + + sb = in->i_sb; + vmudetails = (struct memcard *) sb->u.generic_sbp; + bh = bread(sb->s_dev, vmudetails->fat_bnum, in->i_blksize); + /*FAT now read in - seek start of file and wonder through FAT */ + nextblock = in->i_ino; + do { + fatdata = ((__u16 *) bh->b_data)[nextblock]; + ((__u16 *) bh->b_data)[nextblock] = 0xfffc; + if (fatdata == 0xfffa) + break; /*end of file */ + nextblock = fatdata; + } while (1); + mark_buffer_dirty(bh); + brelse(bh); + /* Now clean the directory entry + * Have to wander through this + * to find the appropriate entry */ + blck_read = vmudetails->dir_bnum; + bh = bread(sb->s_dev, blck_read, 512); + 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); + } + if (le16_to_cpu + (((__u16 *) bh->b_data)[(y % 0x10) * 0x10 + + 0x01]) == in->i_ino) + break; + } + + /* Found directory entry - so NULL it now */ + for (z = 0; z < 0x10; z++) { + ((__u16 *) bh->b_data)[(y % 0x10) * 0x10 + z] = 0x0000; + } + /* Replace it with another entry - if one exists */ + mark_buffer_dirty(bh); + x = y; /* save for later use */ + for (y = x + 1; 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); + } + if (bh->b_data[(y % 0x10) * 0x20] == 0x00) { /* Not a file */ + y--; + if (y == x) + break; /* At the end in any case */ + brelse(bh); + /* force read of correct block */ + bh = bread(sb->s_dev, + (vmudetails->dir_bnum - y / 0x10), 512); + bh_old = + bread(sb->s_dev, + (vmudetails->dir_bnum - x / 0x10), 512); + /* Copy this directory entry over */ + for (z = 0; z < 0x10; z++) { + ((__u16 *) bh_old->b_data)[(x % 0x10) * + 0x10 + z] = + ((__u16 *) bh->b_data)[(y % 0x10) * + 0x10 + z]; + ((__u16 *) bh->b_data)[(y % 0x10) * 0x10 + + z] = 0x00; + } + mark_buffer_dirty(bh); + mark_buffer_dirty(bh_old); /*In case it has been written back already */ + brelse(bh_old); + break; + } + } + + + brelse(bh); + +} + +static void vmufs_write_inode(struct inode *in) +{ + + /* Nothing at present */ + +} static struct super_operations vmufs_super_operations = { + + read_inode:vmufs_read_inode, write_inode:vmufs_write_inode, + delete_inode:vmufs_delete_inode, put_super:vmufs_put_super, statfs:vmufs_statfs, }; @@ -211,7 +311,6 @@ } - static struct super_block *vmufs_read_super(struct super_block *sb, void *data, int silent) { @@ -232,8 +331,8 @@ return NULL; } } - /* Store this data in the super block */ + struct memcard *vmudata = kmalloc(sizeof(struct memcard), GFP_KERNEL); vmudata->numblocks = z; @@ -295,9 +394,8 @@ unregister_filesystem(&vmufs_fs_type); } -module_init(init_vmufs_fs) - module_exit(exit_vmufs_fs) - +module_init(init_vmufs_fs); +module_exit(exit_vmufs_fs); MODULE_DESCRIPTION("Filesystem for Sega Dreamcast VMU"); MODULE_AUTHOR("Adrian McMenamin"); Index: inode.c =================================================================== RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmufs/Attic/inode.c,v retrieving revision 1.1.2.14 retrieving revision 1.1.2.15 diff -u -d -r1.1.2.14 -r1.1.2.15 --- inode.c 10 Nov 2002 00:52:00 -0000 1.1.2.14 +++ inode.c 20 Nov 2002 22:53:00 -0000 1.1.2.15 @@ -107,8 +107,24 @@ } + +static int vmufs_inode_unlink(struct inode *in, struct dentry *de) +{ + + /* find the inode of the specified dentry + * and then call the superblock delete_inode */ + struct super_block *sb = in->i_sb; + struct super_operations *s_op = sb->s_op; + s_op->delete_inode(de->d_inode); + + return 0; +} + + + struct inode_operations vmufs_inode_operations = { lookup:vmufs_inode_lookup, + unlink:vmufs_inode_unlink, }; |