aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache/operation.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fscache/operation.c')
-rw-r--r--fs/fscache/operation.c82
1 files changed, 54 insertions, 28 deletions
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index 09e43b6e822f..296492efb81b 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
@@ -34,32 +34,31 @@ void fscache_enqueue_operation(struct fscache_operation *op)
34 34
35 fscache_set_op_state(op, "EnQ"); 35 fscache_set_op_state(op, "EnQ");
36 36
37 ASSERT(list_empty(&op->pend_link));
37 ASSERT(op->processor != NULL); 38 ASSERT(op->processor != NULL);
38 ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE); 39 ASSERTCMP(op->object->state, >=, FSCACHE_OBJECT_AVAILABLE);
39 ASSERTCMP(atomic_read(&op->usage), >, 0); 40 ASSERTCMP(atomic_read(&op->usage), >, 0);
40 41
41 if (list_empty(&op->pend_link)) { 42 fscache_stat(&fscache_n_op_enqueue);
42 switch (op->flags & FSCACHE_OP_TYPE) { 43 switch (op->flags & FSCACHE_OP_TYPE) {
43 case FSCACHE_OP_FAST: 44 case FSCACHE_OP_FAST:
44 _debug("queue fast"); 45 _debug("queue fast");
45 atomic_inc(&op->usage); 46 atomic_inc(&op->usage);
46 if (!schedule_work(&op->fast_work)) 47 if (!schedule_work(&op->fast_work))
47 fscache_put_operation(op); 48 fscache_put_operation(op);
48 break; 49 break;
49 case FSCACHE_OP_SLOW: 50 case FSCACHE_OP_SLOW:
50 _debug("queue slow"); 51 _debug("queue slow");
51 slow_work_enqueue(&op->slow_work); 52 slow_work_enqueue(&op->slow_work);
52 break; 53 break;
53 case FSCACHE_OP_MYTHREAD: 54 case FSCACHE_OP_MYTHREAD:
54 _debug("queue for caller's attention"); 55 _debug("queue for caller's attention");
55 break; 56 break;
56 default: 57 default:
57 printk(KERN_ERR "FS-Cache: Unexpected op type %lx", 58 printk(KERN_ERR "FS-Cache: Unexpected op type %lx",
58 op->flags); 59 op->flags);
59 BUG(); 60 BUG();
60 break; 61 break;
61 }
62 fscache_stat(&fscache_n_op_enqueue);
63 } 62 }
64} 63}
65EXPORT_SYMBOL(fscache_enqueue_operation); 64EXPORT_SYMBOL(fscache_enqueue_operation);
@@ -97,6 +96,7 @@ int fscache_submit_exclusive_op(struct fscache_object *object,
97 spin_lock(&object->lock); 96 spin_lock(&object->lock);
98 ASSERTCMP(object->n_ops, >=, object->n_in_progress); 97 ASSERTCMP(object->n_ops, >=, object->n_in_progress);
99 ASSERTCMP(object->n_ops, >=, object->n_exclusive); 98 ASSERTCMP(object->n_ops, >=, object->n_exclusive);
99 ASSERT(list_empty(&op->pend_link));
100 100
101 ret = -ENOBUFS; 101 ret = -ENOBUFS;
102 if (fscache_object_is_active(object)) { 102 if (fscache_object_is_active(object)) {
@@ -202,6 +202,7 @@ int fscache_submit_op(struct fscache_object *object,
202 spin_lock(&object->lock); 202 spin_lock(&object->lock);
203 ASSERTCMP(object->n_ops, >=, object->n_in_progress); 203 ASSERTCMP(object->n_ops, >=, object->n_in_progress);
204 ASSERTCMP(object->n_ops, >=, object->n_exclusive); 204 ASSERTCMP(object->n_ops, >=, object->n_exclusive);
205 ASSERT(list_empty(&op->pend_link));
205 206
206 ostate = object->state; 207 ostate = object->state;
207 smp_rmb(); 208 smp_rmb();
@@ -273,12 +274,7 @@ void fscache_start_operations(struct fscache_object *object)
273 stop = true; 274 stop = true;
274 } 275 }
275 list_del_init(&op->pend_link); 276 list_del_init(&op->pend_link);
276 object->n_in_progress++; 277 fscache_run_op(object, op);
277
278 if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
279 wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
280 if (op->processor)
281 fscache_enqueue_operation(op);
282 278
283 /* the pending queue was holding a ref on the object */ 279 /* the pending queue was holding a ref on the object */
284 fscache_put_operation(op); 280 fscache_put_operation(op);
@@ -291,6 +287,36 @@ void fscache_start_operations(struct fscache_object *object)
291} 287}
292 288
293/* 289/*
290 * cancel an operation that's pending on an object
291 */
292int fscache_cancel_op(struct fscache_operation *op)
293{
294 struct fscache_object *object = op->object;
295 int ret;
296
297 _enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id);
298
299 spin_lock(&object->lock);
300
301 ret = -EBUSY;
302 if (!list_empty(&op->pend_link)) {
303 fscache_stat(&fscache_n_op_cancelled);
304 list_del_init(&op->pend_link);
305 object->n_ops--;
306 if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
307 object->n_exclusive--;
308 if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
309 wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
310 fscache_put_operation(op);
311 ret = 0;
312 }
313
314 spin_unlock(&object->lock);
315 _leave(" = %d", ret);
316 return ret;
317}
318
319/*
294 * release an operation 320 * release an operation
295 * - queues pending ops if this is the last in-progress op 321 * - queues pending ops if this is the last in-progress op
296 */ 322 */