lkml.org 
[lkml]   [2011]   [Sep]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH v5 1/8] SUNRPC: introduce helpers for reference counted rpcbind clients
    v5: fixed races with rpcb_users in rpcb_get_local()

    This helpers will be used for dynamical creation and destruction of rpcbind
    clients.
    Variable rpcb_users is actually a counter of lauched RPC services. If rpcbind
    clients has been created already, then we just increase rpcb_users.

    Signed-off-by: Stanislav Kinsbursky <skinsbursky@parallels.com>

    ---
    net/sunrpc/rpcb_clnt.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++
    1 files changed, 53 insertions(+), 0 deletions(-)

    diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c
    index e45d2fb..5f4a406 100644
    --- a/net/sunrpc/rpcb_clnt.c
    +++ b/net/sunrpc/rpcb_clnt.c
    @@ -114,6 +114,9 @@ static struct rpc_program rpcb_program;
    static struct rpc_clnt * rpcb_local_clnt;
    static struct rpc_clnt * rpcb_local_clnt4;
    +DEFINE_SPINLOCK(rpcb_clnt_lock);
    +unsigned int rpcb_users;
    +
    struct rpcbind_args {
    struct rpc_xprt * r_xprt;
    @@ -161,6 +164,56 @@ static void rpcb_map_release(void *data)
    kfree(map);
    }
    +static int rpcb_get_local(void)
    +{
    + int cnt;
    +
    + spin_lock(&rpcb_clnt_lock);
    + if (rpcb_users)
    + rpcb_users++;
    + cnt = rpcb_users;
    + spin_unlock(&rpcb_clnt_lock);
    +
    + return cnt;
    +}
    +
    +void rpcb_put_local(void)
    +{
    + struct rpc_clnt *clnt = rpcb_local_clnt;
    + struct rpc_clnt *clnt4 = rpcb_local_clnt4;
    + int shutdown;
    +
    + spin_lock(&rpcb_clnt_lock);
    + if (--rpcb_users == 0) {
    + rpcb_local_clnt = NULL;
    + rpcb_local_clnt4 = NULL;
    + }
    + shutdown = !rpcb_users;
    + spin_unlock(&rpcb_clnt_lock);
    +
    + if (shutdown) {
    + /*
    + * cleanup_rpcb_clnt - remove xprtsock's sysctls, unregister
    + */
    + if (clnt4)
    + rpc_shutdown_client(clnt4);
    + if (clnt)
    + rpc_shutdown_client(clnt);
    + }
    + return;
    +}
    +
    +static void rpcb_set_local(struct rpc_clnt *clnt, struct rpc_clnt *clnt4)
    +{
    + /* Protected by rpcb_create_local_mutex */
    + rpcb_local_clnt = clnt;
    + rpcb_local_clnt4 = clnt4;
    + rpcb_users++;
    + dprintk("RPC: created new rpcb local clients (rpcb_local_clnt: "
    + "%p, rpcb_local_clnt4: %p)\n", rpcb_local_clnt,
    + rpcb_local_clnt4);
    +}
    +
    /*
    * Returns zero on success, otherwise a negative errno value
    * is returned.

    \
     
     \ /
      Last update: 2011-09-20 15:51    [W:0.034 / U:92.324 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site