Commit 47cb498e authored by Trond Myklebust's avatar Trond Myklebust

NFSv4.1: Clean ups for the device id cache

The fact that the global device id cache holds a reference to the
nfs4_deviceid_node until it is invisible to rcu lookups implies that
we can always assume that the reference count is non-zero in
_find_get_deviceid.

Also clean up nfs4_put_deviceid_node and the removal of the device id
from the cache.
Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent e885de1a
...@@ -198,7 +198,6 @@ struct nfs4_deviceid_node { ...@@ -198,7 +198,6 @@ struct nfs4_deviceid_node {
void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id); void nfs4_print_deviceid(const struct nfs4_deviceid *dev_id);
struct nfs4_deviceid_node *nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *); struct nfs4_deviceid_node *nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
struct nfs4_deviceid_node *nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *); void nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *, const struct nfs_client *, const struct nfs4_deviceid *);
void nfs4_init_deviceid_node(struct nfs4_deviceid_node *, void nfs4_init_deviceid_node(struct nfs4_deviceid_node *,
const struct pnfs_layoutdriver_type *, const struct pnfs_layoutdriver_type *,
......
...@@ -100,8 +100,8 @@ _find_get_deviceid(const struct pnfs_layoutdriver_type *ld, ...@@ -100,8 +100,8 @@ _find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
rcu_read_lock(); rcu_read_lock();
d = _lookup_deviceid(ld, clp, id, hash); d = _lookup_deviceid(ld, clp, id, hash);
if (d && !atomic_inc_not_zero(&d->ref)) if (d != NULL)
d = NULL; atomic_inc(&d->ref);
rcu_read_unlock(); rcu_read_unlock();
return d; return d;
} }
...@@ -115,15 +115,15 @@ nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *ld, ...@@ -115,15 +115,15 @@ nfs4_find_get_deviceid(const struct pnfs_layoutdriver_type *ld,
EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid); EXPORT_SYMBOL_GPL(nfs4_find_get_deviceid);
/* /*
* Unhash and put deviceid * Remove a deviceid from cache
* *
* @clp nfs_client associated with deviceid * @clp nfs_client associated with deviceid
* @id the deviceid to unhash * @id the deviceid to unhash
* *
* @ret the unhashed node, if found and dereferenced to zero, NULL otherwise. * @ret the unhashed node, if found and dereferenced to zero, NULL otherwise.
*/ */
struct nfs4_deviceid_node * void
nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld, nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
const struct nfs_client *clp, const struct nfs4_deviceid *id) const struct nfs_client *clp, const struct nfs4_deviceid *id)
{ {
struct nfs4_deviceid_node *d; struct nfs4_deviceid_node *d;
...@@ -134,7 +134,7 @@ nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld, ...@@ -134,7 +134,7 @@ nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld,
rcu_read_unlock(); rcu_read_unlock();
if (!d) { if (!d) {
spin_unlock(&nfs4_deviceid_lock); spin_unlock(&nfs4_deviceid_lock);
return NULL; return;
} }
hlist_del_init_rcu(&d->node); hlist_del_init_rcu(&d->node);
spin_unlock(&nfs4_deviceid_lock); spin_unlock(&nfs4_deviceid_lock);
...@@ -142,27 +142,6 @@ nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld, ...@@ -142,27 +142,6 @@ nfs4_unhash_put_deviceid(const struct pnfs_layoutdriver_type *ld,
/* balance the initial ref set in pnfs_insert_deviceid */ /* balance the initial ref set in pnfs_insert_deviceid */
if (atomic_dec_and_test(&d->ref)) if (atomic_dec_and_test(&d->ref))
return d;
return NULL;
}
EXPORT_SYMBOL_GPL(nfs4_unhash_put_deviceid);
/*
* Delete a deviceid from cache
*
* @clp struct nfs_client qualifying the deviceid
* @id deviceid to delete
*/
void
nfs4_delete_deviceid(const struct pnfs_layoutdriver_type *ld,
const struct nfs_client *clp, const struct nfs4_deviceid *id)
{
struct nfs4_deviceid_node *d;
d = nfs4_unhash_put_deviceid(ld, clp, id);
if (!d)
return;
d->ld->free_deviceid_node(d); d->ld->free_deviceid_node(d);
} }
EXPORT_SYMBOL_GPL(nfs4_delete_deviceid); EXPORT_SYMBOL_GPL(nfs4_delete_deviceid);
...@@ -221,16 +200,15 @@ EXPORT_SYMBOL_GPL(nfs4_insert_deviceid_node); ...@@ -221,16 +200,15 @@ EXPORT_SYMBOL_GPL(nfs4_insert_deviceid_node);
* *
* @d deviceid node to put * @d deviceid node to put
* *
* @ret true iff the node was deleted * return true iff the node was deleted
* Note that since the test for d->ref == 0 is sufficient to establish
* that the node is no longer hashed in the global device id cache.
*/ */
bool bool
nfs4_put_deviceid_node(struct nfs4_deviceid_node *d) nfs4_put_deviceid_node(struct nfs4_deviceid_node *d)
{ {
if (!atomic_dec_and_lock(&d->ref, &nfs4_deviceid_lock)) if (!atomic_dec_and_test(&d->ref))
return false; return false;
hlist_del_init_rcu(&d->node);
spin_unlock(&nfs4_deviceid_lock);
synchronize_rcu();
d->ld->free_deviceid_node(d); d->ld->free_deviceid_node(d);
return true; return true;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment