summaryrefslogtreecommitdiff
path: root/fs/bcachefs/six.c
diff options
context:
space:
mode:
authorKent Overstreet <kent.overstreet@linux.dev>2023-08-12 17:10:42 -0400
committerKent Overstreet <kent.overstreet@linux.dev>2023-10-22 17:10:10 -0400
commitf854ce4d0a3f7281b5b99b28dd028abe21c1b0c8 (patch)
treeef25cdde9b57eef88a45a068534358db4df6b8a7 /fs/bcachefs/six.c
parent93ee2c4b211b6fcfa0d796801372732a8214617c (diff)
bcachefs: six locks: Guard against wakee exiting in __six_lock_wakeup()
Signed-off-by: Kent Overstreet <kent.overstreet@linux.dev>
Diffstat (limited to 'fs/bcachefs/six.c')
-rw-r--r--fs/bcachefs/six.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/fs/bcachefs/six.c b/fs/bcachefs/six.c
index 0473aa4dd18a..7faa27310de4 100644
--- a/fs/bcachefs/six.c
+++ b/fs/bcachefs/six.c
@@ -8,6 +8,7 @@
#include <linux/sched.h>
#include <linux/sched/clock.h>
#include <linux/sched/rt.h>
+#include <linux/sched/task.h>
#include <linux/slab.h>
#include "six.h"
@@ -221,7 +222,12 @@ again:
if (ret <= 0)
goto unlock;
- task = w->task;
+ /*
+ * Similar to percpu_rwsem_wake_function(), we need to guard
+ * against the wakee noticing w->lock_acquired, returning, and
+ * then exiting before we do the wakeup:
+ */
+ task = get_task_struct(w->task);
__list_del(w->list.prev, w->list.next);
/*
* The release barrier here ensures the ordering of the
@@ -232,6 +238,7 @@ again:
*/
smp_store_release(&w->lock_acquired, true);
wake_up_process(task);
+ put_task_struct(task);
}
six_clear_bitmask(lock, SIX_LOCK_WAITING_read << lock_type);