{
        enum fscache_object_state new_state;
        struct fscache_cookie *cookie;
+       int event;
 
        ASSERT(object != NULL);
 
 
        /* determine the transition from a lookup state */
 lookup_transit:
-       switch (fls(object->events & object->event_mask) - 1) {
+       event = fls(object->events & object->event_mask) - 1;
+       switch (event) {
        case FSCACHE_OBJECT_EV_WITHDRAW:
        case FSCACHE_OBJECT_EV_RETIRE:
        case FSCACHE_OBJECT_EV_RELEASE:
 
        /* determine the transition from an active state */
 active_transit:
-       switch (fls(object->events & object->event_mask) - 1) {
+       event = fls(object->events & object->event_mask) - 1;
+       switch (event) {
        case FSCACHE_OBJECT_EV_WITHDRAW:
        case FSCACHE_OBJECT_EV_RETIRE:
        case FSCACHE_OBJECT_EV_RELEASE:
 
        /* determine the transition from a terminal state */
 terminal_transit:
-       switch (fls(object->events & object->event_mask) - 1) {
+       event = fls(object->events & object->event_mask) - 1;
+       switch (event) {
        case FSCACHE_OBJECT_EV_WITHDRAW:
                new_state = FSCACHE_OBJECT_WITHDRAWING;
                goto change_state;
 
 unsupported_event:
        printk(KERN_ERR "FS-Cache:"
-              " Unsupported event %lx [mask %lx] in state %s\n",
-              object->events, object->event_mask,
+              " Unsupported event %d [%lx/%lx] in state %s\n",
+              event, object->events, object->event_mask,
               fscache_object_states[object->state]);
        BUG();
 }
 
        spin_lock(&cookie->lock);
        if (fscache_submit_exclusive_op(object, op) < 0)
-               BUG();
+               goto submit_op_failed;
        spin_unlock(&cookie->lock);
        fscache_put_operation(op);
 
         */
        fscache_invalidation_complete(cookie);
        _leave("");
+       return;
+
+submit_op_failed:
+       spin_unlock(&cookie->lock);
+       kfree(op);
+       fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR);
+       _leave(" [EIO]");
 }
 
 int fscache_submit_exclusive_op(struct fscache_object *object,
                                struct fscache_operation *op)
 {
+       int ret;
+
        _enter("{OBJ%x OP%x},", object->debug_id, op->debug_id);
 
        ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED);
 
                /* need to issue a new write op after this */
                clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
+               ret = 0;
        } else if (object->state == FSCACHE_OBJECT_CREATING) {
                op->object = object;
                object->n_ops++;
                atomic_inc(&op->usage);
                list_add_tail(&op->pend_link, &object->pending_ops);
                fscache_stat(&fscache_n_op_pend);
+               ret = 0;
        } else {
-               /* not allowed to submit ops in any other state */
-               BUG();
+               /* If we're in any other state, there must have been an I/O
+                * error of some nature.
+                */
+               ASSERT(test_bit(FSCACHE_IOERROR, &object->cache->flags));
+               ret = -EIO;
        }
 
        spin_unlock(&object->lock);
-       return 0;
+       return ret;
 }
 
 /*