All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/5] NLM fl_pid fixup
@ 2019-05-23 14:45 Benjamin Coddington
  2019-05-23 14:45 ` [PATCH 1/5] lockd: prepare nlm_lockowner for use by the server Benjamin Coddington
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Benjamin Coddington @ 2019-05-23 14:45 UTC (permalink / raw)
  To: J . Bruce Fields, jlayton; +Cc: linux-nfs

This series aims to correct the fl_pid value for locks held by the NLM
server, or lockd.  It applies onto the revert of the previous attempt to fix
this problem sent ealier this week: '[PATCH] Revert "lockd: Show pid of
lockd for remote locks"'.

The problem with the earlier attempt was that we discarded the svid, and so
we couldn't distinguish remote lockowners on each host.  It is necessary to
turn the svid and host into a distinct owner.

We can take a page from the NLM client and make an allocation to track the
svid and host together, which is what we do here.  The mechanisms to do so
aren't quite similar enough to generalize, but I did share the nlm_lockowner
structure.  There is one field unsed on the server: nlm_lockowner.owner.

It turns out that the LTP's testcases/network/nfsv4/locks/locktests.c was
useful for testing this, as it coordinates locking tests amongst NFS
clients.

Changes on:
	v2 - Fixed typos in commit log messages, and whitespace.

Benjamin Coddington (5):
  lockd: prepare nlm_lockowner for use by the server
  lockd: Convert NLM service fl_owner to nlm_lockowner
  lockd: Remove lm_compare_owner and lm_owner_key
  lockd: Show pid of lockd for remote locks
  locks: Cleanup lm_compare_owner and lm_owner_key

 Documentation/filesystems/Locking |  14 ----
 fs/lockd/clntproc.c               |  21 +++---
 fs/lockd/svc4proc.c               |  14 +++-
 fs/lockd/svclock.c                | 118 +++++++++++++++++++++++++-----
 fs/lockd/svcproc.c                |  14 +++-
 fs/lockd/svcsubs.c                |   2 +-
 fs/lockd/xdr.c                    |   3 -
 fs/lockd/xdr4.c                   |   3 -
 fs/locks.c                        |   5 --
 include/linux/fs.h                |   2 -
 include/linux/lockd/lockd.h       |   2 +
 11 files changed, 138 insertions(+), 60 deletions(-)

-- 
2.20.1


^ permalink raw reply	[flat|nested] 8+ messages in thread

* [PATCH 1/5] lockd: prepare nlm_lockowner for use by the server
  2019-05-23 14:45 [PATCH v2 0/5] NLM fl_pid fixup Benjamin Coddington
@ 2019-05-23 14:45 ` Benjamin Coddington
  2019-05-23 14:45 ` [PATCH 2/5] lockd: Convert NLM service fl_owner to nlm_lockowner Benjamin Coddington
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Benjamin Coddington @ 2019-05-23 14:45 UTC (permalink / raw)
  To: J . Bruce Fields, jlayton; +Cc: linux-nfs

The nlm_lockowner structure that the client uses to track locks is
generally useful to the server as well.  Very similar functions to handle
allocation and tracking of the nlm_lockowner will follow. Rename the client
functions for clarity.

Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
---
 fs/lockd/clntproc.c | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c
index d9c32d1a20c0..529f0be547bc 100644
--- a/fs/lockd/clntproc.c
+++ b/fs/lockd/clntproc.c
@@ -46,13 +46,14 @@ void nlmclnt_next_cookie(struct nlm_cookie *c)
 	c->len=4;
 }
 
-static struct nlm_lockowner *nlm_get_lockowner(struct nlm_lockowner *lockowner)
+static struct nlm_lockowner *
+nlmclnt_get_lockowner(struct nlm_lockowner *lockowner)
 {
 	refcount_inc(&lockowner->count);
 	return lockowner;
 }
 
-static void nlm_put_lockowner(struct nlm_lockowner *lockowner)
+void nlmclnt_put_lockowner(struct nlm_lockowner *lockowner)
 {
 	if (!refcount_dec_and_lock(&lockowner->count, &lockowner->host->h_lock))
 		return;
@@ -81,28 +82,28 @@ static inline uint32_t __nlm_alloc_pid(struct nlm_host *host)
 	return res;
 }
 
-static struct nlm_lockowner *__nlm_find_lockowner(struct nlm_host *host, fl_owner_t owner)
+static struct nlm_lockowner *__nlmclnt_find_lockowner(struct nlm_host *host, fl_owner_t owner)
 {
 	struct nlm_lockowner *lockowner;
 	list_for_each_entry(lockowner, &host->h_lockowners, list) {
 		if (lockowner->owner != owner)
 			continue;
-		return nlm_get_lockowner(lockowner);
+		return nlmclnt_get_lockowner(lockowner);
 	}
 	return NULL;
 }
 
-static struct nlm_lockowner *nlm_find_lockowner(struct nlm_host *host, fl_owner_t owner)
+static struct nlm_lockowner *nlmclnt_find_lockowner(struct nlm_host *host, fl_owner_t owner)
 {
 	struct nlm_lockowner *res, *new = NULL;
 
 	spin_lock(&host->h_lock);
-	res = __nlm_find_lockowner(host, owner);
+	res = __nlmclnt_find_lockowner(host, owner);
 	if (res == NULL) {
 		spin_unlock(&host->h_lock);
 		new = kmalloc(sizeof(*new), GFP_KERNEL);
 		spin_lock(&host->h_lock);
-		res = __nlm_find_lockowner(host, owner);
+		res = __nlmclnt_find_lockowner(host, owner);
 		if (res == NULL && new != NULL) {
 			res = new;
 			refcount_set(&new->count, 1);
@@ -456,7 +457,7 @@ static void nlmclnt_locks_copy_lock(struct file_lock *new, struct file_lock *fl)
 {
 	spin_lock(&fl->fl_u.nfs_fl.owner->host->h_lock);
 	new->fl_u.nfs_fl.state = fl->fl_u.nfs_fl.state;
-	new->fl_u.nfs_fl.owner = nlm_get_lockowner(fl->fl_u.nfs_fl.owner);
+	new->fl_u.nfs_fl.owner = nlmclnt_get_lockowner(fl->fl_u.nfs_fl.owner);
 	list_add_tail(&new->fl_u.nfs_fl.list, &fl->fl_u.nfs_fl.owner->host->h_granted);
 	spin_unlock(&fl->fl_u.nfs_fl.owner->host->h_lock);
 }
@@ -466,7 +467,7 @@ static void nlmclnt_locks_release_private(struct file_lock *fl)
 	spin_lock(&fl->fl_u.nfs_fl.owner->host->h_lock);
 	list_del(&fl->fl_u.nfs_fl.list);
 	spin_unlock(&fl->fl_u.nfs_fl.owner->host->h_lock);
-	nlm_put_lockowner(fl->fl_u.nfs_fl.owner);
+	nlmclnt_put_lockowner(fl->fl_u.nfs_fl.owner);
 }
 
 static const struct file_lock_operations nlmclnt_lock_ops = {
@@ -477,7 +478,7 @@ static const struct file_lock_operations nlmclnt_lock_ops = {
 static void nlmclnt_locks_init_private(struct file_lock *fl, struct nlm_host *host)
 {
 	fl->fl_u.nfs_fl.state = 0;
-	fl->fl_u.nfs_fl.owner = nlm_find_lockowner(host, fl->fl_owner);
+	fl->fl_u.nfs_fl.owner = nlmclnt_find_lockowner(host, fl->fl_owner);
 	INIT_LIST_HEAD(&fl->fl_u.nfs_fl.list);
 	fl->fl_ops = &nlmclnt_lock_ops;
 }
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 2/5] lockd: Convert NLM service fl_owner to nlm_lockowner
  2019-05-23 14:45 [PATCH v2 0/5] NLM fl_pid fixup Benjamin Coddington
  2019-05-23 14:45 ` [PATCH 1/5] lockd: prepare nlm_lockowner for use by the server Benjamin Coddington
