Commit 3c0ed9c3a561ca744b2b76921bb8352ba2340669
Committed by
Tom Rini
1 parent
ed76f91277
Exists in
v2017.01-smarct4x
and in
25 other branches
fs/fat: Do not write unmodified fat entries to disk
The code caches 6 sectors of the FAT. On FAT traversal, the old contents needs to be flushed to disk, but only if any FAT entries had been modified. Explicitly flag the buffer on modification. Currently, creating a new file traverses the whole FAT up to the first free cluster and rewrites the on-disk blocks. Signed-off-by: Stefan Brüns <stefan.bruens@rwth-aachen.de> Reviewed-by: Lukasz Majewski <l.majewski@samsung.com>
Showing 3 changed files with 21 additions and 12 deletions Side-by-side Diff
fs/fat/fat.c
fs/fat/fat_write.c
... | ... | @@ -104,13 +104,19 @@ |
104 | 104 | /* |
105 | 105 | * Write fat buffer into block device |
106 | 106 | */ |
107 | -static int flush_fat_buffer(fsdata *mydata) | |
107 | +static int flush_dirty_fat_buffer(fsdata *mydata) | |
108 | 108 | { |
109 | 109 | int getsize = FATBUFBLOCKS; |
110 | 110 | __u32 fatlength = mydata->fatlength; |
111 | 111 | __u8 *bufptr = mydata->fatbuf; |
112 | 112 | __u32 startblock = mydata->fatbufnum * FATBUFBLOCKS; |
113 | 113 | |
114 | + debug("debug: evicting %d, dirty: %d\n", mydata->fatbufnum, | |
115 | + (int)mydata->fat_dirty); | |
116 | + | |
117 | + if ((!mydata->fat_dirty) || (mydata->fatbufnum == -1)) | |
118 | + return 0; | |
119 | + | |
114 | 120 | startblock += mydata->fat_sect; |
115 | 121 | |
116 | 122 | if (getsize > fatlength) |
... | ... | @@ -130,6 +136,7 @@ |
130 | 136 | return -1; |
131 | 137 | } |
132 | 138 | } |
139 | + mydata->fat_dirty = 0; | |
133 | 140 | |
134 | 141 | return 0; |
135 | 142 | } |
... | ... | @@ -186,10 +193,8 @@ |
186 | 193 | startblock += mydata->fat_sect; /* Offset from start of disk */ |
187 | 194 | |
188 | 195 | /* Write back the fatbuf to the disk */ |
189 | - if (mydata->fatbufnum != -1) { | |
190 | - if (flush_fat_buffer(mydata) < 0) | |
191 | - return -1; | |
192 | - } | |
196 | + if (flush_dirty_fat_buffer(mydata) < 0) | |
197 | + return -1; | |
193 | 198 | |
194 | 199 | if (disk_read(startblock, getsize, bufptr) < 0) { |
195 | 200 | debug("Error reading FAT blocks\n"); |
... | ... | @@ -494,10 +499,8 @@ |
494 | 499 | if (getsize > fatlength) |
495 | 500 | getsize = fatlength; |
496 | 501 | |
497 | - if (mydata->fatbufnum != -1) { | |
498 | - if (flush_fat_buffer(mydata) < 0) | |
499 | - return -1; | |
500 | - } | |
502 | + if (flush_dirty_fat_buffer(mydata) < 0) | |
503 | + return -1; | |
501 | 504 | |
502 | 505 | if (disk_read(startblock, getsize, bufptr) < 0) { |
503 | 506 | debug("Error reading FAT blocks\n"); |
... | ... | @@ -506,6 +509,9 @@ |
506 | 509 | mydata->fatbufnum = bufnum; |
507 | 510 | } |
508 | 511 | |
512 | + /* Mark as dirty */ | |
513 | + mydata->fat_dirty = 1; | |
514 | + | |
509 | 515 | /* Set the actual entry */ |
510 | 516 | switch (mydata->fatsize) { |
511 | 517 | case 32: |
... | ... | @@ -645,7 +651,7 @@ |
645 | 651 | |
646 | 652 | dir_curclust = dir_newclust; |
647 | 653 | |
648 | - if (flush_fat_buffer(mydata) < 0) | |
654 | + if (flush_dirty_fat_buffer(mydata) < 0) | |
649 | 655 | return; |
650 | 656 | |
651 | 657 | memset(get_dentfromdir_block, 0x00, |
... | ... | @@ -675,7 +681,7 @@ |
675 | 681 | } |
676 | 682 | |
677 | 683 | /* Flush fat buffer */ |
678 | - if (flush_fat_buffer(mydata) < 0) | |
684 | + if (flush_dirty_fat_buffer(mydata) < 0) | |
679 | 685 | return -1; |
680 | 686 | |
681 | 687 | return 0; |
... | ... | @@ -1011,6 +1017,7 @@ |
1011 | 1017 | } |
1012 | 1018 | |
1013 | 1019 | mydata->fatbufnum = -1; |
1020 | + mydata->fat_dirty = 0; | |
1014 | 1021 | mydata->fatbuf = memalign(ARCH_DMA_MINALIGN, FATBUFSIZE); |
1015 | 1022 | if (mydata->fatbuf == NULL) { |
1016 | 1023 | debug("Error: allocating memory\n"); |
... | ... | @@ -1111,7 +1118,7 @@ |
1111 | 1118 | debug("attempt to write 0x%llx bytes\n", *actwrite); |
1112 | 1119 | |
1113 | 1120 | /* Flush fat buffer */ |
1114 | - ret = flush_fat_buffer(mydata); | |
1121 | + ret = flush_dirty_fat_buffer(mydata); | |
1115 | 1122 | if (ret) { |
1116 | 1123 | printf("Error: flush fat buffer\n"); |
1117 | 1124 | goto exit; |
include/fat.h
... | ... | @@ -169,6 +169,7 @@ |
169 | 169 | int fatsize; /* Size of FAT in bits */ |
170 | 170 | __u32 fatlength; /* Length of FAT in sectors */ |
171 | 171 | __u16 fat_sect; /* Starting sector of the FAT */ |
172 | + __u8 fat_dirty; /* Set if fatbuf has been modified */ | |
172 | 173 | __u32 rootdir_sect; /* Start sector of root directory */ |
173 | 174 | __u16 sect_size; /* Size of sectors in bytes */ |
174 | 175 | __u16 clust_size; /* Size of clusters in sectors */ |