I can not make my MTA work.
To: [EMAIL PROTECTED]
From: Jun Su <[EMAIL PROTECTED]>
Reply-To: Jun Su <[EMAIL PROTECTED]>
Cc:
X-send-pr-version: 3.113
X-GNATS-Notify:
>Submitter-Id: current-users
>Originator:Jun Su
>Organization: none
>Confidential: no
>Synopsis: [PATCH] MSDOSFS dirty path (importing from
Darwin)
>Severity: non-critical
>Priority: medium
>Category: kern
>Class: change-request
>Release: FreeBSD 5.1-CURRENT i386
>Environment:
System: FreeBSD junsufr.gwbn.sh.cn 5.1-CURRENT FreeBSD
5.1-CURRENT #1: Thu Jul 17 18:01:10 CST 2003
[EMAIL PROTECTED]:/usr/obj/usr/src/sys/VAIO i386
>Description:
A TODO item in the 5.2 Release Must Resolve List.
>How-To-Repeat:
>Fix:
diff -u /usr/src/sys/fs/msdosfs.orig/fat.h
msdosfs/fat.h
--- /usr/src/sys/fs/msdosfs.orig/fat.h Tue Mar 19
22:20:10 2002
+++ msdosfs/fat.h Mon Jul 14 21:02:10 2003
@@ -99,5 +99,6 @@
int freeclusterchain(struct msdosfsmount *pmp, u_long
startchain);
int extendfile(struct denode *dep, u_long count,
struct buf **bpp, u_long *ncp, int flags);
void fc_purge(struct denode *dep, u_int frcn);
+int markvoldirty(struct msdosfsmount *pmp, int
dirty);
#endif /* _KERNEL */
Only in msdosfs: fat.h.orig
diff -u /usr/src/sys/fs/msdosfs.orig/msdosfs_fat.c
msdosfs/msdosfs_fat.c
--- /usr/src/sys/fs/msdosfs.orig/msdosfs_fat.c Tue Mar
4 00:04:42 2003
+++ msdosfs/msdosfs_fat.c Mon Jul 14 21:02:10 2003
@@ -1106,3 +1106,70 @@
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 &= 0xF7FF; /* dirty means
clear the "clean" bit */
+else
+fatval |= 0x0800; /* 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);
+}
Only in msdosfs: msdosfs_fat.c.orig
diff -u /usr/src/sys/fs/msdosfs.orig/msdosfs_vfsops.c
msdosfs/msdosfs_vfsops.c
--- /usr/src/sys/fs/msdosfs.orig/msdosfs_vfsops.c Sun
Jun 29 03:05:59 2003
+++ msdosfs/msdosfs_vfsops.cMon Jul 14 21:02:11 2003
@@ -203,6 +203,11 @@
VOP_UNLOCK(devvp, 0, td);
}
pmp->pm_flags &= ~MSDOSFSMNT_RONLY;
+
+/* [2753891] Now that the
volume is modifiable, mark it dirty */
+error = markvoldirty(pmp, 1);
+if (error)
+return error;
}
if (args.fspec == 0) {
#ifdef __notyet__ /* doesn't work correctly with
current mountd XXX */
@@ -603,8 +608,13 @@
*/
if (ronly)
pmp->pm_flags |= MSDOSFSMNT_RONLY;
- else
+ else {
+/* [2753891] Mark the volume dirty
while it is mounted read/write */
+if ((error = markvoldirty(pmp, 1)) !=
0)
+goto error_exit;
+
pmp->pm_fmod = 1;
+