From: Dave Kleikamp Date: Wed, 11 Jan 2012 21:25:26 +0000 (-0600) Subject: dio: add dio_lock_and_flush() helper X-Git-Tag: v2.6.39-400.9.0~594^2~12 X-Git-Url: https://www.infradead.org/git/?a=commitdiff_plain;h=17a7d5edf5c6efe5dfe4c93c3ed070ffe981722b;p=users%2Fjedix%2Flinux-maple.git dio: add dio_lock_and_flush() helper This creates a helper function which performs locking based on DIO_LOCKING and flushes dirty pages. This will be called by 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 9462ed92371e..ba4063e88fe9 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c @@ -1118,6 +1118,35 @@ static void sdio_init(struct dio_submit *sdio, struct inode *inode, sdio->pages_in_io = 2; } +static int dio_lock_and_flush(struct dio *dio, loff_t offset, loff_t end) +{ + struct inode *inode = dio->inode; + int ret; + + if (dio->flags & DIO_LOCKING) { + /* watch out for a 0 len io from a tricksy fs */ + if (dio->rw == READ && end > offset) { + + /* will be released by do_blockdev_direct_IO */ + mutex_lock(&inode->i_mutex); + + ret = filemap_write_and_wait_range(inode->i_mapping, + offset, end - 1); + if (ret) { + mutex_unlock(&inode->i_mutex); + return ret; + } + } + + /* + * Will be released at I/O completion, possibly in a + * different thread. + */ + down_read_non_owner(&inode->i_alloc_sem); + } + return 0; +} + /* * This is a library function for use by filesystem drivers. * @@ -1180,33 +1209,12 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode, if (!dio) goto out; - if (dio->flags & DIO_LOCKING) { - /* watch out for a 0 len io from a tricksy fs */ - if (rw == READ && end > offset) { - struct address_space *mapping = - iocb->ki_filp->f_mapping; - - /* will be released by direct_io_worker */ - mutex_lock(&inode->i_mutex); - - retval = filemap_write_and_wait_range(mapping, offset, - end - 1); - if (retval) { - mutex_unlock(&inode->i_mutex); - kmem_cache_free(dio_cache, dio); - goto out; - } - } - - /* - * Will be released at I/O completion, possibly in a - * different thread. - */ - down_read_non_owner(&inode->i_alloc_sem); + retval = dio_lock_and_flush(dio, offset, end); + if (retval) { + kmem_cache_free(dio_cache, dio); + goto out; } - retval = 0; - sdio_init(&sdio, inode, offset, blkbits, get_block, submit_io); for (seg = 0; seg < nr_segs; seg++) {