Whamcloud - gitweb
Branch HEAD
authorfanyong <fanyong>
Tue, 24 Mar 2009 03:43:30 +0000 (03:43 +0000)
committerfanyong <fanyong>
Tue, 24 Mar 2009 03:43:30 +0000 (03:43 +0000)
b=17336
i=robert.read
i=jinshan.xiong

Do not trigger readpage when objective page index exceeds the end-of-file page index.

lustre/include/lclient.h
lustre/lclient/lcommon_cl.c
lustre/liblustre/llite_cl.c
lustre/llite/vvp_io.c

index 974a03f..6d60864 100644 (file)
@@ -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,
index 2b96562..b161c11 100644 (file)
@@ -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
index 59c7d68..ebd5064 100644 (file)
@@ -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,
index 7adac17..9635fa5 100644 (file)
@@ -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;