From khivi@psyche.nj.us.utstar.com  Thu Feb 12 16:04:56 2004
Return-Path: <khivi@psyche.nj.us.utstar.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id EE04C16A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 12 Feb 2004 16:04:55 -0800 (PST)
Received: from psyche.nj.us.utstar.com (gwnj8.utstar.com [65.200.123.8])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 616B943D2F
	for <FreeBSD-gnats-submit@freebsd.org>; Thu, 12 Feb 2004 16:04:55 -0800 (PST)
	(envelope-from khivi@psyche.nj.us.utstar.com)
Received: (from khivi@localhost)
	by psyche.nj.us.utstar.com (8.11.6/8.11.6) id i1D04Yd97539;
	Thu, 12 Feb 2004 19:04:34 -0500 (EST)
	(envelope-from khivi)
Message-Id: <200402130004.i1D04Yd97539@psyche.nj.us.utstar.com>
Date: Thu, 12 Feb 2004 19:04:34 -0500 (EST)
From: Amit Khivesara <khivi@psyche.nj.us.utstar.com>
Reply-To: amit.khivesara@utstar.com
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: Fsync for msdos fs does not sync entries
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         62762
>Category:       kern
>Synopsis:       [msdosfs] Fsync for msdos fs does not sync entries
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kib
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Feb 12 16:10:13 PST 2004
>Closed-Date:    Mon Jul 01 14:34:42 UTC 2013
>Last-Modified:  Mon Jul 01 14:34:42 UTC 2013
>Originator:     Amit Khivesara
>Release:        FreeBSD 4.9-RELEASE i386
>Organization:
>Environment:
System: FreeBSD mobo11 4.9-XOS-kernel-4.9-dev Build 44281 2004/02/12 16:34:09, khivi@psyche 2004/02/12 18:53:46 FreeBSD  root@psyche.nj.us.utstar.com:/usr/home/khivi/p4/mobo-4.9/kernel/build/kernel/DISKLESS  i386
>Description:
	Fsync on a file should sync all the data and meta-data blocks
	for the file. For the msdos fs, the fat enteries do not get synced.
	
>How-To-Repeat:
	Do multiple file writes on a file  and fsync the file.
	Reboot really fast (pull power plug or reboot -q -n ).  Basically you
	do not want the syncher to come in and sync the dirty blocks.
	On power up the files will contain a partial file or a bad file.
>Fix:

diff -ur msdosfs.old/fat.h msdosfs.new/fat.h
--- msdosfs.old/fat.h	Thu Feb 12 18:39:32 2004
+++ msdosfs.new/fat.h	Thu Feb 12 18:36:13 2004
@@ -104,5 +104,6 @@
 int freeclusterchain __P((struct msdosfsmount *pmp, u_long startchain));
 int extendfile __P((struct denode *dep, u_long count, struct buf **bpp, u_long *ncp, int flags));
 void fc_purge __P((struct denode *dep, u_int frcn));
+void fat_sync __P((struct vnode * , struct denode *dep));
 
 #endif	/* _KERNEL */
diff -ur msdosfs.old/msdosfs_fat.c msdosfs.new/msdosfs_fat.c
--- msdosfs.old/msdosfs_fat.c	Thu Feb 12 18:39:32 2004
+++ msdosfs.new/msdosfs_fat.c	Thu Feb 12 18:49:38 2004
@@ -322,6 +322,80 @@
 	}
 }
 
