All of lore.kernel.org
 help / color / mirror / Atom feed
From: "J. Bruce Fields" <bfields@fieldses.org>
To: Peng Tao <tao.peng@primarydata.com>
Cc: linux-nfs@vger.kernel.org,
	Trond Myklebust <trond.myklebust@primarydata.com>,
	Anna Schumaker <anna.schumaker@netapp.com>,
	Christoph Hellwig <hch@infradead.org>, Zach Brown <zab@zabbo.net>,
	Darren Hart <dvhart@linux.intel.com>,
	Jeff Layton <jeff.layton@primarydata.com>,
	Anna Schumaker <bjschuma@netapp.com>,
	Christoph Hellwig <hch@lst.de>
Subject: Re: [PATCH RFC 11/11] NFSD: Implement the CLONE call
Date: Tue, 25 Aug 2015 18:11:21 -0400	[thread overview]
Message-ID: <20150825221121.GH8579@fieldses.org> (raw)
In-Reply-To: <1440516829-116041-12-git-send-email-tao.peng@primarydata.com>

On Tue, Aug 25, 2015 at 11:33:49PM +0800, Peng Tao wrote:
> From: Anna Schumaker <bjschuma@netapp.com>
> 
> I can simply call vfs_file_clone_range() and have the vfs do the
> right thing for the filesystem being exported.
> 
> Signed-off-by: Anna Schumaker <bjschuma@netapp.com>
> [hch: change to implement the CLONE op instead of COPY]
> Signed-off-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Peng Tao <tao.peng@primarydata.com>
> ---
>  fs/nfsd/nfs4proc.c   | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++
>  fs/nfsd/nfs4xdr.c    | 21 ++++++++++++++
>  fs/nfsd/vfs.c        |  7 +++++
>  fs/nfsd/vfs.h        |  1 +
>  fs/nfsd/xdr4.h       | 10 +++++++
>  include/linux/nfs4.h |  4 +--
>  6 files changed, 120 insertions(+), 2 deletions(-)
> 
> diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
> index d34c967..c2d3558 100644
> --- a/fs/nfsd/nfs4proc.c
> +++ b/fs/nfsd/nfs4proc.c
> @@ -1014,6 +1014,79 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
>  }
>  
>  static __be32
> +nfsd4_verify_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
> +		  struct nfsd4_clone *clone, struct file **src, struct file **dst)
> +{
> +	struct inode *src_ino, *dst_ino;
> +	__be32 status;
> +
> +	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh,
> +					    &clone->cl_src_stateid, RD_STATE,
> +					    src, NULL);
> +	if (status) {
> +		dprintk("NFSD: %s: couldn't process src stateid!\n", __func__);
> +		return status;
> +	}
> +
> +	status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->current_fh,
> +					    &clone->cl_dst_stateid, WR_STATE,
> +					    dst, NULL);
> +	if (status) {
> +		dprintk("NFSD: %s: couldn't process dst stateid!\n", __func__);
> +		fput(*src);
> +	}
> +
> +	/* a few extra check to make sure we send back proper errors per RFC */
> +	src_ino = file_inode(*src);
> +	dst_ino = file_inode(*dst);
> +
> +        if (S_ISDIR(src_ino->i_mode) || S_ISDIR(dst_ino->i_mode)) {
> +		status = nfserr_wrong_type;
> +		goto out_fput;
> +	}
> +
> +	if (src_ino == dst_ino) {
> +		status = nfserr_inval;
> +		goto out_fput;
> +	}
> +
> +	if (!(*src)->f_op || !(*src)->f_op->clone_range) {
> +		status = nfserr_notsupp;
> +		goto out_fput;
> +	}
> +out:
> +	return status;
> +out_fput:
> +	fput(*src);
> +	fput(*dst);
> +	goto out;
> +}
> +
> +static __be32
> +nfsd4_clone(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
> +		struct nfsd4_clone *clone)
> +{
> +	int ret;
> +	__be32 status;
> +	struct file *src = NULL, *dst = NULL;
> +
> +	status = nfsd4_verify_clone(rqstp, cstate, clone, &src, &dst);
> +	if (status)
> +		return status;
> +
> +	ret = nfsd4_clone_range(src, dst, clone->cl_src_pos,
> +				clone->cl_count, clone->cl_dst_pos);
> +	if (ret < 0)
> +		status = nfserrno(ret);
> +	else
> +		status = nfs_ok;

Can ret be positive, then?  If so are we discarding some information?
(E.g. can clone_range return a success having cloned only part of the
range?)

--b.

> +
> +	fput(src);
> +	fput(dst);
> +	return status;
> +}
> +
> +static __be32
>  nfsd4_fallocate(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
>  		struct nfsd4_fallocate *fallocate, int flags)
>  {
> @@ -2283,6 +2356,12 @@ static struct nfsd4_operation nfsd4_ops[] = {
>  		.op_name = "OP_DEALLOCATE",
>  		.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
>  	},
> +	[OP_CLONE] = {
> +		.op_func = (nfsd4op_func)nfsd4_clone,
> +		.op_flags = OP_MODIFIES_SOMETHING | OP_CACHEME,
> +		.op_name = "OP_CLONE",
> +		.op_rsize_bop = (nfsd4op_rsize)nfsd4_only_status_rsize,
> +	},
>  	[OP_SEEK] = {
>  		.op_func = (nfsd4op_func)nfsd4_seek,
>  		.op_name = "OP_SEEK",
> diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
> index 5463385..a845db1 100644
> --- a/fs/nfsd/nfs4xdr.c
> +++ b/fs/nfsd/nfs4xdr.c
> @@ -1675,6 +1675,25 @@ nfsd4_decode_fallocate(struct nfsd4_compoundargs *argp,
>  }
>  
>  static __be32
> +nfsd4_decode_clone(struct nfsd4_compoundargs *argp, struct nfsd4_clone *clone)
> +{
> +	DECODE_HEAD;
> +
> +	status = nfsd4_decode_stateid(argp, &clone->cl_src_stateid);
> +	if (status)
> +		return status;
> +	status = nfsd4_decode_stateid(argp, &clone->cl_dst_stateid);
> +	if (status)
> +		return status;
> +
> +	READ_BUF(8 + 8 + 8);
> +	p = xdr_decode_hyper(p, &clone->cl_src_pos);
> +	p = xdr_decode_hyper(p, &clone->cl_dst_pos);
> +	p = xdr_decode_hyper(p, &clone->cl_count);
> +	DECODE_TAIL;
> +}
> +
> +static __be32
>  nfsd4_decode_seek(struct nfsd4_compoundargs *argp, struct nfsd4_seek *seek)
>  {
>  	DECODE_HEAD;
> @@ -1785,6 +1804,7 @@ static nfsd4_dec nfsd4_dec_ops[] = {
>  	[OP_READ_PLUS]		= (nfsd4_dec)nfsd4_decode_notsupp,
>  	[OP_SEEK]		= (nfsd4_dec)nfsd4_decode_seek,
>  	[OP_WRITE_SAME]		= (nfsd4_dec)nfsd4_decode_notsupp,
> +	[OP_CLONE]		= (nfsd4_dec)nfsd4_decode_clone,
>  };
>  
>  static inline bool
> @@ -4249,6 +4269,7 @@ static nfsd4_enc nfsd4_enc_ops[] = {
>  	[OP_READ_PLUS]		= (nfsd4_enc)nfsd4_encode_noop,
>  	[OP_SEEK]		= (nfsd4_enc)nfsd4_encode_seek,
>  	[OP_WRITE_SAME]		= (nfsd4_enc)nfsd4_encode_noop,
> +	[OP_CLONE]		= (nfsd4_enc)nfsd4_encode_noop,
>  };
>  
>  /*
> diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
> index b5e077a..7d43097 100644
> --- a/fs/nfsd/vfs.c
> +++ b/fs/nfsd/vfs.c
> @@ -36,6 +36,7 @@
>  #endif /* CONFIG_NFSD_V3 */
>  
>  #ifdef CONFIG_NFSD_V4
> +#include "../internal.h"
>  #include "acl.h"
>  #include "idmap.h"
>  #endif /* CONFIG_NFSD_V4 */
> @@ -498,6 +499,12 @@ __be32 nfsd4_set_nfs4_label(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  }
>  #endif
>  
> +int nfsd4_clone_range(struct file *src, struct file *dst, u64 src_pos,
> +		      u64 count, u64 dst_pos)
> +{
> +	return vfs_file_clone_range(src, dst, src_pos, count, dst_pos);
> +}
> +
>  __be32 nfsd4_vfs_fallocate(struct svc_rqst *rqstp, struct svc_fh *fhp,
>  			   struct file *file, loff_t offset, loff_t len,
>  			   int flags)
> diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h
> index 5be875e..31d56a3 100644
> --- a/fs/nfsd/vfs.h
> +++ b/fs/nfsd/vfs.h
> @@ -56,6 +56,7 @@ __be32          nfsd4_set_nfs4_label(struct svc_rqst *, struct svc_fh *,
>  		    struct xdr_netobj *);
>  __be32		nfsd4_vfs_fallocate(struct svc_rqst *, struct svc_fh *,
>  				    struct file *, loff_t, loff_t, int);
> +int		nfsd4_clone_range(struct file *, struct file *, u64, u64, u64);
>  #endif /* CONFIG_NFSD_V4 */
>  __be32		nfsd_create(struct svc_rqst *, struct svc_fh *,
>  				char *name, int len, struct iattr *attrs,
> diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
> index 9f99100..3d70712 100644
> --- a/fs/nfsd/xdr4.h
> +++ b/fs/nfsd/xdr4.h
> @@ -491,6 +491,15 @@ struct nfsd4_fallocate {
>  	u64		falloc_length;
>  };
>  
> +struct nfsd4_clone {
> +	/* request */
> +	stateid_t	cl_src_stateid;
> +	stateid_t	cl_dst_stateid;
> +	u64		cl_src_pos;
> +	u64		cl_dst_pos;
> +	u64		cl_count;
> +};
> +
>  struct nfsd4_seek {
>  	/* request */
>  	stateid_t	seek_stateid;
> @@ -555,6 +564,7 @@ struct nfsd4_op {
>  		/* NFSv4.2 */
>  		struct nfsd4_fallocate		allocate;
>  		struct nfsd4_fallocate		deallocate;
> +		struct nfsd4_clone		clone;
>  		struct nfsd4_seek		seek;
>  	} u;
>  	struct nfs4_replay *			replay;
> diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h
> index e7e7853..21c6612 100644
> --- a/include/linux/nfs4.h
> +++ b/include/linux/nfs4.h
> @@ -139,10 +139,10 @@ enum nfs_opnum4 {
>  Needs to be updated if more operations are defined in future.*/
>  
>  #define FIRST_NFS4_OP	OP_ACCESS
> -#define LAST_NFS4_OP 	OP_WRITE_SAME
>  #define LAST_NFS40_OP	OP_RELEASE_LOCKOWNER
>  #define LAST_NFS41_OP	OP_RECLAIM_COMPLETE
> -#define LAST_NFS42_OP	OP_WRITE_SAME
> +#define LAST_NFS42_OP	OP_CLONE
> +#define LAST_NFS4_OP 	LAST_NFS42_OP
>  
>  enum nfsstat4 {
>  	NFS4_OK = 0,
> -- 
> 1.8.3.1

  parent reply	other threads:[~2015-08-25 22:11 UTC|newest]

Thread overview: 34+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-08-25 15:33 [PATCH RFC 00/11] NFS/NFSD: add NFSv42 COPY operation support Peng Tao
2015-08-25 15:33 ` [PATCH RFC 01/11] vfs: pull btrfs clone API to vfs layer Peng Tao
2015-08-25 15:33   ` Peng Tao
2015-08-26  1:40   ` Peng Tao
2015-08-26  1:50   ` Dave Chinner
2015-08-26  1:59     ` Dave Chinner
2015-08-26  4:09   ` Darrick J. Wong
2015-08-26  8:03     ` Peng Tao
2015-08-26  8:03       ` Peng Tao
2015-08-25 15:33 ` [PATCH RFC 02/11] vfs/btrfs: add .clone_range file operation Peng Tao
2015-08-26  8:01   ` David Sterba
2015-08-26  8:01     ` David Sterba
2015-08-26  8:31     ` Peng Tao
2015-08-26  8:31       ` Peng Tao
2015-08-26 13:00       ` David Sterba
2015-08-26 13:00         ` David Sterba
2015-08-26 13:07         ` Christoph Hellwig
2015-08-25 15:33 ` [PATCH RFC 03/11] nfs42: decode_layoutstats does not need res parameter Peng Tao
2015-08-25 16:04   ` Anna Schumaker
2015-08-25 15:33 ` [PATCH RFC 04/11] nfs42: remove unused declaration Peng Tao
2015-08-25 16:05   ` Anna Schumaker
2015-08-25 16:08     ` Peng Tao
2015-08-25 15:33 ` [PATCH RFC 05/11] nfs42: add CLONE xdr functions Peng Tao
2015-08-25 15:33 ` [PATCH RFC 06/11] nfs42: add CLONE proc functions Peng Tao
2015-08-25 15:33 ` [PATCH RFC 07/11] nfs42: add .copy_range file operation Peng Tao
2015-08-25 15:33 ` [PATCH RFC 08/11] nfs: get clone_blksize when probing fsinfo Peng Tao
2015-08-25 15:33 ` [PATCH RFC 09/11] nfs42: respect clone_blksize Peng Tao
2015-08-25 15:33 ` [PATCH RFC 10/11] nfsd: Pass filehandle to nfs4_preprocess_stateid_op() Peng Tao
2015-08-25 15:33 ` [PATCH RFC 11/11] NFSD: Implement the CLONE call Peng Tao
2015-08-25 22:09   ` J. Bruce Fields
2015-08-25 22:11   ` J. Bruce Fields [this message]
2015-08-26  1:33     ` Peng Tao
2015-08-25 15:42 ` [PATCH RFC 00/11] NFS/NFSD: add NFSv42 COPY operation support Peng Tao
2015-08-25 16:01   ` Anna Schumaker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150825221121.GH8579@fieldses.org \
    --to=bfields@fieldses.org \
    --cc=anna.schumaker@netapp.com \
    --cc=bjschuma@netapp.com \
    --cc=dvhart@linux.intel.com \
    --cc=hch@infradead.org \
    --cc=hch@lst.de \
    --cc=jeff.layton@primarydata.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=tao.peng@primarydata.com \
    --cc=trond.myklebust@primarydata.com \
    --cc=zab@zabbo.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.