Skip to content

Commit

Permalink
fs/block_dev.c: remove #if 0'ed code
Browse files Browse the repository at this point in the history
Commit b2e895d #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>
  • Loading branch information
Adrian Bunk authored and Jens Axboe committed Feb 19, 2008
1 parent 4c54ac6 commit 86b6c7a
Show file tree
Hide file tree
Showing 4 changed files with 1 addition and 200 deletions.
2 changes: 1 addition & 1 deletion fs/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
197 changes: 0 additions & 197 deletions fs/block_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -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(&current->mm->mmap_sem);
ret = get_user_pages(current, current->mm, addr, nr_pages,
rw == READ, 0, pvec->page, NULL);
up_read(&current->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);
Expand Down
1 change: 0 additions & 1 deletion include/linux/aio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion include/linux/bio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit 86b6c7a

Please sign in to comment.