Whamcloud - gitweb
LU-6227 vvp: Use range lock for direct IO reads 85/14385/3
authorPatrick Farrell <paf@cray.com>
Tue, 7 Apr 2015 22:24:36 +0000 (17:24 -0500)
committerOleg Drokin <oleg.drokin@intel.com>
Tue, 28 Apr 2015 05:14:12 +0000 (05:14 +0000)
Direct IO does not use the page cache like normal IO, so
concurrent direct IO reads of the same pages are not safe.

As a result, direct IO reads must take the range lock
in ll_file_io_generic, otherwise they will attempt to work
on the same pages and hit assertions like:
(osc_request.c:1219:osc_brw_prep_request())
ASSERTION( i == 0 || pg->off > pg_prev->off ) failed:
i 3 p_c 10 pg ffffea00017a5208 [pri 0 ind 2771] off 16384
prev_pg ffffea00017a51d0 [pri 0 ind 2256] off 16384

Also added a test for dio vs dio reads.

Signed-off-by: Patrick Farrell <paf@cray.com>
Change-Id: I5af524a42891bfa4c52d0fe8d2f7cc94c1ba5c57
Reviewed-on: http://review.whamcloud.com/14385
Tested-by: Jenkins
Reviewed-by: Alexander Boyko <alexander.boyko@seagate.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Bobi Jam <bobijam@hotmail.com>
Reviewed-by: Jinshan Xiong <jinshan.xiong@intel.com>
Reviewed-by: Oleg Drokin <oleg.drokin@intel.com>
lustre/llite/file.c
lustre/tests/sanity.sh

index 6653783..65b1ffe 100644 (file)
@@ -1035,7 +1035,11 @@ restart:
                        vio->vui_nrsegs = args->u.normal.via_nrsegs;
                        vio->vui_tot_nrsegs = vio->vui_nrsegs;
                        vio->vui_iocb = args->u.normal.via_iocb;
-                       if ((iot == CIT_WRITE) &&
+                       /* Direct IO reads must also take range lock,
+                        * or multiple reads will try to work on the same pages
+                        * See LU-6227 for details. */
+                       if (((iot == CIT_WRITE) ||
+                           (iot == CIT_READ && (file->f_flags & O_DIRECT))) &&
                            !(vio->vui_fd->fd_flags & LL_FILE_GROUP_LOCKED)) {
                                CDEBUG(D_VFSTRACE, "Range lock "RL_FMT"\n",
                                       RL_PARA(&range));
index a685e63..0bbfe69 100644 (file)
@@ -12876,6 +12876,16 @@ test_241() {
 }
 run_test 241 "bio vs dio"
 
+test_241b() {
+       dd if=/dev/zero of=$DIR/$tfile count=1 bs=40960
+       ls -la $DIR/$tfile
+       test_241_dio 1000 &
+       PID=$!
+       test_241_dio 1000
+       wait $PID
+}
+run_test 241b "dio vs dio"
+
 test_242() {
        mkdir -p $DIR/$tdir
        touch $DIR/$tdir/$tfile