From 5b464b45746153889e3dead4e2254d3ebda77f8d Mon Sep 17 00:00:00 2001 From: Patrick Farrell Date: Tue, 7 Apr 2015 17:24:36 -0500 Subject: [PATCH] LU-6227 vvp: Use range lock for direct IO reads 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 Change-Id: I5af524a42891bfa4c52d0fe8d2f7cc94c1ba5c57 Reviewed-on: http://review.whamcloud.com/14385 Tested-by: Jenkins Reviewed-by: Alexander Boyko Tested-by: Maloo Reviewed-by: Bobi Jam Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin --- lustre/llite/file.c | 6 +++++- lustre/tests/sanity.sh | 10 ++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 6653783..65b1ffe 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -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)); diff --git a/lustre/tests/sanity.sh b/lustre/tests/sanity.sh index a685e63..0bbfe69 100644 --- a/lustre/tests/sanity.sh +++ b/lustre/tests/sanity.sh @@ -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 -- 1.8.3.1