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>
This commit is contained in:
		
							parent
							
								
									28cf22d0ba
								
							
						
					
					
						commit
						e092693443
					
				| @ -495,7 +495,6 @@ void nfs_mark_request_commit(struct nfs_page *req, | ||||
| 			     u32 ds_commit_idx); | ||||
| int nfs_write_need_commit(struct nfs_pgio_header *); | ||||
| void nfs_writeback_update_inode(struct nfs_pgio_header *hdr); | ||||
| int nfs_commit_file(struct file *file, struct nfs_write_verifier *verf); | ||||
| int nfs_generic_commit_list(struct inode *inode, struct list_head *head, | ||||
| 			    int how, struct nfs_commit_info *cinfo); | ||||
| void nfs_retry_commit(struct list_head *page_list, | ||||
|  | ||||
| @ -167,23 +167,29 @@ static ssize_t _nfs42_proc_copy(struct file *src, | ||||
| 	if (status) | ||||
| 		return status; | ||||
| 
 | ||||
| 	res->commit_res.verf = kzalloc(sizeof(struct nfs_writeverf), GFP_NOFS); | ||||
| 	if (!res->commit_res.verf) | ||||
| 		return -ENOMEM; | ||||
| 	status = nfs4_call_sync(server->client, server, &msg, | ||||
| 				&args->seq_args, &res->seq_res, 0); | ||||
| 	if (status == -ENOTSUPP) | ||||
| 		server->caps &= ~NFS_CAP_COPY; | ||||
| 	if (status) | ||||
| 		return status; | ||||
| 		goto out; | ||||
| 
 | ||||
| 	if (res->write_res.verifier.committed != NFS_FILE_SYNC) { | ||||
| 		status = nfs_commit_file(dst, &res->write_res.verifier.verifier); | ||||
| 		if (status) | ||||
| 			return status; | ||||
| 	if (!nfs_write_verifier_cmp(&res->write_res.verifier.verifier, | ||||
| 				    &res->commit_res.verf->verifier)) { | ||||
| 		status = -EAGAIN; | ||||
| 		goto out; | ||||
| 	} | ||||
| 
 | ||||
| 	truncate_pagecache_range(dst_inode, pos_dst, | ||||
| 				 pos_dst + res->write_res.count); | ||||
| 
 | ||||
| 	return res->write_res.count; | ||||
| 	status = res->write_res.count; | ||||
| out: | ||||
| 	kfree(res->commit_res.verf); | ||||
| 	return status; | ||||
| } | ||||
| 
 | ||||
| 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, | ||||
| 		if (err == -ENOTSUPP) { | ||||
| 			err = -EOPNOTSUPP; | ||||
| 			break; | ||||
| 		} if (err == -EAGAIN) { | ||||
| 			dst_exception.retry = 1; | ||||
| 			continue; | ||||
| 		} | ||||
| 
 | ||||
| 		err2 = nfs4_handle_exception(server, err, &src_exception); | ||||
|  | ||||
| @ -66,12 +66,14 @@ | ||||
| 					 encode_putfh_maxsz + \ | ||||
| 					 encode_savefh_maxsz + \ | ||||
| 					 encode_putfh_maxsz + \ | ||||
| 					 encode_copy_maxsz) | ||||
| 					 encode_copy_maxsz + \ | ||||
| 					 encode_commit_maxsz) | ||||
| #define NFS4_dec_copy_sz		(compound_decode_hdr_maxsz + \ | ||||
| 					 decode_putfh_maxsz + \ | ||||
| 					 decode_savefh_maxsz + \ | ||||
| 					 decode_putfh_maxsz + \ | ||||
| 					 decode_copy_maxsz) | ||||
| 					 decode_copy_maxsz + \ | ||||
| 					 decode_commit_maxsz) | ||||
| #define NFS4_enc_deallocate_sz		(compound_encode_hdr_maxsz + \ | ||||
| 					 encode_putfh_maxsz + \ | ||||
| 					 encode_deallocate_maxsz + \ | ||||
| @ -222,6 +224,18 @@ static void nfs4_xdr_enc_allocate(struct rpc_rqst *req, | ||||
| 	encode_nops(&hdr); | ||||
| } | ||||
| 
 | ||||
| static void encode_copy_commit(struct xdr_stream *xdr, | ||||
| 			  struct nfs42_copy_args *args, | ||||
| 			  struct compound_hdr *hdr) | ||||
| { | ||||
| 	__be32 *p; | ||||
| 
 | ||||
| 	encode_op_hdr(xdr, OP_COMMIT, decode_commit_maxsz, hdr); | ||||
| 	p = reserve_space(xdr, 12); | ||||
| 	p = xdr_encode_hyper(p, args->dst_pos); | ||||
| 	*p = cpu_to_be32(args->count); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Encode COPY request | ||||
|  */ | ||||
| @ -239,6 +253,7 @@ static void nfs4_xdr_enc_copy(struct rpc_rqst *req, | ||||
| 	encode_savefh(xdr, &hdr); | ||||
| 	encode_putfh(xdr, args->dst_fh, &hdr); | ||||
| 	encode_copy(xdr, args, &hdr); | ||||
| 	encode_copy_commit(xdr, args, &hdr); | ||||
| 	encode_nops(&hdr); | ||||
| } | ||||
| 
 | ||||
| @ -481,6 +496,9 @@ static int nfs4_xdr_dec_copy(struct rpc_rqst *rqstp, | ||||
| 	if (status) | ||||
| 		goto out; | ||||
| 	status = decode_copy(xdr, res); | ||||
| 	if (status) | ||||
| 		goto out; | ||||
| 	status = decode_commit(xdr, &res->commit_res); | ||||
| out: | ||||
| 	return status; | ||||
| } | ||||
|  | ||||
| @ -1742,36 +1742,6 @@ nfs_commit_list(struct inode *inode, struct list_head *head, int how, | ||||
| 				   data->mds_ops, how, 0); | ||||
| } | ||||
| 
 | ||||
| int nfs_commit_file(struct file *file, struct nfs_write_verifier *verf) | ||||
| { | ||||
| 	struct inode *inode = file_inode(file); | ||||
| 	struct nfs_open_context *open; | ||||
| 	struct nfs_commit_info cinfo; | ||||
| 	struct nfs_page *req; | ||||
| 	int ret; | ||||
| 
 | ||||
| 	open = get_nfs_open_context(nfs_file_open_context(file)); | ||||
| 	req  = nfs_create_request(open, NULL, NULL, 0, i_size_read(inode)); | ||||
| 	if (IS_ERR(req)) { | ||||
| 		ret = PTR_ERR(req); | ||||
| 		goto out_put; | ||||
| 	} | ||||
| 
 | ||||
| 	nfs_init_cinfo_from_inode(&cinfo, inode); | ||||
| 
 | ||||
| 	memcpy(&req->wb_verf, verf, sizeof(struct nfs_write_verifier)); | ||||
| 	nfs_request_add_commit_list(req, &cinfo); | ||||
| 	ret = nfs_commit_inode(inode, FLUSH_SYNC); | ||||
| 	if (ret > 0) | ||||
| 		ret = 0; | ||||
| 
 | ||||
| 	nfs_free_request(req); | ||||
| out_put: | ||||
| 	put_nfs_open_context(open); | ||||
| 	return ret; | ||||
| } | ||||
| EXPORT_SYMBOL_GPL(nfs_commit_file); | ||||
| 
 | ||||
| /*
 | ||||
|  * COMMIT call returned | ||||
|  */ | ||||
|  | ||||
| @ -1383,6 +1383,7 @@ struct nfs42_copy_res { | ||||
| 	struct nfs42_write_res		write_res; | ||||
| 	bool				consecutive; | ||||
| 	bool				synchronous; | ||||
| 	struct nfs_commitres		commit_res; | ||||
| }; | ||||
| 
 | ||||
| struct nfs42_seek_args { | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user