Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e0926934 authored by Olga Kornievskaia's avatar Olga Kornievskaia Committed by Trond Myklebust
Browse files

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: default avatarOlga Kornievskaia <kolga@netapp.com>
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@primarydata.com>
parent 28cf22d0
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -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,
+15 −6
Original line number Diff line number Diff line
@@ -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);
+20 −2
Original line number Diff line number Diff line
@@ -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;
}
+0 −30
Original line number Diff line number Diff line
@@ -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
 */
+1 −0
Original line number Diff line number Diff line
@@ -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 {