fs/block_dev.c: remove #if 0'ed code
Commit b2e895dbd8
#if 0'ed this code stating:
<-- snip -->
[PATCH] revert blockdev direct io back to 2.6.19 version
Andrew Vasquez is reporting as-iosched oopses and a 65% throughput
slowdown due to the recent special-casing of direct-io against
blockdevs. We don't know why either of these things are occurring.
The patch minimally reverts us back to the 2.6.19 code for a 2.6.20
release.
<-- snip -->
It has since been dead code, and unless someone wants to revive it now
it's time to remove it.
This patch also makes bio_release_pages() static again and removes the
ki_bio_count member from struct kiocb, reverting changes that had been
done for this dead code.
Signed-off-by: Adrian Bunk <bunk@kernel.org>
Signed-off-by: Jens Axboe <axboe@carl.home.kernel.dk>
This commit is contained in:
Родитель
4c54ac62dc
Коммит
86b6c7a7f7
2
fs/bio.c
2
fs/bio.c
|
@ -903,7 +903,7 @@ void bio_set_pages_dirty(struct bio *bio)
|
|||
}
|
||||
}
|
||||
|
||||
void bio_release_pages(struct bio *bio)
|
||||
static void bio_release_pages(struct bio *bio)
|
||||
{
|
||||
struct bio_vec *bvec = bio->bi_io_vec;
|
||||
int i;
|
||||
|
|
197
fs/block_dev.c
197
fs/block_dev.c
|
@ -173,203 +173,6 @@ blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
|
|||
iov, offset, nr_segs, blkdev_get_blocks, NULL);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void blk_end_aio(struct bio *bio, int error)
|
||||
{
|
||||
struct kiocb *iocb = bio->bi_private;
|
||||
atomic_t *bio_count = &iocb->ki_bio_count;
|
||||
|
||||
if (bio_data_dir(bio) == READ)
|
||||
bio_check_pages_dirty(bio);
|
||||
else {
|
||||
bio_release_pages(bio);
|
||||
bio_put(bio);
|
||||
}
|
||||
|
||||
/* iocb->ki_nbytes stores error code from LLDD */
|
||||
if (error)
|
||||
iocb->ki_nbytes = -EIO;
|
||||
|
||||
if (atomic_dec_and_test(bio_count)) {
|
||||
if ((long)iocb->ki_nbytes < 0)
|
||||
aio_complete(iocb, iocb->ki_nbytes, 0);
|
||||
else
|
||||
aio_complete(iocb, iocb->ki_left, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define VEC_SIZE 16
|
||||
struct pvec {
|
||||
unsigned short nr;
|
||||
unsigned short idx;
|
||||
struct page *page[VEC_SIZE];
|
||||
};
|
||||
|
||||
#define PAGES_SPANNED(addr, len) \
|
||||
(DIV_ROUND_UP((addr) + (len), PAGE_SIZE) - (addr) / PAGE_SIZE);
|
||||
|
||||
/*
|
||||
* get page pointer for user addr, we internally cache struct page array for
|
||||
* (addr, count) range in pvec to avoid frequent call to get_user_pages. If
|
||||
* internal page list is exhausted, a batch count of up to VEC_SIZE is used
|
||||
* to get next set of page struct.
|
||||
*/
|
||||
static struct page *blk_get_page(unsigned long addr, size_t count, int rw,
|
||||
struct pvec *pvec)
|
||||
{
|
||||
int ret, nr_pages;
|
||||
if (pvec->idx == pvec->nr) {
|
||||
nr_pages = PAGES_SPANNED(addr, count);
|
||||
nr_pages = min(nr_pages, VEC_SIZE);
|
||||
down_read(¤t->mm->mmap_sem);
|
||||
ret = get_user_pages(current, current->mm, addr, nr_pages,
|
||||
rw == READ, 0, pvec->page, NULL);
|
||||
up_read(¤t->mm->mmap_sem);
|
||||
if (ret < 0)
|
||||
return ERR_PTR(ret);
|
||||
pvec->nr = ret;
|
||||
pvec->idx = 0;
|
||||
}
|
||||
return pvec->page[pvec->idx++];
|
||||
}
|
||||
|
||||
/* return a page back to pvec array */
|
||||
static void blk_unget_page(struct page *page, struct pvec *pvec)
|
||||
{
|
||||
pvec->page[--pvec->idx] = page;
|
||||
}
|
||||
|
||||
static ssize_t
|
||||
blkdev_direct_IO(int rw, struct kiocb *iocb, const struct iovec *iov,
|
||||
loff_t pos, unsigned long nr_segs)
|
||||
{
|
||||
struct inode *inode = iocb->ki_filp->f_mapping->host;
|
||||
unsigned blkbits = blksize_bits(bdev_hardsect_size(I_BDEV(inode)));
|
||||
unsigned blocksize_mask = (1 << blkbits) - 1;
|
||||
unsigned long seg = 0; /* iov segment iterator */
|
||||
unsigned long nvec; /* number of bio vec needed */
|
||||
unsigned long cur_off; /* offset into current page */
|
||||
unsigned long cur_len; /* I/O len of current page, up to PAGE_SIZE */
|
||||
|
||||
unsigned long addr; /* user iovec address */
|
||||
size_t count; /* user iovec len */
|
||||
size_t nbytes = iocb->ki_nbytes = iocb->ki_left; /* total xfer size */
|
||||
loff_t size; /* size of block device */
|
||||
struct bio *bio;
|
||||
atomic_t *bio_count = &iocb->ki_bio_count;
|
||||
struct page *page;
|
||||
struct pvec pvec;
|
||||
|
||||
pvec.nr = 0;
|
||||
pvec.idx = 0;
|
||||
|
||||
if (pos & blocksize_mask)
|
||||
return -EINVAL;
|
||||
|
||||
size = i_size_read(inode);
|
||||
if (pos + nbytes > size) {
|
||||
nbytes = size - pos;
|
||||
iocb->ki_left = nbytes;
|
||||
}
|
||||
|
||||
/*
|
||||
* check first non-zero iov alignment, the remaining
|
||||
* iov alignment is checked inside bio loop below.
|
||||
*/
|
||||
do {
|
||||
addr = (unsigned long) iov[seg].iov_base;
|
||||
count = min(iov[seg].iov_len, nbytes);
|
||||
if (addr & blocksize_mask || count & blocksize_mask)
|
||||
return -EINVAL;
|
||||
} while (!count && ++seg < nr_segs);
|
||||
atomic_set(bio_count, 1);
|
||||
|
||||
while (nbytes) {
|
||||
/* roughly estimate number of bio vec needed */
|
||||
nvec = (nbytes + PAGE_SIZE - 1) / PAGE_SIZE;
|
||||
nvec = max(nvec, nr_segs - seg);
|
||||
nvec = min(nvec, (unsigned long) BIO_MAX_PAGES);
|
||||
|
||||
/* bio_alloc should not fail with GFP_KERNEL flag */
|
||||
bio = bio_alloc(GFP_KERNEL, nvec);
|
||||
bio->bi_bdev = I_BDEV(inode);
|
||||
bio->bi_end_io = blk_end_aio;
|
||||
bio->bi_private = iocb;
|
||||
bio->bi_sector = pos >> blkbits;
|
||||
same_bio:
|
||||
cur_off = addr & ~PAGE_MASK;
|
||||
cur_len = PAGE_SIZE - cur_off;
|
||||
if (count < cur_len)
|
||||
cur_len = count;
|
||||
|
||||
page = blk_get_page(addr, count, rw, &pvec);
|
||||
if (unlikely(IS_ERR(page)))
|
||||
goto backout;
|
||||
|
||||
if (bio_add_page(bio, page, cur_len, cur_off)) {
|
||||
pos += cur_len;
|
||||
addr += cur_len;
|
||||
count -= cur_len;
|
||||
nbytes -= cur_len;
|
||||
|
||||
if (count)
|
||||
goto same_bio;
|
||||
while (++seg < nr_segs) {
|
||||
addr = (unsigned long) iov[seg].iov_base;
|
||||
count = iov[seg].iov_len;
|
||||
if (!count)
|
||||
continue;
|
||||
if (unlikely(addr & blocksize_mask ||
|
||||
count & blocksize_mask)) {
|
||||
page = ERR_PTR(-EINVAL);
|
||||
goto backout;
|
||||
}
|
||||
count = min(count, nbytes);
|
||||
goto same_bio;
|
||||
}
|
||||
} else {
|
||||
blk_unget_page(page, &pvec);
|
||||
}
|
||||
|
||||
/* bio is ready, submit it */
|
||||
if (rw == READ)
|
||||
bio_set_pages_dirty(bio);
|
||||
atomic_inc(bio_count);
|
||||
submit_bio(rw, bio);
|
||||
}
|
||||
|
||||
completion:
|
||||
iocb->ki_left -= nbytes;
|
||||
nbytes = iocb->ki_left;
|
||||
iocb->ki_pos += nbytes;
|
||||
|
||||
blk_run_address_space(inode->i_mapping);
|
||||
if (atomic_dec_and_test(bio_count))
|
||||
aio_complete(iocb, nbytes, 0);
|
||||
|
||||
return -EIOCBQUEUED;
|
||||
|
||||
backout:
|
||||
/*
|
||||
* back out nbytes count constructed so far for this bio,
|
||||
* we will throw away current bio.
|
||||
*/
|
||||
nbytes += bio->bi_size;
|
||||
bio_release_pages(bio);
|
||||
bio_put(bio);
|
||||
|
||||
/*
|
||||
* if no bio was submmitted, return the error code.
|
||||
* otherwise, proceed with pending I/O completion.
|
||||
*/
|
||||
if (atomic_read(bio_count) == 1)
|
||||
return PTR_ERR(page);
|
||||
goto completion;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int blkdev_writepage(struct page *page, struct writeback_control *wbc)
|
||||
{
|
||||
return block_write_full_page(page, blkdev_get_block, wbc);
|
||||
|
|
|
@ -105,7 +105,6 @@ struct kiocb {
|
|||
wait_queue_t ki_wait;
|
||||
loff_t ki_pos;
|
||||
|
||||
atomic_t ki_bio_count; /* num bio used for this iocb */
|
||||
void *private;
|
||||
/* State that we remember to be able to restart/retry */
|
||||
unsigned short ki_opcode;
|
||||
|
|
|
@ -326,7 +326,6 @@ extern struct bio *bio_map_kern(struct request_queue *, void *, unsigned int,
|
|||
gfp_t);
|
||||
extern void bio_set_pages_dirty(struct bio *bio);
|
||||
extern void bio_check_pages_dirty(struct bio *bio);
|
||||
extern void bio_release_pages(struct bio *bio);
|
||||
extern struct bio *bio_copy_user(struct request_queue *, unsigned long, unsigned int, int);
|
||||
extern int bio_uncopy_user(struct bio *);
|
||||
void zero_fill_bio(struct bio *bio);
|
||||
|
|
Загрузка…
Ссылка в новой задаче