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

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

 



On Tue, Oct 23, 2018 at 4:23 PM Schumaker, Anna
<Anna.Schumaker@xxxxxxxxxx> wrote:
>
> 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?

Nope, doesn't need to be here, a left over debugging. I'll remove it.

> 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