Whamcloud - gitweb
Branch b1_6
authorfanyong <fanyong>
Fri, 20 Mar 2009 08:50:16 +0000 (08:50 +0000)
committerfanyong <fanyong>
Fri, 20 Mar 2009 08:50:16 +0000 (08:50 +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/liblustre/rw.c
lustre/llite/file.c

index d4b4a2b..ac0ebae 100644 (file)
@@ -699,6 +699,15 @@ ssize_t llu_file_prwv(const struct iovec *iovec, int iovlen,
                          */
                         if ((err = llu_glimpse_size(inode))) {
                                 GOTO(err_unlock, err);
+                        } else {
+                                /* If objective page index exceed end-of-file
+                                 * page index, return directly. --bug 17336 */
+                                size_t size = st->st_size;
+                                unsigned long cur_index = pos >> CFS_PAGE_SHIFT;
+
+                                if ((size == 0 && cur_index != 0) ||
+                                    (((size - 1) >> CFS_PAGE_SHIFT) < cur_index))
+                                        GOTO(err_unlock, err);
                         }
                 } else {
                         st->st_size = kms;
index d725dbf..f203105 100644 (file)
@@ -1538,6 +1538,24 @@ repeat:
                                 up_read(&lli->lli_truncate_rwsem);
                         }
                         goto out;
+                } else {
+                        /* If objective page index exceed the 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 = i_size_read(inode);
+                        unsigned long cur_index = *ppos >> CFS_PAGE_SHIFT;
+
+                        if ((size == 0 && cur_index != 0) ||
+                            (((size - 1) >> CFS_PAGE_SHIFT) < cur_index)) {
+                                if (lock_style != LL_LOCK_STYLE_NOLOCK) {
+                                        ll_file_put_lock(inode, end, lock_style,
+                                                         cookie, &tree,
+                                                         OBD_BRW_READ);
+                                        up_read(&lli->lli_truncate_rwsem);
+                                }
+                                goto out;
+                        }
                 }
         } else {
                 /* region is within kms and, hence, within real file size (A).