NFS implement v4.0 callback_ident
Use the small id to pointer translator service to provide a unique callback identifier per SETCLIENTID call used to identify the v4.0 callback service associated with the clientid. Signed-off-by: Andy Adamson <andros@netapp.com> Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
ea00528126
commit
f4eecd5da3
5 changed files with 55 additions and 0 deletions
|
@ -56,6 +56,30 @@ static DEFINE_SPINLOCK(nfs_client_lock);
|
|||
static LIST_HEAD(nfs_client_list);
|
||||
static LIST_HEAD(nfs_volume_list);
|
||||
static DECLARE_WAIT_QUEUE_HEAD(nfs_client_active_wq);
|
||||
#ifdef CONFIG_NFS_V4
|
||||
static DEFINE_IDR(cb_ident_idr); /* Protected by nfs_client_lock */
|
||||
|
||||
/*
|
||||
* Get a unique NFSv4.0 callback identifier which will be used
|
||||
* by the V4.0 callback service to lookup the nfs_client struct
|
||||
*/
|
||||
static int nfs_get_cb_ident_idr(struct nfs_client *clp, int minorversion)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (clp->rpc_ops->version != 4 || minorversion != 0)
|
||||
return ret;
|
||||
retry:
|
||||
if (!idr_pre_get(&cb_ident_idr, GFP_KERNEL))
|
||||
return -ENOMEM;
|
||||
spin_lock(&nfs_client_lock);
|
||||
ret = idr_get_new(&cb_ident_idr, clp, &clp->cl_cb_ident);
|
||||
spin_unlock(&nfs_client_lock);
|
||||
if (ret == -EAGAIN)
|
||||
goto retry;
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
|
||||
/*
|
||||
* RPC cruft for NFS
|
||||
|
@ -144,6 +168,10 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_
|
|||
clp->cl_proto = cl_init->proto;
|
||||
|
||||
#ifdef CONFIG_NFS_V4
|
||||
err = nfs_get_cb_ident_idr(clp, cl_init->minorversion);
|
||||
if (err)
|
||||
goto error_cleanup;
|
||||
|
||||
INIT_LIST_HEAD(&clp->cl_delegations);
|
||||
spin_lock_init(&clp->cl_lock);
|
||||
INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state);
|
||||
|
@ -202,10 +230,32 @@ static void nfs4_shutdown_client(struct nfs_client *clp)
|
|||
|
||||
rpc_destroy_wait_queue(&clp->cl_rpcwaitq);
|
||||
}
|
||||
|
||||
/* idr_remove_all is not needed as all id's are removed by nfs_put_client */
|
||||
void nfs_cleanup_cb_ident_idr(void)
|
||||
{
|
||||
idr_destroy(&cb_ident_idr);
|
||||
}
|
||||
|
||||
/* nfs_client_lock held */
|
||||
static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
|
||||
{
|
||||
if (clp->cl_cb_ident)
|
||||
idr_remove(&cb_ident_idr, clp->cl_cb_ident);
|
||||
}
|
||||
|
||||
#else
|
||||
static void nfs4_shutdown_client(struct nfs_client *clp)
|
||||
{
|
||||
}
|
||||
|
||||
void nfs_cleanup_cb_ident_idr(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void nfs_cb_idr_remove_locked(struct nfs_client *clp)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
|
||||
/*
|
||||
|
@ -244,6 +294,7 @@ void nfs_put_client(struct nfs_client *clp)
|
|||
|
||||
if (atomic_dec_and_lock(&clp->cl_count, &nfs_client_lock)) {
|
||||
list_del(&clp->cl_share_link);
|
||||
nfs_cb_idr_remove_locked(clp);
|
||||
spin_unlock(&nfs_client_lock);
|
||||
|
||||
BUG_ON(!list_empty(&clp->cl_superblocks));
|
||||
|
|
|
@ -1612,6 +1612,7 @@ static void __exit exit_nfs_fs(void)
|
|||
#ifdef CONFIG_PROC_FS
|
||||
rpc_proc_unregister("nfs");
|
||||
#endif
|
||||
nfs_cleanup_cb_ident_idr();
|
||||
unregister_nfs_fs();
|
||||
nfs_fs_proc_exit();
|
||||
nfsiod_stop();
|
||||
|
|
|
@ -128,6 +128,7 @@ extern void nfs_umount(const struct nfs_mount_request *info);
|
|||
/* client.c */
|
||||
extern struct rpc_program nfs_program;
|
||||
|
||||
extern void nfs_cleanup_cb_ident_idr(void);
|
||||
extern void nfs_put_client(struct nfs_client *);
|
||||
extern struct nfs_client *nfs_find_client(const struct sockaddr *, u32);
|
||||
extern struct nfs_client *nfs_find_client_next(struct nfs_client *);
|
||||
|
|
|
@ -3484,6 +3484,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program,
|
|||
struct nfs4_setclientid setclientid = {
|
||||
.sc_verifier = &sc_verifier,
|
||||
.sc_prog = program,
|
||||
.sc_cb_ident = clp->cl_cb_ident,
|
||||
};
|
||||
struct rpc_message msg = {
|
||||
.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_SETCLIENTID],
|
||||
|
|
|
@ -71,6 +71,7 @@ struct nfs_client {
|
|||
*/
|
||||
char cl_ipaddr[48];
|
||||
unsigned char cl_id_uniquifier;
|
||||
u32 cl_cb_ident; /* v4.0 callback identifier */
|
||||
const struct nfs4_minor_version_ops *cl_mvops;
|
||||
#endif /* CONFIG_NFS_V4 */
|
||||
|
||||
|
|
Loading…
Reference in a new issue