diff --git a/include/linux/lockref.h b/include/linux/lockref.h index ca07b5028b012abd94deabbe5891c6b7f150843f..f279ed9a91631cca7f236d20ef5a29d152332932 100644 --- a/include/linux/lockref.h +++ b/include/linux/lockref.h @@ -33,4 +33,7 @@ extern int lockref_get_not_zero(struct lockref *); extern int lockref_get_or_lock(struct lockref *); extern int lockref_put_or_lock(struct lockref *); +extern void lockref_mark_dead(struct lockref *); +extern int lockref_get_not_dead(struct lockref *); + #endif /* __LINUX_LOCKREF_H */ diff --git a/lib/lockref.c b/lib/lockref.c index 7aae8df37f6745ec7b3d42b32a205dfa068f6be5..e2cd2c0a882126c58e04e47102fb4975c5247d3c 100644 --- a/lib/lockref.c +++ b/lib/lockref.c @@ -126,3 +126,41 @@ int lockref_put_or_lock(struct lockref *lockref) return 1; } EXPORT_SYMBOL(lockref_put_or_lock); + +/** + * lockref_mark_dead - mark lockref dead + * @lockref: pointer to lockref structure + */ +void lockref_mark_dead(struct lockref *lockref) +{ + assert_spin_locked(&lockref->lock); + lockref->count = -128; +} + +/** + * lockref_get_not_dead - Increments count unless the ref is dead + * @lockref: pointer to lockref structure + * Return: 1 if count updated successfully or 0 if lockref was dead + */ +int lockref_get_not_dead(struct lockref *lockref) +{ + int retval; + + CMPXCHG_LOOP( + new.count++; + if ((int)old.count < 0) + return 0; + , + return 1; + ); + + spin_lock(&lockref->lock); + retval = 0; + if ((int) lockref->count >= 0) { + lockref->count++; + retval = 1; + } + spin_unlock(&lockref->lock); + return retval; +} +EXPORT_SYMBOL(lockref_get_not_dead);