From: mool@oce.nl (Bram Moolenaar)
Subject: Amiga locks up; bug in DOS 2.0 filesystem?
Summary: The Amiga locks up if a certain sequence of file I/O commands is used.
Originator: mool@oce-rd2
Keywords: bug, filesystem, lockup
Organization: OCE Nederland B.V.
Date: Thu, 19 Nov 92 13:34:53 GMT


Short description of the problem: The Amiga locks up if a certain sequence of 
file I/O commands is used.

Several people experienced the problem with my text editor "Vim" (Vi 
IMitation). In Vim a script file is used to remember the typed commands. If 
the edited file has been written to disk, the script file is deleted and a 
new one is opened for any new commands. A few bytes are written into the new 
file. The sequence "close, delete, open, write" seems to cause the lockup. I 
wrote a small program that can reproduce the bug. It is at the end of this 
message. As you can see it uses only "normal" file I/O functions.

The problem is that the machine locks up: It seems to be so busy with 
something that it does not react to commands anymore. The mouse pointer may 
move, but slowly.

Does anybody know what causes this problem? Is this a bug in the DOS
filesystem? And more important: How can I avoid it? I discovered that
timing is important. Inserting some kind of delay makes the bug appear
less often. How can I make sure it is 100% safe (on all Amigas under all
circumstances)?

Any help is welcomed!


/*
 * test for lockup bug
 *
 * WARNING: this program locks up the Amiga, use at your own risk!
 *
 * The lockup does not happen always. Until now I discovered:
 * - It depends on how full the partition is (easy to lockup on an empty partition).
 * - Adding printf's changes the chance for a lockup (timing seems to be important).
 *   The more characters are printed, the smaller the lockup chance. Outputting
 *   a newline seems to remove the lockup on my machine.
 * - Sometimes you may have to run this program several times.
 * - Using 32- or 16-bit ints does not change the problem.
 * - It does not happen in RAM:.
 * - It probably only happens under DOS 2.04 or higher.
 * - Lockup happens with both Manx 5.2 and with SAS 6.0.
 * - Lockup happens with different brands of harddisk controllers, but so far
 *   only with DMA types (timing).
 * - Using fopen/fwrite/fclose or open/write/close gives the same problem.
 * - Removing the line "if (Write(fd, "this is a test", 14L) != 14)"
 *   seems to make the bug disappear. This is no solution, I need to write
 *   to that file.
 */

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <clib/dos_protos.h>

/*
 * In some cases the lockup only happens without the debug messages.
 */
#if 1
# define debug(x)		fprintf(stderr, (x)); fflush(stderr);
#else
# define debug(x)
#endif

main(argc, argv)
	int argc;
	char **argv;
{
	BPTR	fd;
	int	i;
	char	vimname[100];
	char	bakname[100];

	if (argc != 2)
	{
		fprintf(stderr, "Usage: test filename\n");
		exit(10);
	}
	if (strlen(argv[1]) > 90)
	{
		fprintf(stderr, "argument too long\n");
		exit(10);
	}
	strcpy(vimname, argv[1]);
	strcat(vimname, ".vim");
	strcpy(bakname, argv[1]);
	strcat(bakname, ".bak");

	for (i = 0; i < 100; ++i)
	{
		fprintf(stderr, "%d ", i);
		fflush(stderr);

		fd = Open((UBYTE *)vimname, (long)MODE_NEWFILE);
		debug("A ");
		if (fd < 0)
		{
			fprintf(stderr, "Cannot open for writing: %s\n", vimname);
			exit(10);
		}
		debug("B ");
	/* the lockup sometimes happens HERE (B is printed, C is not) */
		if (Write(fd, "this is a test", 14L) != 14)
			fprintf(stderr, "Cannot write to %s\n", vimname);
		debug("C ");

	/* the lockup sometimes happens HERE (C is printed, D is not) */
		Close(fd);
		debug("D ");
		if (DeleteFile((UBYTE *)vimname) == 0)
			fprintf(stderr, "DeleteFile(%s) failed\n", vimname);
		debug("; ");
	}
	return 0;
}

===============================================================================
Bram Moolenaar                             | DISCLAIMER:  This  note  does  not
Oce Nederland B.V., Research & Development | necessarily represent the position
p.o. box 101, 5900 MA  Venlo               | of  Oce-Nederland  B.V.  Therefore
The Netherlands        phone +31 77 594077 | no liability or responsibility for
UUCP: mool@oce.nl        fax +31 77 595450 | whatever will be accepted.