[PATCH] cleanup nfsd state lock
Benny Halevy
bhalevy at ns1.bhalevy.com
Mon May 7 09:58:42 EDT 2007
make sure nfs4 file and client are got and freed
under the state lock
get... code asserts that the lock is taken (with BUG_ON)
free... code just takes the lock if needed
---
fs/nfsd/nfs4state.c | 19 ++++++++++++++++++-
1 files changed, 18 insertions(+), 1 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index d1355b2..71c9ec3 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -108,6 +108,12 @@ static kmem_cache_t *file_slab = NULL;
static kmem_cache_t *stateid_slab = NULL;
static kmem_cache_t *deleg_slab = NULL;
+static int
+nfs4_trylock_state(void)
+{
+ return mutex_trylock(&client_mutex);
+}
+
void
nfs4_lock_state(void)
{
@@ -120,6 +126,8 @@ nfs4_unlock_state(void)
mutex_unlock(&client_mutex);
}
+#define BUG_ON_UNLOCKED_STATE() BUG_ON(nfs4_trylock_state());
+
static inline u32
opaque_hashval(const void *ptr, int nbytes)
{
@@ -148,8 +156,12 @@ static struct list_head del_recall_lru;
static void
free_nfs4_file(struct kref *kref)
{
+ int did_lock;
struct nfs4_file *fp = container_of(kref, struct nfs4_file, fi_ref);
+ did_lock = nfs4_trylock_state();
list_del(&fp->fi_hash);
+ if (did_lock)
+ nfs4_unlock_state();
iput(fp->fi_inode);
kmem_cache_free(file_slab, fp);
}
@@ -157,12 +169,15 @@ free_nfs4_file(struct kref *kref)
static inline void
put_nfs4_file(struct nfs4_file *fi)
{
- kref_put(&fi->fi_ref, free_nfs4_file);
+ BUG_ON_UNLOCKED_STATE();
+ if (fi)
+ kref_put(&fi->fi_ref, free_nfs4_file);
}
static inline void
get_nfs4_file(struct nfs4_file *fi)
{
+ BUG_ON_UNLOCKED_STATE();
kref_get(&fi->fi_ref);
}
@@ -538,6 +553,7 @@ alloc_client(struct xdr_netobj name)
static inline struct nfs4_client *
get_nfs4_client(struct nfs4_client *clp)
{
+ BUG_ON_UNLOCKED_STATE();
kref_get(&clp->cl_ref);
return clp;
}
@@ -1661,6 +1677,7 @@ find_file(struct inode *ino)
unsigned int hashval = file_hashval(ino);
struct nfs4_file *fp;
+ BUG_ON_UNLOCKED_STATE();
list_for_each_entry(fp, &file_hashtbl[hashval], fi_hash) {
if (fp->fi_inode == ino) {
get_nfs4_file(fp);
--
1.5.1
--------------060903090305060208070700--
More information about the pNFS
mailing list