fs/lockd/clntproc.c

Source file repositories/reference/linux-study-clean/fs/lockd/clntproc.c

File Facts

System
Linux kernel
Corpus path
fs/lockd/clntproc.c
Extension
.c
Size
23108 bytes
Lines
890
Domain
Core OS
Bucket
VFS And Filesystem Core
Inferred role
Core OS: exported/initcall integration point
Status
integration 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 (res == NULL && new != NULL) {
			res = new;
			refcount_set(&new->count, 1);
			new->owner = owner;
			new->pid = __nlm_alloc_pid(host);
			new->host = nlm_get_host(host);
			list_add(&new->list, &host->h_lockowners);
			new = NULL;
		}
	}
	spin_unlock(&host->h_lock);
	kfree(new);
	return res;
}

/*
 * Initialize arguments for TEST/LOCK/UNLOCK/CANCEL calls
 */
static void nlmclnt_setlockargs(struct nlm_rqst *req, struct file_lock *fl)
{
	struct lockd_args *argp = &req->a_args;
	struct lockd_lock *lock = &argp->lock;
	char *nodename = req->a_host->h_rpcclnt->cl_nodename;

	nlmclnt_next_cookie(&argp->cookie);
	memcpy(&lock->fh, NFS_FH(file_inode(fl->c.flc_file)),
	       sizeof(struct nfs_fh));
	lock->caller  = nodename;
	lock->oh.data = req->a_owner;
	lock->oh.len  = snprintf(req->a_owner, sizeof(req->a_owner), "%u@%s",
				(unsigned int)fl->fl_u.nfs_fl.owner->pid,
				nodename);
	lock->svid = fl->fl_u.nfs_fl.owner->pid;
	lock->fl.fl_start = fl->fl_start;
	lock->fl.fl_end = fl->fl_end;
	lock->fl.c.flc_type = fl->c.flc_type;
}

static void nlmclnt_release_lockargs(struct nlm_rqst *req)
{
	WARN_ON_ONCE(req->a_args.lock.fl.fl_ops != NULL);
}

/**
 * nlmclnt_proc - Perform a single client-side lock request
 * @host: address of a valid nlm_host context representing the NLM server
 * @cmd: fcntl-style file lock operation to perform
 * @fl: address of arguments for the lock operation
 * @data: address of data to be sent to callback operations
 *
 */
int nlmclnt_proc(struct nlm_host *host, int cmd, struct file_lock *fl, void *data)
{
	struct nlm_rqst		*call;
	int			status;
	const struct nlmclnt_operations *nlmclnt_ops = host->h_nlmclnt_ops;

	call = nlm_alloc_call(host);
	if (call == NULL)
		return -ENOMEM;

	if (nlmclnt_ops && nlmclnt_ops->nlmclnt_alloc_call)
		nlmclnt_ops->nlmclnt_alloc_call(data);

	nlmclnt_locks_init_private(fl, host);
	if (!fl->fl_u.nfs_fl.owner) {
		/* lockowner allocation has failed */
		nlmclnt_release_call(call);
		return -ENOMEM;
	}
	/* Set up the argument struct */
	nlmclnt_setlockargs(call, fl);
	call->a_callback_data = data;

	if (IS_SETLK(cmd) || IS_SETLKW(cmd)) {
		if (fl->c.flc_type != F_UNLCK) {
			call->a_args.block = IS_SETLKW(cmd) ? 1 : 0;
			status = nlmclnt_lock(call, fl);
		} else
			status = nlmclnt_unlock(call, fl);
	} else if (IS_GETLK(cmd))
		status = nlmclnt_test(call, fl);
	else
		status = -EINVAL;
	fl->fl_ops->fl_release_private(fl);
	fl->fl_ops = NULL;

	dprintk("lockd: clnt proc returns %d\n", status);
	return status;
}

Annotation

Implementation Notes