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

Commit b7e6b869 authored by Oleg Drokin's avatar Oleg Drokin Committed by J. Bruce Fields
Browse files

lockd: fix reference count leaks in async locking case



In a number of places where we wish only to translate nlm_drop_reply to
rpc_drop_reply errors we instead return early with rpc_drop_reply,
skipping some important end-of-function cleanup.

This results in reference count leaks when lockd is doing posix locking
on GFS2.

Signed-off-by: default avatarOleg Drokin <green@linuxhacker.ru>
Signed-off-by: default avatarJ. Bruce Fields <bfields@citi.umich.edu>
parent 404ec117
Loading
Loading
Loading
Loading
+12 −8
Original line number Original line Diff line number Diff line
@@ -84,6 +84,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
{
{
	struct nlm_host	*host;
	struct nlm_host	*host;
	struct nlm_file	*file;
	struct nlm_file	*file;
	int rc = rpc_success;


	dprintk("lockd: TEST4        called\n");
	dprintk("lockd: TEST4        called\n");
	resp->cookie = argp->cookie;
	resp->cookie = argp->cookie;
@@ -91,7 +92,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
	/* Don't accept test requests during grace period */
	/* Don't accept test requests during grace period */
	if (nlmsvc_grace_period) {
	if (nlmsvc_grace_period) {
		resp->status = nlm_lck_denied_grace_period;
		resp->status = nlm_lck_denied_grace_period;
		return rpc_success;
		return rc;
	}
	}


	/* Obtain client and file */
	/* Obtain client and file */
@@ -101,12 +102,13 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
	/* Now check for conflicting locks */
	/* Now check for conflicting locks */
	resp->status = nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie);
	resp->status = nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie);
	if (resp->status == nlm_drop_reply)
	if (resp->status == nlm_drop_reply)
		return rpc_drop_reply;
		rc = rpc_drop_reply;

	else
		dprintk("lockd: TEST4        status %d\n", ntohl(resp->status));
		dprintk("lockd: TEST4        status %d\n", ntohl(resp->status));

	nlm_release_host(host);
	nlm_release_host(host);
	nlm_release_file(file);
	nlm_release_file(file);
	return rpc_success;
	return rc;
}
}


static __be32
static __be32
@@ -115,6 +117,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
{
{
	struct nlm_host	*host;
	struct nlm_host	*host;
	struct nlm_file	*file;
	struct nlm_file	*file;
	int rc = rpc_success;


	dprintk("lockd: LOCK          called\n");
	dprintk("lockd: LOCK          called\n");


@@ -123,7 +126,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
	/* Don't accept new lock requests during grace period */
	/* Don't accept new lock requests during grace period */
	if (nlmsvc_grace_period && !argp->reclaim) {
	if (nlmsvc_grace_period && !argp->reclaim) {
		resp->status = nlm_lck_denied_grace_period;
		resp->status = nlm_lck_denied_grace_period;
		return rpc_success;
		return rc;
	}
	}


	/* Obtain client and file */
	/* Obtain client and file */
@@ -146,12 +149,13 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
	resp->status = nlmsvc_lock(rqstp, file, &argp->lock,
	resp->status = nlmsvc_lock(rqstp, file, &argp->lock,
					argp->block, &argp->cookie);
					argp->block, &argp->cookie);
	if (resp->status == nlm_drop_reply)
	if (resp->status == nlm_drop_reply)
		return rpc_drop_reply;
		rc = rpc_drop_reply;

	else
		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));
		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));

	nlm_release_host(host);
	nlm_release_host(host);
	nlm_release_file(file);
	nlm_release_file(file);
	return rpc_success;
	return rc;
}
}


static __be32
static __be32
+13 −9
Original line number Original line Diff line number Diff line
@@ -113,6 +113,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
{
{
	struct nlm_host	*host;
	struct nlm_host	*host;
	struct nlm_file	*file;
	struct nlm_file	*file;
	int rc = rpc_success;


	dprintk("lockd: TEST          called\n");
	dprintk("lockd: TEST          called\n");
	resp->cookie = argp->cookie;
	resp->cookie = argp->cookie;
@@ -120,7 +121,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
	/* Don't accept test requests during grace period */
	/* Don't accept test requests during grace period */
	if (nlmsvc_grace_period) {
	if (nlmsvc_grace_period) {
		resp->status = nlm_lck_denied_grace_period;
		resp->status = nlm_lck_denied_grace_period;
		return rpc_success;
		return rc;
	}
	}


	/* Obtain client and file */
	/* Obtain client and file */
@@ -130,13 +131,14 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
	/* Now check for conflicting locks */
	/* Now check for conflicting locks */
	resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie));
	resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie));
	if (resp->status == nlm_drop_reply)
	if (resp->status == nlm_drop_reply)
		return rpc_drop_reply;
		rc = rpc_drop_reply;

	else
		dprintk("lockd: TEST          status %d vers %d\n",
		dprintk("lockd: TEST          status %d vers %d\n",
			ntohl(resp->status), rqstp->rq_vers);
			ntohl(resp->status), rqstp->rq_vers);

	nlm_release_host(host);
	nlm_release_host(host);
	nlm_release_file(file);
	nlm_release_file(file);
	return rpc_success;
	return rc;
}
}


static __be32
static __be32
@@ -145,6 +147,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
{
{
	struct nlm_host	*host;
	struct nlm_host	*host;
	struct nlm_file	*file;
	struct nlm_file	*file;
	int rc = rpc_success;


	dprintk("lockd: LOCK          called\n");
	dprintk("lockd: LOCK          called\n");


@@ -153,7 +156,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
	/* Don't accept new lock requests during grace period */
	/* Don't accept new lock requests during grace period */
	if (nlmsvc_grace_period && !argp->reclaim) {
	if (nlmsvc_grace_period && !argp->reclaim) {
		resp->status = nlm_lck_denied_grace_period;
		resp->status = nlm_lck_denied_grace_period;
		return rpc_success;
		return rc;
	}
	}


	/* Obtain client and file */
	/* Obtain client and file */
@@ -176,12 +179,13 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp,
	resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock,
	resp->status = cast_status(nlmsvc_lock(rqstp, file, &argp->lock,
					       argp->block, &argp->cookie));
					       argp->block, &argp->cookie));
	if (resp->status == nlm_drop_reply)
	if (resp->status == nlm_drop_reply)
		return rpc_drop_reply;
		rc = rpc_drop_reply;

	else
		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));
		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));

	nlm_release_host(host);
	nlm_release_host(host);
	nlm_release_file(file);
	nlm_release_file(file);
	return rpc_success;
	return rc;
}
}


static __be32
static __be32