예제 #1
0
/**
 * 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;
    }
}
예제 #2
0
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);
}
예제 #3
0
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) {