From nobody@FreeBSD.org  Mon Aug 19 12:51:31 2002
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id C0C6537B400
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 19 Aug 2002 12:51:31 -0700 (PDT)
Received: from www.freebsd.org (www.FreeBSD.org [216.136.204.117])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 3465B43E3B
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 19 Aug 2002 12:51:31 -0700 (PDT)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.12.4/8.12.4) with ESMTP id g7JJpUOT099118
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 19 Aug 2002 12:51:30 -0700 (PDT)
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.12.4/8.12.4/Submit) id g7JJpUcB099117;
	Mon, 19 Aug 2002 12:51:30 -0700 (PDT)
Message-Id: <200208191951.g7JJpUcB099117@www.freebsd.org>
Date: Mon, 19 Aug 2002 12:51:30 -0700 (PDT)
From: Yury Izrailevsky <izrailev@yahoo.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: lseek after ftruncate fails
X-Send-Pr-Version: www-1.0

>Number:         41792
>Category:       misc
>Synopsis:       lseek after ftruncate fails
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    tjr
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 19 13:00:04 PDT 2002
>Closed-Date:    Sat Jan 10 00:26:27 PST 2004
>Last-Modified:  Sat Jan 10 00:26:27 PST 2004
>Originator:     Yury Izrailevsky
>Release:        FreeBSD 4.6.1 RELEASE
>Organization:
University of Utah
>Environment:
FreeBSD 4.6.1-RELEASE-p10
>Description:
      File operation problem. Running the following:

write(fd, buffer, 8K);
ftruncate(fd, 0);
write(fd, buffer, 1);
off = lseek(fd, 0, SEEK_END);
printf("%d", off);

Output: 24576, expected: 1.

The size of the actual file is 1 (if you ls -l on it). However, lseek goes way past it...

Noticed this while running connectathon rewind test (part of special test suite). But fails even if don't go over NFS but just run on the local file system.

I suspect the problem is with the FS cache. Or perhaps lseek and/or ftruncate are just broken...

>How-To-Repeat:
      Here is the full source code. Running it on a 4.6 BSD causes the problem described above:

#if defined (DOS) || defined (WIN32)
#define DOSorWIN32
#include "../tests.h"
#endif

#ifndef DOSorWIN32
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#endif /* DOSorWIN32 */

main()
{
	char buffer[8192];
	int size = 8192;
	int fd;
	int i;
	off_t off;

#ifdef DOSorWIN32
	fprintf(stderr, "This Test Not Executable on DOS or Windows\n");
	exit(1);
#else
	if ((fd = open("test.file", O_RDWR | O_CREAT, 0666)) == -1) {
		perror("open");
		exit(1);
	}

	for (i = 0; i < 3; i++) {
		if (write(fd, buffer, size) != size) {
			perror("write");
			exit(1);
		}
	}

	if ((off = lseek(fd, (off_t)0, SEEK_SET)) != 0) {
		printf("file offset=%ld, expected 0\n", (long)off);
		exit(1);
	}

	if (ftruncate(fd, 0)) {
		perror("ftruncate");
		exit(1);
	}

	if (write(fd, buffer, 1) != 1) {
		perror("write");
		exit(1);
	}

	if ((off = lseek(fd, 0, SEEK_END)) != 1) {
		printf("file offset=%ld, expected 1\n", (long)off);
		exit(1);
	}

	close(fd);

	exit(0);
#endif /* DOSorWIN32 */
}

>Fix:
      Works fine on FreeBSD 4.5 and earlier.

Thanks for the help!
>Release-Note:
>Audit-Trail:

From: "Yury Izrailevsky" <yury@decru.com>
To: <freebsd-gnats-submit@FreeBSD.org>, <izrailev@yahoo.com>
Cc:  
Subject: Re: misc/41792: lseek after ftruncate fails
Date: Mon, 19 Aug 2002 13:15:18 -0700

 Clarification: apparently, BSD 4.5 also has the problem. 4.4-STABLE is fine
 though.
 

