@@ -30,6 +30,7 @@ static const struct fscache_state *fscache_look_up_object(struct fscache_object
30
30
static const struct fscache_state * fscache_object_available (struct fscache_object * , int );
31
31
static const struct fscache_state * fscache_parent_ready (struct fscache_object * , int );
32
32
static const struct fscache_state * fscache_update_object (struct fscache_object * , int );
33
+ static const struct fscache_state * fscache_object_dead (struct fscache_object * , int );
33
34
34
35
#define __STATE_NAME (n ) fscache_osm_##n
35
36
#define STATE (n ) (&__STATE_NAME(n))
@@ -91,7 +92,7 @@ static WORK_STATE(LOOKUP_FAILURE, "LCFL", fscache_lookup_failure);
91
92
static WORK_STATE (KILL_OBJECT , "KILL ", fscache_kill_object ) ;
92
93
static WORK_STATE (KILL_DEPENDENTS , "KDEP ", fscache_kill_dependents ) ;
93
94
static WORK_STATE (DROP_OBJECT , "DROP ", fscache_drop_object ) ;
94
- static WORK_STATE (OBJECT_DEAD , "DEAD ", ( void * ) 2UL );
95
+ static WORK_STATE (OBJECT_DEAD , "DEAD ", fscache_object_dead ) ;
95
96
96
97
static WAIT_STATE (WAIT_FOR_INIT , "?INI ",
97
98
TRANSIT_TO (INIT_OBJECT , 1 << FSCACHE_OBJECT_EV_NEW_CHILD )) ;
@@ -229,6 +230,10 @@ static void fscache_object_sm_dispatcher(struct fscache_object *object)
229
230
event = -1 ;
230
231
if (new_state == NO_TRANSIT ) {
231
232
_debug ("{OBJ%x} %s notrans" , object -> debug_id , state -> name );
233
+ if (unlikely (state == STATE (OBJECT_DEAD ))) {
234
+ _leave (" [dead]" );
235
+ return ;
236
+ }
232
237
fscache_enqueue_object (object );
233
238
event_mask = object -> oob_event_mask ;
234
239
goto unmask_events ;
@@ -239,7 +244,7 @@ static void fscache_object_sm_dispatcher(struct fscache_object *object)
239
244
object -> state = state = new_state ;
240
245
241
246
if (state -> work ) {
242
- if (unlikely (state -> work == (( void * ) 2UL ))) {
247
+ if (unlikely (state == STATE ( OBJECT_DEAD ))) {
243
248
_leave (" [dead]" );
244
249
return ;
245
250
}
@@ -645,6 +650,12 @@ static const struct fscache_state *fscache_kill_object(struct fscache_object *ob
645
650
fscache_mark_object_dead (object );
646
651
object -> oob_event_mask = 0 ;
647
652
653
+ if (test_bit (FSCACHE_OBJECT_RETIRED , & object -> flags )) {
654
+ /* Reject any new read/write ops and abort any that are pending. */
655
+ clear_bit (FSCACHE_OBJECT_PENDING_WRITE , & object -> flags );
656
+ fscache_cancel_all_ops (object );
657
+ }
658
+
648
659
if (list_empty (& object -> dependents ) &&
649
660
object -> n_ops == 0 &&
650
661
object -> n_children == 0 )
@@ -1077,3 +1088,20 @@ void fscache_object_mark_killed(struct fscache_object *object,
1077
1088
}
1078
1089
}
1079
1090
EXPORT_SYMBOL (fscache_object_mark_killed );
1091
+
1092
+ /*
1093
+ * The object is dead. We can get here if an object gets queued by an event
1094
+ * that would lead to its death (such as EV_KILL) when the dispatcher is
1095
+ * already running (and so can be requeued) but hasn't yet cleared the event
1096
+ * mask.
1097
+ */
1098
+ static const struct fscache_state * fscache_object_dead (struct fscache_object * object ,
1099
+ int event )
1100
+ {
1101
+ if (!test_and_set_bit (FSCACHE_OBJECT_RUN_AFTER_DEAD ,
1102
+ & object -> flags ))
1103
+ return NO_TRANSIT ;
1104
+
1105
+ WARN (true, "FS-Cache object redispatched after death" );
1106
+ return NO_TRANSIT ;
1107
+ }
0 commit comments