
From: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>

This changes ->free_clusters and ->prev_free from "int" to "unsigned int". 
These value should be never negative value (but it's using 0xffffffff(-1) as
undefined state).

With this changes, fatfs would handle the corruption of free_clusters
more proper.

Signed-off-by: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/fat/fatent.c          |    3 +--
 25-akpm/fs/fat/inode.c           |    6 +++++-
 25-akpm/include/linux/msdos_fs.h |    4 ++--
 3 files changed, 8 insertions(+), 5 deletions(-)

diff -puN fs/fat/fatent.c~fat-use-unsigned-int-for-free_clusters-and fs/fat/fatent.c
--- 25/fs/fat/fatent.c~fat-use-unsigned-int-for-free_clusters-and	Sun Mar  6 17:13:10 2005
+++ 25-akpm/fs/fat/fatent.c	Sun Mar  6 17:13:10 2005
@@ -453,8 +453,7 @@ int fat_alloc_clusters(struct inode *ino
 	fatent_init(&fatent);
 	fatent_set_entry(&fatent, sbi->prev_free + 1);
 	while (count < sbi->max_cluster) {
-		fatent.entry %= sbi->max_cluster;
-		if (fatent.entry < FAT_START_ENT)
+		if (fatent.entry >= sbi->max_cluster)
 			fatent.entry = FAT_START_ENT;
 		fatent_set_entry(&fatent, fatent.entry);
 		err = fat_ent_read_block(sb, &fatent);
diff -puN fs/fat/inode.c~fat-use-unsigned-int-for-free_clusters-and fs/fat/inode.c
--- 25/fs/fat/inode.c~fat-use-unsigned-int-for-free_clusters-and	Sun Mar  6 17:13:10 2005
+++ 25-akpm/fs/fat/inode.c	Sun Mar  6 17:13:10 2005
@@ -1163,7 +1163,7 @@ int fat_fill_super(struct super_block *s
 	sbi->fat_length = le16_to_cpu(b->fat_length);
 	sbi->root_cluster = 0;
 	sbi->free_clusters = -1;	/* Don't know yet */
-	sbi->prev_free = -1;
+	sbi->prev_free = FAT_START_ENT;
 
 	if (!sbi->fat_length && b->fat32_length) {
 		struct fat_boot_fsinfo *fsinfo;
@@ -1247,6 +1247,10 @@ int fat_fill_super(struct super_block *s
 	/* check the free_clusters, it's not necessarily correct */
 	if (sbi->free_clusters != -1 && sbi->free_clusters > total_clusters)
 		sbi->free_clusters = -1;
+	/* check the prev_free, it's not necessarily correct */
+	sbi->prev_free %= sbi->max_cluster;
+	if (sbi->prev_free < FAT_START_ENT)
+		sbi->prev_free = FAT_START_ENT;
 
 	brelse(bh);
 
diff -puN include/linux/msdos_fs.h~fat-use-unsigned-int-for-free_clusters-and include/linux/msdos_fs.h
--- 25/include/linux/msdos_fs.h~fat-use-unsigned-int-for-free_clusters-and	Sun Mar  6 17:13:10 2005
+++ 25-akpm/include/linux/msdos_fs.h	Sun Mar  6 17:13:10 2005
@@ -225,8 +225,8 @@ struct msdos_sb_info {
 	unsigned long root_cluster;  /* first cluster of the root directory */
 	unsigned long fsinfo_sector; /* sector number of FAT32 fsinfo */
 	struct semaphore fat_lock;
-	int prev_free;               /* previously allocated cluster number */
-	int free_clusters;           /* -1 if undefined */
+	unsigned int prev_free;      /* previously allocated cluster number */
+	unsigned int free_clusters;  /* -1 if undefined */
 	struct fat_mount_options options;
 	struct nls_table *nls_disk;  /* Codepage used on disk */
 	struct nls_table *nls_io;    /* Charset used for input and display */
_
