|
From: Adrian M. <zx8...@us...> - 2003-05-13 22:29:30
|
Update of /cvsroot/linuxdc/linux-sh-dc/fs/vmufs
In directory sc8-pr-cvs1:/tmp/cvs-serv22192/fs/vmufs
Modified Files:
Tag: linux-sh-dc-2_4-branch
vmufs.h inode.c super.c
Log Message:
Updated vmufs with more write support: BEWARE - experimental code
Index: vmufs.h
===================================================================
RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmufs/Attic/vmufs.h,v
retrieving revision 1.1.2.4
retrieving revision 1.1.2.5
diff -u -d -r1.1.2.4 -r1.1.2.5
--- vmufs.h 3 May 2003 16:31:14 -0000 1.1.2.4
+++ vmufs.h 13 May 2003 22:29:26 -0000 1.1.2.5
@@ -8,6 +8,8 @@
#define VMUFS_NAMELEN 12
+#define VMUFS_ZEROBLOCK 32768
+
extern struct inode_operations vmufs_inode_operations;
extern struct inode_operations vmufs_file_inode_operations;
Index: inode.c
===================================================================
RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmufs/Attic/inode.c,v
retrieving revision 1.1.2.16
retrieving revision 1.1.2.17
diff -u -d -r1.1.2.16 -r1.1.2.17
--- inode.c 3 May 2003 16:31:14 -0000 1.1.2.16
+++ inode.c 13 May 2003 22:29:26 -0000 1.1.2.17
@@ -62,6 +62,7 @@
bh->b_data + 4 + (fno % 0x10) * 0x20, 12);
+
fno++;
if ((fno / 0x10) > (vmudetails->dir_bnum - blck_read)) {
brelse(bh);
@@ -84,7 +85,12 @@
/* No files at all */
return ERR_PTR(error);
}
- if (memcmp(dent->d_name.name, first_one->fname, 12) != 0) {
+ int filenamelen = strlen(dent->d_name.name);
+ if (filenamelen > 12)
+ filenamelen = 12;
+ if (memcmp
+ (dent->d_name.name, first_one->fname,
+ filenamelen) != 0) {
if (first_one->next) {
first_one = first_one->next;
kfree(first_one->prev);
@@ -138,7 +144,7 @@
{
/* Create an inode */
if (de->d_name.len > VMUFS_NAMELEN)
- return (ERR_PTR(-ENAMETOOLONG));
+ return -ENAMETOOLONG;
int y;
struct inode *inode;
@@ -157,7 +163,7 @@
/* Is this an executible file? */
if (imode & 73) { /*Octal 111 */
- inode->i_ino = 0;
+ inode->i_ino = VMUFS_ZEROBLOCK;
/* But this already allocated? */
bh_fat =
bread(sb->s_dev, vmudetails->fat_bnum,
@@ -173,7 +179,7 @@
} else {
/*Look for a free block in the FAT */
- long nextblock = 199; /*TO DO: Make this portable */
+ long nextblock = vmudetails->numblocks - 1;
bh_fat =
bread(sb->s_dev, vmudetails->fat_bnum,
sb->s_blocksize);
@@ -226,14 +232,22 @@
/* Have the directory entry
* so now update it */
int z = (y % 0x10) * 0x20;
- if (inode->i_ino != 0)
+ if (inode->i_ino != VMUFS_ZEROBLOCK)
bh->b_data[z] = 0x33; /* data file */
else
bh->b_data[z] = 0xcc;
if ((bh->b_data[z + 1] != (char) 0x00)
&& (bh->b_data[z + 1] != (char) 0xff))
bh->b_data[z + 1] = (char) 0x00;
- ((__u16 *) bh->b_data)[z / 2 + 1] = cpu_to_le16(inode->i_ino);
+ if (inode->i_ino != VMUFS_ZEROBLOCK) {
+ ((__u16 *) bh->b_data)[z / 2 + 1] =
+ cpu_to_le16(inode->i_ino);
+ ((__u16 *) bh->b_data)[z / 2 + 0x0D] = 0;
+ } else {
+ ((__u16 *) bh->b_data)[z / 2 + 1] = 0;
+ ((__u16 *) bh->b_data)[z / 2 + 0x0D] = 1;
+ }
+
/* Name */
memset((char *) (bh->b_data + z + 0x04), '\0', 0x0C);
memcpy((char *) (bh->b_data + z + 0x04), ((de->d_name).name),
@@ -274,10 +288,6 @@
((__u16 *) bh->b_data)[z / 2 + 0x0C] =
cpu_to_le16(inode->i_blocks);
- if (inode->i_ino != 0)
- ((__u16 *) bh->b_data)[z / 2 + 0x0D] = 0;
- else
- ((__u16 *) bh->b_data)[z / 2 + 0x0D] = 1; /*game */
inode->i_mtime = unix_date;
mark_buffer_dirty(bh);
brelse(bh);
@@ -309,6 +319,7 @@
int vmufs_readdir(struct file *filp, void *dirent, filldir_t filldir)
{
+ int filenamelen;
struct dentry *dentry = filp->f_dentry;
struct inode *inode = dentry->d_inode;
struct super_block *sb = inode->i_sb;
@@ -353,8 +364,7 @@
bh = bread(sb->s_dev, blck_read, 512);
}
- saved_file->ftype =
- ((__u8 *) bh->b_data)[0 + ((i - 2) % 0x10) * 0x20];
+ saved_file->ftype = bh->b_data[((i - 2) % 0x10) * 0x20];
if (saved_file->ftype == 0)
break;
@@ -364,12 +374,16 @@
((i -
2) % 0x10) *
0x10]);
+ if (saved_file->fblk == 0)
+ saved_file->fblk = VMUFS_ZEROBLOCK; /*Make sure we can see file */
memcpy(saved_file->fname,
bh->b_data + 4 + ((i - 2) % 0x10) * 0x20, 12);
-
+ filenamelen = strlen(saved_file->fname);
+ if (filenamelen > 12)
+ filenamelen = 12;
if (filldir
- (dirent, saved_file->fname, 12, i++, saved_file->fblk,
- DT_REG) < 0) {
+ (dirent, saved_file->fname, filenamelen, i++,
+ saved_file->fblk, DT_REG) < 0) {
goto finish;
}
@@ -393,10 +407,61 @@
int vmufs_game_write(struct file *file, const char *buf, char *writebuf,
- size_t count)
+ size_t count, loff_t * ppos)
{
- /* Assume this is a game */
- return -EIO;
+ __u16 fatdata;
+ struct buffer_head *bh_fat, *bh;
+ struct inode *in = (file->f_dentry)->d_inode;
+ struct super_block *sb = in->i_sb;
+ struct memcard *vmudetails =
+ ((struct memcard *) sb->u.generic_sbp);
+
+ unsigned long blkoffset = *ppos >> in->i_sb->s_blocksize_bits;
+ if (blkoffset < 1) {
+ /* Additional sanity check */
+ kfree(writebuf);
+ return -EIO;
+ }
+ unsigned long blksize = in->i_blksize;
+
+ /* Is the next block free in the VMU? */
+ bh_fat = bread(in->i_sb->s_dev, vmudetails->fat_bnum, blksize);
+ fatdata = ((__u16 *) bh_fat->b_data)[(__u16) blkoffset];
+
+ if (fatdata != 0xfffc) {
+ printk(KERN_ERR
+ "vmufs: Cannot save game file - insufficient linear space\n");
+ kfree(writebuf);
+ return -EFBIG;
+ }
+
+ /*Now we have the space - write the block out */
+ bh = bread(sb->s_dev, blkoffset, in->i_blksize);
+ if (count < in->i_blksize)
+ memset((char *) (bh->b_data), '\0', in->i_blksize);
+ memcpy((char *) (bh->b_data), writebuf, count);
+ mark_buffer_dirty(bh);
+ brelse(bh);
+ in->i_size += in->i_blksize;
+ in->i_blocks++;
+ /*Now update the FAT */
+
+
+ ((__u16 *) (bh_fat->b_data))[(__u16) blkoffset] = 0xfffa;
+ ((__u16 *) (bh_fat->b_data))[((__u16) (blkoffset - 1))] =
+ cpu_to_le16(blkoffset);
+ mark_buffer_dirty(bh_fat);
+
+
+ brelse(bh_fat);
+
+
+ kfree(writebuf);
+ *ppos += count;
+ return count;
+
+
+
}
ssize_t vmufs_file_write(struct file * file, const char *buf, size_t count,
@@ -429,65 +494,62 @@
copy_from_user(writebuf, buf, count);
- if (in->i_ino == 0) {
- vmufs_game_write(file, buf, writebuf, count);
- } else {
- /* We have a data file -
- * so let's write it out to
- * the vmu */
+ /* Handle game files */
+ unsigned long inode_num = in->i_ino;
+ if (inode_num == VMUFS_ZEROBLOCK)
+ inode_num = 0;
- /*Start by writing out to first block */
- if (blkoffset == 0) {
- unsigned long currentblock = in->i_ino;
- __u16 fatdata;
- bh = bread(sb->s_dev, in->i_ino, in->i_blksize);
- if (count < in->i_blksize)
- memset((char *) (bh->b_data), '\0',
- in->i_blksize);
- memcpy((char *) (bh->b_data), writebuf, count);
- mark_buffer_dirty(bh);
- brelse(bh);
- in->i_size = in->i_blksize; /* will increment as we grow */
- in->i_blocks = 1;
- /* Update FAT */
- bh_fat =
- bread(in->i_sb->s_dev, vmudetails->fat_bnum,
- blksize);
- /*Wipe out any old FAT records for this inode */
- do {
- fatdata =
- ((__u16 *) bh_fat->
- b_data)[(__u16) currentblock];
- if (fatdata == 0xfffc)
- break; /* already empty */
- ((__u16 *) (bh_fat->
- b_data))[(__u16) currentblock]
- = 0xfffc;
- mark_buffer_dirty(bh_fat);
- if (fatdata == 0xfffa)
- break; /* end of file */
- } while (1);
- /* Avoid writes to mtd if possible
- * so check if a write is really
- * required here */
+ /*Start by writing out to first block */
+ if (blkoffset == 0) {
+ unsigned long currentblock = inode_num;
+ __u16 fatdata;
+ bh = bread(sb->s_dev, inode_num, in->i_blksize);
+ if (count < in->i_blksize)
+ memset((char *) (bh->b_data), '\0', in->i_blksize);
+ memcpy((char *) (bh->b_data), writebuf, count);
+ mark_buffer_dirty(bh);
+ brelse(bh);
+ in->i_size = in->i_blksize; /* will increment as we grow */
+ in->i_blocks = 1;
+ /* Update FAT */
+ bh_fat =
+ bread(in->i_sb->s_dev, vmudetails->fat_bnum, blksize);
+ /*Wipe out any old FAT records for this inode */
+ do {
fatdata =
((__u16 *) bh_fat->
- b_data)[(__u16) (in->i_ino)];
- if (fatdata != 0xfffa) {
- ((__u16 *) (bh_fat->b_data))[(__u16) (in->
- i_ino)]
- = 0xfffa;
- mark_buffer_dirty(bh_fat);
- }
- brelse(bh_fat);
-
+ b_data)[(__u16) currentblock];
+ if (fatdata == 0xfffc)
+ break; /* already empty */
+ ((__u16 *) (bh_fat->b_data))[(__u16) currentblock]
+ = 0xfffc;
+ mark_buffer_dirty(bh_fat);
+ if (fatdata == 0xfffa)
+ break; /* end of file */
+ } while (1);
+ /* Avoid writes to mtd if possible
+ * so check if a write is really
+ * required here */
+ fatdata = ((__u16 *) bh_fat->b_data)[(__u16) (inode_num)];
+ if (fatdata != 0xfffa) {
+ ((__u16 *) (bh_fat->b_data))[(__u16) (inode_num)]
+ = 0xfffa;
+ mark_buffer_dirty(bh_fat);
}
- /* Now every other block */
- else {
+ brelse(bh_fat);
+
+ }
+ /* Now every other block */
+ else {
+ if (inode_num == 0) {
+ return vmufs_game_write(file, buf, writebuf, count,
+ ppos);
+ } else {
+
/*Look for a free block in the FAT */
__u16 fatdata;
- unsigned long nextblock = in->i_ino - 1;
+ unsigned long nextblock = inode_num - 1;
bh_fat =
bread(in->i_sb->s_dev, vmudetails->fat_bnum,
blksize);
@@ -525,7 +587,7 @@
0xfffa;
mark_buffer_dirty(bh_fat);
}
- int previousblock = in->i_ino;
+ int previousblock = inode_num;
do {
fatdata =
((__u16 *) bh_fat->
@@ -534,7 +596,7 @@
|| (fatdata == 0xfffa)) {
((__u16 *) bh_fat->
b_data)[previousblock] =
- nextblock;
+ cpu_to_le16(nextblock);
mark_buffer_dirty(bh_fat);
break;
}
@@ -563,6 +625,9 @@
loff_t * ppos)
{
struct inode *in = file->f_dentry->d_inode;
+ unsigned long inode_num = in->i_ino;
+ if (inode_num == VMUFS_ZEROBLOCK)
+ inode_num = 0;
unsigned long blkoffset = *ppos >> in->i_sb->s_blocksize_bits;
unsigned long blksize = in->i_blksize;
unsigned long blcks_to_read, x;
@@ -586,7 +651,7 @@
readbuf = kmalloc(count, GFP_KERNEL);
/* Traverse through FAT to read the blocks in */
x = 0;
- next_block = in->i_ino;
+ next_block = inode_num;
bh_fat = bread(in->i_sb->s_dev, vmudetails->fat_bnum, blksize);
/*Walk through to where we are */
if (blkoffset > 0) {
Index: super.c
===================================================================
RCS file: /cvsroot/linuxdc/linux-sh-dc/fs/vmufs/Attic/super.c,v
retrieving revision 1.1.2.15
retrieving revision 1.1.2.16
diff -u -d -r1.1.2.15 -r1.1.2.16
--- super.c 3 May 2003 16:31:14 -0000 1.1.2.15
+++ super.c 13 May 2003 22:29:26 -0000 1.1.2.16
@@ -94,15 +94,22 @@
in->i_version = ++event;
brelse(bh);
} else {
- int blck_read = vmudetails->dir_bnum;
- struct buffer_head *bh = bread(sb->s_dev, blck_read, 512);
- int y;
- if (in->i_ino > (vmudetails->dir_len * 0x10)) {
+ if ((in->i_ino > vmudetails->numblocks)
+ && (in->i_ino != VMUFS_ZEROBLOCK)) {
/* Not here */
- brelse(bh);
+ printk(KERN_INFO
+ "vmufs: Attempt to access file which cannot exist on this size of VMU\n");
return;
}
+ unsigned long inode_num = in->i_ino;
+ if (inode_num == VMUFS_ZEROBLOCK)
+ inode_num = 0;
+
+ int blck_read = vmudetails->dir_bnum;
+ struct buffer_head *bh = bread(sb->s_dev, blck_read, 512);
+ int y;
+
/*
* Do the same here.. clear out the old mask, and force
@@ -114,7 +121,7 @@
in->i_mode |= S_IFREG;
/* Scan through the directory to find the matching file */
- for (y = 0; y < (vmudetails->dir_len * 0x10); y++) {
+ for (y = 0; y < vmudetails->numblocks; y++) {
if ((y / 0x10) >
(vmudetails->dir_bnum - blck_read)) {
brelse(bh);
@@ -123,12 +130,14 @@
}
if (le16_to_cpu
(((__u16 *) bh->b_data)[(y % 0x10) * 0x10 +
- 0x01]) == in->i_ino)
+ 0x01]) == inode_num)
break;
}
- if (y >= (vmudetails->dir_len * 0x10)) {
+ if (y >= vmudetails->numblocks) {
brelse(bh);
+ printk(KERN_INFO
+ "vmufs: could not find this file on the vmu\n");
/* TO DO: error return required */
return;
}
@@ -176,7 +185,7 @@
0x0C]);
in->i_size = in->i_blocks * 512;
in->i_blksize = 512;
-
+ /*printk(KERN_INFO "File has inode %i and is %i bytes long\n", in->i_ino, in->i_size); */
brelse(bh);
}
}
@@ -215,7 +224,8 @@
int z, y, x, blck_read;
__u16 nextblock, fatdata;
-
+ if (in->i_ino == VMUFS_ZEROBLOCK)
+ in->i_ino = 0;
sb = in->i_sb;
vmudetails = (struct memcard *) sb->u.generic_sbp;
bh = bread(sb->s_dev, vmudetails->fat_bnum, in->i_blksize);
@@ -298,21 +308,22 @@
{
struct buffer_head *bh;
+ unsigned long inode_num;
int y, blck_read, name_len;
struct super_block *sb = in->i_sb;
struct memcard *vmudetails =
((struct memcard *) sb->u.generic_sbp);
-
- printk(KERN_INFO "In vmufs_write_inode\n");
-
+ if (in->i_ino == VMUFS_ZEROBLOCK)
+ inode_num = 0;
+ else
+ inode_num = in->i_ino;
/* update the directory and inode details */
-
/* Now search for the directory entry */
blck_read = vmudetails->dir_bnum;
bh = bread(sb->s_dev, blck_read, in->i_blksize);
- for (y = 0; y < (vmudetails->dir_len * 0x10); y++) {
+ for (y = 0; y < vmudetails->numblocks; y++) {
if ((y / 0x10) > (vmudetails->dir_bnum - blck_read)) {
brelse(bh);
blck_read--;
@@ -320,20 +331,20 @@
}
if (le16_to_cpu
(((__u16 *) bh->b_data)[(y % 0x10) * 0x10 +
- 0x01]) == in->i_ino)
+ 0x01]) == inode_num)
break;
}
/* Have the directory entry
* so now update it */
int z = (y % 0x10) * 0x20;
- if (in->i_ino != 0)
+ if (inode_num != 0)
bh->b_data[z] = 0x33; /* data file */
else
bh->b_data[z] = 0xcc;
if ((bh->b_data[z + 1] != (char) 0x00)
&& (bh->b_data[z + 1] != (char) 0xff))
bh->b_data[z + 1] = (char) 0x00;
- ((__u16 *) bh->b_data)[z / 2 + 1] = cpu_to_le16(in->i_ino);
+ ((__u16 *) bh->b_data)[z / 2 + 1] = cpu_to_le16(inode_num);
/* BCD timestamp it */
unsigned long unix_date = CURRENT_TIME;
int year, day, nl_day, month; /*inspired by FAT driver */
@@ -369,10 +380,10 @@
bh->b_data[z + 0x16] = bcd_from_u8((__u8) (unix_date % 60));
((__u16 *) bh->b_data)[z / 2 + 0x0C] = cpu_to_le16(in->i_blocks);
- if (in->i_ino != 0)
+ if (inode_num != 0)
((__u16 *) bh->b_data)[z / 2 + 0x0D] = 0;
else
- ((__u16 *) bh->b_data)[z / 2 + 0x0D] = 1; /*game */
+ ((__u16 *) bh->b_data)[z / 2 + 0x0D] = cpu_to_le16(1); /*game */
in->i_mtime = unix_date;
mark_buffer_dirty(bh);
brelse(bh);
@@ -402,6 +413,14 @@
}
+
+/**********************
+ * vmufs_read_super *
+ * Read directory *
+ * locations off *
+ * superblock *
+ * ********************/
+
static struct super_block *vmufs_read_super(struct super_block *sb,
void *data, int silent)
{
@@ -426,20 +445,13 @@
struct memcard *vmudata =
kmalloc(sizeof(struct memcard), GFP_KERNEL);
- vmudata->numblocks = z;
+
+ vmudata->numblocks = le16_to_cpu(((__u16 *) bh->b_data)[0x50 / 2]); /*User blocks */
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);
+ vmudata->fat_bnum = le16_to_cpu(((__u16 *) bh->b_data)[0x46 / 2]);
+ vmudata->fat_len = le16_to_cpu(((__u16 *) bh->b_data)[0x48 / 2]);
+ vmudata->dir_bnum = le16_to_cpu(((__u16 *) bh->b_data)[0x4a / 2]);
+ vmudata->dir_len = le16_to_cpu(((__u16 *) bh->b_data)[0x4c / 2]);
sb->u.generic_sbp = vmudata;
struct inode *root_i;
|