Hi Greg,

Bellow is backport of upstream commit 96c9eae638765c2bf2ca4f5a6325484f9bb69aa7,
to the 3.6.y branch.

Thanks,
Tao

From 132ed333bdd529ee19812e5fffa5396364915a4e Mon Sep 17 00:00:00 2001
From: Peng Tao <bergw...@gmail.com>
Date: Fri, 24 Aug 2012 00:27:53 +0800
Subject: [PATCH 2/2] pnfsblock: fix non-aligned DIO write

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>
---
 fs/nfs/blocklayout/blocklayout.c |   34 +++++++++++++++++++++++++++++++---
 1 files changed, 31 insertions(+), 3 deletions(-)

diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index e5dfef5..1093968 100644
--- a/fs/nfs/blocklayout/blocklayout.c
+++ b/fs/nfs/blocklayout/blocklayout.c
@@ -685,7 +685,7 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
        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 *wdata, int sync)
            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_descriptor *pgio, 
struct nfs_page *prev,
        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_read_ops = {
 };
 
 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,
 };
 
-- 
1.7.1

> -----Original Message-----
> From: gre...@linuxfoundation.org [mailto:gre...@linuxfoundation.org]
> Sent: Sunday, October 14, 2012 6:29 PM
> To: bergw...@gmail.com; stable@vger.kernel.org; Peng, Tao; 
> trond.mykleb...@netapp.com
> Cc: stable@vger.kernel.org
> Subject: FAILED: patch "[PATCH] pnfsblock: fix non-aligned DIO write" failed 
> to apply to 3.6-stable
> tree
> 
> 
> The patch below does not apply to the 3.6-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <stable@vger.kernel.org>.
> 
> thanks,
> 
> greg k-h
> 
> ------------------ original commit in Linus's tree ------------------
> 
> 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: [PATCH] pnfsblock: fix non-aligned DIO write
> 
> 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.
> 
> Cc: stable <stable@vger.kernel.org> [since v3.4]
> Signed-off-by: Peng Tao <tao.p...@emc.com>
> Signed-off-by: Trond Myklebust <trond.mykleb...@netapp.com>
> 
> diff --git a/fs/nfs/blocklayout/blocklayout.c 
> b/fs/nfs/blocklayout/blocklayout.c
> index 61e04fb..af3ef0e 100644
> --- a/fs/nfs/blocklayout/blocklayout.c
> +++ b/fs/nfs/blocklayout/blocklayout.c
> @@ -685,7 +685,7 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
>       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 *wdata, int sync)
>           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_descriptor *pgio, 
> struct nfs_page *prev,
>       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_read_ops = {
>  };
> 
>  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,
>  };
> 
> 

Reply via email to