scoutfs: drop lock refcnt/users under task ref

If scoutfs_unlock() sees that it isn't the last task using a lock it
just returns.  It doesn't unlock the lock and it doesn't drop the lock
refcnt and users.

This leaks the lock refcnt and users because find_alloc_scoutfs_lock()
always increments them when it finds a lock.  Inflated counts will stop
the shrinker from freeing the locks and eventually the counts will wrap
and could cause locks to be freed while they're still in use.

We can either always drop the refcnt/users in unlock or we can drop them
in lock as we notice that our task already has the lock.  I chose to
have the task ref hold one refcnt/users which are only dropped as the
final task unlocks.

Signed-off-by: Zach Brown <zab@versity.com>
This commit is contained in:
Zach Brown
2018-01-12 12:53:23 -08:00
committed by Mark Fasheh
parent f54e59eef1
commit e803b10bca

View File

@@ -732,6 +732,8 @@ static int lock_name_keys(struct super_block *sb, int mode, int flags,
*/
BUG_ON(!ocfs2_levels_compat(&lock->lockres, mode));
get_task_ref(ref);
dec_lock_users(lock);
put_scoutfs_lock(sb, lock);
ret = 0;
goto out;
}