+
+/*
+ * Sync the fat cache in denode dep of all entries relating to file
+ */
+void
+fat_sync(vnode,dep)
+	struct vnode *vnode;
+	struct denode *dep;
+{
+    u_long cn;
+    u_long prevcn;
+
+    u_long byteoffset;
+    u_long bsize;
+    u_long bo;
+    u_long bn;
+	u_long bp_bn = -1;
+	int error;
+    struct buf *bp = NULL;
+    struct msdosfsmount *pmp = dep->de_pmp;
+
+    u_int pm_flags=pmp->pm_flags;
+    pmp->pm_flags |= MSDOSFSMNT_WAITONFAT;
+
+     cn=dep->de_StartCluster;
+     while (1){
+		/*
+		 * Stop with all reserved clusters, not just with EOF.
+		 */
+		if ((cn | ~pmp->pm_fatmask) >= CLUST_RSRVD)
+			goto hiteof;
+		byteoffset = FATOFS(pmp, cn);
+		fatblock(pmp, byteoffset, &bn, &bsize, &bo);
+		if (bn != bp_bn) {
+			if (bp) {
+                                updatefats(pmp, bp, bp_bn);
+                        }
+			error = bread(pmp->pm_devvp, bn, bsize, NOCRED, &bp);
+			if (error) {
+				brelse(bp);
+				goto func_ret;
+			}
+			bp_bn = bn;
+		}
+
+		prevcn = cn;
+		if (FAT32(pmp))
+			cn = getulong(&bp->b_data[bo]);
+		else
+			cn = getushort(&bp->b_data[bo]);
+		if (FAT12(pmp) && (prevcn & 1))
+			cn >>= 4;
+		cn &= pmp->pm_fatmask;
+
+		/*
+		 * Force the special cluster numbers
+		 * to be the same for all cluster sizes
+		 * to let the rest of msdosfs handle
+		 * all cases the same.
+		 */
+		if ((cn | ~pmp->pm_fatmask) >= CLUST_RSRVD)
+			cn |= ~pmp->pm_fatmask;
+     }
+
+     
+hiteof:
+    if (bp) {
+        updatefats(pmp, bp, bp_bn);
+    }
+func_ret:
+    pmp->pm_flags=pm_flags;
+    return;
+}
+
 /*
  * Update the fat.
  * If mirroring the fat, update all copies, with the first copy as last.
diff -ur msdosfs.old/msdosfs_vnops.c msdosfs.new/msdosfs_vnops.c
--- msdosfs.old/msdosfs_vnops.c	Thu Feb 12 18:39:32 2004
+++ msdosfs.new/msdosfs_vnops.c	Thu Feb 12 18:50:37 2004
@@ -875,6 +875,7 @@
 		(void) bwrite(bp);
 		goto loop;
 	}
+	fat_sync(vp,VTODE(vp));
 	while (vp->v_numoutput) {
 		vp->v_flag |= VBWAIT;
 		(void) tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "msdosfsn", 0);
>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->trhodes 
Responsible-Changed-By: trhodes 
Responsible-Changed-When: Fri Feb 13 08:52:58 PST 2004 
Responsible-Changed-Why:  
Take this PR. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=62762 
Responsible-Changed-From-To: trhodes->bde 
Responsible-Changed-By: kmacy 
Responsible-Changed-When: Fri Nov 16 01:13:56 UTC 2007 
Responsible-Changed-Why:  

BDE has been most active in msdosfs. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=62762 

From: John Baldwin <jhb@FreeBSD.org>
To: bug-followup@FreeBSD.org, amit.khivesara@utstar.com
Cc:  
Subject: Re: kern/62762: [msdosfs] Fsync for msdos fs does not sync entries
Date: Mon, 14 May 2012 13:49:18 -0400

 Looking at the current code in HEAD, msdosfs_fsync() calls deupdat()
 which only writes the directory entry to disk.  It does not flush any
 modified FAT clusters to disk.
 
 -- 
 John Baldwin
State-Changed-From-To: open->patched 
State-Changed-By: kib 
State-Changed-When: Fri May 3 20:34:19 UTC 2013 
State-Changed-Why:  
A change which should fix syncing the FAT for fsync(2) was committed. 
The approach is different. 


Responsible-Changed-From-To: bde->kib 
Responsible-Changed-By: kib 
Responsible-Changed-When: Fri May 3 20:34:19 UTC 2013 
Responsible-Changed-Why:  
A change which should fix syncing the FAT for fsync(2) was committed. 
The approach is different. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=62762 
State-Changed-From-To: patched->closed 
State-Changed-By: kib 
State-Changed-When: Mon Jul 1 14:33:49 UTC 2013 
State-Changed-Why:  
Merged to stable. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=62762 
>Unformatted:
I doubt this particular issue is still present. I believe that BDE would know.
