summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/fat/fat.c1
-rw-r--r--fs/fat/fat_write.c31
-rw-r--r--include/fat.h1
3 files changed, 21 insertions, 12 deletions
diff --git a/fs/fat/fat.c b/fs/fat/fat.c
index 826bd85286..df9f2b5656 100644
--- a/fs/fat/fat.c
+++ b/fs/fat/fat.c
@@ -876,6 +876,7 @@ int do_fat_read_at(const char *filename, loff_t pos, void *buffer,
}
mydata->fatbufnum = -1;
+ mydata->fat_dirty = 0;
mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE);
if (mydata->fatbuf == NULL) {
debug("Error: allocating memory\n");
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 961ccd8e24..babe9c8dd0 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -104,13 +104,19 @@ static __u8 num_of_fats;
/*
* Write fat buffer into block device
*/
-static int flush_fat_buffer(fsdata *mydata)
+static int flush_dirty_fat_buffer(fsdata *mydata)
{
int getsize = FATBUFBLOCKS;
__u32 fatlength = mydata->fatlength;
__u8 *bufptr = mydata->fatbuf;
__u32 startblock = mydata->fatbufnum * FATBUFBLOCKS;
+ debug("debug: evicting %d, dirty: %d\n", mydata->fatbufnum,
+ (int)mydata->fat_dirty);
+
+ if ((!mydata->fat_dirty) || (mydata->fatbufnum == -1))
+ return 0;
+
startblock += mydata->fat_sect;
if (getsize > fatlength)
@@ -130,6 +136,7 @@ static int flush_fat_buffer(fsdata *mydata)
return -1;
}
}
+ mydata->fat_dirty = 0;
return 0;
}
@@ -186,10 +193,8 @@ static __u32 get_fatent_value(fsdata *mydata, __u32 entry)
startblock += mydata->fat_sect; /* Offset from start of disk */
/* Write back the fatbuf to the disk */
- if (mydata->fatbufnum != -1) {
- if (flush_fat_buffer(mydata) < 0)
- return -1;
- }
+ if (flush_dirty_fat_buffer(mydata) < 0)
+ return -1;
if (disk_read(startblock, getsize, bufptr) < 0) {
debug("Error reading FAT blocks\n");
@@ -494,10 +499,8 @@ static int set_fatent_value(fsdata *mydata, __u32 entry, __u32 entry_value)
if (getsize > fatlength)
getsize = fatlength;
- if (mydata->fatbufnum != -1) {
- if (flush_fat_buffer(mydata) < 0)
- return -1;
- }
+ if (flush_dirty_fat_buffer(mydata) < 0)
+ return -1;
if (disk_read(startblock, getsize, bufptr) < 0) {
debug("Error reading FAT blocks\n");
@@ -506,6 +509,9 @@ static int set_fatent_value(fsdata *mydata, __u32 entry, __u32 entry_value)
mydata->fatbufnum = bufnum;
}
+ /* Mark as dirty */
+ mydata->fat_dirty = 1;
+
/* Set the actual entry */
switch (mydata->fatsize) {
case 32:
@@ -645,7 +651,7 @@ static void flush_dir_table(fsdata *mydata, dir_entry **dentptr)
dir_curclust = dir_newclust;
- if (flush_fat_buffer(mydata) < 0)
+ if (flush_dirty_fat_buffer(mydata) < 0)
return;
memset(get_dentfromdir_block, 0x00,
@@ -675,7 +681,7 @@ static int clear_fatent(fsdata *mydata, __u32 entry)
}
/* Flush fat buffer */
- if (flush_fat_buffer(mydata) < 0)
+ if (flush_dirty_fat_buffer(mydata) < 0)
return -1;
return 0;
@@ -1011,6 +1017,7 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size,
}
mydata->fatbufnum = -1;
+ mydata->fat_dirty = 0;
mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE);
if (mydata->fatbuf == NULL) {
debug("Error: allocating memory\n");
@@ -1111,7 +1118,7 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size,
debug("attempt to write 0x%llx bytes\n", *actwrite);
/* Flush fat buffer */
- ret = flush_fat_buffer(mydata);
+ ret = flush_dirty_fat_buffer(mydata);
if (ret) {
printf("Error: flush fat buffer\n");
goto exit;
diff --git a/include/fat.h b/include/fat.h
index 9d053e6fa6..8ec91cda75 100644
--- a/include/fat.h
+++ b/include/fat.h
@@ -169,6 +169,7 @@ typedef struct {
int fatsize; /* Size of FAT in bits */
__u32 fatlength; /* Length of FAT in sectors */
__u16 fat_sect; /* Starting sector of the FAT */
+ __u8 fat_dirty; /* Set if fatbuf has been modified */
__u32 rootdir_sect; /* Start sector of root directory */
__u16 sect_size; /* Size of sectors in bytes */
__u16 clust_size; /* Size of clusters in sectors */