fs/autofs/waitq.c

Source file repositories/reference/linux-study-clean/fs/autofs/waitq.c

File Facts

System
Linux kernel
Corpus path
fs/autofs/waitq.c
Extension
.c
Size
12835 bytes
Lines
514
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

while (ino->flags & AUTOFS_INF_EXPIRING) {
			mutex_unlock(&sbi->wq_mutex);
			schedule_timeout_interruptible(HZ/10);
			if (mutex_lock_interruptible(&sbi->wq_mutex))
				return -EINTR;

			if (sbi->flags & AUTOFS_SBI_CATATONIC)
				return -ENOENT;

			wq = autofs_find_wait(sbi, qstr);
			if (wq) {
				*wait = wq;
				return 1;
			}
		}

		/*
		 * Not ideal but the status has already gone. Of the two
		 * cases where we wait on NFY_NONE neither depend on the
		 * return status of the wait.
		 */
		return 0;
	}

	/*
	 * If we've been asked to trigger a mount and the request
	 * completed while we waited on the mutex ...
	 */
	if (notify == NFY_MOUNT) {
		struct dentry *new = NULL;
		struct path this;
		int valid = 1;

		/*
		 * If the dentry was successfully mounted while we slept
		 * on the wait queue mutex we can return success. If it
		 * isn't mounted (doesn't have submounts for the case of
		 * a multi-mount with no mount at it's base) we can
		 * continue on and create a new request.
		 */
		if (!IS_ROOT(dentry)) {
			if (d_unhashed(dentry) &&
			    d_really_is_positive(dentry)) {
				struct dentry *parent = dentry->d_parent;

				new = d_lookup(parent, &dentry->d_name);
				if (new)
					dentry = new;
			}
		}
		this.mnt = path->mnt;
		this.dentry = dentry;
		if (path_has_submounts(&this))
			valid = 0;

		if (new)
			dput(new);
		return valid;
	}

	return 1;
}

int autofs_wait(struct autofs_sb_info *sbi,
		 const struct path *path, enum autofs_notify notify)
{
	struct dentry *dentry = path->dentry;
	struct autofs_wait_queue *wq;
	struct qstr qstr;
	char *name;
	int status, ret, type;
	unsigned int offset = 0;
	pid_t pid;
	pid_t tgid;

	/* In catatonic mode, we don't wait for nobody */
	if (sbi->flags & AUTOFS_SBI_CATATONIC)
		return -ENOENT;

	/*
	 * Try translating pids to the namespace of the daemon.
	 *
	 * Zero means failure: we are in an unrelated pid namespace.
	 */
	pid = task_pid_nr_ns(current, ns_of_pid(sbi->oz_pgrp));
	tgid = task_tgid_nr_ns(current, ns_of_pid(sbi->oz_pgrp));
	if (pid == 0 || tgid == 0)
		return -ENOENT;

	if (d_really_is_negative(dentry)) {

Annotation

Implementation Notes