From: Benjamin LaHaise <bcrl@redhat.com>
To: linux-aio@kvack.org
Cc: linux-kernel@vger.kernel.org
Subject: patch: aio + bio for raw io
Date: Fri, 8 Feb 2002 02:53:13 -0500 [thread overview]
Message-ID: <20020208025313.A11893@redhat.com> (raw)
Quick message: this patch makes aio use bio directly for brw_kvec_async.
This is against yesterday's patchset. Comments?
-ben
===== fs/Makefile 1.15 vs 1.16 =====
--- 1.15/fs/Makefile Wed Jan 30 02:21:55 2002
+++ 1.16/fs/Makefile Fri Feb 8 14:57:54 2002
@@ -22,6 +22,7 @@
obj-y += noquot.o
endif
+export-objs += aio.o
obj-y += aio.o
subdir-$(CONFIG_PROC_FS) += proc
===== fs/buffer.c 1.60 vs 1.61 =====
--- 1.60/fs/buffer.c Tue Jan 15 05:53:34 2002
+++ 1.61/fs/buffer.c Fri Feb 8 17:22:14 2002
@@ -54,6 +54,8 @@
#include <asm/bitops.h>
#include <asm/mmu_context.h>
+extern struct bio *bio_setup_from_kvec(int gfp_mask, struct kvec *kvec);
+
#define MAX_BUF_PER_PAGE (PAGE_CACHE_SIZE / 512)
#define NR_RESERVED (10*MAX_BUF_PER_PAGE)
#define MAX_UNUSED_BUFFERS NR_RESERVED+20 /* don't ever have more than this
@@ -2764,16 +2766,26 @@
* It is up to the caller to make sure that there are enough blocks
* passed in to completely map the iobufs to disk.
*/
+static int brw_kvec_end_io(struct bio *bio, int nr_sectors)
+{
+ kvec_cb_t cb = bio->cb;
+ int res = nr_sectors * 512;
+ if (!test_bit(BIO_UPTODATE, &bio->bi_flags))
+ res = -EIO;
+ bio_put(bio);
+ cb.fn(cb.data, cb.vec, res);
+ return 0;
+}
-int brw_kvec_async(int rw, kvec_cb_t cb, kdev_t dev, unsigned blocks, unsigned long blknr, int sector_shift)
+int brw_kvec_async(int rw, kvec_cb_t cb, kdev_t dev, unsigned blocks, sector_t blknr, int sector_shift)
{
struct kvec *vec = cb.vec;
struct kveclet *veclet;
- int err;
int length;
unsigned sector_size = 1 << sector_shift;
int i;
+ struct bio *bio;
struct brw_cb *brw_cb;
if (!vec->nr)
@@ -2795,125 +2807,21 @@
if (length < (blocks << sector_shift))
BUG();
- /*
- * OK to walk down the iovec doing page IO on each page we find.
- */
- err = 0;
-
if (!blocks) {
printk("brw_kiovec_async: !i\n");
return -EINVAL;
}
- /* FIXME: tie into userbeans here */
- brw_cb = kmalloc(sizeof(*brw_cb) + (blocks * sizeof(struct buffer_head *)), GFP_KERNEL);
- if (!brw_cb)
+ bio = bio_setup_from_kvec(GFP_KERNEL, vec);
+ if (unlikely(!bio))
return -ENOMEM;
-
- brw_cb->cb = cb;
- brw_cb->nr = 0;
-
- /* This is ugly. FIXME. */
- for (i=0, veclet=vec->veclet; i<vec->nr; i++,veclet++) {
- struct page *page = veclet->page;
- unsigned offset = veclet->offset;
- unsigned length = veclet->length;
-
- if (!page)
- BUG();
-
- while (length > 0) {
- struct buffer_head *tmp;
- tmp = kmem_cache_alloc(bh_cachep, GFP_NOIO);
- err = -ENOMEM;
- if (!tmp)
- goto error;
-
- tmp->b_dev = B_FREE;
- tmp->b_size = sector_size;
- set_bh_page(tmp, page, offset);
- tmp->b_this_page = tmp;
-
- init_buffer(tmp, end_buffer_io_kiobuf_async, NULL);
- tmp->b_dev = dev;
- tmp->b_blocknr = blknr++;
- tmp->b_state = (1 << BH_Mapped) | (1 << BH_Lock)
- | (1 << BH_Req);
- tmp->b_private = brw_cb;
-
- if (rw == WRITE) {
- set_bit(BH_Uptodate, &tmp->b_state);
- clear_bit(BH_Dirty, &tmp->b_state);
- }
-
- brw_cb->bh[brw_cb->nr++] = tmp;
- length -= sector_size;
- offset += sector_size;
-
- if (offset >= PAGE_SIZE) {
- offset = 0;
- break;
- }
-
- if (brw_cb->nr >= blocks)
- goto submit;
- } /* End of block loop */
- } /* End of page loop */
-
-submit:
- atomic_set(&brw_cb->io_count, brw_cb->nr+1);
- /* okay, we've setup all our io requests, now fire them off! */
- for (i=0; i<brw_cb->nr; i++)
- submit_bh(rw, brw_cb->bh[i]);
- brw_cb_put(brw_cb);
+ bio->cb = cb;
+ bio->bi_sector = blknr;
+ bio->bi_dev = dev;
+ bio->bi_vcnt = vec->nr;
+ bio->bi_size = length;
+ bio->bi_end_io = brw_kvec_end_io;
+ submit_bio(rw, bio);
return 0;
-
-error:
- /* Walk brw_cb_table freeing all the goop associated with each kiobuf */
- if (brw_cb) {
- /* We got an error allocating the bh'es. Just free the current
- buffer_heads and exit. */
- for (i=0; i<brw_cb->nr; i++)
- kmem_cache_free(bh_cachep, brw_cb->bh[i]);
- kfree(brw_cb);
- }
-
- return err;
-}
-#if 0
-int brw_kiovec(int rw, int nr, struct kiobuf *iovec[],
- kdev_t dev, int nr_blocks, unsigned long b[], int sector_size)
-{
- int i;
- int transferred = 0;
- int err = 0;
-
- if (!nr)
- return 0;
-
- /* queue up and trigger the io */
- err = brw_kiovec_async(rw, nr, iovec, dev, nr_blocks, b, sector_size);
- if (err)
- goto out;
-
- /* wait on the last iovec first -- it's more likely to finish last */
- for (i=nr; --i >= 0; )
- kiobuf_wait_for_io(iovec[i]);
-
- run_task_queue(&tq_disk);
-
- /* okay, how much data actually got through? */
- for (i=0; i<nr; i++) {
- if (iovec[i]->errno) {
- if (!err)
- err = iovec[i]->errno;
- break;
- }
- transferred += iovec[i]->length;
- }
-
-out:
- return transferred ? transferred : err;
}
-#endif
===== fs/bio.c 1.14 vs 1.15 =====
--- 1.14/fs/bio.c Thu Feb 7 16:13:25 2002
+++ 1.15/fs/bio.c Fri Feb 8 17:22:14 2002
@@ -151,6 +151,22 @@
return NULL;
}
+struct bio *bio_setup_from_kvec(int gfp_mask, struct kvec *kvec)
+{
+ struct bio *bio = mempool_alloc(bio_pool, gfp_mask);
+ struct bio_vec *bvl = NULL;
+
+ if (unlikely(!bio))
+ return NULL;
+
+ bio->bi_max = kvec->max_nr;
+ bio_init(bio);
+ bio->bi_destructor = bio_destructor;
+ bio->bi_io_vec = (struct bio_vec *)kvec->veclet; /* shoot me */
+ bio->bi_flags |= 1 << BIO_CLONED; /* don't free the vec */
+ return bio;
+}
+
/**
* bio_put - release a reference to a bio
* @bio: bio to release reference to
===== include/linux/kiovec.h 1.1 vs 1.2 =====
--- 1.1/include/linux/kiovec.h Sat Jan 12 02:19:10 2002
+++ 1.2/include/linux/kiovec.h Fri Feb 8 15:00:54 2002
@@ -6,8 +6,8 @@
struct kveclet {
struct page *page;
- unsigned offset;
unsigned length;
+ unsigned offset;
};
struct kvec {
===== include/linux/bio.h 1.11 vs 1.12 =====
--- 1.11/include/linux/bio.h Wed Feb 6 01:23:04 2002
+++ 1.12/include/linux/bio.h Fri Feb 8 17:22:23 2002
@@ -26,6 +26,8 @@
#define BIO_VMERGE_BOUNDARY 0
#endif
+#include <linux/kiovec.h>
+
#define BIO_DEBUG
#ifdef BIO_DEBUG
@@ -91,6 +93,7 @@
void *bi_private;
bio_destructor_t *bi_destructor; /* destructor */
+ kvec_cb_t cb;
};
/*
===== fs/aio.c 1.1 vs 1.2 =====
--- 1.1/fs/aio.c Wed Jan 30 13:12:34 2002
+++ 1.2/fs/aio.c Fri Feb 8 14:58:10 2002
@@ -37,6 +37,7 @@
#include <linux/smp_lock.h>
#include <linux/compiler.h>
#include <linux/poll.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
@@ -964,3 +965,8 @@
}
__initcall(aio_setup);
+EXPORT_SYMBOL_GPL(generic_file_kvec_read);
+EXPORT_SYMBOL_GPL(generic_file_aio_read);
+EXPORT_SYMBOL_GPL(generic_file_kvec_write);
+EXPORT_SYMBOL_GPL(generic_file_aio_write);
+EXPORT_SYMBOL_GPL(generic_file_new_read);
next reply other threads:[~2002-02-08 7:53 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-02-08 7:53 Benjamin LaHaise [this message]
2002-02-08 9:40 ` patch: aio + bio for raw io Suparna Bhattacharya
2002-02-08 22:02 ` Benjamin LaHaise
2002-02-11 18:11 ` Suparna Bhattacharya
2002-02-08 21:07 ` Badari Pulavarty
2002-02-08 21:18 ` arjan
2002-02-08 22:13 ` Benjamin LaHaise
2002-02-08 22:54 ` Linus Torvalds
[not found] ` <200202082254.g18Mspq08299@penguin.transmeta.com>
2002-02-09 0:01 ` Benjamin LaHaise
2002-02-09 0:25 ` Linus Torvalds
2002-02-14 4:46 ` Suparna Bhattacharya
2002-02-11 11:09 ` Jens Axboe
2002-02-11 21:37 ` Badari Pulavarty
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20020208025313.A11893@redhat.com \
--to=bcrl@redhat.com \
--cc=linux-aio@kvack.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.