summaryrefslogtreecommitdiffstats
path: root/sys/fs/msdosfs/msdosfs_fat.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2013-02-01 18:25:53 +0000
committerkib <kib@FreeBSD.org>2013-02-01 18:25:53 +0000
commit35907051bb7af5a3d9532671d959a88be064bce7 (patch)
treedbd388781f222c8d5211829f726a7cbeb745bcf2 /sys/fs/msdosfs/msdosfs_fat.c
parent96b12145fb2d0521fe7cd4e58d4691a3cf2861ea (diff)
downloadFreeBSD-src-35907051bb7af5a3d9532671d959a88be064bce7.zip
FreeBSD-src-35907051bb7af5a3d9532671d959a88be064bce7.tar.gz
Backup FATs were sometimes marked dirty by copying their first block
from the primary FAT, and then they were not marked clean on unmount. Force marking them clean when appropriate. Submitted by: bde MFC after: 1 week
Diffstat (limited to 'sys/fs/msdosfs/msdosfs_fat.c')
-rw-r--r--sys/fs/msdosfs/msdosfs_fat.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c
index c2cff23..9cb7634 100644
--- a/sys/fs/msdosfs/msdosfs_fat.c
+++ b/sys/fs/msdosfs/msdosfs_fat.c
@@ -321,8 +321,8 @@ updatefats(pmp, bp, fatbn)
struct buf *bp;
u_long fatbn;
{
- int i;
struct buf *bpn;
+ int cleanfat, i;
#ifdef MSDOSFS_DEBUG
printf("updatefats(pmp %p, bp %p, fatbn %lu)\n", pmp, bp, fatbn);
@@ -362,12 +362,23 @@ updatefats(pmp, bp, fatbn)
* filesystem was mounted. If synch is asked for then use
* bwrite()'s and really slow things down.
*/
+ if (fatbn != pmp->pm_fatblk || FAT12(pmp))
+ cleanfat = 0;
+ else if (FAT16(pmp))
+ cleanfat = 16;
+ else
+ cleanfat = 32;
for (i = 1; i < pmp->pm_FATs; i++) {
fatbn += pmp->pm_FATsecs;
/* getblk() never fails */
bpn = getblk(pmp->pm_devvp, fatbn, bp->b_bcount,
0, 0, 0);
bcopy(bp->b_data, bpn->b_data, bp->b_bcount);
+ /* Force the clean bit on in the other copies. */
+ if (cleanfat == 16)
+ ((u_int8_t *)bpn->b_data)[3] |= 0x80;
+ else if (cleanfat == 32)
+ ((u_int8_t *)bpn->b_data)[7] |= 0x08;
if (pmp->pm_flags & MSDOSFSMNT_WAITONFAT)
bwrite(bpn);
else
OpenPOWER on IntegriCloud