Unverified Commit bf99c651 authored by openeuler-ci-bot's avatar openeuler-ci-bot Committed by Gitee
Browse files
parents 7881f070 b9cd9e78
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ struct afs_call {
	wait_queue_head_t	waitq;		/* processes awaiting completion */
	struct work_struct	async_work;	/* async I/O processor */
	struct work_struct	work;		/* actual work processor */
	struct work_struct	free_work;	/* Deferred free processor */
	struct rxrpc_call	*rxcall;	/* RxRPC call handle */
	struct key		*key;		/* security for this call */
	struct afs_net		*net;		/* The network namespace */
@@ -1275,6 +1276,7 @@ extern int __net_init afs_open_socket(struct afs_net *);
extern void __net_exit afs_close_socket(struct afs_net *);
extern void afs_charge_preallocation(struct work_struct *);
extern void afs_put_call(struct afs_call *);
void afs_deferred_put_call(struct afs_call *call);
extern void afs_make_call(struct afs_addr_cursor *, struct afs_call *, gfp_t);
extern long afs_wait_for_call_to_complete(struct afs_call *, struct afs_addr_cursor *);
extern struct afs_call *afs_alloc_flat_call(struct afs_net *,
+58 −23
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@

struct workqueue_struct *afs_async_calls;

static void afs_deferred_free_worker(struct work_struct *work);
static void afs_wake_up_call_waiter(struct sock *, struct rxrpc_call *, unsigned long);
static void afs_wake_up_async_call(struct sock *, struct rxrpc_call *, unsigned long);
static void afs_process_async_call(struct work_struct *);
@@ -149,6 +150,7 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
	call->debug_id = atomic_inc_return(&rxrpc_debug_id);
	refcount_set(&call->ref, 1);
	INIT_WORK(&call->async_work, afs_process_async_call);
	INIT_WORK(&call->free_work, afs_deferred_free_worker);
	init_waitqueue_head(&call->waitq);
	spin_lock_init(&call->state_lock);
	call->iter = &call->def_iter;
@@ -159,24 +161,12 @@ static struct afs_call *afs_alloc_call(struct afs_net *net,
	return call;
}

/*
 * Dispose of a reference on a call.
 */
void afs_put_call(struct afs_call *call)
static void afs_free_call(struct afs_call *call)
{
	struct afs_net *net = call->net;
	unsigned int debug_id = call->debug_id;
	bool zero;
	int r, o;

	zero = __refcount_dec_and_test(&call->ref, &r);
	o = atomic_read(&net->nr_outstanding_calls);
	trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
		       __builtin_return_address(0));
	int o;

	if (zero) {
	ASSERT(!work_pending(&call->async_work));
		ASSERT(call->type->name != NULL);

	if (call->rxcall) {
		rxrpc_kernel_shutdown_call(net->socket, call->rxcall);
@@ -190,6 +180,7 @@ void afs_put_call(struct afs_call *call)
	afs_put_addrlist(call->alist);
	kfree(call->request);

	o = atomic_read(&net->nr_outstanding_calls);
	trace_afs_call(call->debug_id, afs_call_trace_free, 0, o,
		       __builtin_return_address(0));
	kfree(call);
@@ -198,6 +189,49 @@ void afs_put_call(struct afs_call *call)
	if (o == 0)
		wake_up_var(&net->nr_outstanding_calls);
}

/*
 * Dispose of a reference on a call.
 */
void afs_put_call(struct afs_call *call)
{
	struct afs_net *net = call->net;
	unsigned int debug_id = call->debug_id;
	bool zero;
	int r, o;

	zero = __refcount_dec_and_test(&call->ref, &r);
	o = atomic_read(&net->nr_outstanding_calls);
	trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
		       __builtin_return_address(0));
	if (zero)
		afs_free_call(call);
}

static void afs_deferred_free_worker(struct work_struct *work)
{
	struct afs_call *call = container_of(work, struct afs_call, free_work);

	afs_free_call(call);
}

/*
 * Dispose of a reference on a call, deferring the cleanup to a workqueue
 * to avoid lock recursion.
 */
void afs_deferred_put_call(struct afs_call *call)
{
	struct afs_net *net = call->net;
	unsigned int debug_id = call->debug_id;
	bool zero;
	int r, o;

	zero = __refcount_dec_and_test(&call->ref, &r);
	o = atomic_read(&net->nr_outstanding_calls);
	trace_afs_call(debug_id, afs_call_trace_put, r - 1, o,
		       __builtin_return_address(0));
	if (zero)
		schedule_work(&call->free_work);
}

static struct afs_call *afs_get_call(struct afs_call *call,
@@ -665,7 +699,8 @@ static void afs_wake_up_call_waiter(struct sock *sk, struct rxrpc_call *rxcall,
}

/*
 * wake up an asynchronous call
 * Wake up an asynchronous call.  The caller is holding the call notify
 * spinlock around this, so we can't call afs_put_call().
 */
static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
				   unsigned long call_user_ID)
@@ -682,7 +717,7 @@ static void afs_wake_up_async_call(struct sock *sk, struct rxrpc_call *rxcall,
			       __builtin_return_address(0));

		if (!queue_work(afs_async_calls, &call->async_work))
			afs_put_call(call);
			afs_deferred_put_call(call);
	}
}