From: Bruce Evans <bde@zeta.org.au>
To: Yury Izrailevsky <izrailev@yahoo.com>
Cc: freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: misc/41792: lseek after ftruncate fails
Date: Tue, 20 Aug 2002 07:58:51 +1000 (EST)

 On Mon, 19 Aug 2002, Yury Izrailevsky wrote:
 
 > >Description:
 >       File operation problem. Running the following:
 >
 > write(fd, buffer, 8K);
 > ftruncate(fd, 0);
 > write(fd, buffer, 1);
 > off = lseek(fd, 0, SEEK_END);
 > printf("%d", off);
 >
 > Output: 24576, expected: 1.
 >
 > The size of the actual file is 1 (if you ls -l on it). However, lseek goes way past it...
 >
 > Noticed this while running connectathon rewind test (part of special test suite). But fails even if don't go over NFS but just run on the local file system.
 >
 > I suspect the problem is with the FS cache. Or perhaps lseek and/or ftruncate are just broken...
 
 This only fails over nfs under -current.  stat(2) and thus ls(1) shows that
 the file size is 24576 until the next read(2) of the file.  Then the size
 becomes 1.
 
 Bruce
 

From: Maxim Konovalov <maxim@FreeBSD.org>
To: Yury Izrailevsky <izrailev@yahoo.com>
Cc: bug-followup@FreeBSD.org
Subject: Re: misc/41792: lseek after ftruncate fails
Date: Mon, 23 Sep 2002 13:59:50 +0400 (MSD)

 Hello,
 
 [...]
 > >Environment:
 > FreeBSD 4.6.1-RELEASE-p10
 > >Description:
 >       File operation problem. Running the following:
 >
 > write(fd, buffer, 8K);
 > ftruncate(fd, 0);
 > write(fd, buffer, 1);
 > off = lseek(fd, 0, SEEK_END);
 > printf("%d", off);
 >
 > Output: 24576, expected: 1.
 
 Can't reproduce on 4.6-STABLE:
 
 $ uname -a
 FreeBSD golf.macomnet.net 4.6-20020805-MACOMNET-STABLE FreeBSD
 4.6-20020805-MACOMNET-STABLE #19: Fri Sep 20 17:09:52 MSD 2002
 maxim@golf.macomnet.net:/usr/obj/usr/src/sys/GOLF  i386
 $ rm test.file
 $ ./trunc
 file offset=1, expected 1
 $ ls -l test.file
 -rw-r--r--  1 maxim  staff  1 23  13:55 test.file
 $
 
 > The size of the actual file is 1 (if you ls -l on it). However,
 > lseek goes way past it...
 >
 > Noticed this while running connectathon rewind test (part of special
 > test suite). But fails even if don't go over NFS but just run on the
 > local file system.
 >
 > I suspect the problem is with the FS cache. Or perhaps lseek and/or
 > ftruncate are just broken...
 
 [...]
 
 -- 
 Maxim Konovalov, maxim@FreeBSD.org
 
 

