|
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,
};
|