Skip to content

Commit 2e18d4d

Browse files
committed
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 <[email protected]>
1 parent bc28e1c commit 2e18d4d

File tree

5 files changed

+30
-9
lines changed

5 files changed

+30
-9
lines changed

fs/nfs/filelayout/filelayout.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -255,13 +255,16 @@ static int filelayout_read_done_cb(struct rpc_task *task,
255255
static void
256256
filelayout_set_layoutcommit(struct nfs_pgio_header *hdr)
257257
{
258+
loff_t end_offs = 0;
258259

259260
if (FILELAYOUT_LSEG(hdr->lseg)->commit_through_mds ||
260-
hdr->res.verf->committed != NFS_DATA_SYNC)
261+
hdr->res.verf->committed == NFS_FILE_SYNC)
261262
return;
263+
if (hdr->res.verf->committed == NFS_DATA_SYNC)
264+
end_offs = hdr->mds_offset + (loff_t)hdr->res.count;
262265

263-
pnfs_set_layoutcommit(hdr->inode, hdr->lseg,
264-
hdr->mds_offset + hdr->res.count);
266+
/* Note: if the write is unstable, don't set end_offs until commit */
267+
pnfs_set_layoutcommit(hdr->inode, hdr->lseg, end_offs);
265268
dprintk("%s inode %lu pls_end_pos %lu\n", __func__, hdr->inode->i_ino,
266269
(unsigned long) NFS_I(hdr->inode)->layout->plh_lwb);
267270
}

fs/nfs/flexfilelayout/flexfilelayout.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1470,6 +1470,7 @@ static void ff_layout_read_release(void *data)
14701470
static int ff_layout_write_done_cb(struct rpc_task *task,
14711471
struct nfs_pgio_header *hdr)
14721472
{
1473+
loff_t end_offs = 0;
14731474
int err;
14741475

14751476
trace_nfs4_pnfs_write(hdr, task->tk_status);
@@ -1495,8 +1496,10 @@ static int ff_layout_write_done_cb(struct rpc_task *task,
14951496

14961497
if (hdr->res.verf->committed == NFS_FILE_SYNC ||
14971498
hdr->res.verf->committed == NFS_DATA_SYNC)
1498-
ff_layout_set_layoutcommit(hdr->inode, hdr->lseg,
1499-
hdr->mds_offset + (loff_t)hdr->res.count);
1499+
end_offs = 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);
15001503

15011504
/* zero out fattr since we don't care DS attr at all */
15021505
hdr->fattr.valid = 0;

fs/nfs/nfs4xdr.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,9 +1985,14 @@ encode_layoutcommit(struct xdr_stream *xdr,
19851985
p = xdr_encode_hyper(p, args->lastbytewritten + 1); /* length */
19861986
*p = cpu_to_be32(0); /* reclaim */
19871987
encode_nfs4_stateid(xdr, &args->stateid);
1988-
p = reserve_space(xdr, 20);
1989-
*p++ = cpu_to_be32(1); /* newoffset = TRUE */
1990-
p = xdr_encode_hyper(p, args->lastbytewritten);
1988+
if (args->lastbytewritten != U64_MAX) {
1989+
p = reserve_space(xdr, 20);
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+
}
19911996
*p++ = cpu_to_be32(0); /* Never send time_modify_changed */
19921997
*p++ = cpu_to_be32(NFS_SERVER(args->inode)->pnfs_curr_ld->id);/* type */
19931998

fs/nfs/pnfs.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2378,7 +2378,10 @@ pnfs_layoutcommit_inode(struct inode *inode, bool sync)
23782378
nfs_fattr_init(&data->fattr);
23792379
data->args.bitmask = NFS_SERVER(inode)->cache_consistency_bitmask;
23802380
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;
23822385
data->res.server = NFS_SERVER(inode);
23832386

23842387
if (ld->prepare_layoutcommit) {

fs/nfs/pnfs_nfs.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -932,6 +932,13 @@ EXPORT_SYMBOL_GPL(pnfs_layout_mark_request_commit);
932932
int
933933
pnfs_nfs_generic_sync(struct inode *inode, bool datasync)
934934
{
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;
935942
if (datasync)
936943
return 0;
937944
return pnfs_layoutcommit_inode(inode, true);

0 commit comments

Comments
 (0)