/** * fscache_enqueue_operation - Enqueue an operation for processing * @op: The operation to enqueue * * Enqueue an operation for processing by the FS-Cache thread pool. * * This will get its own ref on the object. */ void fscache_enqueue_operation(struct fscache_operation *op) { _enter("{OBJ%x OP%x,%u}", op->object->debug_id, op->debug_id, atomic_read(&op->usage)); fscache_set_op_state(op, "EnQ"); ASSERT(list_empty(&op->pend_link)); ASSERT(op->processor != NULL); ASSERT(fscache_object_is_available(op->object)); ASSERTCMP(atomic_read(&op->usage), >, 0); ASSERTCMP(op->state, ==, FSCACHE_OP_ST_IN_PROGRESS); fscache_stat(&fscache_n_op_enqueue); switch (op->flags & FSCACHE_OP_TYPE) { case FSCACHE_OP_FAST: _debug("queue fast"); atomic_inc(&op->usage); if (!schedule_work(&op->fast_work)) fscache_put_operation(op); break; case FSCACHE_OP_SLOW: _debug("queue slow"); slow_work_enqueue(&op->slow_work); break; case FSCACHE_OP_MYTHREAD: _debug("queue for caller's attention"); break; default: printk(KERN_ERR "FS-Cache: Unexpected op type %lx", op->flags); BUG(); break; } }
static void fscache_run_op(struct fscache_object *object, struct fscache_operation *op) { fscache_set_op_state(op, "Run"); object->n_in_progress++; if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags)) wake_up_bit(&op->flags, FSCACHE_OP_WAITING); if (op->processor) fscache_enqueue_operation(op); fscache_stat(&fscache_n_op_run); }
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); fscache_set_op_state(op, "SubmitX"); spin_lock(&object->lock); ASSERTCMP(object->n_ops, >=, object->n_in_progress); ASSERTCMP(object->n_ops, >=, object->n_exclusive); ASSERT(list_empty(&op->pend_link)); ret = -ENOBUFS; if (fscache_object_is_active(object)) { op->object = object; object->n_ops++; object->n_exclusive++; /* reads and writes must wait */ if (object->n_ops > 0) { atomic_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); } else if (!list_empty(&object->pending_ops)) { atomic_inc(&op->usage); list_add_tail(&op->pend_link, &object->pending_ops); fscache_stat(&fscache_n_op_pend); fscache_start_operations(object); } else { ASSERTCMP(object->n_in_progress, ==, 0); fscache_run_op(object, op); } /* 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) {