Skip to content

Commit e092693

Browse files
olgakorn1trondmypd
authored andcommitted
NFS append COMMIT after synchronous COPY
Instead of messing with the commit path which has been causing issues, add a COMMIT op after the COPY and ask for stable copies in the first space. It saves a round trip, since after the COPY, the client sends a COMMIT anyway. Signed-off-by: Olga Kornievskaia <kolga@netapp.com> Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
1 parent 28cf22d commit e092693

File tree

5 files changed

+36
-39
lines changed

5 files changed

+36
-39
lines changed

fs/nfs/internal.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,6 @@ void nfs_mark_request_commit(struct nfs_page *req,
495495
u32 ds_commit_idx);
496496
int nfs_write_need_commit(struct nfs_pgio_header *);
497497
void nfs_writeback_update_inode(struct nfs_pgio_header *hdr);
498-
int nfs_commit_file(struct file *file, struct nfs_write_verifier *verf);
499498
int nfs_generic_commit_list(struct inode *inode, struct list_head *head,
500499
int how, struct nfs_commit_info *cinfo);
501500
void nfs_retry_commit(struct list_head *page_list,

fs/nfs/nfs42proc.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -167,23 +167,29 @@ static ssize_t _nfs42_proc_copy(struct file *src,
167167
if (status)
168168
return status;
169169

170+
res->commit_res.verf = kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS);
171+
if (!res->commit_res.verf)
172+
return -ENOMEM;
170173
status = nfs4_call_sync(server->client, server, &msg,
171174
&args->seq_args, &res->seq_res, 0);
172175
if (status == -ENOTSUPP)
173176
server->caps &= ~NFS_CAP_COPY;
174177
if (status)
175-
return status;
178+
goto out;
176179

177-
if (res->write_res.verifier.committed != NFS_FILE_SYNC) {
178-
status = nfs_commit_file(dst, &res->write_res.verifier.verifier);
179-
if (status)
180-
return status;
180+
if (!nfs_write_verifier_cmp(&res->write_res.verifier.verifier,
181+
&res->commit_res.verf->verifier)) {
182+
status = -EAGAIN;
183+
goto out;
181184
}
182185

183186
truncate_pagecache_range(dst_inode, pos_dst,
184187
pos_dst + res->write_res.count);
185188

186-
return res->write_res.count;
189+
status = res->write_res.count;
190+
out:
191+
kfree(res->commit_res.verf);
192+
return status;
187193
}
188194

189195
ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
@@ -240,6 +246,9 @@ ssize_t nfs42_proc_copy(struct file *src, loff_t pos_src,
240246
if (err == -ENOTSUPP) {
241247
err = -EOPNOTSUPP;
242248
break;
249+
} if (err == -EAGAIN) {
250+
dst_exception.retry = 1;
251+
continue;
243252
}
244253

245254
err2 = nfs4_handle_exception(server, err, &src_exception);

fs/nfs/nfs42xdr.c

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,14 @@
6666
encode_putfh_maxsz + \
6767
encode_savefh_maxsz + \
6868
encode_putfh_maxsz + \
69-
encode_copy_maxsz)
69+
encode_copy_maxsz + \
70+
encode_commit_maxsz)
7071
#define NFS4_dec_copy_sz (compound_decode_hdr_maxsz + \
7172
decode_putfh_maxsz + \
7273
decode_savefh_maxsz + \
7374
decode_putfh_maxsz + \
74-
decode_copy_maxsz)
75+
decode_copy_maxsz + \
76+
decode_commit_maxsz)
7577
#define NFS4_enc_deallocate_sz (compound_encode_hdr_maxsz + \
7678
encode_putfh_maxsz + \
7779
encode_deallocate_maxsz + \
@@ -222,6 +224,18 @@ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req,
222224
encode_nops(&hdr);
223225
}
224226

227+
static void encode_copy_commit(struct xdr_stream *xdr,
228+
struct nfs42_copy_args *args,
229+
struct compound_hdr *hdr)
230+
{
231+
__be32 *p;
232+
233+
encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr);
234+
p = reserve_space(xdr, 12);
235+
p = xdr_encode_hyper(p, args->dst_pos);
236+
*p = cpu_to_be32(args->count);
237+
}
238+
225239
/*
226240
* Encode COPY request
227241
*/
@@ -239,6 +253,7 @@ static void nfs4_xdr_enc_copy(struct rpc_rqst *req,
239253
encode_savefh(xdr, &hdr);
240254
encode_putfh(xdr, args->dst_fh, &hdr);
241255
encode_copy(xdr, args, &hdr);
256+
encode_copy_commit(xdr, args, &hdr);
242257
encode_nops(&hdr);
243258
}
244259

@@ -481,6 +496,9 @@ static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp,
481496
if (status)
482497
goto out;
483498
status = decode_copy(xdr, res);
499+
if (status)
500+
goto out;
501+
status = decode_commit(xdr, &res->commit_res);
484502
out:
485503
return status;
486504
}

fs/nfs/write.c

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1742,36 +1742,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how,
17421742
data->mds_ops, how, 0);
17431743
}
17441744

1745-
int nfs_commit_file(struct file *file, struct nfs_write_verifier *verf)
1746-
{
1747-
struct inode *inode = file_inode(file);
1748-
struct nfs_open_context *open;
1749-
struct nfs_commit_info cinfo;
1750-
struct nfs_page *req;
1751-
int ret;
1752-
1753-
open = get_nfs_open_context(nfs_file_open_context(file));
1754-
req = nfs_create_request(open, NULL, NULL, 0, i_size_read(inode));
1755-
if (IS_ERR(req)) {
1756-
ret = PTR_ERR(req);
1757-
goto out_put;
1758-
}
1759-
1760-
nfs_init_cinfo_from_inode(&cinfo, inode);
1761-
1762-
memcpy(&req->wb_verf, verf, sizeof(struct nfs_write_verifier));
1763-
nfs_request_add_commit_list(req, &cinfo);
1764-
ret = nfs_commit_inode(inode, FLUSH_SYNC);
1765-
if (ret > 0)
1766-
ret = 0;
1767-
1768-
nfs_free_request(req);
1769-
out_put:
1770-
put_nfs_open_context(open);
1771-
return ret;
1772-
}
1773-
EXPORT_SYMBOL_GPL(nfs_commit_file);
1774-
17751745
/*
17761746
* COMMIT call returned
17771747
*/

include/linux/nfs_xdr.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1383,6 +1383,7 @@ struct nfs42_copy_res {
13831383
struct nfs42_write_res write_res;
13841384
bool consecutive;
13851385
bool synchronous;
1386+
struct nfs_commitres commit_res;
13861387
};
13871388

13881389
struct nfs42_seek_args {

0 commit comments

Comments
 (0)