Subject: kern/17143: ftruncate on msdosfs file corrupts data
To: None <gnats-bugs@gnats.netbsd.org>
From: None <rb-netbsd@bigscarychildren.net>
List: netbsd-bugs
Date: 06/02/2002 14:14:37
>Number:         17143
>Category:       kern
>Synopsis:       ftruncate on msdosfs file corrupts data
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sun Jun 02 11:15:00 PDT 2002
>Closed-Date:
>Last-Modified:
>Originator:     Rick Byers
>Release:        NetBSD 1.6_BETA1 2002-05-29
>Organization:
>Environment:
System: NetBSD pbrane.Apenheul.BigScaryChildren.net 1.6_BETA1 NetBSD 1.6_BETA1 (PBRANE) #5: Sun Jun 2 13:44:01 EDT 2002 rick@pbrane.Apenheul.BigScaryChildren.net:/usr/src/sys/arch/i386/compile/PBRANE i386
Architecture: i386
Machine: i386
>Description:
If I create a file on my msdosfs filesystem with the editor "pico", and
then unmount and remount the filesystem, the file contains garbage data
(often all 'U' characters).

The file looks fine until the unount/remount is done.
If I use the shell to create the file (and presumably other editors), it
works fine.  

I narrowed the problem down to the use of ftruncate.  After writing the
data to the file, pico calls ftruncate to truncate the file to the length
of the data.

Here are some MSDOSFS_DEBUG messages from around the time the file written
and truncted.  Theese might be helpfull when tracing through the msdosfs 
code looking for the problem:

Jun  2 14:06:40 pbrane /netbsd: msdosfs_create(cnp 0xe34adf04, vap 0xe34ade3c
Jun  2 14:06:40 pbrane /netbsd: createde(dep 0xe34add24, ddep 0xe3285000, depp 0xe34add18, cnp 0xe34adf04)
Jun  2 14:06:40 pbrane /netbsd: deget(pmp 0xc0e8e200, dirclust 2, diroffset 1c0, depp 0xe34add18)
Jun  2 14:06:40 pbrane /netbsd: msdosfs_write(vp 0xe34b4194, uio 0xe34adee0, ioflag 1, cred 0xc0ecac00
Jun  2 14:06:40 pbrane /netbsd: msdosfs_write(): diroff 448, dirclust 2, startcluster 0
Jun  2 14:06:40 pbrane /netbsd: clusteralloc(): find 1 clusters
Jun  2 14:06:40 pbrane /netbsd: fatchain(pmp 0xc0e8e200, start 713224, count 1, fillwith ffffffff)
Jun  2 14:06:40 pbrane /netbsd: updatefats(pmp 0xc0e8e200, bp 0xc9f07178, fatbn 5536)
Jun  2 14:06:40 pbrane /netbsd: clusteralloc(): allocated cluster chain at 713224 (1 clusters)
Jun  2 14:06:40 pbrane /netbsd: msdosfs_setattr(): vp 0xe34b4194, vap 0xe34adedc, cred 0xc0ecac00, p 0xe33801e4
Jun  2 14:06:40 pbrane /netbsd: detrunc(): file TST     TXT, length 22, flags 0
Jun  2 14:06:40 pbrane /netbsd: detrunc(): allerror 0, eofentry 713224
Jun  2 14:06:40 pbrane /netbsd: fatentry(func 3, pmp 0xc0e8e200, clust 713224, oldcon 0xe34ade04, newcon ffffffff)
Jun  2 14:06:40 pbrane /netbsd: updatefats(pmp 0xc0e8e200, bp 0xc9f07178, fatbn 5536)
Jun  2 14:06:40 pbrane /netbsd: msdosfs_inactive(): dep 0xe3285460, de_Name[0] 54
Jun  2 14:06:40 pbrane /netbsd: msdosfs_inactive(): dep 0xe3285460, refcnt 1, mntflag 1004 
Jun  2 14:06:40 pbrane /netbsd: msdosfs_inactive(): v_usecount 0, de_Name[0] 54

>How-To-Repeat:
Use the follwing C program to create a file on an msdos fs filesystem and
call ftruncate using its existing length:

#include <stdio.h>
#include <fcntl.h>

int main()
{
	const char buf[] = "testing, 1...2...3...\n";
	int fd;

	fd = open( "tst.txt", O_WRONLY | O_CREAT, 0644 );
	if( fd == -1 )
		err( 1, "open" );
	write( fd, buf, sizeof(buf)-1 );
	ftruncate( fd, sizeof(buf)-1 );

	close( fd );
	return 0;
}


pbrane:/msdos/data# ~rick/tst
pbrane:/msdos/data# cat tst.txt
testing, 1...2...3...
pbrane:/msdos/data# cat tst.txt > tst2.txt
pbrane:/msdos/data# cat tst2.txt
testing, 1...2...3...
pbrane:/msdos/data# cat tst.txt
testing, 1...2...3...
pbrane:/msdos/data# cd ..
pbrane:/msdos# umount /msdos/data; mount /msdos/data
pbrane:/msdos# cd data
pbrane:/msdos/data# cat tst.txt
UUUUUUUUUUUUUUUUUUUUUUpbrane:/msdos/data# cat tst2.txt
testing, 1...2...3...

Note: fstab entry for /msdos/data is:
/dev/wd1f       /msdos/data     msdos   rw,noexec,-l

>Fix:
Unknown.
>Release-Note:
>Audit-Trail:
>Unformatted: