I had noticed some strange behaviour with some programs on FAT32 partitions, then I got into kern/39043 (moving files over samba), wich has been open for over 3 years. Then I decided to do some research. I made a simple program, that opens some files, write some data, and close the file (included at end). Inmediately after the program is done, the files are ok, all data is plain text, and they have what is expected. But after some time, or some disk access (unrelated to the files), the files are corrupted!, with lots of garbage. By looking at the uncorrupted text (specially formated for this), it seems that the corruption is in blocks of 4096 (the size of the partition's clusters). This leads me to belive there is a problem flushing cache entries to the directory structure (so directory entries get corrupted, by pointing to unrelated clusters). Sometimes files are ok, but its easy to get a corrupted one. This is what I did: $ uname -a FreeBSD moonlight.e-shell.net 5.4-STABLE FreeBSD 5.4-STABLE #1: Fri Sep 30 01:02:32 CDT 2005 loox@...:/usr/obj/usr/src/sys/LXAMD64 amd64 $ ./fat32 /mnt/wina5/tmp/test0 /mnt/wina5/tmp/test1 /mnt/wina5/tmp/test2 /mnt/wina5/tmp/test3 /mnt/wina5/tmp/test4 /mnt/wina5/tmp/test5 /mnt/wina5/tmp/test6 /mnt/wina5/tmp/test7 Files are created ok $ cat test0 | grep -v file00 $ file is ok.. no weird data do some disk access: $ find / > /dev/null $ test the file again: $ cat test0 | grep -v file00 (lots of binary garbage) $ The program I used to test: ************************************************** #include <stdio.h> #include <unistd.h> #include <fcntl.h> #define _PATH "/mnt/wina5/tmp" #define BLOCK 8192 #define NUM 1024 #define FN 8 int main() { int i, j, k; int fd[FN]; char file[128]; char name[128] = "test"; char str[BLOCK + 1]; for (j = 0; j < FN; j++) { sprintf(file, "%s/%s%d", _PATH, name, j); printf("%s\n", file); fd[j] = open(file, O_RDWR | O_TRUNC | O_CREAT); for (i = NUM; i >= 0; i--) { for (k = 0; k < BLOCK; k += 32) sprintf(str + k, "file%02d | Block: %06d [%06d]\n", j, i, k); lseek(fd[j], i * BLOCK, SEEK_SET); write(fd[j], str, BLOCK); } } for (j = 0; j < FN; j++) close(fd[j]); }