Andrew,
Taking another look at the fsx-linux hole fill failure, the real
problem was that generic_file_aio_write_nolock() was not handling
the partial DIO write correctly. Here's a patch lets DIO do the
partial write, and the fallback to buffered is done (correctly)
for what is left. I ran
fsx-linux -l 500000 -r 4096 -t 4096 -w 4096 -Z -N 10000 junk -R -W
and it passed with this patch (on ext3).
BTW, the code in direct_io_worker() incrementing dio->result is correct
(just not obvious).
Daniel
diff -rup linux-2.6.7-rc3-mm1.orig/fs/direct-io.c
linux-2.6.7-rc3-mm1/fs/direct-io.c
--- linux-2.6.7-rc3-mm1.orig/fs/direct-io.c 2004-06-10 14:19:01.118592030
-0700
+++ linux-2.6.7-rc3-mm1/fs/direct-io.c 2004-06-10 14:22:31.599731989 -0700
@@ -990,6 +990,13 @@ direct_io_worker(int rw, struct kiocb *i
}
} /* end iovec loop */
+ if (ret == -ENOTBLK && rw == WRITE) {
+ /*
+ * The remaining part of the request will be
+ * be handled by buffered I/O when we return
+ */
+ ret = 0;
+ }
/*
* There may be some unwritten disk at the end of a part-written
* fs-block-sized block. Go zero that now.
@@ -1089,13 +1096,6 @@ direct_io_worker(int rw, struct kiocb *i
aio_complete(iocb, ret, 0);
kfree(dio);
}
- if (ret == -ENOTBLK && rw == WRITE) {
- /*
- * The entire request will be be handled by buffered I/O
- * when we return
- */
- ret = 0;
- }
return ret;
}
diff -rup linux-2.6.7-rc3-mm1.orig/mm/filemap.c linux-2.6.7-rc3-mm1/mm/filemap.c
--- linux-2.6.7-rc3-mm1.orig/mm/filemap.c 2004-06-10 14:19:13.014403370
-0700
+++ linux-2.6.7-rc3-mm1/mm/filemap.c 2004-06-10 14:24:31.909458684 -0700
@@ -1915,7 +1915,7 @@ generic_file_aio_write_nolock(struct kio
count -= written;
}
- buf = iov->iov_base;
+ buf = iov->iov_base + written; /* handle partial DIO write */
do {
unsigned long index;
unsigned long offset;
|