Date: Thu, 12 Feb 2004 19:04:34 -0500 (EST) From: Amit Khivesara <khivi@psyche.nj.us.utstar.com> To: FreeBSD-gnats-submit@FreeBSD.org Subject: kern/62762: Fsync for msdos fs does not sync entries Message-ID: <200402130004.i1D04Yd97539@psyche.nj.us.utstar.com> Resent-Message-ID: <200402130010.i1D0ADpf043209@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 62762 >Category: kern >Synopsis: Fsync for msdos fs does not sync entries >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Feb 12 16:10:13 PST 2004 >Closed-Date: >Last-Modified: >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: >Unformatted:
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200402130004.i1D04Yd97539>