Re: [PATCH v1 08/11] NFS inter ssc open

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Olga,

On Fri, 2018-10-19 at 11:29 -0400, Olga Kornievskaia wrote:
> From: Olga Kornievskaia <kolga@xxxxxxxxxx>
> 
> NFSv4.2 inter server to server copy requires the destination server to
> READ the data from the source server using the provided stateid and
> file handle.
> 
> Given an NFSv4 stateid and filehandle from the COPY operaion, provide the
> destination server with an NFS client function to create a struct file
> suitable for the destiniation server to READ the data to be copied.
> 
> Signed-off-by: Andy Adamson <andros@xxxxxxxxxx>
> Signed-off-by: Olga Kornievskaia <kolga@xxxxxxxxxx>
> ---
>  fs/nfs/nfs4_fs.h  |  7 ++++
>  fs/nfs/nfs4file.c | 98
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  fs/nfs/nfs4proc.c |  5 ++-
>  3 files changed, 107 insertions(+), 3 deletions(-)
> 
> diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h
> index 8d59c96..f229864 100644
> --- a/fs/nfs/nfs4_fs.h
> +++ b/fs/nfs/nfs4_fs.h
> @@ -307,6 +307,13 @@ extern int nfs4_set_rw_stateid(nfs4_stateid *stateid,
>  		const struct nfs_open_context *ctx,
>  		const struct nfs_lock_context *l_ctx,
>  		fmode_t fmode);
> +extern int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh
> *fhandle,
> +			     struct nfs_fattr *fattr, struct nfs4_label *label,
> +			     struct inode *inode);
> +extern int update_open_stateid(struct nfs4_state *state,
> +				const nfs4_stateid *open_stateid,
> +				const nfs4_stateid *deleg_stateid,
> +				fmode_t fmode);
>  
>  #if defined(CONFIG_NFS_V4_1)
>  extern int nfs41_sequence_done(struct rpc_task *, struct nfs4_sequence_res
> *);
> diff --git a/fs/nfs/nfs4file.c b/fs/nfs/nfs4file.c
> index 005862e..7f226f4 100644
> --- a/fs/nfs/nfs4file.c
> +++ b/fs/nfs/nfs4file.c
> @@ -8,6 +8,7 @@
>  #include <linux/file.h>
>  #include <linux/falloc.h>
>  #include <linux/nfs_fs.h>
> +#include <linux/file.h>
>  #include "delegation.h"
>  #include "internal.h"
>  #include "iostat.h"
> @@ -264,6 +265,103 @@ static int nfs42_clone_file_range(struct file *src_file,
> loff_t src_off,
>  out:
>  	return ret;
>  }
> +
> +static int read_name_gen = 1;
> +#define SSC_READ_NAME_BODY "ssc_read_%d"
> +
> +struct file *
> +nfs42_ssc_open(struct vfsmount *ss_mnt, struct nfs_fh *src_fh,
> +		nfs4_stateid *stateid)
> +{
> +	struct nfs_fattr fattr;
> +	struct file *filep, *res;
> +	struct nfs_server *server;
> +	struct inode *r_ino = NULL;
> +	struct nfs_open_context *ctx;
> +	struct nfs4_state_owner *sp;
> +	char *read_name;
> +	int len, status = 0;
> +
> +	server = NFS_SERVER(ss_mnt->mnt_root->d_inode);
> +
> +	nfs_fattr_init(&fattr);
> +
> +	status = nfs4_proc_getattr(server, src_fh, &fattr, NULL, NULL);
> +	if (status < 0) {
> +		res = ERR_PTR(status);
> +		goto out;
> +	}
> +
> +	res = ERR_PTR(-ENOMEM);
> +	len = strlen(SSC_READ_NAME_BODY) + 16;
> +	read_name = kzalloc(len, GFP_NOFS);
> +	if (read_name == NULL)
> +		goto out;
> +	snprintf(read_name, len, SSC_READ_NAME_BODY, read_name_gen++);
> +	dprintk("%s read_name %s\n", __func__, read_name);

Does this dprintk() need to be here?  I'm wondering if it would work better as a
tracepoint (or if it should just be removed altogether).

Thanks,
Anna

> +
> +	r_ino = nfs_fhget(ss_mnt->mnt_root->d_inode->i_sb, src_fh, &fattr,
> +			NULL);
> +	if (IS_ERR(r_ino)) {
> +		res = ERR_CAST(r_ino);
> +		goto out;
> +	}
> +
> +	filep = alloc_file_pseudo(r_ino, ss_mnt, read_name, FMODE_READ,
> +				     r_ino->i_fop);
> +	if (IS_ERR(filep)) {
> +		res = ERR_CAST(filep);
> +		goto out;
> +	}
> +	filep->f_mode |= FMODE_READ;
> +
> +	ctx = alloc_nfs_open_context(filep->f_path.dentry, filep->f_mode,
> +					filep);
> +	if (IS_ERR(ctx)) {
> +		res = ERR_CAST(ctx);
> +		goto out_filep;
> +	}
> +
> +	res = ERR_PTR(-EINVAL);
> +	sp = nfs4_get_state_owner(server, ctx->cred, GFP_KERNEL);
> +	if (sp == NULL)
> +		goto out_ctx;
> +
> +	ctx->state = nfs4_get_open_state(r_ino, sp);
> +	if (ctx->state == NULL)
> +		goto out_stateowner;
> +
> +	set_bit(NFS_OPEN_STATE, &ctx->state->flags);
> +	memcpy(&ctx->state->open_stateid.other, &stateid->other,
> +	       NFS4_STATEID_OTHER_SIZE);
> +	update_open_stateid(ctx->state, stateid, NULL, filep->f_mode);
> +
> +	nfs_file_set_open_context(filep, ctx);
> +	put_nfs_open_context(ctx);
> +
> +	file_ra_state_init(&filep->f_ra, filep->f_mapping->host->i_mapping);
> +	res = filep;
> +out:
> +	dprintk("<-- %s error %ld filep %p r_ino %p\n",
> +		__func__, IS_ERR(res) ? PTR_ERR(res) : 0, res, r_ino);
> +
> +	return res;
> +out_stateowner:
> +	nfs4_put_state_owner(sp);
> +out_ctx:
> +	put_nfs_open_context(ctx);
> +out_filep:
> +	fput(filep);
> +	goto out;
> +}
> +EXPORT_SYMBOL_GPL(nfs42_ssc_open);
> +void nfs42_ssc_close(struct file *filep)
> +{
> +	struct nfs_open_context *ctx = nfs_file_open_context(filep);
> +
> +	ctx->state->flags = 0;
> +}
> +EXPORT_SYMBOL_GPL(nfs42_ssc_close);
>  #endif /* CONFIG_NFS_V4_2 */
>  
>  const struct file_operations nfs4_file_operations = {
> diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c
> index fec6e6b..e5178b2f 100644
> --- a/fs/nfs/nfs4proc.c
> +++ b/fs/nfs/nfs4proc.c
> @@ -91,7 +91,6 @@
>  static int _nfs4_recover_proc_open(struct nfs4_opendata *data);
>  static int nfs4_do_fsinfo(struct nfs_server *, struct nfs_fh *, struct
> nfs_fsinfo *);
>  static void nfs_fixup_referral_attributes(struct nfs_fattr *fattr);
> -static int nfs4_proc_getattr(struct nfs_server *, struct nfs_fh *, struct
> nfs_fattr *, struct nfs4_label *label, struct inode *inode);
>  static int _nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh
> *fhandle, struct nfs_fattr *fattr, struct nfs4_label *label, struct inode
> *inode);
>  static int nfs4_do_setattr(struct inode *inode, struct rpc_cred *cred,
>  			    struct nfs_fattr *fattr, struct iattr *sattr,
> @@ -1653,7 +1652,7 @@ static void nfs_state_clear_delegation(struct nfs4_state
> *state)
>  	write_sequnlock(&state->seqlock);
>  }
>  
> -static int update_open_stateid(struct nfs4_state *state,
> +int update_open_stateid(struct nfs4_state *state,
>  		const nfs4_stateid *open_stateid,
>  		const nfs4_stateid *delegation,
>  		fmode_t fmode)
> @@ -3936,7 +3935,7 @@ static int _nfs4_proc_getattr(struct nfs_server *server,
> struct nfs_fh *fhandle,
>  	return nfs4_call_sync(server->client, server, &msg, &args.seq_args,
> &res.seq_res, 0);
>  }
>  
> -static int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh
> *fhandle,
> +int nfs4_proc_getattr(struct nfs_server *server, struct nfs_fh *fhandle,
>  				struct nfs_fattr *fattr, struct nfs4_label
> *label,
>  				struct inode *inode)
>  {




[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux