summaryrefslogtreecommitdiffstats
path: root/xlators/performance/read-ahead/src
diff options
context:
space:
mode:
authorRaghavendra G <rgowdapp@redhat.com>2014-04-11 15:58:47 +0530
committerRaghavendra G <rgowdapp@redhat.com>2017-05-09 10:06:39 +0000
commit2ff39c5cbea6fbda0d7a442f55e6dc2a72efb171 (patch)
tree8fe676783e4fed824bfad390d20790da081f4100 /xlators/performance/read-ahead/src
parentaf226d250bcced782d19412bd7de1ca32834c8eb (diff)
performance/read-ahead: prevent stale data being returned to application.
Assume that fd is shared by two application threads/processes. T0 read is triggered from app-thread t1 and read call passes through write-behind. T1 app-thread t2 issues a write. The page on which read from t1 is waiting is marked stale T2 write-behind caches write and indicates to application as write complete. T3 app-thread t2 issues read to same region. Since, there is already a page for that region (created as part of read at T0), this read request waits on that page to be filled (though it is stale, which is a bug). T4 read (triggered at T0) completes from brick (with write still pending). Now both read requests from t1 and t2 are served this data (though data is stale from app-thread t2's perspective - which is a bug) T5 write is flushed to brick by write-behind. Fix is to not to serve data from a stale page, but instead initiate a fresh read to back-end. Change-Id: Id6af733464fa41bb4e81fd29c7451c73d06453fb BUG: 1414242 Signed-off-by: Raghavendra G <rgowdapp@redhat.com> Reviewed-on: https://review.gluster.org/7447 Smoke: Gluster Build System <jenkins@build.gluster.org> CentOS-regression: Gluster Build System <jenkins@build.gluster.org> Reviewed-by: Csaba Henk <csaba@redhat.com> NetBSD-regression: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Zhou Zhengping <johnzzpcrystal@gmail.com> Reviewed-by: Amar Tumballi <amarts@redhat.com>
Diffstat (limited to 'xlators/performance/read-ahead/src')
-rw-r--r--xlators/performance/read-ahead/src/page.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/xlators/performance/read-ahead/src/page.c b/xlators/performance/read-ahead/src/page.c
index 216e327af74..17e346ec947 100644
--- a/xlators/performance/read-ahead/src/page.c
+++ b/xlators/performance/read-ahead/src/page.c
@@ -139,6 +139,7 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
ra_waitq_t *waitq = NULL;
fd_t *fd = NULL;
uint64_t tmp_file = 0;
+ gf_boolean_t stale = _gf_false;
GF_ASSERT (frame);
@@ -174,6 +175,13 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
goto unlock;
}
+ if (page->stale) {
+ page->stale = 0;
+ page->ready = 0;
+ stale = 1;
+ goto unlock;
+ }
+
/*
* "Dirty" means that the request was a pure read-ahead; it's
* set for requests we issue ourselves, and cleared when user
@@ -219,6 +227,16 @@ ra_fault_cbk (call_frame_t *frame, void *cookie, xlator_t *this,
unlock:
ra_file_unlock (file);
+ if (stale) {
+ STACK_WIND (frame, ra_fault_cbk,
+ FIRST_CHILD (frame->this),
+ FIRST_CHILD (frame->this)->fops->readv,
+ local->fd, local->pending_size,
+ local->pending_offset, 0, NULL);
+
+ return 0;
+ }
+
ra_waitq_return (waitq);
fd_unref (local->fd);