From 2267fc79d94dea3778cb4600027698e0155f1af3 Mon Sep 17 00:00:00 2001 From: Bruno Faccini Date: Tue, 10 Feb 2015 11:07:11 +0100 Subject: [PATCH 1/1] LU-5393 osd-ldiskfs: read i_size once to protect against race There have been several occurences of ASSERTION(local_nb[i].rc == 0) failures in ost_brw_read(), where inode's i_size has changed due to a racing write/growth beyond EOF. osd_read_prep() must protect himself against this legal behavior by only reading i_size once. Also removed m local variable declaration/usage apparently outdated. Signed-off-by: Bruno Faccini Change-Id: I5d931d5254b970e7031363f37114d0bad8b573fa Reviewed-on: http://review.whamcloud.com/13707 Reviewed-by: Alex Zhuravlev Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Oleg Drokin --- lustre/osd-ldiskfs/osd_io.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index e2e08e3..45822ff 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -1285,7 +1285,8 @@ static int osd_read_prep(const struct lu_env *env, struct dt_object *dt, struct osd_device *osd = osd_obj2dev(osd_dt_obj(dt)); struct timeval start, end; unsigned long timediff; - int rc = 0, i, m = 0, cache = 0, cache_hits = 0, cache_misses = 0; + int rc = 0, i, cache = 0, cache_hits = 0, cache_misses = 0; + loff_t isize; LASSERT(inode); @@ -1293,26 +1294,25 @@ static int osd_read_prep(const struct lu_env *env, struct dt_object *dt, if (unlikely(rc != 0)) RETURN(rc); + isize = i_size_read(inode); + if (osd->od_read_cache) cache = 1; - if (i_size_read(inode) > osd->od_readcache_max_filesize) + if (isize > osd->od_readcache_max_filesize) cache = 0; do_gettimeofday(&start); for (i = 0; i < npages; i++) { - if (i_size_read(inode) <= lnb[i].lnb_file_offset) + if (isize <= lnb[i].lnb_file_offset) /* If there's no more data, abort early. * lnb->lnb_rc == 0, so it's easy to detect later. */ break; - if (i_size_read(inode) < - lnb[i].lnb_file_offset + lnb[i].lnb_len - 1) - lnb[i].lnb_rc = i_size_read(inode) - - lnb[i].lnb_file_offset; + if (isize < lnb[i].lnb_file_offset + lnb[i].lnb_len - 1) + lnb[i].lnb_rc = isize - lnb[i].lnb_file_offset; else lnb[i].lnb_rc = lnb[i].lnb_len; - m += lnb[i].lnb_len; if (PageUptodate(lnb[i].lnb_page)) { cache_hits++; -- 1.8.3.1