All of lore.kernel.org
 help / color / mirror / Atom feed
From: Suparna Bhattacharya <suparna@in.ibm.com>
To: Benjamin LaHaise <bcrl@redhat.com>
Cc: linux-aio@kvack.org, linux-kernel@vger.kernel.org
Subject: Re: patch: aio + bio for raw io
Date: Fri, 8 Feb 2002 15:10:09 +0530	[thread overview]
Message-ID: <20020208151009.A1810@in.ibm.com> (raw)
In-Reply-To: <20020208025313.A11893@redhat.com>
In-Reply-To: <20020208025313.A11893@redhat.com>; from bcrl@redhat.com on Fri, Feb 08, 2002 at 02:53:13AM -0500

On Fri, Feb 08, 2002 at 02:53:13AM -0500, Benjamin LaHaise wrote:
> Quick message: this patch makes aio use bio directly for brw_kvec_async.  
> This is against yesterday's patchset.  Comments?
> 

I was looking for this in yesterday's aio patchset for 2.5 and was just 
about to send you a note asking you about this :)

You chose to add a kvec_cb field to the bio structure rather than use
bi_private ?
 
For the raw path, you are OK since you never have to copy data out of 
the kvecs after i/o completion, and unmap_kvec only looks at veclet pages. 
So the fact block can change the offset and len fields in the veclets 
doesn't affect you, but thought I'd mention it as a point of caution
anyhow ...

> 		-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);
> --
> To unsubscribe, send a message with 'unsubscribe linux-aio' in
> the body to majordomo@kvack.org.  For more info on Linux AIO,
> see: http://www.kvack.org/aio/

  reply	other threads:[~2002-02-08  9:37 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-02-08  7:53 patch: aio + bio for raw io Benjamin LaHaise
2002-02-08  9:40 ` Suparna Bhattacharya [this message]
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=20020208151009.A1810@in.ibm.com \
    --to=suparna@in.ibm.com \
    --cc=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.