diff options
author | trhodes <trhodes@FreeBSD.org> | 2003-12-26 17:19:19 +0000 |
---|---|---|
committer | trhodes <trhodes@FreeBSD.org> | 2003-12-26 17:19:19 +0000 |
commit | 7dde93f1df429cf9a818bf7b716962298f489807 (patch) | |
tree | 9835c24a1c804ff149a9d1763c5619fbd69ab703 /sys/fs/msdosfs/msdosfs_fat.c | |
parent | 1b287b69e9efa62bb22618045208556c1edcbff7 (diff) | |
download | FreeBSD-src-7dde93f1df429cf9a818bf7b716962298f489807.zip FreeBSD-src-7dde93f1df429cf9a818bf7b716962298f489807.tar.gz |
Make msdosfs support the dirty flag in FAT16 and FAT32.
Enable lockf support.
PR: 55861
Submitted by: Jun Su <junsu@m-net.arbornet.org> (original version)
Reviewed by: make universe
Diffstat (limited to 'sys/fs/msdosfs/msdosfs_fat.c')
-rw-r--r-- | sys/fs/msdosfs/msdosfs_fat.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/sys/fs/msdosfs/msdosfs_fat.c b/sys/fs/msdosfs/msdosfs_fat.c index 1e9a3cf..1f75d7a 100644 --- a/sys/fs/msdosfs/msdosfs_fat.c +++ b/sys/fs/msdosfs/msdosfs_fat.c @@ -1106,3 +1106,70 @@ extendfile(dep, count, bpp, ncp, flags) return (0); } + +/* [2753891] + * Routine to mark a FAT16 or FAT32 volume as "clean" or "dirty" by manipulating the upper bit + * of the FAT entry for cluster 1. Note that this bit is not defined for FAT12 volumes, which + * are always assumed to be dirty. + * + * The fatentry() routine only works on cluster numbers that a file could occupy, so it won't + * manipulate the entry for cluster 1. So we have to do it here. The code is ripped from + * fatentry(), and tailored for cluster 1. + * + * Inputs: + * pmp The MS-DOS volume to mark + * dirty Non-zero if the volume should be marked dirty; zero if it should be marked clean. + * + * Result: + * 0 Success + * EROFS Volume is read-only + * ? (other errors from called routines) + */ +int markvoldirty(struct msdosfsmount *pmp, int dirty) +{ + int error; + u_long bn, bo, bsize, byteoffset; + u_long fatval; + struct buf *bp; + + /* FAT12 does not support a "clean" bit, so don't do anything */ + if (FAT12(pmp)) + return 0; + + /* Can't change the bit on a read-only filesystem */ + if (pmp->pm_flags & MSDOSFSMNT_RONLY) + return EROFS; + + /* Fetch the block containing the FAT entry */ + byteoffset = FATOFS(pmp, 1); /* Find the location of cluster 1 */ + fatblock(pmp, byteoffset, &bn, &bsize, &bo); + + error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp); + if (error) { + brelse(bp); + return (error); + } + + /* Get the current value of the FAT entry and set/clear the high bit */ + if (FAT32(pmp)) { + /* FAT32 uses bit 27 */ + fatval = getulong(&bp->b_data[bo]); + if (dirty) + fatval &= 0xF7FFFFFF; /* dirty means clear the "clean" bit */ + else + fatval |= 0x08000000; /* clean means set the "clean" bit */ + putulong(&bp->b_data[bo], fatval); + } + else { + /* Must be FAT16; use bit 15 */ + fatval = getushort(&bp->b_data[bo]); + if (dirty) + fatval &= 0x7FFF; /* dirty means clear the "clean" bit */ + else + fatval |= 0x8000; /* clean means set the "clean" bit */ + putushort(&bp->b_data[bo], fatval); + } + + /* Write out the modified FAT block immediately */ + return bwrite(bp); +} |