Commit 2e18d4d8 authored by Trond Myklebust's avatar Trond Myklebust

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: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent bc28e1c2
...@@ -255,13 +255,16 @@ static int filelayout_read_done_cb(struct rpc_task *task, ...@@ -255,13 +255,16 @@ static int filelayout_read_done_cb(struct rpc_task *task,
static void static void
filelayout_set_layoutcommit(struct nfs_pgio_header *hdr) filelayout_set_layoutcommit(struct nfs_pgio_header *hdr)
{ {
loff_t end_offs = 0;
if (FILELAYOUT_LSEG(hdr->lseg)->commit_through_mds || if (FILELAYOUT_LSEG(hdr->lseg)->commit_through_mds ||
hdr->res.verf->committed != NFS_DATA_SYNC) hdr->res.verf->committed == NFS_FILE_SYNC)
return; return;
if (hdr->res.verf->committed == NFS_DATA_SYNC)
end_offs = hdr->mds_offset + (loff_t)hdr->res.count;
pnfs_set_layoutcommit(hdr->inode, hdr->lseg, /* Note: if the write is unstable, don't set end_offs until commit */
hdr->mds_offset + hdr->res.count); pnfs_set_layoutcommit(hdr->inode, hdr->lseg, end_offs);
dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino, dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino,
(unsigned long) NFS_I(hdr->inode)->layout->plh_lwb); (unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
} }
......
...@@ -1470,6 +1470,7 @@ static void ff_layout_read_release(void *data) ...@@ -1470,6 +1470,7 @@ static void ff_layout_read_release(void *data)
static int ff_layout_write_done_cb(struct rpc_task *task, static int ff_layout_write_done_cb(struct rpc_task *task,
struct nfs_pgio_header *hdr) struct nfs_pgio_header *hdr)
{ {
loff_t end_offs = 0;
int err; int err;
trace_nfs4_pnfs_write(hdr, task->tk_status); trace_nfs4_pnfs_write(hdr, task->tk_status);
...@@ -1495,8 +1496,10 @@ static int ff_layout_write_done_cb(struct rpc_task *task, ...@@ -1495,8 +1496,10 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
if (hdr->res.verf->committed == NFS_FILE_SYNC || if (hdr->res.verf->committed == NFS_FILE_SYNC ||
hdr->res.verf->committed == NFS_DATA_SYNC) hdr->res.verf->committed == NFS_DATA_SYNC)
ff_layout_set_layoutcommit(hdr->inode, hdr->lseg, end_offs = hdr->mds_offset + (loff_t)hdr->res.count;
hdr->mds_offset + (loff_t)hdr->res.count);
/* Note: if the write is unstable, don't set end_offs until commit */
ff_layout_set_layoutcommit(hdr->inode, hdr->lseg, end_offs);
/* zero out fattr since we don't care DS attr at all */ /* zero out fattr since we don't care DS attr at all */
hdr->fattr.valid = 0; hdr->fattr.valid = 0;
......
...@@ -1985,9 +1985,14 @@ encode_layoutcommit(struct xdr_stream *xdr, ...@@ -1985,9 +1985,14 @@ encode_layoutcommit(struct xdr_stream *xdr,
p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */ p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */
*p = cpu_to_be32(0); /* reclaim */ *p = cpu_to_be32(0); /* reclaim */
encode_nfs4_stateid(xdr, &args->stateid); encode_nfs4_stateid(xdr, &args->stateid);
p = reserve_space(xdr, 20); if (args->lastbytewritten != U64_MAX) {
*p++ = cpu_to_be32(1); /* newoffset = TRUE */ p = reserve_space(xdr, 20);
p = xdr_encode_hyper(p, args->lastbytewritten); *p++ = cpu_to_be32(1); /* newoffset = TRUE */
p = xdr_encode_hyper(p, args->lastbytewritten);
} else {
p = reserve_space(xdr, 12);
*p++ = cpu_to_be32(0); /* newoffset = FALSE */
}
*p++ = cpu_to_be32(0); /* Never send time_modify_changed */ *p++ = cpu_to_be32(0); /* Never send time_modify_changed */
*p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */ *p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
......
...@@ -2378,7 +2378,10 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync) ...@@ -2378,7 +2378,10 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
nfs_fattr_init(&data->fattr); nfs_fattr_init(&data->fattr);
data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask; data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
data->res.fattr = &data->fattr; data->res.fattr = &data->fattr;
data->args.lastbytewritten = end_pos - 1; if (end_pos != 0)
data->args.lastbytewritten = end_pos - 1;
else
data->args.lastbytewritten = U64_MAX;
data->res.server = NFS_SERVER(inode); data->res.server = NFS_SERVER(inode);
if (ld->prepare_layoutcommit) { if (ld->prepare_layoutcommit) {
......
...@@ -932,6 +932,13 @@ EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit); ...@@ -932,6 +932,13 @@ EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit);
int int
pnfs_nfs_generic_sync(struct inode *inode, bool datasync) pnfs_nfs_generic_sync(struct inode *inode, bool datasync)
{ {
int ret;
if (!pnfs_layoutcommit_outstanding(inode))
return 0;
ret = nfs_commit_inode(inode, FLUSH_SYNC);
if (ret < 0)
return ret;
if (datasync) if (datasync)
return 0; return 0;
return pnfs_layoutcommit_inode(inode, true); return pnfs_layoutcommit_inode(inode, true);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment