FS-Cache: The operation cancellation method needs calling in more places
[firefly-linux-kernel-4.4.55.git] / fs / fscache / operation.c
index c76c097307682d195a5b3e9c827b36698deed5d1..57d4abb68656fd61915e9a5663bd5f8bcb3952bc 100644 (file)
 atomic_t fscache_op_debug_id;
 EXPORT_SYMBOL(fscache_op_debug_id);
 
+static void fscache_operation_dummy_cancel(struct fscache_operation *op)
+{
+}
+
 /**
  * fscache_operation_init - Do basic initialisation of an operation
  * @op: The operation to initialise
@@ -30,6 +34,7 @@ EXPORT_SYMBOL(fscache_op_debug_id);
  */
 void fscache_operation_init(struct fscache_operation *op,
                            fscache_operation_processor_t processor,
+                           fscache_operation_cancel_t cancel,
                            fscache_operation_release_t release)
 {
        INIT_WORK(&op->work, fscache_op_work_func);
@@ -37,6 +42,7 @@ void fscache_operation_init(struct fscache_operation *op,
        op->state = FSCACHE_OP_ST_INITIALISED;
        op->debug_id = atomic_inc_return(&fscache_op_debug_id);
        op->processor = processor;
+       op->cancel = cancel ?: fscache_operation_dummy_cancel;
        op->release = release;
        INIT_LIST_HEAD(&op->pend_link);
        fscache_stat(&fscache_n_op_initialised);
@@ -164,9 +170,11 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
        flags = READ_ONCE(object->flags);
        if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) {
                fscache_stat(&fscache_n_op_rejected);
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                ret = -ENOBUFS;
        } else if (unlikely(fscache_cache_is_broken(object))) {
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                ret = -EIO;
        } else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) {
@@ -200,10 +208,12 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
                fscache_stat(&fscache_n_op_pend);
                ret = 0;
        } else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) {
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                ret = -ENOBUFS;
        } else {
                fscache_report_unexpected_submission(object, op, ostate);
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                ret = -ENOBUFS;
        }
@@ -245,9 +255,11 @@ int fscache_submit_op(struct fscache_object *object,
        flags = READ_ONCE(object->flags);
        if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) {
                fscache_stat(&fscache_n_op_rejected);
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                ret = -ENOBUFS;
        } else if (unlikely(fscache_cache_is_broken(object))) {
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                ret = -EIO;
        } else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) {
@@ -276,11 +288,13 @@ int fscache_submit_op(struct fscache_object *object,
                fscache_stat(&fscache_n_op_pend);
                ret = 0;
        } else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) {
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                ret = -ENOBUFS;
        } else {
                fscache_report_unexpected_submission(object, op, ostate);
                ASSERT(!fscache_object_is_active(object));
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                ret = -ENOBUFS;
        }
@@ -335,7 +349,6 @@ void fscache_start_operations(struct fscache_object *object)
  * cancel an operation that's pending on an object
  */
 int fscache_cancel_op(struct fscache_operation *op,
-                     void (*do_cancel)(struct fscache_operation *),
                      bool cancel_in_progress_op)
 {
        struct fscache_object *object = op->object;
@@ -355,9 +368,9 @@ int fscache_cancel_op(struct fscache_operation *op,
                ASSERT(!list_empty(&op->pend_link));
                list_del_init(&op->pend_link);
                put = true;
+
                fscache_stat(&fscache_n_op_cancelled);
-               if (do_cancel)
-                       do_cancel(op);
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
                        object->n_exclusive--;
@@ -373,8 +386,7 @@ int fscache_cancel_op(struct fscache_operation *op,
                        fscache_start_operations(object);
 
                fscache_stat(&fscache_n_op_cancelled);
-               if (do_cancel)
-                       do_cancel(op);
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
                if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
                        object->n_exclusive--;
@@ -408,6 +420,7 @@ void fscache_cancel_all_ops(struct fscache_object *object)
                list_del_init(&op->pend_link);
 
                ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING);
+               op->cancel(op);
                op->state = FSCACHE_OP_ST_CANCELLED;
 
                if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
@@ -440,8 +453,12 @@ void fscache_op_complete(struct fscache_operation *op, bool cancelled)
 
        spin_lock(&object->lock);
 
-       op->state = cancelled ?
-               FSCACHE_OP_ST_CANCELLED : FSCACHE_OP_ST_COMPLETE;
+       if (!cancelled) {
+               op->state = FSCACHE_OP_ST_COMPLETE;
+       } else {
+               op->cancel(op);
+               op->state = FSCACHE_OP_ST_CANCELLED;
+       }
 
        if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
                object->n_exclusive--;