Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 19 Aug 2002 12:51:30 -0700 (PDT)
From:      Yury Izrailevsky <izrailev@yahoo.com>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   misc/41792: lseek after ftruncate fails
Message-ID:  <200208191951.g7JJpUcB099117@www.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         41792
>Category:       misc
>Synopsis:       lseek after ftruncate fails
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Aug 19 13:00:04 PDT 2002
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200208191951.g7JJpUcB099117>