Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /* FS-Cache worker operation management routines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2008 Red Hat, Inc. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  * Written by David Howells (dhowells@redhat.com)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  * See Documentation/filesystems/caching/operations.rst
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #define FSCACHE_DEBUG_LEVEL OPERATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/seq_file.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #include "internal.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) atomic_t fscache_op_debug_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) EXPORT_SYMBOL(fscache_op_debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) static void fscache_operation_dummy_cancel(struct fscache_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * fscache_operation_init - Do basic initialisation of an operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * @op: The operation to initialise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  * @release: The release function to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28)  * Do basic initialisation of an operation.  The caller must still set flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29)  * object and processor if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) void fscache_operation_init(struct fscache_cookie *cookie,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 			    struct fscache_operation *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 			    fscache_operation_processor_t processor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 			    fscache_operation_cancel_t cancel,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 			    fscache_operation_release_t release)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	INIT_WORK(&op->work, fscache_op_work_func);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 	atomic_set(&op->usage, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	op->state = FSCACHE_OP_ST_INITIALISED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	op->debug_id = atomic_inc_return(&fscache_op_debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	op->processor = processor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	op->cancel = cancel ?: fscache_operation_dummy_cancel;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	op->release = release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 	INIT_LIST_HEAD(&op->pend_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	fscache_stat(&fscache_n_op_initialised);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 	trace_fscache_op(cookie, op, fscache_op_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) EXPORT_SYMBOL(fscache_operation_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51)  * fscache_enqueue_operation - Enqueue an operation for processing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52)  * @op: The operation to enqueue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54)  * Enqueue an operation for processing by the FS-Cache thread pool.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56)  * This will get its own ref on the object.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) void fscache_enqueue_operation(struct fscache_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	struct fscache_cookie *cookie = op->object->cookie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	_enter("{OBJ%x OP%x,%u}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	       op->object->debug_id, op->debug_id, atomic_read(&op->usage));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	ASSERT(list_empty(&op->pend_link));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	ASSERT(op->processor != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	ASSERT(fscache_object_is_available(op->object));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	ASSERTCMP(atomic_read(&op->usage), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	ASSERTIFCMP(op->state != FSCACHE_OP_ST_IN_PROGRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		    op->state, ==,  FSCACHE_OP_ST_CANCELLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	fscache_stat(&fscache_n_op_enqueue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	switch (op->flags & FSCACHE_OP_TYPE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	case FSCACHE_OP_ASYNC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		trace_fscache_op(cookie, op, fscache_op_enqueue_async);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		_debug("queue async");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		atomic_inc(&op->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		if (!queue_work(fscache_op_wq, &op->work))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			fscache_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 	case FSCACHE_OP_MYTHREAD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 		trace_fscache_op(cookie, op, fscache_op_enqueue_mythread);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 		_debug("queue for caller's attention");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 		pr_err("Unexpected op type %lx", op->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 		BUG();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) EXPORT_SYMBOL(fscache_enqueue_operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * start an op running
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) static void fscache_run_op(struct fscache_object *object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 			   struct fscache_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	op->state = FSCACHE_OP_ST_IN_PROGRESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	object->n_in_progress++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	if (op->processor)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		fscache_enqueue_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		trace_fscache_op(object->cookie, op, fscache_op_run);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	fscache_stat(&fscache_n_op_run);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)  * report an unexpected submission
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) static void fscache_report_unexpected_submission(struct fscache_object *object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 						 struct fscache_operation *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 						 const struct fscache_state *ostate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	static bool once_only;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	struct fscache_operation *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	unsigned n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (once_only)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 	once_only = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	kdebug("unexpected submission OP%x [OBJ%x %s]",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	       op->debug_id, object->debug_id, object->state->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	kdebug("objstate=%s [%s]", object->state->name, ostate->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	kdebug("objflags=%lx", object->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	kdebug("objevent=%lx [%lx]", object->events, object->event_mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	kdebug("ops=%u inp=%u exc=%u",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	       object->n_ops, object->n_in_progress, object->n_exclusive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	if (!list_empty(&object->pending_ops)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 		n = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 		list_for_each_entry(p, &object->pending_ops, pend_link) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 			ASSERTCMP(p->object, ==, object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) 			kdebug("%p %p", op->processor, op->release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 			n++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 		kdebug("n=%u", n);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	dump_stack();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150)  * submit an exclusive operation for an object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)  * - other ops are excluded from running simultaneously with this one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)  * - this gets any extra refs it needs on an op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) int fscache_submit_exclusive_op(struct fscache_object *object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 				struct fscache_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	const struct fscache_state *ostate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	_enter("{OBJ%x OP%x},", object->debug_id, op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	trace_fscache_op(object->cookie, op, fscache_op_submit_ex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 	ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 	ASSERTCMP(atomic_read(&op->usage), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 	spin_lock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	ASSERTCMP(object->n_ops, >=, object->n_in_progress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	ASSERTCMP(object->n_ops, >=, object->n_exclusive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	ASSERT(list_empty(&op->pend_link));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 	ostate = object->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 	smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	op->state = FSCACHE_OP_ST_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	flags = READ_ONCE(object->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 		fscache_stat(&fscache_n_op_rejected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 		ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	} else if (unlikely(fscache_cache_is_broken(object))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	} else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		op->object = object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 		object->n_ops++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 		object->n_exclusive++;	/* reads and writes must wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) 		if (object->n_in_progress > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 			atomic_inc(&op->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 			list_add_tail(&op->pend_link, &object->pending_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 			fscache_stat(&fscache_n_op_pend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 		} else if (!list_empty(&object->pending_ops)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			atomic_inc(&op->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 			list_add_tail(&op->pend_link, &object->pending_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 			fscache_stat(&fscache_n_op_pend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) 			fscache_start_operations(object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) 			ASSERTCMP(object->n_in_progress, ==, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) 			fscache_run_op(object, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) 		/* need to issue a new write op after this */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 		clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 	} else if (flags & BIT(FSCACHE_OBJECT_IS_LOOKED_UP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 		op->object = object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 		object->n_ops++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 		object->n_exclusive++;	/* reads and writes must wait */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 		atomic_inc(&op->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 		list_add_tail(&op->pend_link, &object->pending_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 		fscache_stat(&fscache_n_op_pend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	} else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 		ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 		fscache_report_unexpected_submission(object, op, ostate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) 		ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 	spin_unlock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)  * submit an operation for an object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  * - objects may be submitted only in the following states:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  *   - during object creation (write ops may be submitted)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  *   - whilst the object is active
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  *   - after an I/O error incurred in one of the two above states (op rejected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)  * - this gets any extra refs it needs on an op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) int fscache_submit_op(struct fscache_object *object,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		      struct fscache_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 	const struct fscache_state *ostate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 	_enter("{OBJ%x OP%x},{%u}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) 	       object->debug_id, op->debug_id, atomic_read(&op->usage));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	trace_fscache_op(object->cookie, op, fscache_op_submit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	ASSERTCMP(op->state, ==, FSCACHE_OP_ST_INITIALISED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	ASSERTCMP(atomic_read(&op->usage), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	spin_lock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	ASSERTCMP(object->n_ops, >=, object->n_in_progress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	ASSERTCMP(object->n_ops, >=, object->n_exclusive);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	ASSERT(list_empty(&op->pend_link));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	ostate = object->state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	smp_rmb();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 	op->state = FSCACHE_OP_ST_PENDING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	flags = READ_ONCE(object->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	if (unlikely(!(flags & BIT(FSCACHE_OBJECT_IS_LIVE)))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		fscache_stat(&fscache_n_op_rejected);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 		ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 	} else if (unlikely(fscache_cache_is_broken(object))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 		ret = -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	} else if (flags & BIT(FSCACHE_OBJECT_IS_AVAILABLE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 		op->object = object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		object->n_ops++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 		if (object->n_exclusive > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 			atomic_inc(&op->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 			list_add_tail(&op->pend_link, &object->pending_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 			fscache_stat(&fscache_n_op_pend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 		} else if (!list_empty(&object->pending_ops)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 			atomic_inc(&op->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 			list_add_tail(&op->pend_link, &object->pending_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 			fscache_stat(&fscache_n_op_pend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 			fscache_start_operations(object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 			ASSERTCMP(object->n_exclusive, ==, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 			fscache_run_op(object, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	} else if (flags & BIT(FSCACHE_OBJECT_IS_LOOKED_UP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 		op->object = object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 		object->n_ops++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 		atomic_inc(&op->usage);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 		list_add_tail(&op->pend_link, &object->pending_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		fscache_stat(&fscache_n_op_pend);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	} else if (flags & BIT(FSCACHE_OBJECT_KILLED_BY_CACHE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 		ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 		fscache_report_unexpected_submission(object, op, ostate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 		ASSERT(!fscache_object_is_active(object));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) 		ret = -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	spin_unlock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)  * queue an object for withdrawal on error, aborting all following asynchronous
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)  * operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) void fscache_abort_object(struct fscache_object *object)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) 	_enter("{OBJ%x}", object->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) 	fscache_raise_event(object, FSCACHE_OBJECT_EV_ERROR);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)  * Jump start the operation processing on an object.  The caller must hold
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)  * object->lock.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) void fscache_start_operations(struct fscache_object *object)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	struct fscache_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	bool stop = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	while (!list_empty(&object->pending_ops) && !stop) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		op = list_entry(object->pending_ops.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 				struct fscache_operation, pend_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) 		if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 			if (object->n_in_progress > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 			stop = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 		list_del_init(&op->pend_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 		fscache_run_op(object, op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 		/* the pending queue was holding a ref on the object */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 		fscache_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 	ASSERTCMP(object->n_in_progress, <=, object->n_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 	_debug("woke %d ops on OBJ%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 	       object->n_in_progress, object->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)  * cancel an operation that's pending on an object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) int fscache_cancel_op(struct fscache_operation *op,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 		      bool cancel_in_progress_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) 	struct fscache_object *object = op->object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 	bool put = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 	_enter("OBJ%x OP%x}", op->object->debug_id, op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	trace_fscache_op(object->cookie, op, fscache_op_cancel);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 	ASSERTCMP(op->state, >=, FSCACHE_OP_ST_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 	ASSERTCMP(op->state, !=, FSCACHE_OP_ST_CANCELLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	ASSERTCMP(atomic_read(&op->usage), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 	spin_lock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 	ret = -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 	if (op->state == FSCACHE_OP_ST_PENDING) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 		ASSERT(!list_empty(&op->pend_link));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 		list_del_init(&op->pend_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 		put = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 		fscache_stat(&fscache_n_op_cancelled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 		if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 			object->n_exclusive--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 		if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 			wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	} else if (op->state == FSCACHE_OP_ST_IN_PROGRESS && cancel_in_progress_op) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 		ASSERTCMP(object->n_in_progress, >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 		if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 			object->n_exclusive--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 		object->n_in_progress--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 		if (object->n_in_progress == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 			fscache_start_operations(object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 		fscache_stat(&fscache_n_op_cancelled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 		if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 			object->n_exclusive--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 		if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 			wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 	if (put)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 		fscache_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) 	spin_unlock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	_leave(" = %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)  * Cancel all pending operations on an object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) void fscache_cancel_all_ops(struct fscache_object *object)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	struct fscache_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	_enter("OBJ%x", object->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	spin_lock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	while (!list_empty(&object->pending_ops)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 		op = list_entry(object->pending_ops.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 				struct fscache_operation, pend_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 		fscache_stat(&fscache_n_op_cancelled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 		list_del_init(&op->pend_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 		trace_fscache_op(object->cookie, op, fscache_op_cancel_all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 		ASSERTCMP(op->state, ==, FSCACHE_OP_ST_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 			object->n_exclusive--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 		if (test_and_clear_bit(FSCACHE_OP_WAITING, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 			wake_up_bit(&op->flags, FSCACHE_OP_WAITING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 		fscache_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 		cond_resched_lock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	spin_unlock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 	_leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)  * Record the completion or cancellation of an in-progress operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) void fscache_op_complete(struct fscache_operation *op, bool cancelled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) 	struct fscache_object *object = op->object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	_enter("OBJ%x", object->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	ASSERTCMP(op->state, ==, FSCACHE_OP_ST_IN_PROGRESS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	ASSERTCMP(object->n_in_progress, >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	ASSERTIFCMP(test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 		    object->n_exclusive, >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 	ASSERTIFCMP(test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 		    object->n_in_progress, ==, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 	spin_lock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 	if (!cancelled) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		trace_fscache_op(object->cookie, op, fscache_op_completed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		op->state = FSCACHE_OP_ST_COMPLETE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 		op->cancel(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 		trace_fscache_op(object->cookie, op, fscache_op_cancelled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		op->state = FSCACHE_OP_ST_CANCELLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 	if (test_bit(FSCACHE_OP_EXCLUSIVE, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		object->n_exclusive--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 	object->n_in_progress--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	if (object->n_in_progress == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 		fscache_start_operations(object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	spin_unlock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	_leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) EXPORT_SYMBOL(fscache_op_complete);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490)  * release an operation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491)  * - queues pending ops if this is the last in-progress op
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) void fscache_put_operation(struct fscache_operation *op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 	struct fscache_cache *cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	_enter("{OBJ%x OP%x,%d}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 	       op->object ? op->object->debug_id : 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 	       op->debug_id, atomic_read(&op->usage));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	ASSERTCMP(atomic_read(&op->usage), >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	if (!atomic_dec_and_test(&op->usage))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	trace_fscache_op(op->object ? op->object->cookie : NULL, op, fscache_op_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	_debug("PUT OP");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) 	ASSERTIFCMP(op->state != FSCACHE_OP_ST_INITIALISED &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 		    op->state != FSCACHE_OP_ST_COMPLETE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) 		    op->state, ==, FSCACHE_OP_ST_CANCELLED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 	fscache_stat(&fscache_n_op_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) 	if (op->release) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) 		op->release(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 		op->release = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	op->state = FSCACHE_OP_ST_DEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 	object = op->object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	if (likely(object)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 			atomic_dec(&object->n_reads);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 		if (test_bit(FSCACHE_OP_UNUSE_COOKIE, &op->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 			fscache_unuse_cookie(object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		/* now... we may get called with the object spinlock held, so we
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 		 * complete the cleanup here only if we can immediately acquire the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 		 * lock, and defer it otherwise */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		if (!spin_trylock(&object->lock)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 			_debug("defer put");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 			fscache_stat(&fscache_n_op_deferred_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 			cache = object->cache;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 			spin_lock(&cache->op_gc_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 			list_add_tail(&op->pend_link, &cache->op_gc_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 			spin_unlock(&cache->op_gc_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 			schedule_work(&cache->op_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 			_leave(" [defer]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 			return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 		ASSERTCMP(object->n_ops, >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 		object->n_ops--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 		if (object->n_ops == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 			fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 		spin_unlock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 	kfree(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 	_leave(" [done]");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) EXPORT_SYMBOL(fscache_put_operation);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)  * garbage collect operations that have had their release deferred
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) void fscache_operation_gc(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 	struct fscache_operation *op;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 	struct fscache_object *object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 	struct fscache_cache *cache =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 		container_of(work, struct fscache_cache, op_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 	int count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	_enter("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 		spin_lock(&cache->op_gc_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 		if (list_empty(&cache->op_gc_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 			spin_unlock(&cache->op_gc_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		op = list_entry(cache->op_gc_list.next,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 				struct fscache_operation, pend_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		list_del(&op->pend_link);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 		spin_unlock(&cache->op_gc_list_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 		object = op->object;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) 		trace_fscache_op(object->cookie, op, fscache_op_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 		spin_lock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 		_debug("GC DEFERRED REL OBJ%x OP%x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 		       object->debug_id, op->debug_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		fscache_stat(&fscache_n_op_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		ASSERTCMP(atomic_read(&op->usage), ==, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		ASSERTCMP(op->state, ==, FSCACHE_OP_ST_DEAD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) 		ASSERTCMP(object->n_ops, >, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 		object->n_ops--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 		if (object->n_ops == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) 			fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		spin_unlock(&object->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 		kfree(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 	} while (count++ < 20);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 	if (!list_empty(&cache->op_gc_list))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 		schedule_work(&cache->op_gc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	_leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612)  * execute an operation using fs_op_wq to provide processing context -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613)  * the caller holds a ref to this object, so we don't need to hold one
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) void fscache_op_work_func(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	struct fscache_operation *op =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 		container_of(work, struct fscache_operation, work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 	unsigned long start;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	_enter("{OBJ%x OP%x,%d}",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	       op->object->debug_id, op->debug_id, atomic_read(&op->usage));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) 	trace_fscache_op(op->object->cookie, op, fscache_op_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	ASSERT(op->processor != NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 	start = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	op->processor(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	fscache_hist(fscache_ops_histogram, start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 	fscache_put_operation(op);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	_leave("");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }