This is a note to let you know that I've just added the patch titled pnfsblock: fix non-aligned DIO write
to the 3.6-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: pnfsblock-fix-non-aligned-dio-write.patch and it can be found in the queue-3.6 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@vger.kernel.org> know about it. >From 96c9eae638765c2bf2ca4f5a6325484f9bb69aa7 Mon Sep 17 00:00:00 2001 From: Peng Tao <bergw...@gmail.com> Date: Fri, 24 Aug 2012 00:27:53 +0800 Subject: pnfsblock: fix non-aligned DIO write From: Peng Tao <bergw...@gmail.com> commit 96c9eae638765c2bf2ca4f5a6325484f9bb69aa7 upstream. For DIO writes, if it is not blocksize aligned, we need to do internal serialization. It may slow down writers anyway. So we just bail them out and resend to MDS. Signed-off-by: Peng Tao <tao.p...@emc.com> Signed-off-by: Trond Myklebust <trond.mykleb...@netapp.com> Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org> --- fs/nfs/blocklayout/blocklayout.c | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) --- a/fs/nfs/blocklayout/blocklayout.c +++ b/fs/nfs/blocklayout/blocklayout.c @@ -685,7 +685,7 @@ bl_write_pagelist(struct nfs_write_data struct bio *bio = NULL; struct pnfs_block_extent *be = NULL, *cow_read = NULL; sector_t isect, last_isect = 0, extent_length = 0; - struct parallel_io *par; + struct parallel_io *par = NULL; loff_t offset = wdata->args.offset; size_t count = wdata->args.count; unsigned int pg_offset, pg_len, saved_len; @@ -697,6 +697,13 @@ bl_write_pagelist(struct nfs_write_data NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT; dprintk("%s enter, %Zu@%lld\n", __func__, count, offset); + + if (header->dreq != NULL && + (!IS_ALIGNED(offset, NFS_SERVER(header->inode)->pnfs_blksize) || + !IS_ALIGNED(count, NFS_SERVER(header->inode)->pnfs_blksize))) { + dprintk("pnfsblock nonblock aligned DIO writes. Resend MDS\n"); + goto out_mds; + } /* At this point, wdata->pages is a (sequential) list of nfs_pages. * We want to write each, and if there is an error set pnfs_error * to have it redone using nfs. @@ -1197,6 +1204,27 @@ bl_pg_test_read(struct nfs_pageio_descri return pnfs_generic_pg_test(pgio, prev, req); } +void +bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req) +{ + if (pgio->pg_dreq != NULL && + !is_aligned_req(req, PAGE_CACHE_SIZE)) + nfs_pageio_reset_write_mds(pgio); + else + pnfs_generic_pg_init_write(pgio, req); +} + +static bool +bl_pg_test_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev, + struct nfs_page *req) +{ + if (pgio->pg_dreq != NULL && + !is_aligned_req(req, PAGE_CACHE_SIZE)) + return false; + + return pnfs_generic_pg_test(pgio, prev, req); +} + static const struct nfs_pageio_ops bl_pg_read_ops = { .pg_init = bl_pg_init_read, .pg_test = bl_pg_test_read, @@ -1204,8 +1232,8 @@ static const struct nfs_pageio_ops bl_pg }; static const struct nfs_pageio_ops bl_pg_write_ops = { - .pg_init = pnfs_generic_pg_init_write, - .pg_test = pnfs_generic_pg_test, + .pg_init = bl_pg_init_write, + .pg_test = bl_pg_test_write, .pg_doio = pnfs_generic_pg_writepages, }; Patches currently in stable-queue which might be from bergw...@gmail.com are queue-3.6/pnfsblock-fix-non-aligned-dio-write.patch queue-3.6/pnfsblock-fix-non-aligned-dio-read.patch -- To unsubscribe from this list: send the line "unsubscribe stable" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html