From: fanyong Date: Tue, 24 Mar 2009 03:43:30 +0000 (+0000) Subject: Branch HEAD X-Git-Tag: v1_9_166~14 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=401614615d3e6512bb7f2376992b9ce0bd59f7c7;p=fs%2Flustre-release.git Branch HEAD b=17336 i=robert.read i=jinshan.xiong Do not trigger readpage when objective page index exceeds the end-of-file page index. --- diff --git a/lustre/include/lclient.h b/lustre/include/lclient.h index 974a03f..6d60864 100644 --- a/lustre/include/lclient.h +++ b/lustre/include/lclient.h @@ -327,7 +327,8 @@ int ccc_io_one_lock(const struct lu_env *env, struct cl_io *io, loff_t start, loff_t end); void ccc_io_end(const struct lu_env *env, const struct cl_io_slice *ios); int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, loff_t pos, int vfslock); + struct cl_io *io, loff_t start, size_t count, int vfslock, + int *exceed); void ccc_req_completion(const struct lu_env *env, const struct cl_req_slice *slice, int ioret); void ccc_req_attr_set(const struct lu_env *env,const struct cl_req_slice *slice, diff --git a/lustre/lclient/lcommon_cl.c b/lustre/lclient/lcommon_cl.c index 2b96562..b161c11c 100644 --- a/lustre/lclient/lcommon_cl.c +++ b/lustre/lclient/lcommon_cl.c @@ -781,10 +781,12 @@ static void ccc_object_size_unlock(struct cl_object *obj, int vfslock) * the resulting races. */ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, - struct cl_io *io, loff_t pos, int vfslock) + struct cl_io *io, loff_t start, size_t count, int vfslock, + int *exceed) { struct cl_attr *attr = &ccc_env_info(env)->cti_attr; struct inode *inode = ccc_object_inode(obj); + loff_t pos = start + count - 1; loff_t kms; int result; @@ -818,7 +820,21 @@ int ccc_prep_size(const struct lu_env *env, struct cl_object *obj, * of the buffer (C) */ ccc_object_size_unlock(obj, vfslock); - return cl_glimpse_lock(env, io, inode, obj); + result = cl_glimpse_lock(env, io, inode, obj); + if (result == 0 && exceed != NULL) { + /* If objective page index exceed end-of-file + * page index, return directly. Do not expect + * kernel will check such case correctly. + * linux-2.6.18-128.1.1 miss to do that. + * --bug 17336 */ + size_t size = cl_isize_read(inode); + unsigned long cur_index = start >> CFS_PAGE_SHIFT; + + if ((size == 0 && cur_index != 0) || + (((size - 1) >> CFS_PAGE_SHIFT) < cur_index)) + *exceed = 1; + } + return result; } else { /* * region is within kms and, hence, within real file diff --git a/lustre/liblustre/llite_cl.c b/lustre/liblustre/llite_cl.c index 59c7d68..ebd5064 100644 --- a/lustre/liblustre/llite_cl.c +++ b/lustre/liblustre/llite_cl.c @@ -647,6 +647,7 @@ static int slp_io_start(const struct lu_env *env, const struct cl_io_slice *ios) struct llu_inode_info *lli = llu_i2info(inode); struct llu_io_session *session = cl2slp_io(env, ios)->sio_session; int write = io->ci_type == CIT_WRITE; + int exceed = 0; CLOBINVRNT(env, obj, ccc_object_invariant(obj)); @@ -668,8 +669,8 @@ static int slp_io_start(const struct lu_env *env, const struct cl_io_slice *ios) if (IS_ERR(iogroup)) RETURN(PTR_ERR(iogroup)); - err = ccc_prep_size(env, obj, io, pos + cnt - 1, 0); - if (err != 0) + err = ccc_prep_size(env, obj, io, pos, cnt, 0, &exceed); + if (err != 0 || (write == 0 && exceed != 0)) GOTO(out, err); CDEBUG(D_INODE, diff --git a/lustre/llite/vvp_io.c b/lustre/llite/vvp_io.c index 7adac17..9635fa5 100644 --- a/lustre/llite/vvp_io.c +++ b/lustre/llite/vvp_io.c @@ -456,15 +456,18 @@ static int vvp_io_read_start(const struct lu_env *env, loff_t pos = io->u.ci_rd.rd.crw_pos; size_t cnt = io->u.ci_rd.rd.crw_count; size_t tot = cio->cui_tot_count; + int exceed = 0; CLOBINVRNT(env, obj, ccc_object_invariant(obj)); LASSERT(vio->cui_oneshot == 0); CDEBUG(D_VFSTRACE, "read: -> [%lli, %lli)\n", pos, pos + cnt); - result = ccc_prep_size(env, obj, io, pos + tot - 1, 1); + result = ccc_prep_size(env, obj, io, pos, tot, 1, &exceed); if (result != 0) return result; + else if (exceed != 0) + goto out; LU_OBJECT_HEADER(D_INODE, env, &obj->co_lu, "Read ino %lu, "LPSZ" bytes, offset %lld, size %llu\n", @@ -493,6 +496,7 @@ static int vvp_io_read_start(const struct lu_env *env, result = lustre_generic_file_read(file, cio, &pos); } +out: if (result >= 0) { if (result < cnt) io->ci_continue = 0; @@ -567,7 +571,7 @@ static int vvp_io_fault_start(const struct lu_env *env, /* offset of the last byte on the page */ offset = cl_offset(obj, fio->ft_index + 1) - 1; LASSERT(cl_index(obj, offset) == fio->ft_index); - result = ccc_prep_size(env, obj, io, offset, 0); + result = ccc_prep_size(env, obj, io, 0, offset + 1, 0, NULL); if (result != 0) return result;