fs/orangefs/waitqueue.c

Source file repositories/reference/linux-study-clean/fs/orangefs/waitqueue.c

File Facts

System
Linux kernel
Corpus path
fs/orangefs/waitqueue.c
Extension
.c
Size
10568 bytes
Lines
374
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ret < 0) {
			op->downcall.status = ret;
			gossip_debug(GOSSIP_WAIT_DEBUG,
				     "%s: service_operation interrupted.\n",
				     __func__);
			return ret;
		}
	}

	/* queue up the operation */
	spin_lock(&orangefs_request_list_lock);
	spin_lock(&op->lock);
	set_op_state_waiting(op);
	gossip_debug(GOSSIP_DEV_DEBUG,
		     "%s: op:%s: op_state:%d: process:%s:\n",
		     __func__,
		     get_opname_string(op),
		     op->op_state,
		     current->comm);
	/* add high priority remount op to the front of the line. */
	if (flags & ORANGEFS_OP_PRIORITY)
		list_add(&op->list, &orangefs_request_list);
	else
		list_add_tail(&op->list, &orangefs_request_list);
	spin_unlock(&op->lock);
	wake_up_interruptible(&orangefs_request_list_waitq);
	if (!__is_daemon_in_service()) {
		gossip_debug(GOSSIP_WAIT_DEBUG,
			     "%s:client core is NOT in service.\n",
			     __func__);
		/*
		 * Don't wait for the userspace component to return if
		 * the filesystem is being umounted anyway.
		 */
		if (op->upcall.type == ORANGEFS_VFS_OP_FS_UMOUNT)
			timeout = 0;
		else
			timeout = op_timeout_secs * HZ;
	}
	spin_unlock(&orangefs_request_list_lock);

	if (!(flags & ORANGEFS_OP_NO_MUTEX))
		mutex_unlock(&orangefs_request_mutex);

	ret = wait_for_matching_downcall(op, timeout, flags);
	gossip_debug(GOSSIP_WAIT_DEBUG,
		     "%s: wait_for_matching_downcall returned %d for %p\n",
		     __func__,
		     ret,
		     op);

	/* got matching downcall; make sure status is in errno format */
	if (!ret) {
		spin_unlock(&op->lock);
		op->downcall.status =
		    orangefs_normalize_to_errno(op->downcall.status);
		ret = op->downcall.status;
		goto out;
	}

	/* failed to get matching downcall */
	if (ret == -ETIMEDOUT) {
		gossip_err("%s: %s -- wait timed out; aborting attempt.\n",
			   __func__,
			   op_name);
	}

	/*
	 * remove a waiting op from the request list or
	 * remove an in-progress op from the in-progress list.
	 */
	orangefs_clean_up_interrupted_operation(op);

	op->downcall.status = ret;
	/* retry if operation has not been serviced and if requested */
	if (ret == -EAGAIN) {
		op->attempts++;
		timeout = op_timeout_secs * HZ;
		gossip_debug(GOSSIP_WAIT_DEBUG,
			     "orangefs: tag %llu (%s)"
			     " -- operation to be retried (%d attempt)\n",
			     llu(op->tag),
			     op_name,
			     op->attempts);

		/*
		 * io ops (ops that use the shared memory buffer) have
		 * to be returned to their caller for a retry. Other ops
		 * can just be recycled here.
		 */

Annotation

Implementation Notes