From: Maxim Konovalov <maxim@macomnet.ru>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: misc/41792: lseek after ftruncate fails
Date: Fri, 27 Sep 2002 11:19:46 +0400 (MSD)

 Add to the audit trail.
 
 ---------- Forwarded message ----------
 Date: Thu, 26 Sep 2002 15:53:34 -0700 (PDT)
 From: yury izrailevsky <izrailev@yahoo.com>
 To: Maxim Konovalov <maxim@FreeBSD.org>
 Subject: Re: misc/41792: lseek after ftruncate fails
 
 I was wrong -- it doesn't fail locally. Consistently
 fails over an NFS mount though.
 
 Privet.
 I-Opa
 
 --- Maxim Konovalov <maxim@FreeBSD.org> wrote:
 >
 > Hello,
 >
 > [...]
 > > >Environment:
 > > FreeBSD 4.6.1-RELEASE-p10
 > > >Description:
 > >       File operation problem. Running the
 > following:
 > >
 > > write(fd, buffer, 8K);
 > > ftruncate(fd, 0);
 > > write(fd, buffer, 1);
 > > off = lseek(fd, 0, SEEK_END);
 > > printf("%d", off);
 > >
 > > Output: 24576, expected: 1.
 >
 > Can't reproduce on 4.6-STABLE:
 >
 > $ uname -a
 > FreeBSD golf.macomnet.net
 > 4.6-20020805-MACOMNET-STABLE FreeBSD
 > 4.6-20020805-MACOMNET-STABLE #19: Fri Sep 20
 > 17:09:52 MSD 2002
 > maxim@golf.macomnet.net:/usr/obj/usr/src/sys/GOLF
 > i386
 > $ rm test.file
 > $ ./trunc
 > file offset=1, expected 1
 > $ ls -l test.file
 > -rw-r--r--  1 maxim  staff  1 23  13:55 test.file
 > $
 >
 > > The size of the actual file is 1 (if you ls -l on
 > it). However,
 > > lseek goes way past it...
 > >
 > > Noticed this while running connectathon rewind
 > test (part of special
 > > test suite). But fails even if don't go over NFS
 > but just run on the
 > > local file system.
 > >
 > > I suspect the problem is with the FS cache. Or
 > perhaps lseek and/or
 > > ftruncate are just broken...
 >
 > [...]
 >
 > --
 > Maxim Konovalov, maxim@FreeBSD.org
 >
 >
 
 
 __________________________________________________
 Do you Yahoo!?
 New DSL Internet Access from SBC & Yahoo!
 http://sbc.yahoo.com
 
 
Responsible-Changed-From-To: freebsd-bugs->tjr 
Responsible-Changed-By: kris 
Responsible-Changed-When: Sat Jul 12 22:18:12 PDT 2003 
Responsible-Changed-Why:  
Tag, you're it! 

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

From: Tim Robbins <tjr@FreeBSD.ORG>
To: bug-followup@freebsd.org
Cc:  
Subject: Re: misc/41792: lseek after ftruncate fails
Date: Wed, 16 Jul 2003 21:25:11 +1000

 Here is a patch against -current that seems to fix this problem. It is
 likely to apply to -stable sources after adjusting the pathname to
 nfs_vnops.c.
 
 
 --- sys/nfsclient/nfs_vnops.c.6	Wed Jul 16 21:22:05 2003
 +++ sys/nfsclient/nfs_vnops.c	Wed Jul 16 21:16:41 2003
 @@ -662,7 +662,13 @@
   				return (error);
  			    }
   			}
 - 			np->n_vattr.va_size = vap->va_size;
 +			/*
 +			 * np->n_size has already been set to vap->va_size
 +			 * in nfs_meta_setsize(). We must set it again since
 +			 * nfs_write() could be called when flushing dirty
 +			 * buffers, and nfs_write() can modify np->n_size.
 +			 */
 + 			np->n_vattr.va_size = np->n_size = vap->va_size;
    		};
    	} else if ((vap->va_mtime.tv_sec != VNOVAL ||
  		vap->va_atime.tv_sec != VNOVAL) && (np->n_flag & NMODIFIED) &&
State-Changed-From-To: open->patched 
State-Changed-By: tjr 
State-Changed-When: Fri Oct 17 22:47:28 PDT 2003 
State-Changed-Why:  
This was fixed a few months ago in -current. The fix will be 
MFC'd some time after 4.9 is released. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=41792 
State-Changed-From-To: patched->closed 
State-Changed-By: tjr 
State-Changed-When: Sat Jan 10 00:25:56 PST 2004 
State-Changed-Why:  
Fixed in -stable. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=41792 
>Unformatted:
