aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTrond Myklebust <trond.myklebust@primarydata.com>2016-06-26 18:54:58 -0400
committerTrond Myklebust <trond.myklebust@primarydata.com>2016-07-05 19:08:01 -0400
commit2e18d4d822ea9cc811ea26a880cf2ed47cbf8889 (patch)
tree1ce746bef1598990b96f6f5b4e0c11017a3c9ee7
parentbc28e1c2e3c8a4c5198ebfd8bbae0afd73dfafd5 (diff)
pNFS: Files and flexfiles always need to commit before layoutcommit
So ensure that we mark the layout for commit once the write is done, and then ensure that the commit to ds is finished before sending layoutcommit. Note that by doing this, we're able to optimise away the commit for the case of servers that don't need layoutcommit in order to return updated attributes. Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
-rw-r--r--fs/nfs/filelayout/filelayout.c9
-rw-r--r--fs/nfs/flexfilelayout/flexfilelayout.c7
-rw-r--r--fs/nfs/nfs4xdr.c11
-rw-r--r--fs/nfs/pnfs.c5
-rw-r--r--fs/nfs/pnfs_nfs.c7
5 files changed, 30 insertions, 9 deletions
diff --git a/fs/nfs/filelayout/filelayout.c b/fs/nfs/filelayout/filelayout.c
index b4c1407e8fe4..25bd91a6e088 100644
--- a/fs/nfs/filelayout/filelayout.c
+++ b/fs/nfs/filelayout/filelayout.c
@@ -255,13 +255,16 @@ static int filelayout_read_done_cb(struct rpc_task *task,
255static void 255static void
256filelayout_set_layoutcommit(struct nfs_pgio_header *hdr) 256filelayout_set_layoutcommit(struct nfs_pgio_header *hdr)
257{ 257{
258 loff_t end_offs = 0;
258 259
259 if (FILELAYOUT_LSEG(hdr->lseg)->commit_through_mds || 260 if (FILELAYOUT_LSEG(hdr->lseg)->commit_through_mds ||
260 hdr->res.verf->committed != NFS_DATA_SYNC) 261 hdr->res.verf->committed == NFS_FILE_SYNC)
261 return; 262 return;
263 if (hdr->res.verf->committed == NFS_DATA_SYNC)
264 end_offs = hdr->mds_offset + (loff_t)hdr->res.count;
262 265
263 pnfs_set_layoutcommit(hdr->inode, hdr->lseg, 266 /* Note: if the write is unstable, don't set end_offs until commit */
264 hdr->mds_offset + hdr->res.count); 267 pnfs_set_layoutcommit(hdr->inode, hdr->lseg, end_offs);
265 dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino, 268 dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino,
266 (unsigned long) NFS_I(hdr->inode)->layout->plh_lwb); 269 (unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
267} 270}
diff --git a/fs/nfs/flexfilelayout/flexfilelayout.c b/fs/nfs/flexfilelayout/flexfilelayout.c
index 14f2ed3f1a5b..e6206eaf2bdf 100644
--- a/fs/nfs/flexfilelayout/flexfilelayout.c
+++ b/fs/nfs/flexfilelayout/flexfilelayout.c
@@ -1470,6 +1470,7 @@ static void ff_layout_read_release(void *data)
1470static int ff_layout_write_done_cb(struct rpc_task *task, 1470static int ff_layout_write_done_cb(struct rpc_task *task,
1471 struct nfs_pgio_header *hdr) 1471 struct nfs_pgio_header *hdr)
1472{ 1472{
1473 loff_t end_offs = 0;
1473 int err; 1474 int err;
1474 1475
1475 trace_nfs4_pnfs_write(hdr, task->tk_status); 1476 trace_nfs4_pnfs_write(hdr, task->tk_status);
@@ -1495,8 +1496,10 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
1495 1496
1496 if (hdr->res.verf->committed == NFS_FILE_SYNC || 1497 if (hdr->res.verf->committed == NFS_FILE_SYNC ||
1497 hdr->res.verf->committed == NFS_DATA_SYNC) 1498 hdr->res.verf->committed == NFS_DATA_SYNC)
1498 ff_layout_set_layoutcommit(hdr->inode, hdr->lseg, 1499 end_offs = hdr->mds_offset + (loff_t)hdr->res.count;
1499 hdr->mds_offset + (loff_t)hdr->res.count); 1500
1501 /* Note: if the write is unstable, don't set end_offs until commit */
1502 ff_layout_set_layoutcommit(hdr->inode, hdr->lseg, end_offs);
1500 1503
1501 /* zero out fattr since we don't care DS attr at all */ 1504 /* zero out fattr since we don't care DS attr at all */
1502 hdr->fattr.valid = 0; 1505 hdr->fattr.valid = 0;
diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c
index 661e753fe1c9..7bd3a5c09d31 100644
--- a/fs/nfs/nfs4xdr.c
+++ b/fs/nfs/nfs4xdr.c
@@ -1985,9 +1985,14 @@ encode_layoutcommit(struct xdr_stream *xdr,
1985 p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */ 1985 p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */
1986 *p = cpu_to_be32(0); /* reclaim */ 1986 *p = cpu_to_be32(0); /* reclaim */
1987 encode_nfs4_stateid(xdr, &args->stateid); 1987 encode_nfs4_stateid(xdr, &args->stateid);
1988 p = reserve_space(xdr, 20); 1988 if (args->lastbytewritten != U64_MAX) {
1989 *p++ = cpu_to_be32(1); /* newoffset = TRUE */ 1989 p = reserve_space(xdr, 20);
1990 p = xdr_encode_hyper(p, args->lastbytewritten); 1990 *p++ = cpu_to_be32(1); /* newoffset = TRUE */
1991 p = xdr_encode_hyper(p, args->lastbytewritten);
1992 } else {
1993 p = reserve_space(xdr, 12);
1994 *p++ = cpu_to_be32(0); /* newoffset = FALSE */
1995 }
1991 *p++ = cpu_to_be32(0); /* Never send time_modify_changed */ 1996 *p++ = cpu_to_be32(0); /* Never send time_modify_changed */
1992 *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ 1997 *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
1993 1998
diff --git a/fs/nfs/pnfs.c b/fs/nfs/pnfs.c
index 0c7e0d45a4de..62553182514e 100644
--- a/fs/nfs/pnfs.c
+++ b/fs/nfs/pnfs.c
@@ -2378,7 +2378,10 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
2378 nfs_fattr_init(&data->fattr); 2378 nfs_fattr_init(&data->fattr);
2379 data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask; 2379 data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
2380 data->res.fattr = &data->fattr; 2380 data->res.fattr = &data->fattr;
2381 data->args.lastbytewritten = end_pos - 1; 2381 if (end_pos != 0)
2382 data->args.lastbytewritten = end_pos - 1;
2383 else
2384 data->args.lastbytewritten = U64_MAX;
2382 data->res.server = NFS_SERVER(inode); 2385 data->res.server = NFS_SERVER(inode);
2383 2386
2384 if (ld->prepare_layoutcommit) { 2387 if (ld->prepare_layoutcommit) {
diff --git a/fs/nfs/pnfs_nfs.c b/fs/nfs/pnfs_nfs.c
index 0dfc476da3e1..0d10cc280a23 100644
--- a/fs/nfs/pnfs_nfs.c
+++ b/fs/nfs/pnfs_nfs.c
@@ -932,6 +932,13 @@ EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit);
932int 932int
933pnfs_nfs_generic_sync(struct inode *inode, bool datasync) 933pnfs_nfs_generic_sync(struct inode *inode, bool datasync)
934{ 934{
935 int ret;
936
937 if (!pnfs_layoutcommit_outstanding(inode))
938 return 0;
939 ret = nfs_commit_inode(inode, FLUSH_SYNC);
940 if (ret < 0)
941 return ret;
935 if (datasync) 942 if (datasync)
936 return 0; 943 return 0;
937 return pnfs_layoutcommit_inode(inode, true); 944 return pnfs_layoutcommit_inode(inode, true);