xfs
[Top] [All Lists]

[PATCH 2.6.7-rc3-mm2] handle partial DIO write (was O_DIRECT hole fillin

To: Andrew Morton <akpm@xxxxxxxx>
Subject: [PATCH 2.6.7-rc3-mm2] handle partial DIO write (was O_DIRECT hole filling bug)
From: Daniel McNeil <daniel@xxxxxxxx>
Date: 10 Jun 2004 16:39:48 -0700
Cc: Chris Mason <mason@xxxxxxxx>, janetinc@xxxxxxxxxx, "linux-aio@xxxxxxxxx" <linux-aio@xxxxxxxxx>, linux-xfs@xxxxxxxxxxx
In-reply-to: <20040602223236.3a7dcee8.akpm@xxxxxxxx>
Organization:
References: <1085753950.22636.3208.camel@xxxxxxxxxxxxx> <1085782365.22798.35.camel@xxxxxxxxxxxxxxxxxx> <20040528152839.44bdb7dc.akpm@xxxxxxxx> <1086011001.22636.3379.camel@xxxxxxxxxxxxx> <20040601025641.1721966e.akpm@xxxxxxxx> <1086090295.22636.3398.camel@xxxxxxxxxxxxx> <20040602223236.3a7dcee8.akpm@xxxxxxxx>
Sender: linux-xfs-bounce@xxxxxxxxxxx
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;




<Prev in Thread] Current Thread [Next in Thread>