Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f8120480 authored by Marc Eshel's avatar Marc Eshel Committed by J. Bruce Fields
Browse files

lockd: always preallocate block in nlmsvc_lock()



Normally we could skip ever having to allocate a block in the case where
the client asks for a non-blocking lock, or asks for a blocking lock that
succeeds immediately.

However we're going to want to always look up a block first in order to
check whether we're revisiting a deferred lock call, and to be prepared to
handle the case where the filesystem returns -EINPROGRESS--in that case we
want to make sure the lock we've given the filesystem is the one embedded
in the block that we'll use to track the deferred request.

Signed-off-by: default avatarMarc Eshel <eshel@almaden.ibm.com>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 5ea0d750
Loading
Loading
Loading
Loading
+11 −23
Original line number Diff line number Diff line
@@ -365,7 +365,7 @@ __be32
nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
			struct nlm_lock *lock, int wait, struct nlm_cookie *cookie)
{
	struct nlm_block	*block, *newblock = NULL;
	struct nlm_block	*block = NULL;
	int			error;
	__be32			ret;

@@ -378,17 +378,20 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
				wait);


	lock->fl.fl_flags &= ~FL_SLEEP;
again:
	/* Lock file against concurrent access */
	mutex_lock(&file->f_mutex);
	/* Get existing block (in case client is busy-waiting) */
	/* Get existing block (in case client is busy-waiting)
	 * or create new block
	 */
	block = nlmsvc_lookup_block(file, lock);
	if (block == NULL) {
		if (newblock != NULL)
			lock = &newblock->b_call->a_args.lock;
	} else
		block = nlmsvc_create_block(rqstp, file, lock, cookie);
		ret = nlm_lck_denied_nolocks;
		if (block == NULL)
			goto out;
		lock = &block->b_call->a_args.lock;
	} else
		lock->fl.fl_flags &= ~FL_SLEEP;

	error = posix_lock_file(file->f_file, &lock->fl, NULL);
	lock->fl.fl_flags &= ~FL_SLEEP;
@@ -414,26 +417,11 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
		goto out;

	ret = nlm_lck_blocked;
	if (block != NULL)
		goto out;

	/* If we don't have a block, create and initialize it. Then
	 * retry because we may have slept in kmalloc. */
	/* We have to release f_mutex as nlmsvc_create_block may try to
	 * to claim it while doing host garbage collection */
	if (newblock == NULL) {
		mutex_unlock(&file->f_mutex);
		dprintk("lockd: blocking on this lock (allocating).\n");
		if (!(newblock = nlmsvc_create_block(rqstp, file, lock, cookie)))
			return nlm_lck_denied_nolocks;
		goto again;
	}

	/* Append to list of blocked */
	nlmsvc_insert_block(newblock, NLM_NEVER);
	nlmsvc_insert_block(block, NLM_NEVER);
out:
	mutex_unlock(&file->f_mutex);
	nlmsvc_release_block(newblock);
	nlmsvc_release_block(block);
	dprintk("lockd: nlmsvc_lock returned %u\n", ret);
	return ret;