summaryrefslogtreecommitdiffstats
path: root/fs/fscache/cookie.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2013-05-10 20:50:26 +0200
committerDavid Howells <dhowells@redhat.com>2013-06-19 15:16:47 +0200
commitcaaef6900befb45689b1d1831ce3c7e7fb5b504f (patch)
tree557fa8f425bd18261bea4950a2d821ffe8051903 /fs/fscache/cookie.c
parentFS-Cache: Wrap checks on object state (diff)
downloadlinux-caaef6900befb45689b1d1831ce3c7e7fb5b504f.tar.xz
linux-caaef6900befb45689b1d1831ce3c7e7fb5b504f.zip
FS-Cache: Fix object state machine to have separate work and wait states
Fix object state machine to have separate work and wait states as that makes it easier to envision. There are now three kinds of state: (1) Work state. This is an execution state. No event processing is performed by a work state. The function attached to a work state returns a pointer indicating the next state to which the OSM should transition. Returning NO_TRANSIT repeats the current state, but goes back to the scheduler first. (2) Wait state. This is an event processing state. No execution is performed by a wait state. Wait states are just tables of "if event X occurs, clear it and transition to state Y". The dispatcher returns to the scheduler if none of the events in which the wait state has an interest are currently pending. (3) Out-of-band state. This is a special work state. Transitions to normal states can be overridden when an unexpected event occurs (eg. I/O error). Instead the dispatcher disables and clears the OOB event and transits to the specified work state. This then acts as an ordinary work state, though object->state points to the overridden destination. Returning NO_TRANSIT resumes the overridden transition. In addition, the states have names in their definitions, so there's no need for tables of state names. Further, the EV_REQUEUE event is no longer necessary as that is automatic for work states. Since the states are now separate structs rather than values in an enum, it's not possible to use comparisons other than (non-)equality between them, so use some object->flags to indicate what phase an object is in. The EV_RELEASE, EV_RETIRE and EV_WITHDRAW events have been squished into one (EV_KILL). An object flag now carries the information about retirement. Similarly, the RELEASING, RECYCLING and WITHDRAWING states have been merged into an KILL_OBJECT state and additional states have been added for handling waiting dependent objects (JUMPSTART_DEPS and KILL_DEPENDENTS). A state has also been added for synchronising with parent object initialisation (WAIT_FOR_PARENT) and another for initiating look up (PARENT_READY). Signed-off-by: David Howells <dhowells@redhat.com> Tested-By: Milosz Tanski <milosz@adfin.com> Acked-by: Jeff Layton <jlayton@redhat.com>
Diffstat (limited to 'fs/fscache/cookie.c')
-rw-r--r--fs/fscache/cookie.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index a5f36c921e91..eee436646989 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -205,7 +205,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
/* initiate the process of looking up all the objects in the chain
* (done by fscache_initialise_object()) */
- fscache_enqueue_object(object);
+ fscache_raise_event(object, FSCACHE_OBJECT_EV_NEW_CHILD);
spin_unlock(&cookie->lock);
@@ -469,7 +469,6 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
{
struct fscache_cache *cache;
struct fscache_object *object;
- unsigned long event;
fscache_stat(&fscache_n_relinquishes);
if (retire)
@@ -497,8 +496,6 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
fscache_wait_bit, TASK_UNINTERRUPTIBLE);
}
- event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
-
try_again:
spin_lock(&cookie->lock);
@@ -533,7 +530,9 @@ try_again:
cache = object->cache;
object->cookie = NULL;
- fscache_raise_event(object, event);
+ if (retire)
+ set_bit(FSCACHE_OBJECT_RETIRE, &object->flags);
+ fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL);
spin_unlock(&object->lock);
if (atomic_dec_and_test(&cookie->usage))