From 833b670a1915df9bb3cdcd9cd8dcbdb740af994f Mon Sep 17 00:00:00 2001 From: James Simmons Date: Mon, 11 Aug 2014 09:50:42 -0400 Subject: [PATCH] LU-4993 osd-ldiskfs: Support 3.14 kernel changes to bio api In the 3.14 kernel code base several data fields in struct bio were moved into a new structure called bvec_iter. This patch updates osd-ldiskfs to handle this api change. Change-Id: I849a1d62462c58a79766c176060b27c621627646 Signed-off-by: James Simmons Reviewed-on: http://review.whamcloud.com/10995 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Bob Glossman Reviewed-by: Dmitry Eremin Reviewed-by: Oleg Drokin --- lustre/autoconf/lustre-core.m4 | 21 ++++++++ lustre/include/linux/lustre_compat25.h | 13 +++++ lustre/osd-ldiskfs/osd_io.c | 98 +++++++++++++++++----------------- 3 files changed, 84 insertions(+), 48 deletions(-) diff --git a/lustre/autoconf/lustre-core.m4 b/lustre/autoconf/lustre-core.m4 index e42acbf..3293137 100644 --- a/lustre/autoconf/lustre-core.m4 +++ b/lustre/autoconf/lustre-core.m4 @@ -1275,6 +1275,26 @@ hlist_for_each_entry_3args, [ ]) # LC_HAVE_HLIST_FOR_EACH_3ARG # +# LC_HAVE_BIO_END_SECTOR +# +# 3.9 introduces bio_end_sector macro +# f73a1c7d117d07a96d89475066188a2b79e53c48 +# +AC_DEFUN([LC_HAVE_BIO_END_SECTOR], [ +LB_CHECK_COMPILE([if 'bio_end_sector is defined], +bio_end_sector, [ + #include +],[ + struct bio bio; + + bio_end_sector(&bio); +],[ + AC_DEFINE(HAVE_BIO_END_SECTOR, 1, + [bio_end_sector is defined]) +]) +]) # LC_HAVE_BIO_END_SECTOR + +# # LC_HAVE_ONLY_PROCFS_SEQ # # 3.10+ only supports procfs seq_files handling @@ -1585,6 +1605,7 @@ AC_DEFUN([LC_PROG_LINUX], [ # 3.9 LC_HAVE_HLIST_FOR_EACH_3ARG + LC_HAVE_BIO_END_SECTOR # 3.10 LC_HAVE_ONLY_PROCFS_SEQ diff --git a/lustre/include/linux/lustre_compat25.h b/lustre/include/linux/lustre_compat25.h index a611708..15fb569 100644 --- a/lustre/include/linux/lustre_compat25.h +++ b/lustre/include/linux/lustre_compat25.h @@ -186,6 +186,19 @@ unsigned int ll_crypto_tfm_alg_min_keysize(struct crypto_blkcipher *tfm) # define blkdev_get_by_dev(dev, mode, holder) open_by_devnum(dev, mode) #endif +#ifdef HAVE_BVEC_ITER +#define bio_idx(bio) (bio->bi_iter.bi_idx) +#define bio_set_sector(bio, sector) (bio->bi_iter.bi_sector = sector) +#else +#define bio_idx(bio) (bio->bi_idx) +#define bio_set_sector(bio, sector) (bio->bi_sector = sector) +#define bio_sectors(bio) ((bio)->bi_size >> 9) +#ifndef HAVE_BIO_END_SECTOR +#define bio_end_sector(bio) (bio->bi_sector + bio_sectors(bio)) +#endif +#define bvec_iter_page(bvec, iter) (*bvec->bv_page) +#endif + #ifndef HAVE_BLK_QUEUE_MAX_SEGMENTS #define blk_queue_max_segments(rq, seg) \ do { blk_queue_max_phys_segments(rq, seg); \ diff --git a/lustre/osd-ldiskfs/osd_io.c b/lustre/osd-ldiskfs/osd_io.c index 9b2038a..ccb210c 100644 --- a/lustre/osd-ldiskfs/osd_io.c +++ b/lustre/osd-ldiskfs/osd_io.c @@ -147,9 +147,14 @@ void osd_fini_iobuf(struct osd_device *d, struct osd_iobuf *iobuf) static void dio_complete_routine(struct bio *bio, int error) { - struct osd_iobuf *iobuf = bio->bi_private; - struct bio_vec *bvl; - int i; + struct osd_iobuf *iobuf = bio->bi_private; +#ifdef HAVE_BVEC_ITER + struct bvec_iter iter; + struct bio_vec bvl; +#else + int iter; + struct bio_vec *bvl; +#endif /* CAVEAT EMPTOR: possibly in IRQ context * DO NOT record procfs stats here!!! */ @@ -166,23 +171,23 @@ static void dio_complete_routine(struct bio *bio, int error) CERROR("bi_next: %p, bi_flags: %lx, bi_rw: %lu, bi_vcnt: %d, " "bi_idx: %d, bi->size: %d, bi_end_io: %p, bi_cnt: %d, " "bi_private: %p\n", bio->bi_next, bio->bi_flags, - bio->bi_rw, bio->bi_vcnt, bio->bi_idx, bio->bi_size, - bio->bi_end_io, atomic_read(&bio->bi_cnt), - bio->bi_private); + bio->bi_rw, bio->bi_vcnt, bio_idx(bio), + bio_sectors(bio) << 9, bio->bi_end_io, + atomic_read(&bio->bi_cnt), bio->bi_private); return; } - /* the check is outside of the cycle for performance reason -bzzz */ + /* 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, i) { - if (likely(error == 0)) - SetPageUptodate(bvl->bv_page); - LASSERT(PageLocked(bvl->bv_page)); - } + bio_for_each_segment(bvl, bio, iter) { + if (likely(error == 0)) + SetPageUptodate(bvec_iter_page(&bvl, iter)); + LASSERT(PageLocked(bvec_iter_page(&bvl, iter))); + } atomic_dec(&iobuf->dr_dev->od_r_in_flight); - } else { + } else { atomic_dec(&iobuf->dr_dev->od_w_in_flight); - } + } /* any real error is good enough -bzzz */ if (error != 0 && iobuf->dr_error == 0) @@ -244,13 +249,10 @@ static void osd_submit_bio(int rw, struct bio *bio) static int can_be_merged(struct bio *bio, sector_t sector) { - unsigned int size; - - if (!bio) - return 0; + if (bio == NULL) + return 0; - size = bio->bi_size >> 9; - return bio->bi_sector + size == sector ? 1 : 0; + return bio_end_sector(bio) == sector ? 1 : 0; } static int osd_do_bio(struct osd_device *osd, struct inode *inode, @@ -316,23 +318,23 @@ static int osd_do_bio(struct osd_device *osd, struct inode *inode, blocksize * nblocks, page_offset) != 0) continue; /* added this frag OK */ - if (bio != NULL) { - struct request_queue *q = - bdev_get_queue(bio->bi_bdev); - - /* Dang! I have to fragment this I/O */ - CDEBUG(D_INODE, "bio++ sz %d vcnt %d(%d) " - "sectors %d(%d) psg %d(%d) hsg %d(%d)\n", - bio->bi_size, - bio->bi_vcnt, bio->bi_max_vecs, - bio->bi_size >> 9, queue_max_sectors(q), + if (bio != NULL) { + struct request_queue *q = + bdev_get_queue(bio->bi_bdev); + unsigned int bi_size = bio_sectors(bio) << 9; + + /* Dang! I have to fragment this I/O */ + CDEBUG(D_INODE, "bio++ sz %d vcnt %d(%d) " + "sectors %d(%d) psg %d(%d) hsg %d(%d)\n", + bi_size, bio->bi_vcnt, bio->bi_max_vecs, + bio_sectors(bio), + queue_max_sectors(q), bio_phys_segments(q, bio), queue_max_phys_segments(q), 0, queue_max_hw_segments(q)); - - record_start_io(iobuf, bio->bi_size); - osd_submit_bio(iobuf->dr_rw, bio); - } + record_start_io(iobuf, bi_size); + osd_submit_bio(iobuf->dr_rw, bio); + } /* allocate new bio */ bio = bio_alloc(GFP_NOIO, min(BIO_MAX_PAGES, @@ -346,23 +348,23 @@ static int osd_do_bio(struct osd_device *osd, struct inode *inode, goto out; } - bio->bi_bdev = inode->i_sb->s_bdev; - bio->bi_sector = sector; + bio->bi_bdev = inode->i_sb->s_bdev; + bio_set_sector(bio, sector); bio->bi_rw = (iobuf->dr_rw == 0) ? READ : WRITE; - bio->bi_end_io = dio_complete_routine; - bio->bi_private = iobuf; + bio->bi_end_io = dio_complete_routine; + bio->bi_private = iobuf; - rc = bio_add_page(bio, page, - blocksize * nblocks, page_offset); - LASSERT(rc != 0); - } - } + rc = bio_add_page(bio, page, + blocksize * nblocks, page_offset); + LASSERT(rc != 0); + } + } - if (bio != NULL) { - record_start_io(iobuf, bio->bi_size); - osd_submit_bio(iobuf->dr_rw, bio); - rc = 0; - } + if (bio != NULL) { + record_start_io(iobuf, bio_sectors(bio) << 9); + osd_submit_bio(iobuf->dr_rw, bio); + rc = 0; + } out: /* in order to achieve better IO throughput, we don't wait for writes -- 1.8.3.1