public inbox for linux-nfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Trond Myklebust <trondmy@hammerspace.com>
To: "anna.schumaker@netapp.com" <anna.schumaker@netapp.com>,
	"olga.kornievskaia@gmail.com" <olga.kornievskaia@gmail.com>
Cc: "linux-nfs@vger.kernel.org" <linux-nfs@vger.kernel.org>
Subject: Re: [PATCH v9 10/13] sunrpc: add dst_attr attributes to the sysfs xprt directory
Date: Mon, 7 Jun 2021 21:57:54 +0000	[thread overview]
Message-ID: <fde6e765dbb48ee4d4d43ef1a905dcbd58318d42.camel@hammerspace.com> (raw)
In-Reply-To: <CAFX2Jf==uZQmZfySwWKZZr8PHHwJB5PvfTyyys334c2AWpSiWw@mail.gmail.com>

On Mon, 2021-06-07 at 17:03 -0400, Anna Schumaker wrote:
> Hi Olga,
> 
> On Thu, Jun 3, 2021 at 6:23 PM Olga Kornievskaia
> <olga.kornievskaia@gmail.com> wrote:
> > 
> > From: Olga Kornievskaia <kolga@netapp.com>
> > 
> > Allow to query and set the destination's address of a transport.
> > Setting of the destination address is allowed only for TCP or RDMA
> > based connections.
> > 
> > Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
> > ---
> >  include/linux/sunrpc/xprt.h |  1 +
> >  net/sunrpc/sysfs.c          | 99
> > +++++++++++++++++++++++++++++++++++++
> >  net/sunrpc/xprt.c           |  4 +-
> >  net/sunrpc/xprtmultipath.c  |  2 -
> >  4 files changed, 103 insertions(+), 3 deletions(-)
> > 
> > diff --git a/include/linux/sunrpc/xprt.h
> > b/include/linux/sunrpc/xprt.h
> > index 8360db664e5f..13a4eaf385cf 100644
> > --- a/include/linux/sunrpc/xprt.h
> > +++ b/include/linux/sunrpc/xprt.h
> > @@ -414,6 +414,7 @@ void                       
> > xprt_conditional_disconnect(struct rpc_xprt *xprt, unsigned int
> > cookie);
> > 
> >  bool                   xprt_lock_connect(struct rpc_xprt *, struct
> > rpc_task *, void *);
> >  void                   xprt_unlock_connect(struct rpc_xprt *, void
> > *);
> > +void                   xprt_release_write(struct rpc_xprt *,
> > struct rpc_task *);
> > 
> >  /*
> >   * Reserved bit positions in xprt->state
> > diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
> > index 20f75708594f..4a14342e4d4e 100644
> > --- a/net/sunrpc/sysfs.c
> > +++ b/net/sunrpc/sysfs.c
> > @@ -4,8 +4,23 @@
> >   */
> >  #include <linux/sunrpc/clnt.h>
> >  #include <linux/kobject.h>
> > +#include <linux/sunrpc/addr.h>
> > +
> >  #include "sysfs.h"
> > 
> > +struct xprt_addr {
> > +       const char *addr;
> > +       struct rcu_head rcu;
> > +};
> > +
> > +static void free_xprt_addr(struct rcu_head *head)
> > +{
> > +       struct xprt_addr *addr = container_of(head, struct
> > xprt_addr, rcu);
> > +
> > +       kfree(addr->addr);
> > +       kfree(addr);
> > +}
> > +
> >  static struct kset *rpc_sunrpc_kset;
> >  static struct kobject *rpc_sunrpc_client_kobj,
> > *rpc_sunrpc_xprt_switch_kobj;
> > 
> > @@ -43,6 +58,81 @@ static struct kobject
> > *rpc_sysfs_object_alloc(const char *name,
> >         return NULL;
> >  }
> > 
> > +static inline struct rpc_xprt *
> > +rpc_sysfs_xprt_kobj_get_xprt(struct kobject *kobj)
> > +{
> > +       struct rpc_sysfs_xprt *x = container_of(kobj,
> > +               struct rpc_sysfs_xprt, kobject);
> > +
> > +       return xprt_get(x->xprt);
> > +}
> > +
> > +static ssize_t rpc_sysfs_xprt_dstaddr_show(struct kobject *kobj,
> > +                                          struct kobj_attribute
> > *attr,
> > +                                          char *buf)
> > +{
> > +       struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
> > +       ssize_t ret;
> > +
> > +       if (!xprt)
> > +               return 0;
> > +       ret = sprintf(buf, "%s\n", xprt-
> > >address_strings[RPC_DISPLAY_ADDR]);
> > +       xprt_put(xprt);
> > +       return ret + 1;
> > +}
> > +
> > +static ssize_t rpc_sysfs_xprt_dstaddr_store(struct kobject *kobj,
> > +                                           struct kobj_attribute
> > *attr,
> > +                                           const char *buf, size_t
> > count)
> > +{
> > +       struct rpc_xprt *xprt = rpc_sysfs_xprt_kobj_get_xprt(kobj);
> > +       struct sockaddr *saddr;
> > +       char *dst_addr;
> > +       int port;
> > +       struct xprt_addr *saved_addr;
> > +
> > +       if (!xprt)
> > +               return 0;
> > +       if (!(xprt->xprt_class->ident == XPRT_TRANSPORT_TCP ||
> > +             xprt->xprt_class->ident == XPRT_TRANSPORT_RDMA)) {
> > +               xprt_put(xprt);
> > +               return -EOPNOTSUPP;
> > +       }
> > +
> > +       if (wait_on_bit_lock(&xprt->state, XPRT_LOCKED,
> > TASK_KILLABLE)) {
> > +               count = -EINTR;
> > +               goto out_put;
> > +       }
> > +       saddr = (struct sockaddr *)&xprt->addr;
> > +       port = rpc_get_port(saddr);
> > +
> > +       dst_addr = kstrndup(buf, count - 1, GFP_KERNEL);
> > +       if (!dst_addr)
> > +               goto out_err;
> > +       saved_addr = kzalloc(sizeof(*saved_addr), GFP_KERNEL);
> > +       if (!saved_addr)
> > +               goto out_err_free;
> > +       saved_addr->addr =
> > +               rcu_dereference_raw(xprt-
> > >address_strings[RPC_DISPLAY_ADDR]);
> > +       rcu_assign_pointer(xprt->address_strings[RPC_DISPLAY_ADDR],
> > dst_addr);
> > +       call_rcu(&saved_addr->rcu, free_xprt_addr);
> > +       xprt->addrlen = rpc_pton(xprt->xprt_net, buf, count - 1,
> > saddr,
> 
> The "count - 1" has been there since the beginning to account for
> NULL
> terminated strings (like those passed using `echo` into the file).
> Now
> that I'm working on the userspace side of things, I've realized this
> isn't necessarily always the case. I'm wondering if it would make
> sense to only decrement count if buf[count - 1] is "\0", but
> otherwise
> leave it alone?
> 
> I found this by writing "192.168.111.186" through python, but the
> resulting dstaddr was "192.168.111.18" when I tried reading it back.

kstrndup(buf, count, GFP_KERNEL) would suffice to strip an excess '\0'.
I'm assuming the real problem here is the '\n'?

> 
> Anna
> 
> > +                                sizeof(*saddr));
> > +       rpc_set_port(saddr, port);
> > +
> > +       xprt_force_disconnect(xprt);
> > +out:
> > +       xprt_release_write(xprt, NULL);
> > +out_put:
> > +       xprt_put(xprt);
> > +       return count;
> > +out_err_free:
> > +       kfree(dst_addr);
> > +out_err:
> > +       count = -ENOMEM;
> > +       goto out;
> > +}
> > +
> >  int rpc_sysfs_init(void)
> >  {
> >         rpc_sunrpc_kset = kset_create_and_add("sunrpc", NULL,
> > kernel_kobj);
> > @@ -106,6 +196,14 @@ static const void
> > *rpc_sysfs_xprt_namespace(struct kobject *kobj)
> >                             kobject)->xprt->xprt_net;
> >  }
> > 
> > +static struct kobj_attribute rpc_sysfs_xprt_dstaddr =
> > __ATTR(dstaddr,
> > +       0644, rpc_sysfs_xprt_dstaddr_show,
> > rpc_sysfs_xprt_dstaddr_store);
> > +
> > +static struct attribute *rpc_sysfs_xprt_attrs[] = {
> > +       &rpc_sysfs_xprt_dstaddr.attr,
> > +       NULL,
> > +};
> > +
> >  static struct kobj_type rpc_sysfs_client_type = {
> >         .release = rpc_sysfs_client_release,
> >         .sysfs_ops = &kobj_sysfs_ops,
> > @@ -120,6 +218,7 @@ static struct kobj_type
> > rpc_sysfs_xprt_switch_type = {
> > 
> >  static struct kobj_type rpc_sysfs_xprt_type = {
> >         .release = rpc_sysfs_xprt_release,
> > +       .default_attrs = rpc_sysfs_xprt_attrs,
> >         .sysfs_ops = &kobj_sysfs_ops,
> >         .namespace = rpc_sysfs_xprt_namespace,
> >  };
> > diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
> > index 20b9bd705014..fb6db09725c7 100644
> > --- a/net/sunrpc/xprt.c
> > +++ b/net/sunrpc/xprt.c
> > @@ -55,6 +55,7 @@
> >  #include <trace/events/sunrpc.h>
> > 
> >  #include "sunrpc.h"
> > +#include "sysfs.h"
> > 
> >  /*
> >   * Local variables
> > @@ -443,7 +444,7 @@ void xprt_release_xprt_cong(struct rpc_xprt
> > *xprt, struct rpc_task *task)
> >  }
> >  EXPORT_SYMBOL_GPL(xprt_release_xprt_cong);
> > 
> > -static inline void xprt_release_write(struct rpc_xprt *xprt,
> > struct rpc_task *task)
> > +void xprt_release_write(struct rpc_xprt *xprt, struct rpc_task
> > *task)
> >  {
> >         if (xprt->snd_task != task)
> >                 return;
> > @@ -1812,6 +1813,7 @@ void xprt_free(struct rpc_xprt *xprt)
> >         put_net(xprt->xprt_net);
> >         xprt_free_all_slots(xprt);
> >         xprt_free_id(xprt);
> > +       rpc_sysfs_xprt_destroy(xprt);
> >         kfree_rcu(xprt, rcu);
> >  }
> >  EXPORT_SYMBOL_GPL(xprt_free);
> > diff --git a/net/sunrpc/xprtmultipath.c
> > b/net/sunrpc/xprtmultipath.c
> > index e7973c1ff70c..07e76ae1028a 100644
> > --- a/net/sunrpc/xprtmultipath.c
> > +++ b/net/sunrpc/xprtmultipath.c
> > @@ -86,7 +86,6 @@ void rpc_xprt_switch_remove_xprt(struct
> > rpc_xprt_switch *xps,
> >         spin_lock(&xps->xps_lock);
> >         xprt_switch_remove_xprt_locked(xps, xprt);
> >         spin_unlock(&xps->xps_lock);
> > -       rpc_sysfs_xprt_destroy(xprt);
> >         xprt_put(xprt);
> >  }
> > 
> > @@ -155,7 +154,6 @@ static void xprt_switch_free_entries(struct
> > rpc_xprt_switch *xps)
> >                                 struct rpc_xprt, xprt_switch);
> >                 xprt_switch_remove_xprt_locked(xps, xprt);
> >                 spin_unlock(&xps->xps_lock);
> > -               rpc_sysfs_xprt_destroy(xprt);
> >                 xprt_put(xprt);
> >                 spin_lock(&xps->xps_lock);
> >         }
> > --
> > 2.27.0
> > 

-- 
Trond Myklebust
Linux NFS client maintainer, Hammerspace
trond.myklebust@hammerspace.com



  reply	other threads:[~2021-06-07 21:57 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-03 22:20 [PATCH v9 00/13] create sysfs files for changing IP address Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 01/13] sunrpc: Create a sunrpc directory under /sys/kernel/ Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 02/13] sunrpc: Create a client/ subdirectory in the sunrpc sysfs Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 03/13] sunrpc: Create per-rpc_clnt sysfs kobjects Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 04/13] sunrpc: add xprt id Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 05/13] sunrpc: add IDs to multipath Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 06/13] sunrpc: keep track of the xprt_class in rpc_xprt structure Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 07/13] sunrpc: add xprt_switch direcotry to sunrpc's sysfs Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 08/13] sunrpc: add a symlink from rpc-client directory to the xprt_switch Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 09/13] sunrpc: add add sysfs directory per xprt under each xprt_switch Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 10/13] sunrpc: add dst_attr attributes to the sysfs xprt directory Olga Kornievskaia
2021-06-07 21:03   ` Anna Schumaker
2021-06-07 21:57     ` Trond Myklebust [this message]
2021-06-03 22:20 ` [PATCH v9 11/13] sunrpc: provide transport info in the sysfs directory Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 12/13] sunrpc: provide multipath " Olga Kornievskaia
2021-06-03 22:20 ` [PATCH v9 13/13] sunrpc: provide showing transport's state " Olga Kornievskaia

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=fde6e765dbb48ee4d4d43ef1a905dcbd58318d42.camel@hammerspace.com \
    --to=trondmy@hammerspace.com \
    --cc=anna.schumaker@netapp.com \
    --cc=linux-nfs@vger.kernel.org \
    --cc=olga.kornievskaia@gmail.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox