diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-22 12:56:06 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-08-22 12:56:06 -0400 |
| commit | 467e9e51d07d43d32a1dd8b6ead2351e28fff084 (patch) | |
| tree | d925caa3c94036ba2457f0de64b6e6c40236ca46 /include/linux | |
| parent | 23dcfa61bac244e1200ff9ad19c6e9144dcb6bb5 (diff) | |
| parent | 88ec2789d856056344161aa20420dd37e893b0fe (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
Pull assorted fixes - mostly vfs - from Al Viro:
"Assorted fixes, with an unexpected detour into vfio refcounting logics
(fell out when digging in an analog of eventpoll race in there)."
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
task_work: add a scheduling point in task_work_run()
fs: fix fs/namei.c kernel-doc warnings
eventpoll: use-after-possible-free in epoll_create1()
vfio: grab vfio_device reference *before* exposing the sucker via fd_install()
vfio: get rid of vfio_device_put()/vfio_group_get_device* races
vfio: get rid of open-coding kref_put_mutex
introduce kref_put_mutex()
vfio: don't dereference after kfree...
mqueue: lift mnt_want_write() outside ->i_mutex, clean up a bit
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/kref.h | 18 |
1 files changed, 18 insertions, 0 deletions
diff --git a/include/linux/kref.h b/include/linux/kref.h index 9c07dcebded7..65af6887872f 100644 --- a/include/linux/kref.h +++ b/include/linux/kref.h | |||
| @@ -18,6 +18,7 @@ | |||
| 18 | #include <linux/bug.h> | 18 | #include <linux/bug.h> |
| 19 | #include <linux/atomic.h> | 19 | #include <linux/atomic.h> |
| 20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
| 21 | #include <linux/mutex.h> | ||
| 21 | 22 | ||
| 22 | struct kref { | 23 | struct kref { |
| 23 | atomic_t refcount; | 24 | atomic_t refcount; |
| @@ -93,4 +94,21 @@ static inline int kref_put(struct kref *kref, void (*release)(struct kref *kref) | |||
| 93 | { | 94 | { |
| 94 | return kref_sub(kref, 1, release); | 95 | return kref_sub(kref, 1, release); |
| 95 | } | 96 | } |
| 97 | |||
| 98 | static inline int kref_put_mutex(struct kref *kref, | ||
| 99 | void (*release)(struct kref *kref), | ||
| 100 | struct mutex *lock) | ||
| 101 | { | ||
| 102 | WARN_ON(release == NULL); | ||
| 103 | if (unlikely(!atomic_add_unless(&kref->refcount, -1, 1))) { | ||
| 104 | mutex_lock(lock); | ||
| 105 | if (unlikely(!atomic_dec_and_test(&kref->refcount))) { | ||
| 106 | mutex_unlock(lock); | ||
| 107 | return 0; | ||
| 108 | } | ||
| 109 | release(kref); | ||
| 110 | return 1; | ||
| 111 | } | ||
| 112 | return 0; | ||
| 113 | } | ||
| 96 | #endif /* _KREF_H_ */ | 114 | #endif /* _KREF_H_ */ |
