Whamcloud - gitweb
LU-8210 osd-ldiskfs: fix setting pages PageUptodate state 78/20478/6
authorWang Shilong <wshilong@ddn.com>
Fri, 27 May 2016 12:40:26 +0000 (21:40 +0900)
committerOleg Drokin <oleg.drokin@intel.com>
Thu, 2 Jun 2016 04:41:28 +0000 (04:41 +0000)
In our VM autotest
sanity:156 test failed in rhel7 plataform for writecache
disable and readcache enabled.

After debugging this is because of we miss to set PageUptodate
after reading bio finish, this will make read cache total
unusable for rhel7, because osd_read_prep() will think pages
always not uptodate and triger bio submitting for every reading
request.

Problems come from pages iterating, since bio_for_each_segment_all
introduced, bio_for_each_segment will no longer work right
for pages interating anymore, we should use new interface
for rhel7.

So this problems only exist for some specific Drivers:
From Documentation/block/biodoc.txt

-------------------------------
Drivers which can't process a large bio in one shot can
use the bi_idx field to keep track of the next bio_vec entry
to process.(e.g a 1MB bio_vec needs to be handled in max 128kB
chunks for IDE) [TBD: Should preferably also have a bi_voffset
and bi_vlen to avoid modifying bi_offset an len fields]
-------------------------------

This might explain why intel autotest could not reproduce it
but our clustered can always reproduce the problem.

Signed-off-by: Wang Shilong <wshilong@ddn.com>
Change-Id: I5d3de5bf5facbee8d9450c15b8ab7189d7f2fbfe
Reviewed-on: http://review.whamcloud.com/20478
Tested-by: Jenkins
Reviewed-by: Andreas Dilger <andreas.dilger@intel.com>
Tested-by: Maloo <hpdd-maloo@intel.com>
Reviewed-by: Li Xi <lixi@ddn.com>
Reviewed-by: Alex Zhuravlev <alexey.zhuravlev@intel.com>
lustre/include/lustre_compat.h
lustre/llite/lloop.c
lustre/osd-ldiskfs/osd_io.c

index 4e9f3ac..d777993 100644 (file)
@@ -39,6 +39,7 @@
 
 #include <linux/fs_struct.h>
 #include <linux/namei.h>
 
 #include <linux/fs_struct.h>
 #include <linux/namei.h>
+#include <linux/bio.h>
 
 #include <lustre_patchless_compat.h>
 
 
 #include <lustre_patchless_compat.h>
 
@@ -409,4 +410,8 @@ static inline void truncate_inode_pages_final(struct address_space *map)
         security_inode_init_security(inode, dir, name, value, len)
 #endif
 
         security_inode_init_security(inode, dir, name, value, len)
 #endif
 
+#ifndef bio_for_each_segment_all /* since kernel version 3.9 */
+#define bio_for_each_segment_all(bv, bio, it) bio_for_each_segment(bv, bio, it)
+#endif
+
 #endif /* _LUSTRE_COMPAT_H */
 #endif /* _LUSTRE_COMPAT_H */
index 2a6813f..b8ae0b5 100644 (file)
@@ -226,7 +226,7 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head)
 
 #ifdef HAVE_BVEC_ITER
                offset = (pgoff_t)(bio->bi_iter.bi_sector << 9) + lo->lo_offset;
 
 #ifdef HAVE_BVEC_ITER
                offset = (pgoff_t)(bio->bi_iter.bi_sector << 9) + lo->lo_offset;
-               bio_for_each_segment(bvec, bio, iter) {
+               bio_for_each_segment_all(bvec, bio, iter) {
                        BUG_ON(bvec.bv_offset != 0);
                        BUG_ON(bvec.bv_len != PAGE_CACHE_SIZE);
 
                        BUG_ON(bvec.bv_offset != 0);
                        BUG_ON(bvec.bv_len != PAGE_CACHE_SIZE);
 
@@ -236,7 +236,7 @@ static int do_bio_lustrebacked(struct lloop_device *lo, struct bio *head)
                        offset += bvec.bv_len;
 #else
                offset = (pgoff_t)(bio->bi_sector << 9) + lo->lo_offset;
                        offset += bvec.bv_len;
 #else
                offset = (pgoff_t)(bio->bi_sector << 9) + lo->lo_offset;
-               bio_for_each_segment(bvec, bio, iter) {
+               bio_for_each_segment_all(bvec, bio, iter) {
                        BUG_ON(bvec->bv_offset != 0);
                        BUG_ON(bvec->bv_len != PAGE_CACHE_SIZE);
 
                        BUG_ON(bvec->bv_offset != 0);
                        BUG_ON(bvec->bv_len != PAGE_CACHE_SIZE);
 
index 5ef77b2..aaea2f0 100644 (file)
@@ -179,7 +179,7 @@ static void dio_complete_routine(struct bio *bio, int error)
 
        /* the check is outside of the cycle for performance reason -bzzz */
        if (!test_bit(__REQ_WRITE, &bio->bi_rw)) {
 
        /* the check is outside of the cycle for performance reason -bzzz */
        if (!test_bit(__REQ_WRITE, &bio->bi_rw)) {
-               bio_for_each_segment(bvl, bio, iter) {
+               bio_for_each_segment_all(bvl, bio, iter) {
                        if (likely(error == 0))
                                SetPageUptodate(bvl_to_page(bvl));
                        LASSERT(PageLocked(bvl_to_page(bvl)));
                        if (likely(error == 0))
                                SetPageUptodate(bvl_to_page(bvl));
                        LASSERT(PageLocked(bvl_to_page(bvl)));