X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fbio.c;h=d59ddbf79626cd0ca546a15bac0196544445fafd;hb=f23e7fdad166a4968f1f7f56964b75acfdcf57a4;hp=7ec737eda72bba71718d433820eae4e0c0d6a489;hpb=4522d58275f124105819723e24e912c8e5bf3cdd;p=linux-2.6-omap-h63xx.git diff --git a/fs/bio.c b/fs/bio.c index 7ec737eda72..d59ddbf7962 100644 --- a/fs/bio.c +++ b/fs/bio.c @@ -28,7 +28,7 @@ #include #include /* for struct sg_iovec */ -#define BIO_POOL_SIZE 256 +#define BIO_POOL_SIZE 2 static struct kmem_cache *bio_slab __read_mostly; @@ -38,7 +38,7 @@ static struct kmem_cache *bio_slab __read_mostly; * a small number of entries is fine, not going to be performance critical. * basically we just need to survive */ -#define BIO_SPLIT_ENTRIES 8 +#define BIO_SPLIT_ENTRIES 2 mempool_t *bio_split_pool __read_mostly; struct biovec_slab { @@ -109,11 +109,14 @@ static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned lon void bio_free(struct bio *bio, struct bio_set *bio_set) { - const int pool_idx = BIO_POOL_IDX(bio); + if (bio->bi_io_vec) { + const int pool_idx = BIO_POOL_IDX(bio); - BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS); + BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS); + + mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]); + } - mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]); mempool_free(bio, bio_set->bio_pool); } @@ -127,21 +130,9 @@ static void bio_fs_destructor(struct bio *bio) void bio_init(struct bio *bio) { - bio->bi_next = NULL; - bio->bi_bdev = NULL; + memset(bio, 0, sizeof(*bio)); bio->bi_flags = 1 << BIO_UPTODATE; - bio->bi_rw = 0; - bio->bi_vcnt = 0; - bio->bi_idx = 0; - bio->bi_phys_segments = 0; - bio->bi_hw_segments = 0; - bio->bi_hw_front_size = 0; - bio->bi_hw_back_size = 0; - bio->bi_size = 0; - bio->bi_max_vecs = 0; - bio->bi_end_io = NULL; atomic_set(&bio->bi_cnt, 1); - bio->bi_private = NULL; } /** @@ -230,7 +221,7 @@ void bio_put(struct bio *bio) } } -inline int bio_phys_segments(request_queue_t *q, struct bio *bio) +inline int bio_phys_segments(struct request_queue *q, struct bio *bio) { if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) blk_recount_segments(q, bio); @@ -238,7 +229,7 @@ inline int bio_phys_segments(request_queue_t *q, struct bio *bio) return bio->bi_phys_segments; } -inline int bio_hw_segments(request_queue_t *q, struct bio *bio) +inline int bio_hw_segments(struct request_queue *q, struct bio *bio) { if (unlikely(!bio_flagged(bio, BIO_SEG_VALID))) blk_recount_segments(q, bio); @@ -257,7 +248,7 @@ inline int bio_hw_segments(request_queue_t *q, struct bio *bio) */ void __bio_clone(struct bio *bio, struct bio *bio_src) { - request_queue_t *q = bdev_get_queue(bio_src->bi_bdev); + struct request_queue *q = bdev_get_queue(bio_src->bi_bdev); memcpy(bio->bi_io_vec, bio_src->bi_io_vec, bio_src->bi_max_vecs * sizeof(struct bio_vec)); @@ -303,7 +294,7 @@ struct bio *bio_clone(struct bio *bio, gfp_t gfp_mask) */ int bio_get_nr_vecs(struct block_device *bdev) { - request_queue_t *q = bdev_get_queue(bdev); + struct request_queue *q = bdev_get_queue(bdev); int nr_pages; nr_pages = ((q->max_sectors << 9) + PAGE_SIZE - 1) >> PAGE_SHIFT; @@ -315,7 +306,7 @@ int bio_get_nr_vecs(struct block_device *bdev) return nr_pages; } -static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page +static int __bio_add_page(struct request_queue *q, struct bio *bio, struct page *page, unsigned int len, unsigned int offset, unsigned short max_sectors) { @@ -425,7 +416,7 @@ static int __bio_add_page(request_queue_t *q, struct bio *bio, struct page * smaller than PAGE_SIZE, so it is always possible to add a single * page to an empty bio. This should only be used by REQ_PC bios. */ -int bio_add_pc_page(request_queue_t *q, struct bio *bio, struct page *page, +int bio_add_pc_page(struct request_queue *q, struct bio *bio, struct page *page, unsigned int len, unsigned int offset) { return __bio_add_page(q, bio, page, len, offset, q->max_hw_sectors); @@ -523,7 +514,7 @@ int bio_uncopy_user(struct bio *bio) * to/from kernel pages as necessary. Must be paired with * call bio_uncopy_user() on io completion. */ -struct bio *bio_copy_user(request_queue_t *q, unsigned long uaddr, +struct bio *bio_copy_user(struct request_queue *q, unsigned long uaddr, unsigned int len, int write_to_vm) { unsigned long end = (uaddr + len + PAGE_SIZE - 1) >> PAGE_SHIFT; @@ -600,7 +591,7 @@ out_bmd: return ERR_PTR(ret); } -static struct bio *__bio_map_user_iov(request_queue_t *q, +static struct bio *__bio_map_user_iov(struct request_queue *q, struct block_device *bdev, struct sg_iovec *iov, int iov_count, int write_to_vm) @@ -712,7 +703,7 @@ static struct bio *__bio_map_user_iov(request_queue_t *q, /** * bio_map_user - map user address into bio - * @q: the request_queue_t for the bio + * @q: the struct request_queue for the bio * @bdev: destination block device * @uaddr: start of user address * @len: length in bytes @@ -721,7 +712,7 @@ static struct bio *__bio_map_user_iov(request_queue_t *q, * Map the user space address into a bio suitable for io to a block * device. Returns an error pointer in case of error. */ -struct bio *bio_map_user(request_queue_t *q, struct block_device *bdev, +struct bio *bio_map_user(struct request_queue *q, struct block_device *bdev, unsigned long uaddr, unsigned int len, int write_to_vm) { struct sg_iovec iov; @@ -734,7 +725,7 @@ struct bio *bio_map_user(request_queue_t *q, struct block_device *bdev, /** * bio_map_user_iov - map user sg_iovec table into bio - * @q: the request_queue_t for the bio + * @q: the struct request_queue for the bio * @bdev: destination block device * @iov: the iovec. * @iov_count: number of elements in the iovec @@ -743,7 +734,7 @@ struct bio *bio_map_user(request_queue_t *q, struct block_device *bdev, * Map the user space address into a bio suitable for io to a block * device. Returns an error pointer in case of error. */ -struct bio *bio_map_user_iov(request_queue_t *q, struct block_device *bdev, +struct bio *bio_map_user_iov(struct request_queue *q, struct block_device *bdev, struct sg_iovec *iov, int iov_count, int write_to_vm) { @@ -798,17 +789,13 @@ void bio_unmap_user(struct bio *bio) bio_put(bio); } -static int bio_map_kern_endio(struct bio *bio, unsigned int bytes_done, int err) +static void bio_map_kern_endio(struct bio *bio, int err) { - if (bio->bi_size) - return 1; - bio_put(bio); - return 0; } -static struct bio *__bio_map_kern(request_queue_t *q, void *data, +static struct bio *__bio_map_kern(struct request_queue *q, void *data, unsigned int len, gfp_t gfp_mask) { unsigned long kaddr = (unsigned long)data; @@ -847,7 +834,7 @@ static struct bio *__bio_map_kern(request_queue_t *q, void *data, /** * bio_map_kern - map kernel address into bio - * @q: the request_queue_t for the bio + * @q: the struct request_queue for the bio * @data: pointer to buffer to map * @len: length in bytes * @gfp_mask: allocation flags for bio allocation @@ -855,7 +842,7 @@ static struct bio *__bio_map_kern(request_queue_t *q, void *data, * Map the kernel address into a bio suitable for io to a block * device. Returns an error pointer in case of error. */ -struct bio *bio_map_kern(request_queue_t *q, void *data, unsigned int len, +struct bio *bio_map_kern(struct request_queue *q, void *data, unsigned int len, gfp_t gfp_mask) { struct bio *bio; @@ -916,7 +903,7 @@ void bio_set_pages_dirty(struct bio *bio) } } -static void bio_release_pages(struct bio *bio) +void bio_release_pages(struct bio *bio) { struct bio_vec *bvec = bio->bi_io_vec; int i; @@ -1002,34 +989,26 @@ void bio_check_pages_dirty(struct bio *bio) /** * bio_endio - end I/O on a bio * @bio: bio - * @bytes_done: number of bytes completed * @error: error, if any * * Description: - * bio_endio() will end I/O on @bytes_done number of bytes. This may be - * just a partial part of the bio, or it may be the whole bio. bio_endio() - * is the preferred way to end I/O on a bio, it takes care of decrementing - * bi_size and clearing BIO_UPTODATE on error. @error is 0 on success, and - * and one of the established -Exxxx (-EIO, for instance) error values in - * case something went wrong. Noone should call bi_end_io() directly on - * a bio unless they own it and thus know that it has an end_io function. + * bio_endio() will end I/O on the whole bio. bio_endio() is the + * preferred way to end I/O on a bio, it takes care of clearing + * BIO_UPTODATE on error. @error is 0 on success, and and one of the + * established -Exxxx (-EIO, for instance) error values in case + * something went wrong. Noone should call bi_end_io() directly on a + * bio unless they own it and thus know that it has an end_io + * function. **/ -void bio_endio(struct bio *bio, unsigned int bytes_done, int error) +void bio_endio(struct bio *bio, int error) { if (error) clear_bit(BIO_UPTODATE, &bio->bi_flags); - - if (unlikely(bytes_done > bio->bi_size)) { - printk("%s: want %u bytes done, only %u left\n", __FUNCTION__, - bytes_done, bio->bi_size); - bytes_done = bio->bi_size; - } - - bio->bi_size -= bytes_done; - bio->bi_sector += (bytes_done >> 9); + else if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) + error = -EIO; if (bio->bi_end_io) - bio->bi_end_io(bio, bytes_done, error); + bio->bi_end_io(bio, error); } void bio_pair_release(struct bio_pair *bp) @@ -1037,37 +1016,29 @@ void bio_pair_release(struct bio_pair *bp) if (atomic_dec_and_test(&bp->cnt)) { struct bio *master = bp->bio1.bi_private; - bio_endio(master, master->bi_size, bp->error); + bio_endio(master, bp->error); mempool_free(bp, bp->bio2.bi_private); } } -static int bio_pair_end_1(struct bio * bi, unsigned int done, int err) +static void bio_pair_end_1(struct bio *bi, int err) { struct bio_pair *bp = container_of(bi, struct bio_pair, bio1); if (err) bp->error = err; - if (bi->bi_size) - return 1; - bio_pair_release(bp); - return 0; } -static int bio_pair_end_2(struct bio * bi, unsigned int done, int err) +static void bio_pair_end_2(struct bio *bi, int err) { struct bio_pair *bp = container_of(bi, struct bio_pair, bio2); if (err) bp->error = err; - if (bi->bi_size) - return 1; - bio_pair_release(bp); - return 0; } /* @@ -1120,7 +1091,7 @@ struct bio_pair *bio_split(struct bio *bi, mempool_t *pool, int first_sectors) * create memory pools for biovec's in a bio_set. * use the global biovec slabs created for general use. */ -static int biovec_create_pools(struct bio_set *bs, int pool_entries, int scale) +static int biovec_create_pools(struct bio_set *bs, int pool_entries) { int i; @@ -1128,9 +1099,6 @@ static int biovec_create_pools(struct bio_set *bs, int pool_entries, int scale) struct biovec_slab *bp = bvec_slabs + i; mempool_t **bvp = bs->bvec_pools + i; - if (pool_entries > 1 && i >= scale) - pool_entries >>= 1; - *bvp = mempool_create_slab_pool(pool_entries, bp->slab); if (!*bvp) return -ENOMEM; @@ -1161,7 +1129,7 @@ void bioset_free(struct bio_set *bs) kfree(bs); } -struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale) +struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size) { struct bio_set *bs = kzalloc(sizeof(*bs), GFP_KERNEL); @@ -1172,7 +1140,7 @@ struct bio_set *bioset_create(int bio_pool_size, int bvec_pool_size, int scale) if (!bs->bio_pool) goto bad; - if (!biovec_create_pools(bs, bvec_pool_size, scale)) + if (!biovec_create_pools(bs, bvec_pool_size)) return bs; bad: @@ -1190,44 +1158,17 @@ static void __init biovec_init_slabs(void) size = bvs->nr_vecs * sizeof(struct bio_vec); bvs->slab = kmem_cache_create(bvs->name, size, 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); + SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL); } } static int __init init_bio(void) { - int megabytes, bvec_pool_entries; - int scale = BIOVEC_NR_POOLS; - - bio_slab = kmem_cache_create("bio", sizeof(struct bio), 0, - SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL); + bio_slab = KMEM_CACHE(bio, SLAB_HWCACHE_ALIGN|SLAB_PANIC); biovec_init_slabs(); - megabytes = nr_free_pages() >> (20 - PAGE_SHIFT); - - /* - * find out where to start scaling - */ - if (megabytes <= 16) - scale = 0; - else if (megabytes <= 32) - scale = 1; - else if (megabytes <= 64) - scale = 2; - else if (megabytes <= 96) - scale = 3; - else if (megabytes <= 128) - scale = 4; - - /* - * Limit number of entries reserved -- mempools are only used when - * the system is completely unable to allocate memory, so we only - * need enough to make progress. - */ - bvec_pool_entries = 1 + scale; - - fs_bio_set = bioset_create(BIO_POOL_SIZE, bvec_pool_entries, scale); + fs_bio_set = bioset_create(BIO_POOL_SIZE, 2); if (!fs_bio_set) panic("bio: can't allocate bios\n"); @@ -1253,8 +1194,6 @@ EXPORT_SYMBOL(bio_hw_segments); EXPORT_SYMBOL(bio_add_page); EXPORT_SYMBOL(bio_add_pc_page); EXPORT_SYMBOL(bio_get_nr_vecs); -EXPORT_SYMBOL(bio_map_user); -EXPORT_SYMBOL(bio_unmap_user); EXPORT_SYMBOL(bio_map_kern); EXPORT_SYMBOL(bio_pair_release); EXPORT_SYMBOL(bio_split);