[RFC PATCH 11/22] dio: add dio_lock_and_flush() helper

From: Dave Kleikamp
Date: Mon Feb 27 2012 - 16:22:55 EST


From: Zach Brown <zab@xxxxxxxxx>

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: Dave Kleikamp <dave.kleikamp@xxxxxxxxxx>
Cc: Zach Brown <zab@xxxxxxxxx>
---
fs/direct-io.c | 56 +++++++++++++++++++++++++++++++++-----------------------
1 file changed, 33 insertions(+), 23 deletions(-)

diff --git a/fs/direct-io.c b/fs/direct-io.c
index 1efe4f1..e75b8d7 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -1158,6 +1158,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 decremented at I/O completion time.
+ */
+ atomic_inc(&inode->i_dio_count);
+
+ return 0;
+}
+
/*
* This is a library function for use by filesystem drivers.
*
@@ -1225,31 +1254,12 @@ do_blockdev_direct_IO(int rw, struct kiocb *iocb, struct inode *inode,
if (!dio)
goto out;

- if (dio->flags & DIO_LOCKING) {
- if (rw == READ) {
- 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;
- }
- }
+ retval = dio_lock_and_flush(dio, offset, end);
+ if (retval) {
+ kmem_cache_free(dio_cache, dio);
+ goto out;
}

- /*
- * Will be decremented at I/O completion time.
- */
- atomic_inc(&inode->i_dio_count);
-
- retval = 0;
-
sdio_init(&sdio, inode, offset, blkbits, get_block, submit_io);

for (seg = 0; seg < nr_segs; seg++) {
--
1.7.9.2

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/