aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/blocklayout
diff options
context:
space:
mode:
authorPeng Tao <bergwolf@gmail.com>2012-08-23 12:27:53 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2012-10-01 18:38:35 -0400
commit96c9eae638765c2bf2ca4f5a6325484f9bb69aa7 (patch)
tree9824f378029107b3f7be58df63a8c17a08f9b84b /fs/nfs/blocklayout
parentf742dc4a32587bff50b13dde9d8894b96851951a (diff)
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.peng@emc.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/blocklayout')
-rw-r--r--fs/nfs/blocklayout/blocklayout.c34
1 files changed, 31 insertions, 3 deletions
diff --git a/fs/nfs/blocklayout/blocklayout.c b/fs/nfs/blocklayout/blocklayout.c
index 61e04fb7c4b8..af3ef0e68491 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)
685 struct bio *bio = NULL; 685 struct bio *bio = NULL;
686 struct pnfs_block_extent *be = NULL, *cow_read = NULL; 686 struct pnfs_block_extent *be = NULL, *cow_read = NULL;
687 sector_t isect, last_isect = 0, extent_length = 0; 687 sector_t isect, last_isect = 0, extent_length = 0;
688 struct parallel_io *par; 688 struct parallel_io *par = NULL;
689 loff_t offset = wdata->args.offset; 689 loff_t offset = wdata->args.offset;
690 size_t count = wdata->args.count; 690 size_t count = wdata->args.count;
691 unsigned int pg_offset, pg_len, saved_len; 691 unsigned int pg_offset, pg_len, saved_len;
@@ -697,6 +697,13 @@ bl_write_pagelist(struct nfs_write_data *wdata, int sync)
697 NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT; 697 NFS_SERVER(header->inode)->pnfs_blksize >> PAGE_CACHE_SHIFT;
698 698
699 dprintk("%s enter, %Zu@%lld\n", __func__, count, offset); 699 dprintk("%s enter, %Zu@%lld\n", __func__, count, offset);
700
701 if (header->dreq != NULL &&
702 (!IS_ALIGNED(offset, NFS_SERVER(header->inode)->pnfs_blksize) ||
703 !IS_ALIGNED(count, NFS_SERVER(header->inode)->pnfs_blksize))) {
704 dprintk("pnfsblock nonblock aligned DIO writes. Resend MDS\n");
705 goto out_mds;
706 }
700 /* At this point, wdata->pages is a (sequential) list of nfs_pages. 707 /* At this point, wdata->pages is a (sequential) list of nfs_pages.
701 * We want to write each, and if there is an error set pnfs_error 708 * We want to write each, and if there is an error set pnfs_error
702 * to have it redone using nfs. 709 * to have it redone using nfs.
@@ -1197,6 +1204,27 @@ bl_pg_test_read(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
1197 return pnfs_generic_pg_test(pgio, prev, req); 1204 return pnfs_generic_pg_test(pgio, prev, req);
1198} 1205}
1199 1206
1207void
1208bl_pg_init_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *req)
1209{
1210 if (pgio->pg_dreq != NULL &&
1211 !is_aligned_req(req, PAGE_CACHE_SIZE))
1212 nfs_pageio_reset_write_mds(pgio);
1213 else
1214 pnfs_generic_pg_init_write(pgio, req);
1215}
1216
1217static bool
1218bl_pg_test_write(struct nfs_pageio_descriptor *pgio, struct nfs_page *prev,
1219 struct nfs_page *req)
1220{
1221 if (pgio->pg_dreq != NULL &&
1222 !is_aligned_req(req, PAGE_CACHE_SIZE))
1223 return false;
1224
1225 return pnfs_generic_pg_test(pgio, prev, req);
1226}
1227
1200static const struct nfs_pageio_ops bl_pg_read_ops = { 1228static const struct nfs_pageio_ops bl_pg_read_ops = {
1201 .pg_init = bl_pg_init_read, 1229 .pg_init = bl_pg_init_read,
1202 .pg_test = bl_pg_test_read, 1230 .pg_test = bl_pg_test_read,
@@ -1204,8 +1232,8 @@ static const struct nfs_pageio_ops bl_pg_read_ops = {
1204}; 1232};
1205 1233
1206static const struct nfs_pageio_ops bl_pg_write_ops = { 1234static const struct nfs_pageio_ops bl_pg_write_ops = {
1207 .pg_init = pnfs_generic_pg_init_write, 1235 .pg_init = bl_pg_init_write,
1208 .pg_test = pnfs_generic_pg_test, 1236 .pg_test = bl_pg_test_write,
1209 .pg_doio = pnfs_generic_pg_writepages, 1237 .pg_doio = pnfs_generic_pg_writepages,
1210}; 1238};
1211 1239