|
@@ -20,6 +20,10 @@
|
|
atomic_t fscache_op_debug_id;
|
|
atomic_t fscache_op_debug_id;
|
|
EXPORT_SYMBOL(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
|
|
* fscache_operation_init - Do basic initialisation of an operation
|
|
* @op: The operation to initialise
|
|
* @op: The operation to initialise
|
|
@@ -30,6 +34,7 @@ EXPORT_SYMBOL(fscache_op_debug_id);
|
|
*/
|
|
*/
|
|
void fscache_operation_init(struct fscache_operation *op,
|
|
void fscache_operation_init(struct fscache_operation *op,
|
|
fscache_operation_processor_t processor,
|
|
fscache_operation_processor_t processor,
|
|
|
|
+ fscache_operation_cancel_t cancel,
|
|
fscache_operation_release_t release)
|
|
fscache_operation_release_t release)
|
|
{
|
|
{
|
|
INIT_WORK(&op->work, fscache_op_work_func);
|
|
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->state = FSCACHE_OP_ST_INITIALISED;
|
|
op->debug_id = atomic_inc_return(&fscache_op_debug_id);
|
|
op->debug_id = atomic_inc_return(&fscache_op_debug_id);
|
|
op->processor = processor;
|
|
op->processor = processor;
|
|
|
|
+ op->cancel = cancel ?: fscache_operation_dummy_cancel;
|
|
op->release = release;
|
|
op->release = release;
|
|
INIT_LIST_HEAD(&op->pend_link);
|
|
INIT_LIST_HEAD(&op->pend_link);
|
|
fscache_stat(&fscache_n_op_initialised);
|
|
fscache_stat(&fscache_n_op_initialised);
|
|
@@ -164,9 +170,11 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
|
|
flags = READ_ONCE(object->flags);
|
|
flags = READ_ONCE(object->flags);
|
|
if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) {
|
|
if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) {
|
|
fscache_stat(&fscache_n_op_rejected);
|
|
fscache_stat(&fscache_n_op_rejected);
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
ret = -ENOBUFS;
|
|
ret = -ENOBUFS;
|
|
} else if (unlikely(fscache_cache_is_broken(object))) {
|
|
} else if (unlikely(fscache_cache_is_broken(object))) {
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
ret = -EIO;
|
|
ret = -EIO;
|
|
} else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) {
|
|
} 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);
|
|
fscache_stat(&fscache_n_op_pend);
|
|
ret = 0;
|
|
ret = 0;
|
|
} else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) {
|
|
} else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) {
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
ret = -ENOBUFS;
|
|
ret = -ENOBUFS;
|
|
} else {
|
|
} else {
|
|
fscache_report_unexpected_submission(object, op, ostate);
|
|
fscache_report_unexpected_submission(object, op, ostate);
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
ret = -ENOBUFS;
|
|
ret = -ENOBUFS;
|
|
}
|
|
}
|
|
@@ -245,9 +255,11 @@ int fscache_submit_op(struct fscache_object *object,
|
|
flags = READ_ONCE(object->flags);
|
|
flags = READ_ONCE(object->flags);
|
|
if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) {
|
|
if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) {
|
|
fscache_stat(&fscache_n_op_rejected);
|
|
fscache_stat(&fscache_n_op_rejected);
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
ret = -ENOBUFS;
|
|
ret = -ENOBUFS;
|
|
} else if (unlikely(fscache_cache_is_broken(object))) {
|
|
} else if (unlikely(fscache_cache_is_broken(object))) {
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
ret = -EIO;
|
|
ret = -EIO;
|
|
} else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) {
|
|
} 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);
|
|
fscache_stat(&fscache_n_op_pend);
|
|
ret = 0;
|
|
ret = 0;
|
|
} else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) {
|
|
} else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) {
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
ret = -ENOBUFS;
|
|
ret = -ENOBUFS;
|
|
} else {
|
|
} else {
|
|
fscache_report_unexpected_submission(object, op, ostate);
|
|
fscache_report_unexpected_submission(object, op, ostate);
|
|
ASSERT(!fscache_object_is_active(object));
|
|
ASSERT(!fscache_object_is_active(object));
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
ret = -ENOBUFS;
|
|
ret = -ENOBUFS;
|
|
}
|
|
}
|
|
@@ -335,7 +349,6 @@ void fscache_start_operations(struct fscache_object *object)
|
|
* cancel an operation that's pending on an object
|
|
* cancel an operation that's pending on an object
|
|
*/
|
|
*/
|
|
int fscache_cancel_op(struct fscache_operation *op,
|
|
int fscache_cancel_op(struct fscache_operation *op,
|
|
- void (*do_cancel)(struct fscache_operation *),
|
|
|
|
bool cancel_in_progress_op)
|
|
bool cancel_in_progress_op)
|
|
{
|
|
{
|
|
struct fscache_object *object = op->object;
|
|
struct fscache_object *object = op->object;
|
|
@@ -355,9 +368,9 @@ int fscache_cancel_op(struct fscache_operation *op,
|
|
ASSERT(!list_empty(&op->pend_link));
|
|
ASSERT(!list_empty(&op->pend_link));
|
|
list_del_init(&op->pend_link);
|
|
list_del_init(&op->pend_link);
|
|
put = true;
|
|
put = true;
|
|
|
|
+
|
|
fscache_stat(&fscache_n_op_cancelled);
|
|
fscache_stat(&fscache_n_op_cancelled);
|
|
- if (do_cancel)
|
|
|
|
- do_cancel(op);
|
|
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
|
|
if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
|
|
object->n_exclusive--;
|
|
object->n_exclusive--;
|
|
@@ -373,8 +386,7 @@ int fscache_cancel_op(struct fscache_operation *op,
|
|
fscache_start_operations(object);
|
|
fscache_start_operations(object);
|
|
|
|
|
|
fscache_stat(&fscache_n_op_cancelled);
|
|
fscache_stat(&fscache_n_op_cancelled);
|
|
- if (do_cancel)
|
|
|
|
- do_cancel(op);
|
|
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
|
|
if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
|
|
object->n_exclusive--;
|
|
object->n_exclusive--;
|
|
@@ -408,6 +420,7 @@ void fscache_cancel_all_ops(struct fscache_object *object)
|
|
list_del_init(&op->pend_link);
|
|
list_del_init(&op->pend_link);
|
|
|
|
|
|
ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING);
|
|
ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING);
|
|
|
|
+ op->cancel(op);
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
op->state = FSCACHE_OP_ST_CANCELLED;
|
|
|
|
|
|
if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
|
|
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);
|
|
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))
|
|
if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
|
|
object->n_exclusive--;
|
|
object->n_exclusive--;
|