]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] use bio_get_nr_vecs() for sizing direct-io BIOs
authorAndrew Morton <akpm@digeo.com>
Sat, 5 Oct 2002 03:35:29 +0000 (20:35 -0700)
committerRussell King <rmk@flint.arm.linux.org.uk>
Sat, 5 Oct 2002 03:35:29 +0000 (20:35 -0700)
From Badari Pulavarty.

Rather than allocating maximum-sized BIOs, use the new
bio_get_nr_vecs() hint when sizing the BIOs.

Also keep track of the approximate upper-bound on the number of pages
remaining to do, so we can again avoid allocating excessively-sized
BIOs.

fs/direct-io.c

index e9a135036991409f5a693187c2bd97c882fe6313..61792e0b2d506c4c558a3203bf72a0df0a6349a9 100644 (file)
@@ -49,6 +49,7 @@ struct dio {
        /* Page fetching state */
        int curr_page;                  /* changes */
        int total_pages;                /* doesn't change */
+       int pages_left;                 /* approximate total IO pages */
        unsigned long curr_user_address;/* changes */
 
        /* Page queue */
@@ -396,7 +397,8 @@ static int dio_new_bio(struct dio *dio)
        if (ret)
                goto out;
        sector = dio->next_block_in_bio << (dio->blkbits - 9);
-       nr_pages = min(dio->total_pages, BIO_MAX_PAGES);
+       nr_pages = min(dio->pages_left, bio_get_nr_vecs(dio->map_bh.b_bdev));
+       BUG_ON(nr_pages <= 0);
        ret = dio_bio_alloc(dio, dio->map_bh.b_bdev, sector, nr_pages);
        dio->boundary = 0;
 out:
@@ -423,6 +425,7 @@ dio_bio_add_page(struct dio *dio, struct page *page,
                }
        }
        page_cache_release(page);
+       dio->pages_left--;
 out:
        return ret;
 }
@@ -566,6 +569,10 @@ direct_io_worker(int rw, struct inode *inode, const struct iovec *iov,
        spin_lock_init(&dio.bio_list_lock);
        dio.bio_list = NULL;
        dio.waiter = NULL;
+       dio.pages_left = 0;
+
+       for (seg = 0; seg < nr_segs; seg++) 
+               dio.pages_left += (iov[seg].iov_len / PAGE_SIZE) + 2; 
 
        for (seg = 0; seg < nr_segs; seg++) {
                user_addr = (unsigned long)iov[seg].iov_base;