Re: [PATCH v2 08/13] sunrpc: add xprt_switch direcotry to sunrpc's sysfs

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

 



On Thu, 2021-04-15 at 23:52 -0400, Olga Kornievskaia wrote:
> From: Olga Kornievskaia <kolga@xxxxxxxxxx>
> 
> Add xprt_switch directory to the sysfs and create individual
> xprt_swith subdirectories for multipath transport group.
> 
> Signed-off-by: Olga Kornievskaia <kolga@xxxxxxxxxx>
> ---
>  include/linux/sunrpc/xprtmultipath.h |  1 +
>  net/sunrpc/sysfs.c                   | 97
> ++++++++++++++++++++++++++--
>  net/sunrpc/sysfs.h                   | 10 +++
>  net/sunrpc/xprtmultipath.c           |  4 ++
>  4 files changed, 105 insertions(+), 7 deletions(-)
> 
> diff --git a/include/linux/sunrpc/xprtmultipath.h
> b/include/linux/sunrpc/xprtmultipath.h
> index ef95a6f18ccf..47b0a85cdcfa 100644
> --- a/include/linux/sunrpc/xprtmultipath.h
> +++ b/include/linux/sunrpc/xprtmultipath.h
> @@ -24,6 +24,7 @@ struct rpc_xprt_switch {
>  
>         const struct rpc_xprt_iter_ops *xps_iter_ops;
>  
> +       void                    *xps_sysfs;
>         struct rcu_head         xps_rcu;
>  };
>  
> diff --git a/net/sunrpc/sysfs.c b/net/sunrpc/sysfs.c
> index d14d54f33c65..0c34330714ab 100644
> --- a/net/sunrpc/sysfs.c
> +++ b/net/sunrpc/sysfs.c
> @@ -7,7 +7,7 @@
>  #include "sysfs.h"
>  
>  static struct kset *rpc_sunrpc_kset;
> -static struct kobject *rpc_sunrpc_client_kobj;
> +static struct kobject *rpc_sunrpc_client_kobj,
> *rpc_sunrpc_xprt_switch_kobj;
>  
>  static void rpc_sysfs_object_release(struct kobject *kobj)
>  {
> @@ -47,13 +47,22 @@ int rpc_sysfs_init(void)
>         rpc_sunrpc_kset = kset_create_and_add("sunrpc", NULL,
> kernel_kobj);
>         if (!rpc_sunrpc_kset)
>                 return -ENOMEM;
> -       rpc_sunrpc_client_kobj = rpc_sysfs_object_alloc("client",
> rpc_sunrpc_kset, NULL);
> -       if (!rpc_sunrpc_client_kobj) {
> -               kset_unregister(rpc_sunrpc_kset);
> -               rpc_sunrpc_client_kobj = NULL;
> -               return -ENOMEM;
> -       }
> +       rpc_sunrpc_client_kobj =
> +               rpc_sysfs_object_alloc("rpc-clients",
> rpc_sunrpc_kset, NULL);
> +       if (!rpc_sunrpc_client_kobj)
> +               goto err_client;
> +       rpc_sunrpc_xprt_switch_kobj =
> +               rpc_sysfs_object_alloc("xprt-switches",
> rpc_sunrpc_kset, NULL);
> +       if (!rpc_sunrpc_xprt_switch_kobj)
> +               goto err_switch;
>         return 0;
> +err_switch:
> +       kobject_put(rpc_sunrpc_client_kobj);
> +       rpc_sunrpc_client_kobj = NULL;
> +err_client:
> +       kset_unregister(rpc_sunrpc_kset);
> +       rpc_sunrpc_kset = NULL;
> +       return -ENOMEM;
>  }
>  
>  static void rpc_sysfs_client_release(struct kobject *kobj)
> @@ -64,20 +73,40 @@ static void rpc_sysfs_client_release(struct
> kobject *kobj)
>         kfree(c);
>  }
>  
> +static void rpc_sysfs_xprt_switch_release(struct kobject *kobj)
> +{
> +       struct rpc_sysfs_xprt_switch *xprt_switch;
> +
> +       xprt_switch = container_of(kobj, struct
> rpc_sysfs_xprt_switch, kobject);
> +       kfree(xprt_switch);
> +}
> +
>  static const void *rpc_sysfs_client_namespace(struct kobject *kobj)
>  {
>         return container_of(kobj, struct rpc_sysfs_client, kobject)-
> >net;
>  }
>  
> +static const void *rpc_sysfs_xprt_switch_namespace(struct kobject
> *kobj)
> +{
> +       return container_of(kobj, struct rpc_sysfs_xprt_switch,
> kobject)->net;
> +}
> +
>  static struct kobj_type rpc_sysfs_client_type = {
>         .release = rpc_sysfs_client_release,
>         .sysfs_ops = &kobj_sysfs_ops,
>         .namespace = rpc_sysfs_client_namespace,
>  };
>  
> +static struct kobj_type rpc_sysfs_xprt_switch_type = {
> +       .release = rpc_sysfs_xprt_switch_release,
> +       .sysfs_ops = &kobj_sysfs_ops,
> +       .namespace = rpc_sysfs_xprt_switch_namespace,
> +};
> +
>  void rpc_sysfs_exit(void)
>  {
>         kobject_put(rpc_sunrpc_client_kobj);
> +       kobject_put(rpc_sunrpc_xprt_switch_kobj);
>         kset_unregister(rpc_sunrpc_kset);
>  }
>  
> @@ -99,6 +128,27 @@ static struct rpc_sysfs_client
> *rpc_sysfs_client_alloc(struct kobject *parent,
>         return NULL;
>  }
>  
> +static struct rpc_sysfs_xprt_switch *
> +rpc_sysfs_xprt_switch_alloc(struct kobject *parent,
> +                           struct rpc_xprt_switch *xprt_switch,
> +                           struct net *net)
> +{
> +       struct rpc_sysfs_xprt_switch *p;
> +
> +       p = kzalloc(sizeof(*p), GFP_KERNEL);

Again, this needs to use the allocation mode of xprt_switch_alloc().

> +       if (p) {
> +               p->net = net;
> +               p->kobject.kset = rpc_sunrpc_kset;
> +               if (kobject_init_and_add(&p->kobject,
> +                                        &rpc_sysfs_xprt_switch_type,
> +                                        parent, "switch-%d",
> +                                        xprt_switch->xps_id) == 0)
> +                       return p;
> +               kobject_put(&p->kobject);
> +       }
> +       return NULL;
> +}
> +
>  void rpc_sysfs_client_setup(struct rpc_clnt *clnt, struct net *net)
>  {
>         struct rpc_sysfs_client *rpc_client;
> @@ -110,6 +160,27 @@ void rpc_sysfs_client_setup(struct rpc_clnt
> *clnt, struct net *net)
>         }
>  }
>  
> +void rpc_sysfs_xprt_switch_setup(struct rpc_xprt_switch
> *xprt_switch,
> +                                struct rpc_xprt *xprt)
> +{
> +       struct rpc_sysfs_xprt_switch *rpc_xprt_switch;
> +       struct net *net;
> +
> +       if (xprt_switch->xps_net)
> +               net = xprt_switch->xps_net;
> +       else
> +               net = xprt->xprt_net;
> +       rpc_xprt_switch =
> +               rpc_sysfs_xprt_switch_alloc(rpc_sunrpc_xprt_switch_ko
> bj,
> +                                           xprt_switch, net);
> +       if (rpc_xprt_switch) {
> +               xprt_switch->xps_sysfs = rpc_xprt_switch;
> +               rpc_xprt_switch->xprt_switch = xprt_switch;
> +               rpc_xprt_switch->xprt = xprt;
> +               kobject_uevent(&rpc_xprt_switch->kobject, KOBJ_ADD);

This probably cannot be called from a locked environment.

> +       }
> +}
> +
>  void rpc_sysfs_client_destroy(struct rpc_clnt *clnt)
>  {
>         struct rpc_sysfs_client *rpc_client = clnt->cl_sysfs;
> @@ -121,3 +192,15 @@ void rpc_sysfs_client_destroy(struct rpc_clnt
> *clnt)
>                 clnt->cl_sysfs = NULL;
>         }
>  }
> +
> +void rpc_sysfs_xprt_switch_destroy(struct rpc_xprt_switch
> *xprt_switch)
> +{
> +       struct rpc_sysfs_xprt_switch *rpc_xprt_switch = xprt_switch-
> >xps_sysfs;
> +
> +       if (rpc_xprt_switch) {
> +               kobject_uevent(&rpc_xprt_switch->kobject,
> KOBJ_REMOVE);
> +               kobject_del(&rpc_xprt_switch->kobject);
> +               kobject_put(&rpc_xprt_switch->kobject);
> +               xprt_switch->xps_sysfs = NULL;
> +       }
> +}
> diff --git a/net/sunrpc/sysfs.h b/net/sunrpc/sysfs.h
> index c46afc848993..9b6acd3fd3dc 100644
> --- a/net/sunrpc/sysfs.h
> +++ b/net/sunrpc/sysfs.h
> @@ -10,10 +10,20 @@ struct rpc_sysfs_client {
>         struct net *net;
>  };
>  
> +struct rpc_sysfs_xprt_switch {
> +       struct kobject kobject;
> +       struct net *net;
> +       struct rpc_xprt_switch *xprt_switch;
> +       struct rpc_xprt *xprt;
> +};
> +
>  int rpc_sysfs_init(void);
>  void rpc_sysfs_exit(void);
>  
>  void rpc_sysfs_client_setup(struct rpc_clnt *clnt, struct net *net);
>  void rpc_sysfs_client_destroy(struct rpc_clnt *clnt);
> +void rpc_sysfs_xprt_switch_setup(struct rpc_xprt_switch
> *xprt_switch,
> +                                struct rpc_xprt *xprt);
> +void rpc_sysfs_xprt_switch_destroy(struct rpc_xprt_switch *xprt);
>  
>  #endif
> diff --git a/net/sunrpc/xprtmultipath.c b/net/sunrpc/xprtmultipath.c
> index b71dd95ad7de..1ed16e4cc465 100644
> --- a/net/sunrpc/xprtmultipath.c
> +++ b/net/sunrpc/xprtmultipath.c
> @@ -19,6 +19,8 @@
>  #include <linux/sunrpc/addr.h>
>  #include <linux/sunrpc/xprtmultipath.h>
>  
> +#include "sysfs.h"
> +
>  typedef struct rpc_xprt *(*xprt_switch_find_xprt_t)(struct
> rpc_xprt_switch *xps,
>                 const struct rpc_xprt *cur);
>  
> @@ -133,6 +135,7 @@ struct rpc_xprt_switch *xprt_switch_alloc(struct
> rpc_xprt *xprt,
>                 xps->xps_net = NULL;
>                 INIT_LIST_HEAD(&xps->xps_xprt_list);
>                 xps->xps_iter_ops = &rpc_xprt_iter_singular;
> +               rpc_sysfs_xprt_switch_setup(xps, xprt);
>                 xprt_switch_add_xprt_locked(xps, xprt);
>         }
>  
> @@ -161,6 +164,7 @@ static void xprt_switch_free(struct kref *kref)
>                         struct rpc_xprt_switch, xps_kref);
>  
>         xprt_switch_free_entries(xps);
> +       rpc_sysfs_xprt_switch_destroy(xps);
>         xprt_switch_free_id(xps);
>         kfree_rcu(xps, xps_rcu);
>  }

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






[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