@ 2019-05-23 14:45 ` Benjamin Coddington
  2019-05-23 14:45 ` [PATCH 3/5] lockd: Remove lm_compare_owner and lm_owner_key Benjamin Coddington
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Benjamin Coddington @ 2019-05-23 14:45 UTC (permalink / raw)
  To: J . Bruce Fields, jlayton; +Cc: linux-nfs

Do as the NLM client: allocate and track a struct nlm_lockowner for use as
the fl_owner for locks created by the NLM sever.  This allows us to keep
the svid within this structure for matching locks, and will allow us to
track the pid of lockd in a future patch.  It should also allow easier
reference of the nlm_host in conflicting locks, and simplify lock hashing
and comparison.

Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
---
 fs/lockd/svc4proc.c         | 13 ++++-
 fs/lockd/svclock.c          | 96 +++++++++++++++++++++++++++++++++++++
 fs/lockd/svcproc.c          | 13 ++++-
 fs/lockd/svcsubs.c          |  2 +-
 fs/lockd/xdr.c              |  1 -
 fs/lockd/xdr4.c             |  1 -
 include/linux/lockd/lockd.h |  2 +
 7 files changed, 123 insertions(+), 5 deletions(-)

diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 1bddf70d9656..90d328d61933 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -46,8 +46,13 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
 
 		/* Set up the missing parts of the file_lock structure */
 		lock->fl.fl_file  = file->f_file;
-		lock->fl.fl_owner = (fl_owner_t) host;
 		lock->fl.fl_lmops = &nlmsvc_lock_operations;
+		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
+		if (!lock->fl.fl_owner) {
+			/* lockowner allocation has failed */
+			nlmsvc_release_host(host);
+			return -ENOMEM;
+		}
 	}
 
 	return 0;
@@ -94,6 +99,7 @@ __nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp)
 	else
 		dprintk("lockd: TEST4        status %d\n", ntohl(resp->status));
 
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rc;
@@ -142,6 +148,7 @@ __nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
 	else
 		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));
 
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rc;
@@ -178,6 +185,7 @@ __nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
 	resp->status = nlmsvc_cancel_blocked(SVC_NET(rqstp), file, &argp->lock);
 
 	dprintk("lockd: CANCEL        status %d\n", ntohl(resp->status));
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rpc_success;
@@ -217,6 +225,7 @@ __nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp)
 	resp->status = nlmsvc_unlock(SVC_NET(rqstp), file, &argp->lock);
 
 	dprintk("lockd: UNLOCK        status %d\n", ntohl(resp->status));
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rpc_success;
@@ -365,6 +374,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp)
 	resp->status = nlmsvc_share_file(host, file, argp);
 
 	dprintk("lockd: SHARE         status %d\n", ntohl(resp->status));
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rpc_success;
@@ -399,6 +409,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp)
 	resp->status = nlmsvc_unshare_file(host, file, argp);
 
 	dprintk("lockd: UNSHARE       status %d\n", ntohl(resp->status));
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rpc_success;
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index ea719cdd6a36..34c6ee85274e 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -332,6 +332,93 @@ void nlmsvc_traverse_blocks(struct nlm_host *host,
 	mutex_unlock(&file->f_mutex);
 }
 
+static struct nlm_lockowner *
+nlmsvc_get_lockowner(struct nlm_lockowner *lockowner)
+{
+	refcount_inc(&lockowner->count);
+	return lockowner;
+}
+
+static void nlmsvc_put_lockowner(struct nlm_lockowner *lockowner)
+{
+	if (!refcount_dec_and_lock(&lockowner->count, &lockowner->host->h_lock))
+		return;
+	list_del(&lockowner->list);
+	spin_unlock(&lockowner->host->h_lock);
+	nlmsvc_release_host(lockowner->host);
+	kfree(lockowner);
+}
+
+static struct nlm_lockowner *__nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid)
+{
+	struct nlm_lockowner *lockowner;
+	list_for_each_entry(lockowner, &host->h_lockowners, list) {
+		if (lockowner->pid != pid)
+			continue;
+		return nlmsvc_get_lockowner(lockowner);
+	}
+	return NULL;
+}
+
+static struct nlm_lockowner *nlmsvc_find_lockowner(struct nlm_host *host, pid_t pid)
+{
+	struct nlm_lockowner *res, *new = NULL;
+
+	spin_lock(&host->h_lock);
+	res = __nlmsvc_find_lockowner(host, pid);
+
+	if (res == NULL) {
+		spin_unlock(&host->h_lock);
+		new = kmalloc(sizeof(*res), GFP_KERNEL);
+		spin_lock(&host->h_lock);
+		res = __nlmsvc_find_lockowner(host, pid);
+		if (res == NULL && new != NULL) {
+			res = new;
+			/* fs/locks.c will manage the refcount through lock_ops */
+			refcount_set(&new->count, 1);
+			new->pid = pid;
+			new->host = nlm_get_host(host);
+			list_add(&new->list, &host->h_lockowners);
+			new = NULL;
+		}
+	}
+
+	spin_unlock(&host->h_lock);
+	kfree(new);
+	return res;
+}
+
+void
+nlmsvc_release_lockowner(struct nlm_lock *lock)
+{
+	if (lock->fl.fl_owner)
+		nlmsvc_put_lockowner(lock->fl.fl_owner);
+}
+
+static void nlmsvc_locks_copy_lock(struct file_lock *new, struct file_lock *fl)
+{
+	struct nlm_lockowner *nlm_lo = (struct nlm_lockowner *)fl->fl_owner;
+	new->fl_owner = nlmsvc_get_lockowner(nlm_lo);
+}
+
+static void nlmsvc_locks_release_private(struct file_lock *fl)
+{
+	nlmsvc_put_lockowner((struct nlm_lockowner *)fl->fl_owner);
+}
+
+const struct file_lock_operations nlmsvc_lock_ops = {
+	.fl_copy_lock = nlmsvc_locks_copy_lock,
+	.fl_release_private = nlmsvc_locks_release_private,
+};
+
+void nlmsvc_locks_init_private(struct file_lock *fl, struct nlm_host *host,
+						pid_t pid)
+{
+	fl->fl_owner = nlmsvc_find_lockowner(host, pid);
+	if (fl->fl_owner != NULL)
+		fl->fl_ops = &nlmsvc_lock_ops;
+}
+
 /*
  * Initialize arguments for GRANTED call. The nlm_rqst structure
  * has been cleared already.
@@ -509,6 +596,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 {
 	int			error;
 	__be32			ret;
+	struct nlm_lockowner	*test_owner;
 
 	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
 				locks_inode(file->f_file)->i_sb->s_id,
@@ -522,6 +610,9 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 		goto out;
 	}
 
+	/* If there's a conflicting lock, remember to clean up the test lock */
+	test_owner = (struct nlm_lockowner *)lock->fl.fl_owner;
+
 	error = vfs_test_lock(file->f_file, &lock->fl);
 	if (error) {
 		/* We can't currently deal with deferred test requests */
@@ -548,6 +639,11 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 	conflock->fl.fl_start = lock->fl.fl_start;
 	conflock->fl.fl_end = lock->fl.fl_end;
 	locks_release_private(&lock->fl);
+
+	/* Clean up the test lock */
+	lock->fl.fl_owner = NULL;
+	nlmsvc_put_lockowner(test_owner);
+
 	ret = nlm_lck_denied;
 out:
 	return ret;
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index ea77c66d3cc3..665b7adad3c4 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -76,8 +76,13 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
 
 		/* Set up the missing parts of the file_lock structure */
 		lock->fl.fl_file  = file->f_file;
-		lock->fl.fl_owner = (fl_owner_t) host;
 		lock->fl.fl_lmops = &nlmsvc_lock_operations;
+		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
+		if (!lock->fl.fl_owner) {
+			/* lockowner allocation has failed */
+			nlmsvc_release_host(host);
+			return -ENOMEM;
+		}
 	}
 
 	return 0;
@@ -125,6 +130,7 @@ __nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_res *resp)
 		dprintk("lockd: TEST          status %d vers %d\n",
 			ntohl(resp->status), rqstp->rq_vers);
 
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rc;
@@ -173,6 +179,7 @@ __nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_res *resp)
 	else
 		dprintk("lockd: LOCK         status %d\n", ntohl(resp->status));
 
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rc;
@@ -210,6 +217,7 @@ __nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_res *resp)
 	resp->status = cast_status(nlmsvc_cancel_blocked(net, file, &argp->lock));
 
 	dprintk("lockd: CANCEL        status %d\n", ntohl(resp->status));
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rpc_success;
@@ -250,6 +258,7 @@ __nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_res *resp)
 	resp->status = cast_status(nlmsvc_unlock(net, file, &argp->lock));
 
 	dprintk("lockd: UNLOCK        status %d\n", ntohl(resp->status));
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rpc_success;
@@ -408,6 +417,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp)
 	resp->status = cast_status(nlmsvc_share_file(host, file, argp));
 
 	dprintk("lockd: SHARE         status %d\n", ntohl(resp->status));
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rpc_success;
@@ -442,6 +452,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp)
 	resp->status = cast_status(nlmsvc_unshare_file(host, file, argp));
 
 	dprintk("lockd: UNSHARE       status %d\n", ntohl(resp->status));
+	nlmsvc_release_lockowner(&argp->lock);
 	nlmsvc_release_host(host);
 	nlm_release_file(file);
 	return rpc_success;
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index 899360ba3b84..4ee04b725042 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -179,7 +179,7 @@ nlm_traverse_locks(struct nlm_host *host, struct nlm_file *file,
 		/* update current lock count */
 		file->f_locks++;
 
-		lockhost = (struct nlm_host *) fl->fl_owner;
+		lockhost = ((struct nlm_lockowner *)fl->fl_owner)->host;
 		if (match(lockhost, host)) {
 			struct file_lock lock = *fl;
 
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index 7147e4aebecc..ec717ae41ee3 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -126,7 +126,6 @@ nlm_decode_lock(__be32 *p, struct nlm_lock *lock)
 	lock->svid  = ntohl(*p++);
 
 	locks_init_lock(fl);
-	fl->fl_owner = current->files;
 	fl->fl_pid   = (pid_t)lock->svid;
 	fl->fl_flags = FL_POSIX;
 	fl->fl_type  = F_RDLCK;		/* as good as anything else */
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index 7ed9edf9aed4..45741adfe041 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -118,7 +118,6 @@ nlm4_decode_lock(__be32 *p, struct nlm_lock *lock)
 	lock->svid  = ntohl(*p++);
 
 	locks_init_lock(fl);
-	fl->fl_owner = current->files;
 	fl->fl_pid   = (pid_t)lock->svid;
 	fl->fl_flags = FL_POSIX;
 	fl->fl_type  = F_RDLCK;		/* as good as anything else */
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index c9b422dde542..d294dde9e546 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -282,6 +282,7 @@ void		  nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
 					nlm_host_match_fn_t match);
 void		  nlmsvc_grant_reply(struct nlm_cookie *, __be32);
 void		  nlmsvc_release_call(struct nlm_rqst *);
+void		  nlmsvc_locks_init_private(struct file_lock *, struct nlm_host *, pid_t);
 
 /*
  * File handling for the server personality
@@ -289,6 +290,7 @@ void		  nlmsvc_release_call(struct nlm_rqst *);
 __be32		  nlm_lookup_file(struct svc_rqst *, struct nlm_file **,
 					struct nfs_fh *);
 void		  nlm_release_file(struct nlm_file *);
+void		  nlmsvc_release_lockowner(struct nlm_lock *);
 void		  nlmsvc_mark_resources(struct net *);
 void		  nlmsvc_free_host_resources(struct nlm_host *);
 void		  nlmsvc_invalidate_all(void);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 3/5] lockd: Remove lm_compare_owner and lm_owner_key
  2019-05-23 14:45 [PATCH v2 0/5] NLM fl_pid fixup Benjamin Coddington
  2019-05-23 14:45 ` [PATCH 1/5] lockd: prepare nlm_lockowner for use by the server Benjamin Coddington
  2019-05-23 14:45 ` [PATCH 2/5] lockd: Convert NLM service fl_owner to nlm_lockowner Benjamin Coddington
@ 2019-05-23 14:45 ` Benjamin Coddington
  2019-05-23 14:45 ` [PATCH 4/5] lockd: Show pid of lockd for remote locks Benjamin Coddington
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Benjamin Coddington @ 2019-05-23 14:45 UTC (permalink / raw)
  To: J . Bruce Fields, jlayton; +Cc: linux-nfs

Now that the NLM server allocates an nlm_lockowner for fl_owner, there's
no need for special hashing or comparison.

Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
---
 fs/lockd/svclock.c | 18 ------------------
 1 file changed, 18 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 34c6ee85274e..637c50687fd7 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -788,25 +788,7 @@ nlmsvc_notify_blocked(struct file_lock *fl)
 	printk(KERN_WARNING "lockd: notification for unknown block!\n");
 }
 
-static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
-{
-	return fl1->fl_owner == fl2->fl_owner && fl1->fl_pid == fl2->fl_pid;
-}
-
-/*
- * Since NLM uses two "keys" for tracking locks, we need to hash them down
- * to one for the blocked_hash. Here, we're just xor'ing the host address
- * with the pid in order to create a key value for picking a hash bucket.
- */
-static unsigned long
-nlmsvc_owner_key(struct file_lock *fl)
-{
-	return (unsigned long)fl->fl_owner ^ (unsigned long)fl->fl_pid;
-}
-
 const struct lock_manager_operations nlmsvc_lock_operations = {
-	.lm_compare_owner = nlmsvc_same_owner,
-	.lm_owner_key = nlmsvc_owner_key,
 	.lm_notify = nlmsvc_notify_blocked,
 	.lm_grant = nlmsvc_grant_deferred,
 };
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 4/5] lockd: Show pid of lockd for remote locks
  2019-05-23 14:45 [PATCH v2 0/5] NLM fl_pid fixup Benjamin Coddington
                   ` (2 preceding siblings ...)
  2019-05-23 14:45 ` [PATCH 3/5] lockd: Remove lm_compare_owner and lm_owner_key Benjamin Coddington
@ 2019-05-23 14:45 ` Benjamin Coddington
  2019-05-23 14:45 ` [PATCH 5/5] locks: Cleanup lm_compare_owner and lm_owner_key Benjamin Coddington
  2019-05-24 16:47 ` [PATCH v2 0/5] NLM fl_pid fixup J. Bruce Fields
  5 siblings, 0 replies; 8+ messages in thread
From: Benjamin Coddington @ 2019-05-23 14:45 UTC (permalink / raw)
  To: J . Bruce Fields, jlayton; +Cc: linux-nfs

Use the pid of lockd instead of the remote lock's svid for the fl_pid for
local POSIX locks.  This allows proper enumeration of which local process
owns which lock.  The svid is meaningless to local lock readers.

Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
---
 fs/lockd/svc4proc.c | 1 +
 fs/lockd/svclock.c  | 4 ++--
 fs/lockd/svcproc.c  | 1 +
 fs/lockd/xdr.c      | 2 --
 fs/lockd/xdr4.c     | 2 --
 5 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index 90d328d61933..54c11b0863d1 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -46,6 +46,7 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
 
 		/* Set up the missing parts of the file_lock structure */
 		lock->fl.fl_file  = file->f_file;
+		lock->fl.fl_pid = current->tgid;
 		lock->fl.fl_lmops = &nlmsvc_lock_operations;
 		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
 		if (!lock->fl.fl_owner) {
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 637c50687fd7..5f9f19b81754 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -432,7 +432,7 @@ static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock)
 
 	/* set default data area */
 	call->a_args.lock.oh.data = call->a_owner;
-	call->a_args.lock.svid = lock->fl.fl_pid;
+	call->a_args.lock.svid = ((struct nlm_lockowner *)lock->fl.fl_owner)->pid;
 
 	if (lock->oh.len > NLMCLNT_OHSIZE) {
 		void *data = kmalloc(lock->oh.len, GFP_KERNEL);
@@ -634,7 +634,7 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 	conflock->caller = "somehost";	/* FIXME */
 	conflock->len = strlen(conflock->caller);
 	conflock->oh.len = 0;		/* don't return OH info */
-	conflock->svid = lock->fl.fl_pid;
+	conflock->svid = ((struct nlm_lockowner *)lock->fl.fl_owner)->pid;
 	conflock->fl.fl_type = lock->fl.fl_type;
 	conflock->fl.fl_start = lock->fl.fl_start;
 	conflock->fl.fl_end = lock->fl.fl_end;
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 665b7adad3c4..a24e6d942f89 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -76,6 +76,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp,
 
 		/* Set up the missing parts of the file_lock structure */
 		lock->fl.fl_file  = file->f_file;
+		lock->fl.fl_pid = current->tgid;
 		lock->fl.fl_lmops = &nlmsvc_lock_operations;
 		nlmsvc_locks_init_private(&lock->fl, host, (pid_t)lock->svid);
 		if (!lock->fl.fl_owner) {
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c
index ec717ae41ee3..982629f7b120 100644
--- a/fs/lockd/xdr.c
+++ b/fs/lockd/xdr.c
@@ -126,7 +126,6 @@ nlm_decode_lock(__be32 *p, struct nlm_lock *lock)
 	lock->svid  = ntohl(*p++);
 
 	locks_init_lock(fl);
-	fl->fl_pid   = (pid_t)lock->svid;
 	fl->fl_flags = FL_POSIX;
 	fl->fl_type  = F_RDLCK;		/* as good as anything else */
 	start = ntohl(*p++);
@@ -268,7 +267,6 @@ nlmsvc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p)
 	memset(lock, 0, sizeof(*lock));
 	locks_init_lock(&lock->fl);
 	lock->svid = ~(u32) 0;
-	lock->fl.fl_pid = (pid_t)lock->svid;
 
 	if (!(p = nlm_decode_cookie(p, &argp->cookie))
 	 || !(p = xdr_decode_string_inplace(p, &lock->caller,
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c
index 45741adfe041..5fa9f48a9dba 100644
--- a/fs/lockd/xdr4.c
+++ b/fs/lockd/xdr4.c
@@ -118,7 +118,6 @@ nlm4_decode_lock(__be32 *p, struct nlm_lock *lock)
 	lock->svid  = ntohl(*p++);
 
 	locks_init_lock(fl);
-	fl->fl_pid   = (pid_t)lock->svid;
 	fl->fl_flags = FL_POSIX;
 	fl->fl_type  = F_RDLCK;		/* as good as anything else */
 	p = xdr_decode_hyper(p, &start);
@@ -265,7 +264,6 @@ nlm4svc_decode_shareargs(struct svc_rqst *rqstp, __be32 *p)
 	memset(lock, 0, sizeof(*lock));
 	locks_init_lock(&lock->fl);
 	lock->svid = ~(u32) 0;
-	lock->fl.fl_pid = (pid_t)lock->svid;
 
 	if (!(p = nlm4_decode_cookie(p, &argp->cookie))
 	 || !(p = xdr_decode_string_inplace(p, &lock->caller,
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* [PATCH 5/5] locks: Cleanup lm_compare_owner and lm_owner_key
  2019-05-23 14:45 [PATCH v2 0/5] NLM fl_pid fixup Benjamin Coddington
                   ` (3 preceding siblings ...)
  2019-05-23 14:45 ` [PATCH 4/5] lockd: Show pid of lockd for remote locks Benjamin Coddington
@ 2019-05-23 14:45 ` Benjamin Coddington
  2019-05-24 16:47 ` [PATCH v2 0/5] NLM fl_pid fixup J. Bruce Fields
  5 siblings, 0 replies; 8+ messages in thread
From: Benjamin Coddington @ 2019-05-23 14:45 UTC (permalink / raw)
  To: J . Bruce Fields, jlayton; +Cc: linux-nfs

After the update to use nlm_lockowners for the NLM server, there are no
more users of lm_compare_owner and lm_owner_key.

Signed-off-by: Benjamin Coddington <bcodding@redhat.com>
---
 Documentation/filesystems/Locking | 14 --------------
 fs/locks.c                        |  5 -----
 include/linux/fs.h                |  2 --
 3 files changed, 21 deletions(-)

diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index dac435575384..204dd3ea36bb 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -361,8 +361,6 @@ so fl_release_private called on a lease should not block.
 
 ----------------------- lock_manager_operations ---------------------------
 prototypes:
-	int (*lm_compare_owner)(struct file_lock *, struct file_lock *);
-	unsigned long (*lm_owner_key)(struct file_lock *);
 	void (*lm_notify)(struct file_lock *);  /* unblock callback */
 	int (*lm_grant)(struct file_lock *, struct file_lock *, int);
 	void (*lm_break)(struct file_lock *); /* break_lease callback */
@@ -371,23 +369,11 @@ prototypes:
 locking rules:
 
 			inode->i_lock	blocked_lock_lock	may block
-lm_compare_owner:	yes[1]		maybe			no
-lm_owner_key		yes[1]		yes			no
 lm_notify:		yes		yes			no
 lm_grant:		no		no			no
 lm_break:		yes		no			no
 lm_change		yes		no			no
 
-[1]:	->lm_compare_owner and ->lm_owner_key are generally called with
-*an* inode->i_lock held. It may not be the i_lock of the inode
-associated with either file_lock argument! This is the case with deadlock
-detection, since the code has to chase down the owners of locks that may
-be entirely unrelated to the one on which the lock is being acquired.
-For deadlock detection however, the blocked_lock_lock is also held. The
-fact that these locks are held ensures that the file_locks do not
-disappear out from under you while doing the comparison or generating an
-owner key.
-
 --------------------------- buffer_head -----------------------------------
 prototypes:
 	void (*b_end_io)(struct buffer_head *bh, int uptodate);
diff --git a/fs/locks.c b/fs/locks.c
index 8af49f89ac2f..a647182496ee 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -657,9 +657,6 @@ static inline int locks_overlap(struct file_lock *fl1, struct file_lock *fl2)
  */
 static int posix_same_owner(struct file_lock *fl1, struct file_lock *fl2)
 {
-	if (fl1->fl_lmops && fl1->fl_lmops->lm_compare_owner)
-		return fl2->fl_lmops == fl1->fl_lmops &&
-			fl1->fl_lmops->lm_compare_owner(fl1, fl2);
 	return fl1->fl_owner == fl2->fl_owner;
 }
 
@@ -700,8 +697,6 @@ static void locks_delete_global_locks(struct file_lock *fl)
 static unsigned long
 posix_owner_key(struct file_lock *fl)
 {
-	if (fl->fl_lmops && fl->fl_lmops->lm_owner_key)
-		return fl->fl_lmops->lm_owner_key(fl);
 	return (unsigned long)fl->fl_owner;
 }
 
diff --git a/include/linux/fs.h b/include/linux/fs.h
index f7fdfe93e25d..0fa010bb7b6a 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1019,8 +1019,6 @@ struct file_lock_operations {
 };
 
 struct lock_manager_operations {
-	int (*lm_compare_owner)(struct file_lock *, struct file_lock *);
-	unsigned long (*lm_owner_key)(struct file_lock *);
 	fl_owner_t (*lm_get_owner)(fl_owner_t);
 	void (*lm_put_owner)(fl_owner_t);
 	void (*lm_notify)(struct file_lock *);	/* unblock callback */
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/5] NLM fl_pid fixup
  2019-05-23 14:45 [PATCH v2 0/5] NLM fl_pid fixup Benjamin Coddington
                   ` (4 preceding siblings ...)
  2019-05-23 14:45 ` [PATCH 5/5] locks: Cleanup lm_compare_owner and lm_owner_key Benjamin Coddington
@ 2019-05-24 16:47 ` J. Bruce Fields
  2019-05-25 11:09   ` Benjamin Coddington
  5 siblings, 1 reply; 8+ messages in thread
From: J. Bruce Fields @ 2019-05-24 16:47 UTC (permalink / raw)
  To: Benjamin Coddington; +Cc: J . Bruce Fields, jlayton, linux-nfs

On Thu, May 23, 2019 at 10:45:43AM -0400, Benjamin Coddington wrote:
> This series aims to correct the fl_pid value for locks held by the NLM
> server, or lockd.  It applies onto the revert of the previous attempt to fix
> this problem sent ealier this week: '[PATCH] Revert "lockd: Show pid of
> lockd for remote locks"'.
> 
> The problem with the earlier attempt was that we discarded the svid, and so
> we couldn't distinguish remote lockowners on each host.  It is necessary to
> turn the svid and host into a distinct owner.

So, to make sure I understand, we've got multiple ways to identify a
lock owner:

	- the svid, the pid of the client process: this gets returned to
	  the client in grant callbacks and (possibly to a different
	  client) in testd results.
	- the pid of the server's lockd process: this is what other
	  processes on the server see as the owner of locks held by nfs
	  clients.
	- the nlm_lockowner: a (nlm_host, svid) pair, used to actually
	  decide when locks conflict.

Makes sense to me.

I'll send your earlier revert to stable, then add this on top for the
5.3 merge window.  Sound OK?

--b.

> 
> We can take a page from the NLM client and make an allocation to track the
> svid and host together, which is what we do here.  The mechanisms to do so
> aren't quite similar enough to generalize, but I did share the nlm_lockowner
> structure.  There is one field unsed on the server: nlm_lockowner.owner.
> 
> It turns out that the LTP's testcases/network/nfsv4/locks/locktests.c was
> useful for testing this, as it coordinates locking tests amongst NFS
> clients.
> 
> Changes on:
> 	v2 - Fixed typos in commit log messages, and whitespace.
> 
> Benjamin Coddington (5):
>   lockd: prepare nlm_lockowner for use by the server
>   lockd: Convert NLM service fl_owner to nlm_lockowner
>   lockd: Remove lm_compare_owner and lm_owner_key
>   lockd: Show pid of lockd for remote locks
>   locks: Cleanup lm_compare_owner and lm_owner_key
> 
>  Documentation/filesystems/Locking |  14 ----
>  fs/lockd/clntproc.c               |  21 +++---
>  fs/lockd/svc4proc.c               |  14 +++-
>  fs/lockd/svclock.c                | 118 +++++++++++++++++++++++++-----
>  fs/lockd/svcproc.c                |  14 +++-
>  fs/lockd/svcsubs.c                |   2 +-
>  fs/lockd/xdr.c                    |   3 -
>  fs/lockd/xdr4.c                   |   3 -
>  fs/locks.c                        |   5 --
>  include/linux/fs.h                |   2 -
>  include/linux/lockd/lockd.h       |   2 +
>  11 files changed, 138 insertions(+), 60 deletions(-)
> 
> -- 
> 2.20.1

^ permalink raw reply	[flat|nested] 8+ messages in thread

* Re: [PATCH v2 0/5] NLM fl_pid fixup
  2019-05-24 16:47 ` [PATCH v2 0/5] NLM fl_pid fixup J. Bruce Fields
@ 2019-05-25 11:09   ` Benjamin Coddington
  0 siblings, 0 replies; 8+ messages in thread
From: Benjamin Coddington @ 2019-05-25 11:09 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: J . Bruce Fields, jlayton, linux-nfs


On 24 May 2019, at 12:47, J. Bruce Fields wrote:

> On Thu, May 23, 2019 at 10:45:43AM -0400, Benjamin Coddington wrote:
>> This series aims to correct the fl_pid value for locks held by the 
>> NLM
>> server, or lockd.  It applies onto the revert of the previous attempt 
>> to fix
>> this problem sent ealier this week: '[PATCH] Revert "lockd: Show pid 
>> of
>> lockd for remote locks"'.
>>
>> The problem with the earlier attempt was that we discarded the svid, 
>> and so
>> we couldn't distinguish remote lockowners on each host.  It is 
>> necessary to
>> turn the svid and host into a distinct owner.
>
> So, to make sure I understand, we've got multiple ways to identify a
> lock owner:
>
> 	- the svid, the pid of the client process: this gets returned to
> 	  the client in grant callbacks and (possibly to a different
> 	  client) in testd results.
> 	- the pid of the server's lockd process: this is what other
> 	  processes on the server see as the owner of locks held by nfs
> 	  clients.
> 	- the nlm_lockowner: a (nlm_host, svid) pair, used to actually
> 	  decide when locks conflict.

That's it.

> Makes sense to me.
>
> I'll send your earlier revert to stable, then add this on top for the
> 5.3 merge window.  Sound OK?

Sounds great, thank you!

Ben

^ permalink raw reply	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2019-05-25 11:09 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-23 14:45 [PATCH v2 0/5] NLM fl_pid fixup Benjamin Coddington
2019-05-23 14:45 ` [PATCH 1/5] lockd: prepare nlm_lockowner for use by the server Benjamin Coddington
2019-05-23 14:45 ` [PATCH 2/5] lockd: Convert NLM service fl_owner to nlm_lockowner Benjamin Coddington
2019-05-23 14:45 ` [PATCH 3/5] lockd: Remove lm_compare_owner and lm_owner_key Benjamin Coddington
2019-05-23 14:45 ` [PATCH 4/5] lockd: Show pid of lockd for remote locks Benjamin Coddington
2019-05-23 14:45 ` [PATCH 5/5] locks: Cleanup lm_compare_owner and lm_owner_key Benjamin Coddington
2019-05-24 16:47 ` [PATCH v2 0/5] NLM fl_pid fixup J. Bruce Fields
2019-05-25 11:09   ` Benjamin Coddington

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.