From: Dave Kleikamp Date: Wed, 11 Jan 2012 21:11:29 +0000 (-0600) Subject: dio: add dio_alloc_init() helper function X-Git-Tag: v2.6.39-400.9.0~594^2~14 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=5054ab05ebcb1f1d48e74643707cc90de508bfbf;p=users%2Fjedix%2Flinux-maple.git dio: add dio_alloc_init() helper function This adds a helper function which allocates and initializes the dio structure. We'll be calling this from another entry point like __blockdev_direct_IO() in an upcoming patch. Signed-off-by: Zach Brown Signed-off-by: Dave Kleikamp --- diff --git a/fs/direct-io.c b/fs/direct-io.c index 0b232c69590d..f8631731d59d 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1056,6 +1056,47 @@ static int dio_aligned(unsigned long offset, unsigned *blkbits, return 1; } +static struct dio *dio_alloc_init(int flags, int rw, struct kiocb *iocb, + struct inode *inode, dio_iodone_t end_io, + loff_t end) +{ + struct dio *dio; + + dio = kmem_cache_alloc(dio_cache, GFP_KERNEL); + if (!dio) + return NULL; + + /* + * Believe it or not, zeroing out the page array caused a .5% + * performance regression in a database benchmark. So, we take + * care to only zero out what's needed. + */ + memset(dio, 0, offsetof(struct dio, pages)); + + dio->flags = flags; + /* + * For file extending writes updating i_size before data + * writeouts complete can expose uninitialized blocks. So + * even for AIO, we need to wait for i/o to complete before + * returning in this case. + */ + dio->is_async = !is_sync_kiocb(iocb) && !((rw & WRITE) && + (end > i_size_read(inode))); + + dio->inode = inode; + dio->rw = rw; + + dio->end_io = end_io; + + dio->iocb = iocb; + dio->i_size = i_size_read(inode); + + spin_lock_init(&dio->bio_lock); + dio->refcount = 1; + + return dio; +} + /* * This is a library function for use by filesystem drivers. * @@ -1113,18 +1154,11 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, goto out; } - dio = kmem_cache_alloc(dio_cache, GFP_KERNEL); + dio = dio_alloc_init(flags, rw, iocb, inode, end_io, end); retval = -ENOMEM; if (!dio) goto out; - /* - * Believe it or not, zeroing out the page array caused a .5% - * performance regression in a database benchmark. So, we take - * care to only zero out what's needed. - */ - memset(dio, 0, offsetof(struct dio, pages)); - dio->flags = flags; if (dio->flags & DIO_LOCKING) { /* watch out for a 0 len io from a tricksy fs */ if (rw == READ && end > offset) { @@ -1150,35 +1184,17 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, down_read_non_owner(&inode->i_alloc_sem); } - /* - * For file extending writes updating i_size before data - * writeouts complete can expose uninitialized blocks. So - * even for AIO, we need to wait for i/o to complete before - * returning in this case. - */ - dio->is_async = !is_sync_kiocb(iocb) && !((rw & WRITE) && - (end > i_size_read(inode))); - retval = 0; - dio->inode = inode; - dio->rw = rw; sdio.blkbits = blkbits; sdio.blkfactor = inode->i_blkbits - blkbits; sdio.block_in_file = offset >> blkbits; sdio.get_block = get_block; - dio->end_io = end_io; sdio.submit_io = submit_io; sdio.final_block_in_bio = -1; sdio.next_block_for_io = -1; - dio->iocb = iocb; - dio->i_size = i_size_read(inode); - - spin_lock_init(&dio->bio_lock); - dio->refcount = 1; - /* * In case of non-aligned buffers, we may need 2 more * pages since we need to zero out first and last block.