All of lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code
  2007-02-03  8:51     ` Christoph Hellwig
@ 2007-02-03  5:16       ` Brad Boyer
  2007-02-04  2:27         ` J. Bruce Fields
  2007-02-04  8:37         ` Christoph Hellwig
  2007-02-04  1:58       ` J. Bruce Fields
  1 sibling, 2 replies; 43+ messages in thread
From: Brad Boyer @ 2007-02-03  5:16 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, J. Bruce Fields, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 08:51:36AM +0000, Christoph Hellwig wrote:
> On Sat, Feb 03, 2007 at 12:33:59AM -0500, J. Bruce Fields wrote:
> > + */
> > +int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
> > +{
> > +	if (filp->f_op && filp->f_op->lock)
> > +		return filp->f_op->lock(filp, cmd, fl);
> > +	else
> > +		return posix_lock_file(filp, fl);
> > +}
> > +EXPORT_SYMBOL(vfs_lock_file);
> 
> _GPL please (and same for the last patch)

Any particular reason? It seems like this is a function that
would be exactly the sort of thing to be publically exported.
I know it's not a popular opinion around here, but I think
that the GPL exports should be primarily for things that
aren't intended to be used by normal modules. It seems to
me that people pushing for everything to be marked GPL are
trying to get a backdoor enforcement of their own dislike
of proprietary kernel modules in spite of Linus' known
stance on the issue. I hope this doesn't start a flamewar,
but I do want to bring up this even if many people don't
want to hear it. I'm sure I'm not the only one with this
stance on it.

	Brad Boyer
	flar@allandria.com


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 1/14] locks: always unlock on close
@ 2007-02-03  5:33   ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:33 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Currently locks_remove_posix has a shortcut which returns without doing
anything if it doesn't see anything on the inode's lock list.

That may be the wrong thing to do if a filesystem (such as a network or cluster
filesystem) wants to bookkeep locks on its own.

A filesystem should still be able to keep track of locally held locks (such as
all the locks held by one local process), but the occasional kmalloc() failure,
for example, could get the two sets of data structures out of sync, and it
seems best to allow the filesystem to be authoritative.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/locks.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 52a8100..4390a95 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1917,14 +1917,6 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
 {
 	struct file_lock lock;
 
-	/*
-	 * If there are no locks held on this file, we don't need to call
-	 * posix_lock_file().  Another process could be setting a lock on this
-	 * file at the same time, but we wouldn't remove that lock anyway.
-	 */
-	if (!filp->f_path.dentry->d_inode->i_flock)
-		return;
-
 	lock.fl_type = F_UNLCK;
 	lock.fl_flags = FL_POSIX | FL_CLOSE;
 	lock.fl_start = 0;
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 1/14] locks: always unlock on close
@ 2007-02-03  5:33   ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:33 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Currently locks_remove_posix has a shortcut which returns without doing
anything if it doesn't see anything on the inode's lock list.

That may be the wrong thing to do if a filesystem (such as a network or cluster
filesystem) wants to bookkeep locks on its own.

A filesystem should still be able to keep track of locally held locks (such as
all the locks held by one local process), but the occasional kmalloc() failure,
for example, could get the two sets of data structures out of sync, and it
seems best to allow the filesystem to be authoritative.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/locks.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 52a8100..4390a95 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1917,14 +1917,6 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
 {
 	struct file_lock lock;
 
-	/*
-	 * If there are no locks held on this file, we don't need to call
-	 * posix_lock_file().  Another process could be setting a lock on this
-	 * file at the same time, but we wouldn't remove that lock anyway.
-	 */
-	if (!filp->f_path.dentry->d_inode->i_flock)
-		return;
-
 	lock.fl_type = F_UNLCK;
 	lock.fl_flags = FL_POSIX | FL_CLOSE;
 	lock.fl_start = 0;
-- 
1.5.0.rc1.g72fe


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

* [PATCH 2/14] locks: factor out generic/filesystem switch from test_lock
@ 2007-02-03  5:33     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:33 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: J. Bruce Fields <bfields@snoopy.citi.umich.edu> - unquoted

Factor out the code that switches between generic and filesystem-specific lock
methods; eventually we want to call this from lock managers (lockd and nfsd)
too; currently they only call the generic methods.

This patch does that for test_lock.

Note that this hasn't been necessary until recently, because the few
filesystems that define ->lock() (nfs, cifs...) aren't exportable via NFS.
However GFS (and, in the future, other cluster filesystems) need to implement
their own locking to get cluster-coherent locking, and also want to be able to
export locking to NFS (lockd and NFSv4).

So we accomplish this by factoring out code such as this and exporting it for
the use of lockd and nfsd.

Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
---
 fs/locks.c                 |   59 ++++++++++++++++++++++++++-----------------
 include/linux/lockd/bind.h |    2 +
 2 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 4390a95..95246dc 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1611,6 +1611,33 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
 	return error;
 }
 
+/**
+ * vfs_test_lock - test file byte range lock
+ * @filp: The file to test lock for
+ * @fl: The lock to test
+ * @conf: Place to return a copy of the conflicting lock, if found
+ *
+ * Returns -ERRNO on failure.  Indicates presence of conflicting lock by
+ * setting conf->fl_type to something other than F_UNLCK.
+ */
+int vfs_test_lock(struct file *filp, struct file_lock *fl, struct file_lock *conf)
+{
+	int error;
+
+	conf->fl_type = F_UNLCK;
+	if (filp->f_op && filp->f_op->lock) {
+		__locks_copy_lock(conf, fl);
+		error = filp->f_op->lock(filp, F_GETLK, conf);
+		if (conf->fl_ops && conf->fl_ops->fl_release_private)
+			conf->fl_ops->fl_release_private(conf);
+		return error;
+	} else {
+		posix_test_lock(filp, fl, conf);
+		return 0;
+	}
+}
+EXPORT_SYMBOL(vfs_test_lock);
+
 /* Report the first existing lock that would conflict with l.
  * This implements the F_GETLK command of fcntl().
  */
@@ -1631,17 +1658,10 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock) {
-		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
-		if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
-			file_lock.fl_ops->fl_release_private(&file_lock);
-		if (error < 0)
-			goto out;
-		else
-		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
-	} else {
-		fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
-	}
+	error = vfs_test_lock(filp, &file_lock, &cfl);
+	if (error)
+		goto out;
+	fl = (cfl.fl_type == F_UNLCK ? NULL : &cfl);
  
 	flock.l_type = F_UNLCK;
 	if (fl != NULL) {
@@ -1785,18 +1805,11 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock) {
-		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
-		if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
-			file_lock.fl_ops->fl_release_private(&file_lock);
-		if (error < 0)
-			goto out;
-		else
-		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
-	} else {
-		fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
-	}
- 
+	error = vfs_test_lock(filp, &file_lock, &cfl);
+	if (error)
+		goto out;
+	fl = (cfl.fl_type == F_UNLCK ? NULL : &cfl);
+
 	flock.l_type = F_UNLCK;
 	if (fl != NULL) {
 		flock.l_pid = fl->fl_pid;
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index 246de1d..f78b24a 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -38,4 +38,6 @@ extern int	nlmclnt_proc(struct inode *, int, struct file_lock *);
 extern int	lockd_up(int proto);
 extern void	lockd_down(void);
 
+extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
+
 #endif /* LINUX_LOCKD_BIND_H */
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 2/14] locks: factor out generic/filesystem switch from test_lock
@ 2007-02-03  5:33     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:33 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: J. Bruce Fields <bfields@snoopy.citi.umich.edu> - unquoted

Factor out the code that switches between generic and filesystem-specific lock
methods; eventually we want to call this from lock managers (lockd and nfsd)
too; currently they only call the generic methods.

This patch does that for test_lock.

Note that this hasn't been necessary until recently, because the few
filesystems that define ->lock() (nfs, cifs...) aren't exportable via NFS.
However GFS (and, in the future, other cluster filesystems) need to implement
their own locking to get cluster-coherent locking, and also want to be able to
export locking to NFS (lockd and NFSv4).

So we accomplish this by factoring out code such as this and exporting it for
the use of lockd and nfsd.

Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
---
 fs/locks.c                 |   59 ++++++++++++++++++++++++++-----------------
 include/linux/lockd/bind.h |    2 +
 2 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 4390a95..95246dc 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1611,6 +1611,33 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
 	return error;
 }
 
+/**
+ * vfs_test_lock - test file byte range lock
+ * @filp: The file to test lock for
+ * @fl: The lock to test
+ * @conf: Place to return a copy of the conflicting lock, if found
+ *
+ * Returns -ERRNO on failure.  Indicates presence of conflicting lock by
+ * setting conf->fl_type to something other than F_UNLCK.
+ */
+int vfs_test_lock(struct file *filp, struct file_lock *fl, struct file_lock *conf)
+{
+	int error;
+
+	conf->fl_type = F_UNLCK;
+	if (filp->f_op && filp->f_op->lock) {
+		__locks_copy_lock(conf, fl);
+		error = filp->f_op->lock(filp, F_GETLK, conf);
+		if (conf->fl_ops && conf->fl_ops->fl_release_private)
+			conf->fl_ops->fl_release_private(conf);
+		return error;
+	} else {
+		posix_test_lock(filp, fl, conf);
+		return 0;
+	}
+}
+EXPORT_SYMBOL(vfs_test_lock);
+
 /* Report the first existing lock that would conflict with l.
  * This implements the F_GETLK command of fcntl().
  */
@@ -1631,17 +1658,10 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock) {
-		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
-		if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
-			file_lock.fl_ops->fl_release_private(&file_lock);
-		if (error < 0)
-			goto out;
-		else
-		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
-	} else {
-		fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
-	}
+	error = vfs_test_lock(filp, &file_lock, &cfl);
+	if (error)
+		goto out;
+	fl = (cfl.fl_type == F_UNLCK ? NULL : &cfl);
  
 	flock.l_type = F_UNLCK;
 	if (fl != NULL) {
@@ -1785,18 +1805,11 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock) {
-		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
-		if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
-			file_lock.fl_ops->fl_release_private(&file_lock);
-		if (error < 0)
-			goto out;
-		else
-		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
-	} else {
-		fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
-	}
- 
+	error = vfs_test_lock(filp, &file_lock, &cfl);
+	if (error)
+		goto out;
+	fl = (cfl.fl_type == F_UNLCK ? NULL : &cfl);
+
 	flock.l_type = F_UNLCK;
 	if (fl != NULL) {
 		flock.l_pid = fl->fl_pid;
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index 246de1d..f78b24a 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -38,4 +38,6 @@ extern int	nlmclnt_proc(struct inode *, int, struct file_lock *);
 extern int	lockd_up(int proto);
 extern void	lockd_down(void);
 
+extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
+
 #endif /* LINUX_LOCKD_BIND_H */
-- 
1.5.0.rc1.g72fe


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

* [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code
@ 2007-02-03  5:33     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:33 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Factor out the code that switches between generic and filesystem-specific lock
methods; eventually we want to call this from lock managers (lockd and nfsd)
too; currently they only call the generic methods.

This patch does that for all the setlk code.

Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
---
 fs/locks.c                 |   68 +++++++++++++++++++++++--------------------
 include/linux/lockd/bind.h |    1 +
 2 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 95246dc..c88139d 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1691,6 +1691,21 @@ out:
 	return error;
 }
 
+/**
+ * vfs_lock_file - file byte range lock
+ * @filp: The file to apply the lock to
+ * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.)
+ * @fl: The lock to be applied
+ */
+int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
+{
+	if (filp->f_op && filp->f_op->lock)
+		return filp->f_op->lock(filp, cmd, fl);
+	else
+		return posix_lock_file(filp, fl);
+}
+EXPORT_SYMBOL(vfs_lock_file);
+
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
@@ -1753,21 +1768,17 @@ again:
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock != NULL)
-		error = filp->f_op->lock(filp, cmd, file_lock);
-	else {
-		for (;;) {
-			error = posix_lock_file(filp, file_lock);
-			if ((error != -EAGAIN) || (cmd == F_SETLK))
-				break;
-			error = wait_event_interruptible(file_lock->fl_wait,
-					!file_lock->fl_next);
-			if (!error)
-				continue;
-
-			locks_delete_block(file_lock);
+	for (;;) {
+		error = vfs_lock_file(filp, cmd, file_lock);
+		if ((error != -EAGAIN) || (cmd == F_SETLK))
 			break;
-		}
+		error = wait_event_interruptible(file_lock->fl_wait,
+				!file_lock->fl_next);
+		if (!error)
+			continue;
+
+		locks_delete_block(file_lock);
+		break;
 	}
 
 	/*
@@ -1889,21 +1900,17 @@ again:
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock != NULL)
-		error = filp->f_op->lock(filp, cmd, file_lock);
-	else {
-		for (;;) {
-			error = posix_lock_file(filp, file_lock);
-			if ((error != -EAGAIN) || (cmd == F_SETLK64))
-				break;
-			error = wait_event_interruptible(file_lock->fl_wait,
-					!file_lock->fl_next);
-			if (!error)
-				continue;
-
-			locks_delete_block(file_lock);
+	for (;;) {
+		error = vfs_lock_file(filp, cmd, file_lock);
+		if ((error != -EAGAIN) || (cmd == F_SETLK64))
 			break;
-		}
+		error = wait_event_interruptible(file_lock->fl_wait,
+				!file_lock->fl_next);
+		if (!error)
+			continue;
+
+		locks_delete_block(file_lock);
+		break;
 	}
 
 	/*
@@ -1940,10 +1947,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
 	lock.fl_ops = NULL;
 	lock.fl_lmops = NULL;
 
-	if (filp->f_op && filp->f_op->lock != NULL)
-		filp->f_op->lock(filp, F_SETLK, &lock);
-	else
-		posix_lock_file(filp, &lock);
+	vfs_lock_file(filp, F_SETLK, &lock);
 
 	if (lock.fl_ops && lock.fl_ops->fl_release_private)
 		lock.fl_ops->fl_release_private(&lock);
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index f78b24a..c88da8e 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -39,5 +39,6 @@ extern int	lockd_up(int proto);
 extern void	lockd_down(void);
 
 extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
+extern int vfs_lock_file(struct file *, int cmd, struct file_lock *);
 
 #endif /* LINUX_LOCKD_BIND_H */
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code
@ 2007-02-03  5:33     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:33 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Factor out the code that switches between generic and filesystem-specific lock
methods; eventually we want to call this from lock managers (lockd and nfsd)
too; currently they only call the generic methods.

This patch does that for all the setlk code.

Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
---
 fs/locks.c                 |   68 +++++++++++++++++++++++--------------------
 include/linux/lockd/bind.h |    1 +
 2 files changed, 37 insertions(+), 32 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 95246dc..c88139d 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1691,6 +1691,21 @@ out:
 	return error;
 }
 
+/**
+ * vfs_lock_file - file byte range lock
+ * @filp: The file to apply the lock to
+ * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.)
+ * @fl: The lock to be applied
+ */
+int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
+{
+	if (filp->f_op && filp->f_op->lock)
+		return filp->f_op->lock(filp, cmd, fl);
+	else
+		return posix_lock_file(filp, fl);
+}
+EXPORT_SYMBOL(vfs_lock_file);
+
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
@@ -1753,21 +1768,17 @@ again:
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock != NULL)
-		error = filp->f_op->lock(filp, cmd, file_lock);
-	else {
-		for (;;) {
-			error = posix_lock_file(filp, file_lock);
-			if ((error != -EAGAIN) || (cmd == F_SETLK))
-				break;
-			error = wait_event_interruptible(file_lock->fl_wait,
-					!file_lock->fl_next);
-			if (!error)
-				continue;
-
-			locks_delete_block(file_lock);
+	for (;;) {
+		error = vfs_lock_file(filp, cmd, file_lock);
+		if ((error != -EAGAIN) || (cmd == F_SETLK))
 			break;
-		}
+		error = wait_event_interruptible(file_lock->fl_wait,
+				!file_lock->fl_next);
+		if (!error)
+			continue;
+
+		locks_delete_block(file_lock);
+		break;
 	}
 
 	/*
@@ -1889,21 +1900,17 @@ again:
 	if (error)
 		goto out;
 
-	if (filp->f_op && filp->f_op->lock != NULL)
-		error = filp->f_op->lock(filp, cmd, file_lock);
-	else {
-		for (;;) {
-			error = posix_lock_file(filp, file_lock);
-			if ((error != -EAGAIN) || (cmd == F_SETLK64))
-				break;
-			error = wait_event_interruptible(file_lock->fl_wait,
-					!file_lock->fl_next);
-			if (!error)
-				continue;
-
-			locks_delete_block(file_lock);
+	for (;;) {
+		error = vfs_lock_file(filp, cmd, file_lock);
+		if ((error != -EAGAIN) || (cmd == F_SETLK64))
 			break;
-		}
+		error = wait_event_interruptible(file_lock->fl_wait,
+				!file_lock->fl_next);
+		if (!error)
+			continue;
+
+		locks_delete_block(file_lock);
+		break;
 	}
 
 	/*
@@ -1940,10 +1947,7 @@ void locks_remove_posix(struct file *filp, fl_owner_t owner)
 	lock.fl_ops = NULL;
 	lock.fl_lmops = NULL;
 
-	if (filp->f_op && filp->f_op->lock != NULL)
-		filp->f_op->lock(filp, F_SETLK, &lock);
-	else
-		posix_lock_file(filp, &lock);
+	vfs_lock_file(filp, F_SETLK, &lock);
 
 	if (lock.fl_ops && lock.fl_ops->fl_release_private)
 		lock.fl_ops->fl_release_private(&lock);
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index f78b24a..c88da8e 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -39,5 +39,6 @@ extern int	lockd_up(int proto);
 extern void	lockd_down(void);
 
 extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
+extern int vfs_lock_file(struct file *, int cmd, struct file_lock *);
 
 #endif /* LINUX_LOCKD_BIND_H */
-- 
1.5.0.rc1.g72fe


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

* [PATCH 4/14] locks: add locking function that returns conflicting lock
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

The nfsv4 protocol's lock operation, in the case of a conflict, returns
information about the conflicting lock.

It's unclear how clients can use this, so for now we're not going so far as to
add a filesystem method that can return a conflicting lock, but we may as well
return something in the local case when it's easy to.

Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
---
 fs/locks.c                 |   18 ++++++++++++++++++
 include/linux/lockd/bind.h |    1 +
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index c88139d..1bd6418 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1706,6 +1706,24 @@ int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
 }
 EXPORT_SYMBOL(vfs_lock_file);
 
+/**
+ * vfs_lock_file_conf - file byte range lock
+ * @filp: The file to apply the lock to
+ * @fl: The lock to be applied
+ * @conf: Place to return a copy of the conflicting lock, if found.
+ *
+ * read comments for vfs_lock_file()
+ */
+int vfs_lock_file_conf(struct file *filp, struct file_lock *fl, struct file_lock *conf)
+{
+	if (filp->f_op && filp->f_op->lock) {
+		__locks_copy_lock(conf, fl);
+		return filp->f_op->lock(filp, F_SETLK, fl);
+	} else
+		return posix_lock_file_conf(filp, fl, conf);
+}
+EXPORT_SYMBOL(vfs_lock_file_conf);
+
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index c88da8e..01c25e4 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -40,5 +40,6 @@ extern void	lockd_down(void);
 
 extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
 extern int vfs_lock_file(struct file *, int cmd, struct file_lock *);
+extern int vfs_lock_file_conf(struct file *, struct file_lock *, struct file_lock *);
 
 #endif /* LINUX_LOCKD_BIND_H */
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 4/14] locks: add locking function that returns conflicting lock
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

The nfsv4 protocol's lock operation, in the case of a conflict, returns
information about the conflicting lock.

It's unclear how clients can use this, so for now we're not going so far as to
add a filesystem method that can return a conflicting lock, but we may as well
return something in the local case when it's easy to.

Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
---
 fs/locks.c                 |   18 ++++++++++++++++++
 include/linux/lockd/bind.h |    1 +
 2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index c88139d..1bd6418 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -1706,6 +1706,24 @@ int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
 }
 EXPORT_SYMBOL(vfs_lock_file);
 
+/**
+ * vfs_lock_file_conf - file byte range lock
+ * @filp: The file to apply the lock to
+ * @fl: The lock to be applied
+ * @conf: Place to return a copy of the conflicting lock, if found.
+ *
+ * read comments for vfs_lock_file()
+ */
+int vfs_lock_file_conf(struct file *filp, struct file_lock *fl, struct file_lock *conf)
+{
+	if (filp->f_op && filp->f_op->lock) {
+		__locks_copy_lock(conf, fl);
+		return filp->f_op->lock(filp, F_SETLK, fl);
+	} else
+		return posix_lock_file_conf(filp, fl, conf);
+}
+EXPORT_SYMBOL(vfs_lock_file_conf);
+
 /* Apply the lock described by l to an open file descriptor.
  * This implements both the F_SETLK and F_SETLKW commands of fcntl().
  */
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index c88da8e..01c25e4 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -40,5 +40,6 @@ extern void	lockd_down(void);
 
 extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
 extern int vfs_lock_file(struct file *, int cmd, struct file_lock *);
+extern int vfs_lock_file_conf(struct file *, struct file_lock *, struct file_lock *);
 
 #endif /* LINUX_LOCKD_BIND_H */
-- 
1.5.0.rc1.g72fe


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

* [PATCH 5/14] locks: add fl_notify arguments for asynchronous lock return
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Acquiring a lock on a cluster filesystem may require communication with remote
hosts, and to avoid blocking lockd or nfsd threads during such communication,
we allow the results to be returned asynchronously.

When a ->lock() call needs to block, the file system will return -EINPROGRESS,
and then later return the results with a call to the routine in the fl_notify
field of the lock_manager_operations struct.

Note that this is different from the ->lock() call discovering that there is a
conflict which would cause the caller to block; this is still handled in the
same way as before.  In fact, we don't currently handle "blocking" locks at
all; those are less urgent, because the filesystem can always just return an
immediate -EAGAIN without denying the lock.

So this asynchronous interface is only used in the case of a non-blocking lock,
where we must know whether to allow or deny the lock now.

We're using fl_notify to asynchronously return the result of a lock
request.  So we want fl_notify to be able to return a status and, if
appropriate, a conflicting lock.

This only current caller of fl_notify is in the blocked case, in which case
we don't use these extra arguments.

We also allow fl_notify to return an error.  (Also ignored for now.)

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |    7 ++++---
 fs/locks.c         |   21 ++++++++++++++++++++-
 include/linux/fs.h |    2 +-
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index c7db0a5..d2c8020 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -506,12 +506,13 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
  * This function doesn't grant the blocked lock instantly, but rather moves
  * the block to the head of nlm_blocked where it can be picked up by lockd.
  */
-static void
-nlmsvc_notify_blocked(struct file_lock *fl)
+static int
+nlmsvc_notify_blocked(struct file_lock *fl, struct file_lock *conf, int result)
 {
 	struct nlm_block	*block;
 
-	dprintk("lockd: VFS unblock notification for block %p\n", fl);
+	dprintk("lockd: nlmsvc_notify_blocked lock %p conf %p result %d\n",
+							fl, conf, result);
 	list_for_each_entry(block, &nlm_blocked, b_list) {
 		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
 			nlmsvc_insert_block(block, 0);
diff --git a/fs/locks.c b/fs/locks.c
index 1bd6418..819dc28 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -544,7 +544,7 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
 				struct file_lock, fl_block);
 		__locks_delete_block(waiter);
 		if (waiter->fl_lmops && waiter->fl_lmops->fl_notify)
-			waiter->fl_lmops->fl_notify(waiter);
+			waiter->fl_lmops->fl_notify(waiter, NULL, -EAGAIN);
 		else
 			wake_up(&waiter->fl_wait);
 	}
@@ -1696,6 +1696,25 @@ out:
  * @filp: The file to apply the lock to
  * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.)
  * @fl: The lock to be applied
+ *
+ * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX
+ * locks, the ->lock() interface may return asynchronously, before the lock has
+ * been granted or denied by the underlying filesystem, if (and only if)
+ * fl_notify is set. Callers expecting ->lock() to return asynchronously
+ * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if)
+ * the request is for a blocking lock. When ->lock() does return asynchronously,
+ * it must return -EINPROGRESS, and call ->fl_notify() when the lock
+ * request completes.
+ * If the request is for non-blocking lock the file system should return
+ * -EINPROGRESS then try to get the lock and call the callback routine with
+ * the result. If the request timed out the callback routine will return a
+ * nonzero return code and the file system should release the lock. The file
+ * system is also responsible to keep a corresponding posix lock when it
+ * grants a lock so the VFS can find out which locks are locally held and do
+ * the correct lock cleanup when required.
+ * The underlying filesystem must not drop the kernel lock or call
+ * ->fl_notify() before returning to the caller with a -EINPROGRESS
+ * return code.
  */
 int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
 {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1410e53..5d44d25 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -783,7 +783,7 @@ struct file_lock_operations {
 
 struct lock_manager_operations {
 	int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
-	void (*fl_notify)(struct file_lock *);	/* unblock callback */
+	int (*fl_notify)(struct file_lock *, struct file_lock *, int);
 	void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
 	void (*fl_release_private)(struct file_lock *);
 	void (*fl_break)(struct file_lock *);
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 5/14] locks: add fl_notify arguments for asynchronous lock return
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Acquiring a lock on a cluster filesystem may require communication with remote
hosts, and to avoid blocking lockd or nfsd threads during such communication,
we allow the results to be returned asynchronously.

When a ->lock() call needs to block, the file system will return -EINPROGRESS,
and then later return the results with a call to the routine in the fl_notify
field of the lock_manager_operations struct.

Note that this is different from the ->lock() call discovering that there is a
conflict which would cause the caller to block; this is still handled in the
same way as before.  In fact, we don't currently handle "blocking" locks at
all; those are less urgent, because the filesystem can always just return an
immediate -EAGAIN without denying the lock.

So this asynchronous interface is only used in the case of a non-blocking lock,
where we must know whether to allow or deny the lock now.

We're using fl_notify to asynchronously return the result of a lock
request.  So we want fl_notify to be able to return a status and, if
appropriate, a conflicting lock.

This only current caller of fl_notify is in the blocked case, in which case
we don't use these extra arguments.

We also allow fl_notify to return an error.  (Also ignored for now.)

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |    7 ++++---
 fs/locks.c         |   21 ++++++++++++++++++++-
 include/linux/fs.h |    2 +-
 3 files changed, 25 insertions(+), 5 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index c7db0a5..d2c8020 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -506,12 +506,13 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
  * This function doesn't grant the blocked lock instantly, but rather moves
  * the block to the head of nlm_blocked where it can be picked up by lockd.
  */
-static void
-nlmsvc_notify_blocked(struct file_lock *fl)
+static int
+nlmsvc_notify_blocked(struct file_lock *fl, struct file_lock *conf, int result)
 {
 	struct nlm_block	*block;
 
-	dprintk("lockd: VFS unblock notification for block %p\n", fl);
+	dprintk("lockd: nlmsvc_notify_blocked lock %p conf %p result %d\n",
+							fl, conf, result);
 	list_for_each_entry(block, &nlm_blocked, b_list) {
 		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
 			nlmsvc_insert_block(block, 0);
diff --git a/fs/locks.c b/fs/locks.c
index 1bd6418..819dc28 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -544,7 +544,7 @@ static void locks_wake_up_blocks(struct file_lock *blocker)
 				struct file_lock, fl_block);
 		__locks_delete_block(waiter);
 		if (waiter->fl_lmops && waiter->fl_lmops->fl_notify)
-			waiter->fl_lmops->fl_notify(waiter);
+			waiter->fl_lmops->fl_notify(waiter, NULL, -EAGAIN);
 		else
 			wake_up(&waiter->fl_wait);
 	}
@@ -1696,6 +1696,25 @@ out:
  * @filp: The file to apply the lock to
  * @cmd: type of locking operation (F_SETLK, F_GETLK, etc.)
  * @fl: The lock to be applied
+ *
+ * To avoid blocking kernel daemons, such as lockd, that need to acquire POSIX
+ * locks, the ->lock() interface may return asynchronously, before the lock has
+ * been granted or denied by the underlying filesystem, if (and only if)
+ * fl_notify is set. Callers expecting ->lock() to return asynchronously
+ * will only use F_SETLK, not F_SETLKW; they will set FL_SLEEP if (and only if)
+ * the request is for a blocking lock. When ->lock() does return asynchronously,
+ * it must return -EINPROGRESS, and call ->fl_notify() when the lock
+ * request completes.
+ * If the request is for non-blocking lock the file system should return
+ * -EINPROGRESS then try to get the lock and call the callback routine with
+ * the result. If the request timed out the callback routine will return a
+ * nonzero return code and the file system should release the lock. The file
+ * system is also responsible to keep a corresponding posix lock when it
+ * grants a lock so the VFS can find out which locks are locally held and do
+ * the correct lock cleanup when required.
+ * The underlying filesystem must not drop the kernel lock or call
+ * ->fl_notify() before returning to the caller with a -EINPROGRESS
+ * return code.
  */
 int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
 {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 1410e53..5d44d25 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -783,7 +783,7 @@ struct file_lock_operations {
 
 struct lock_manager_operations {
 	int (*fl_compare_owner)(struct file_lock *, struct file_lock *);
-	void (*fl_notify)(struct file_lock *);	/* unblock callback */
+	int (*fl_notify)(struct file_lock *, struct file_lock *, int);
 	void (*fl_copy_lock)(struct file_lock *, struct file_lock *);
 	void (*fl_release_private)(struct file_lock *);
 	void (*fl_break)(struct file_lock *);
-- 
1.5.0.rc1.g72fe


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

* [PATCH 6/14] locks: add lock cancel command
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Lock managers need to be able to cancel pending lock requests.  In the case
where the exported filesystem manages its own locks, it's not sufficient just
to call posix_unblock_lock(); we need to let the filesystem know what's
happening too.

We do this by adding a new fcntl lock command: FL_CANCELLK.  Some day this
might also be made available to userspace applications that could benefit from
an asynchronous locking api.

Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
---
 fs/locks.c                 |   17 +++++++++++++++++
 include/linux/fcntl.h      |    4 ++++
 include/linux/lockd/bind.h |    1 +
 3 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 819dc28..8ee72b3 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2061,6 +2061,23 @@ posix_unblock_lock(struct file *filp, struct file_lock *waiter)
 
 EXPORT_SYMBOL(posix_unblock_lock);
 
+/**
+ * vfs_cancel_lock - file byte range unblock lock
+ * @filp: The file to apply the unblock to
+ * @fl: The lock to be unblocked
+ *
+ * Used by lock managers to cancel blocked requests
+ */
+int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+{
+	if (filp->f_op && filp->f_op->lock)
+		return filp->f_op->lock(filp, F_CANCELLK, fl);
+	else
+		return posix_unblock_lock(filp, fl);
+}
+
+EXPORT_SYMBOL(vfs_cancel_lock);
+
 static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx)
 {
 	struct inode *inode = NULL;
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 996f561..40b9326 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -3,6 +3,10 @@
 
 #include <asm/fcntl.h>
 
+/* Cancel a blocking posix lock; internal use only until we expose an
+ * asynchronous lock api to userspace: */
+#define F_CANCELLK	(F_LINUX_SPECIFIC_BASE+5)
+
 #define F_SETLEASE	(F_LINUX_SPECIFIC_BASE+0)
 #define F_GETLEASE	(F_LINUX_SPECIFIC_BASE+1)
 
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index 01c25e4..1333dcf 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -41,5 +41,6 @@ extern void	lockd_down(void);
 extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
 extern int vfs_lock_file(struct file *, int cmd, struct file_lock *);
 extern int vfs_lock_file_conf(struct file *, struct file_lock *, struct file_lock *);
+extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
 
 #endif /* LINUX_LOCKD_BIND_H */
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 6/14] locks: add lock cancel command
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Lock managers need to be able to cancel pending lock requests.  In the case
where the exported filesystem manages its own locks, it's not sufficient just
to call posix_unblock_lock(); we need to let the filesystem know what's
happening too.

We do this by adding a new fcntl lock command: FL_CANCELLK.  Some day this
might also be made available to userspace applications that could benefit from
an asynchronous locking api.

Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
---
 fs/locks.c                 |   17 +++++++++++++++++
 include/linux/fcntl.h      |    4 ++++
 include/linux/lockd/bind.h |    1 +
 3 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/fs/locks.c b/fs/locks.c
index 819dc28..8ee72b3 100644
--- a/fs/locks.c
+++ b/fs/locks.c
@@ -2061,6 +2061,23 @@ posix_unblock_lock(struct file *filp, struct file_lock *waiter)
 
 EXPORT_SYMBOL(posix_unblock_lock);
 
+/**
+ * vfs_cancel_lock - file byte range unblock lock
+ * @filp: The file to apply the unblock to
+ * @fl: The lock to be unblocked
+ *
+ * Used by lock managers to cancel blocked requests
+ */
+int vfs_cancel_lock(struct file *filp, struct file_lock *fl)
+{
+	if (filp->f_op && filp->f_op->lock)
+		return filp->f_op->lock(filp, F_CANCELLK, fl);
+	else
+		return posix_unblock_lock(filp, fl);
+}
+
+EXPORT_SYMBOL(vfs_cancel_lock);
+
 static void lock_get_status(char* out, struct file_lock *fl, int id, char *pfx)
 {
 	struct inode *inode = NULL;
diff --git a/include/linux/fcntl.h b/include/linux/fcntl.h
index 996f561..40b9326 100644
--- a/include/linux/fcntl.h
+++ b/include/linux/fcntl.h
@@ -3,6 +3,10 @@
 
 #include <asm/fcntl.h>
 
+/* Cancel a blocking posix lock; internal use only until we expose an
+ * asynchronous lock api to userspace: */
+#define F_CANCELLK	(F_LINUX_SPECIFIC_BASE+5)
+
 #define F_SETLEASE	(F_LINUX_SPECIFIC_BASE+0)
 #define F_GETLEASE	(F_LINUX_SPECIFIC_BASE+1)
 
diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
index 01c25e4..1333dcf 100644
--- a/include/linux/lockd/bind.h
+++ b/include/linux/lockd/bind.h
@@ -41,5 +41,6 @@ extern void	lockd_down(void);
 extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
 extern int vfs_lock_file(struct file *, int cmd, struct file_lock *);
 extern int vfs_lock_file_conf(struct file *, struct file_lock *, struct file_lock *);
+extern int vfs_cancel_lock(struct file *filp, struct file_lock *fl);
 
 #endif /* LINUX_LOCKD_BIND_H */
-- 
1.5.0.rc1.g72fe


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

* [PATCH 7/14] nfsd4: Convert NFSv4 to new lock interface
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Convert NFSv4 to the new lock interface.  We don't define any callback for now,
so we're not taking advantage of the asynchronous feature--that's less critical
for the multi-threaded nfsd then it is for the single-threaded lockd.  But this
does allow a cluster filesystems to export cluster-coherent locking to NFS.

Note that it's cluster filesystems that are the issue--of the filesystems that
define lock methods (nfs, cifs, etc.), most are not exportable by nfsd.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/nfsd/nfs4state.c |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9de89df..5d5a454 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -50,6 +50,7 @@
 #include <linux/nfsd/xdr4.h>
 #include <linux/namei.h>
 #include <linux/mutex.h>
+#include <linux/lockd/bind.h>
 
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
@@ -2772,7 +2773,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	 * locks_copy_lock: */
 	conflock.fl_ops = NULL;
 	conflock.fl_lmops = NULL;
-	err = posix_lock_file_conf(filp, &file_lock, &conflock);
+	err = vfs_lock_file_conf(filp, &file_lock, &conflock);
 	switch (-err) {
 	case 0: /* success! */
 		update_stateid(&lock_stp->st_stateid);
@@ -2789,7 +2790,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		status = nfserr_deadlock;
 		break;
 	default:        
-		dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",err);
+		dprintk("NFSD: nfsd4_lock: vfs_lock_file_conf() failed! status %d\n",err);
 		status = nfserr_resource;
 		break;
 	}
@@ -2815,6 +2816,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	struct file file;
 	struct file_lock file_lock;
 	struct file_lock conflock;
+	int error;
 	__be32 status;
 
 	if (nfs4_in_grace())
@@ -2870,16 +2872,23 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
 	nfs4_transform_lock_offset(&file_lock);
 
-	/* posix_test_lock uses the struct file _only_ to resolve the inode.
+	/* vfs_test_lock uses the struct file _only_ to resolve the inode.
 	 * since LOCKT doesn't require an OPEN, and therefore a struct
-	 * file may not exist, pass posix_test_lock a struct file with
+	 * file may not exist, pass vfs_test_lock a struct file with
 	 * only the dentry:inode set.
 	 */
 	memset(&file, 0, sizeof (struct file));
 	file.f_path.dentry = cstate->current_fh.fh_dentry;
 
 	status = nfs_ok;
-	if (posix_test_lock(&file, &file_lock, &conflock)) {
+	conflock.fl_ops = NULL;
+	conflock.fl_lmops = NULL;
+	error = vfs_test_lock(&file, &file_lock, &conflock);
+	if (error) {
+		status = nfserrno(error);
+		goto out;
+	}
+	if (conflock.fl_type != F_UNLCK) {
 		status = nfserr_denied;
 		nfs4_set_lock_denied(&conflock, &lockt->lt_denied);
 	}
@@ -2934,9 +2943,9 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	/*
 	*  Try to unlock the file in the VFS.
 	*/
-	err = posix_lock_file(filp, &file_lock);
+	err = vfs_lock_file(filp, F_SETLK, &file_lock);
 	if (err) {
-		dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
+		dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
 		goto out_nfserr;
 	}
 	/*
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 7/14] nfsd4: Convert NFSv4 to new lock interface
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Convert NFSv4 to the new lock interface.  We don't define any callback for now,
so we're not taking advantage of the asynchronous feature--that's less critical
for the multi-threaded nfsd then it is for the single-threaded lockd.  But this
does allow a cluster filesystems to export cluster-coherent locking to NFS.

Note that it's cluster filesystems that are the issue--of the filesystems that
define lock methods (nfs, cifs, etc.), most are not exportable by nfsd.

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/nfsd/nfs4state.c |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 9de89df..5d5a454 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -50,6 +50,7 @@
 #include <linux/nfsd/xdr4.h>
 #include <linux/namei.h>
 #include <linux/mutex.h>
+#include <linux/lockd/bind.h>
 
 #define NFSDDBG_FACILITY                NFSDDBG_PROC
 
@@ -2772,7 +2773,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	 * locks_copy_lock: */
 	conflock.fl_ops = NULL;
 	conflock.fl_lmops = NULL;
-	err = posix_lock_file_conf(filp, &file_lock, &conflock);
+	err = vfs_lock_file_conf(filp, &file_lock, &conflock);
 	switch (-err) {
 	case 0: /* success! */
 		update_stateid(&lock_stp->st_stateid);
@@ -2789,7 +2790,7 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 		status = nfserr_deadlock;
 		break;
 	default:        
-		dprintk("NFSD: nfsd4_lock: posix_lock_file_conf() failed! status %d\n",err);
+		dprintk("NFSD: nfsd4_lock: vfs_lock_file_conf() failed! status %d\n",err);
 		status = nfserr_resource;
 		break;
 	}
@@ -2815,6 +2816,7 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	struct file file;
 	struct file_lock file_lock;
 	struct file_lock conflock;
+	int error;
 	__be32 status;
 
 	if (nfs4_in_grace())
@@ -2870,16 +2872,23 @@ nfsd4_lockt(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
 	nfs4_transform_lock_offset(&file_lock);
 
-	/* posix_test_lock uses the struct file _only_ to resolve the inode.
+	/* vfs_test_lock uses the struct file _only_ to resolve the inode.
 	 * since LOCKT doesn't require an OPEN, and therefore a struct
-	 * file may not exist, pass posix_test_lock a struct file with
+	 * file may not exist, pass vfs_test_lock a struct file with
 	 * only the dentry:inode set.
 	 */
 	memset(&file, 0, sizeof (struct file));
 	file.f_path.dentry = cstate->current_fh.fh_dentry;
 
 	status = nfs_ok;
-	if (posix_test_lock(&file, &file_lock, &conflock)) {
+	conflock.fl_ops = NULL;
+	conflock.fl_lmops = NULL;
+	error = vfs_test_lock(&file, &file_lock, &conflock);
+	if (error) {
+		status = nfserrno(error);
+		goto out;
+	}
+	if (conflock.fl_type != F_UNLCK) {
 		status = nfserr_denied;
 		nfs4_set_lock_denied(&conflock, &lockt->lt_denied);
 	}
@@ -2934,9 +2943,9 @@ nfsd4_locku(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 	/*
 	*  Try to unlock the file in the VFS.
 	*/
-	err = posix_lock_file(filp, &file_lock);
+	err = vfs_lock_file(filp, F_SETLK, &file_lock);
 	if (err) {
-		dprintk("NFSD: nfs4_locku: posix_lock_file failed!\n");
+		dprintk("NFSD: nfs4_locku: vfs_lock_file failed!\n");
 		goto out_nfserr;
 	}
 	/*
-- 
1.5.0.rc1.g72fe


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

* [PATCH 8/14] lockd: save lock state on deferral
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

We need to keep some state for a pending asynchronous lock request, so this
patch adds that state to struct nlm_block.

This also adds a function which defers the request, by calling
rqstp->rq_chandle.defer and storing the resulting deferred request in a
nlm_block structure which we insert into lockd's global block list.  That
new function isn't called yet, so it's dead code until a later patch.

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c          |   25 +++++++++++++++++++++++++
 include/linux/lockd/lockd.h |   10 ++++++++++
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index d2c8020..00e657a 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -331,6 +331,31 @@ static void nlmsvc_freegrantargs(struct nlm_rqst *call)
 }
 
 /*
+ * Deferred lock request handling for non-blocking lock
+ */
+static u32
+nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block)
+{
+	u32 status = nlm_lck_denied_nolocks;
+
+	block->b_flags |= B_QUEUED;
+
+	nlmsvc_insert_block(block, NLM_TIMEOUT);
+
+	block->b_cache_req = &rqstp->rq_chandle;
+	if (rqstp->rq_chandle.defer) {
+		block->b_deferred_req =
+			rqstp->rq_chandle.defer(block->b_cache_req);
+		if (block->b_deferred_req != NULL)
+			status = nlm_drop_reply;
+	}
+	dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n",
+		block, block->b_flags, status);
+
+	return status;
+}
+
+/*
  * Attempt to establish a lock, and if it can't be granted, block it
  * if required.
  */
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index ac25b56..1df10d7 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -119,6 +119,9 @@ struct nlm_file {
  * couldn't be granted because of a conflicting lock).
  */
 #define NLM_NEVER		(~(unsigned long) 0)
+/* timeout on non-blocking call: */
+#define NLM_TIMEOUT		(7 * HZ)
+
 struct nlm_block {
 	struct kref		b_count;	/* Reference count */
 	struct list_head	b_list;		/* linked list of all blocks */
@@ -130,6 +133,13 @@ struct nlm_block {
 	unsigned int		b_id;		/* block id */
 	unsigned char		b_granted;	/* VFS granted lock */
 	struct nlm_file *	b_file;		/* file in question */
+	struct cache_req *	b_cache_req;	/* deferred request handling */
+	struct file_lock *	b_fl;		/* set for GETLK */
+	struct cache_deferred_req * b_deferred_req;
+	unsigned int		b_flags;	/* block flags */
+#define B_QUEUED		1	/* lock queued */
+#define B_GOT_CALLBACK		2	/* got lock or conflicting lock */
+#define B_TOO_LATE		4	/* too late for non-blocking lock */
 };
 
 /*
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 8/14] lockd: save lock state on deferral
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

We need to keep some state for a pending asynchronous lock request, so this
patch adds that state to struct nlm_block.

This also adds a function which defers the request, by calling
rqstp->rq_chandle.defer and storing the resulting deferred request in a
nlm_block structure which we insert into lockd's global block list.  That
new function isn't called yet, so it's dead code until a later patch.

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c          |   25 +++++++++++++++++++++++++
 include/linux/lockd/lockd.h |   10 ++++++++++
 2 files changed, 35 insertions(+), 0 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index d2c8020..00e657a 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -331,6 +331,31 @@ static void nlmsvc_freegrantargs(struct nlm_rqst *call)
 }
 
 /*
+ * Deferred lock request handling for non-blocking lock
+ */
+static u32
+nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block)
+{
+	u32 status = nlm_lck_denied_nolocks;
+
+	block->b_flags |= B_QUEUED;
+
+	nlmsvc_insert_block(block, NLM_TIMEOUT);
+
+	block->b_cache_req = &rqstp->rq_chandle;
+	if (rqstp->rq_chandle.defer) {
+		block->b_deferred_req =
+			rqstp->rq_chandle.defer(block->b_cache_req);
+		if (block->b_deferred_req != NULL)
+			status = nlm_drop_reply;
+	}
+	dprintk("lockd: nlmsvc_defer_lock_rqst block %p flags %d status %d\n",
+		block, block->b_flags, status);
+
+	return status;
+}
+
+/*
  * Attempt to establish a lock, and if it can't be granted, block it
  * if required.
  */
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index ac25b56..1df10d7 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -119,6 +119,9 @@ struct nlm_file {
  * couldn't be granted because of a conflicting lock).
  */
 #define NLM_NEVER		(~(unsigned long) 0)
+/* timeout on non-blocking call: */
+#define NLM_TIMEOUT		(7 * HZ)
+
 struct nlm_block {
 	struct kref		b_count;	/* Reference count */
 	struct list_head	b_list;		/* linked list of all blocks */
@@ -130,6 +133,13 @@ struct nlm_block {
 	unsigned int		b_id;		/* block id */
 	unsigned char		b_granted;	/* VFS granted lock */
 	struct nlm_file *	b_file;		/* file in question */
+	struct cache_req *	b_cache_req;	/* deferred request handling */
+	struct file_lock *	b_fl;		/* set for GETLK */
+	struct cache_deferred_req * b_deferred_req;
+	unsigned int		b_flags;	/* block flags */
+#define B_QUEUED		1	/* lock queued */
+#define B_GOT_CALLBACK		2	/* got lock or conflicting lock */
+#define B_TOO_LATE		4	/* too late for non-blocking lock */
 };
 
 /*
-- 
1.5.0.rc1.g72fe


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

* [PATCH 9/14] lockd: handle fl_notify callbacks
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Add code to handle file system callback when the lock is finally granted.

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 00e657a..a558360 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -261,6 +261,8 @@ static void nlmsvc_free_block(struct kref *kref)
 	nlmsvc_freegrantargs(block->b_call);
 	nlm_release_call(block->b_call);
 	nlm_release_file(block->b_file);
+	if (block->b_fl)
+		kfree(block->b_fl);
 	kfree(block);
 }
 
@@ -525,6 +527,32 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
 }
 
 /*
+ * This is a callback from the filesystem for VFS file lock requests.
+ * It will be used if fl_notify is defined and the filesystem can not
+ * respond to the request immediately.
+ * For GETLK request it will copy the reply to the nlm_block.
+ * For SETLK or SETLKW request it will get the local posix lock.
+ * In all cases it will move the block to the head of nlm_blocked q where
+ * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
+ * deferred rpc for GETLK and SETLK.
+ */
+static void
+nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
+			     int result)
+{
+	block->b_flags |= B_GOT_CALLBACK;
+	if (result == 0)
+		block->b_granted = 1;
+	else
+		block->b_flags |= B_TOO_LATE;
+	if (conf) {
+		block->b_fl = kzalloc(sizeof(struct file_lock), GFP_KERNEL);
+		if (block->b_fl)
+			locks_copy_lock(block->b_fl, conf);
+	}
+}
+
+/*
  * Unblock a blocked lock request. This is a callback invoked from the
  * VFS layer when a lock on which we blocked is removed.
  *
@@ -535,18 +563,33 @@ static int
 nlmsvc_notify_blocked(struct file_lock *fl, struct file_lock *conf, int result)
 {
 	struct nlm_block	*block;
+	int rc = -ENOENT;
 
 	dprintk("lockd: nlmsvc_notify_blocked lock %p conf %p result %d\n",
 							fl, conf, result);
+	lock_kernel();
 	list_for_each_entry(block, &nlm_blocked, b_list) {
 		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
+			dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
+							block, block->b_flags);
+			if (block->b_flags & B_QUEUED) {
+				if (block->b_flags & B_TOO_LATE) {
+					rc = -ENOLCK;
+					break;
+				}
+				nlmsvc_update_deferred_block(block, conf, result);
+			}
 			nlmsvc_insert_block(block, 0);
 			svc_wake_up(block->b_daemon);
-			return;
+			rc = 0;
+			break;
 		}
 	}
+	unlock_kernel();
 
-	printk(KERN_WARNING "lockd: notification for unknown block!\n");
+	if (rc == -ENOENT)
+		printk(KERN_WARNING "lockd: notification for unknown block!\n");
+	return rc;
 }
 
 static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
@@ -579,6 +622,8 @@ nlmsvc_grant_blocked(struct nlm_block *block)
 
 	dprintk("lockd: grant blocked lock %p\n", block);
 
+	kref_get(&block->b_count);
+
 	/* Unlink block request from list */
 	nlmsvc_unlink_block(block);
 
@@ -601,11 +646,13 @@ nlmsvc_grant_blocked(struct nlm_block *block)
 	case -EAGAIN:
 		dprintk("lockd: lock still blocked\n");
 		nlmsvc_insert_block(block, NLM_NEVER);
+		nlmsvc_release_block(block);
 		return;
 	default:
 		printk(KERN_WARNING "lockd: unexpected error %d in %s!\n",
 				-error, __FUNCTION__);
 		nlmsvc_insert_block(block, 10 * HZ);
+		nlmsvc_release_block(block);
 		return;
 	}
 
@@ -618,7 +665,6 @@ callback:
 	nlmsvc_insert_block(block, 30 * HZ);
 
 	/* Call the client */
-	kref_get(&block->b_count);
 	if (nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG,
 						&nlmsvc_grant_ops) < 0)
 		nlmsvc_release_block(block);
@@ -693,6 +739,23 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
 	nlmsvc_release_block(block);
 }
 
+/* Helper function to handle retry of a deferred block.
+ * If it is a blocking lock, call grant_blocked.
+ * For a non-blocking lock or test lock, revisit the request.
+ */
+static void
+retry_deferred_block(struct nlm_block *block)
+{
+	if (!(block->b_flags & B_GOT_CALLBACK))
+		block->b_flags |= B_TOO_LATE;
+	nlmsvc_insert_block(block, NLM_TIMEOUT);
+	dprintk("revisit block %p flags %d\n",	block, block->b_flags);
+	if (block->b_deferred_req) {
+		block->b_deferred_req->revisit(block->b_deferred_req, 0);
+		block->b_deferred_req = NULL;
+	}
+}
+
 /*
  * Retry all blocked locks that have been notified. This is where lockd
  * picks up locks that can be granted, or grant notifications that must
@@ -716,9 +779,12 @@ nlmsvc_retry_blocked(void)
 
 		dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
 			block, block->b_when);
-		kref_get(&block->b_count);
-		nlmsvc_grant_blocked(block);
-		nlmsvc_release_block(block);
+		if (block->b_flags & B_QUEUED) {
+			dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n",
+				block, block->b_granted, block->b_flags);
+			retry_deferred_block(block);
+		} else
+			nlmsvc_grant_blocked(block);
 	}
 
 	return timeout;
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 9/14] lockd: handle fl_notify callbacks
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Add code to handle file system callback when the lock is finally granted.

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 72 insertions(+), 6 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 00e657a..a558360 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -261,6 +261,8 @@ static void nlmsvc_free_block(struct kref *kref)
 	nlmsvc_freegrantargs(block->b_call);
 	nlm_release_call(block->b_call);
 	nlm_release_file(block->b_file);
+	if (block->b_fl)
+		kfree(block->b_fl);
 	kfree(block);
 }
 
@@ -525,6 +527,32 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
 }
 
 /*
+ * This is a callback from the filesystem for VFS file lock requests.
+ * It will be used if fl_notify is defined and the filesystem can not
+ * respond to the request immediately.
+ * For GETLK request it will copy the reply to the nlm_block.
+ * For SETLK or SETLKW request it will get the local posix lock.
+ * In all cases it will move the block to the head of nlm_blocked q where
+ * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
+ * deferred rpc for GETLK and SETLK.
+ */
+static void
+nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
+			     int result)
+{
+	block->b_flags |= B_GOT_CALLBACK;
+	if (result == 0)
+		block->b_granted = 1;
+	else
+		block->b_flags |= B_TOO_LATE;
+	if (conf) {
+		block->b_fl = kzalloc(sizeof(struct file_lock), GFP_KERNEL);
+		if (block->b_fl)
+			locks_copy_lock(block->b_fl, conf);
+	}
+}
+
+/*
  * Unblock a blocked lock request. This is a callback invoked from the
  * VFS layer when a lock on which we blocked is removed.
  *
@@ -535,18 +563,33 @@ static int
 nlmsvc_notify_blocked(struct file_lock *fl, struct file_lock *conf, int result)
 {
 	struct nlm_block	*block;
+	int rc = -ENOENT;
 
 	dprintk("lockd: nlmsvc_notify_blocked lock %p conf %p result %d\n",
 							fl, conf, result);
+	lock_kernel();
 	list_for_each_entry(block, &nlm_blocked, b_list) {
 		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
+			dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
+							block, block->b_flags);
+			if (block->b_flags & B_QUEUED) {
+				if (block->b_flags & B_TOO_LATE) {
+					rc = -ENOLCK;
+					break;
+				}
+				nlmsvc_update_deferred_block(block, conf, result);
+			}
 			nlmsvc_insert_block(block, 0);
 			svc_wake_up(block->b_daemon);
-			return;
+			rc = 0;
+			break;
 		}
 	}
+	unlock_kernel();
 
-	printk(KERN_WARNING "lockd: notification for unknown block!\n");
+	if (rc == -ENOENT)
+		printk(KERN_WARNING "lockd: notification for unknown block!\n");
+	return rc;
 }
 
 static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
@@ -579,6 +622,8 @@ nlmsvc_grant_blocked(struct nlm_block *block)
 
 	dprintk("lockd: grant blocked lock %p\n", block);
 
+	kref_get(&block->b_count);
+
 	/* Unlink block request from list */
 	nlmsvc_unlink_block(block);
 
@@ -601,11 +646,13 @@ nlmsvc_grant_blocked(struct nlm_block *block)
 	case -EAGAIN:
 		dprintk("lockd: lock still blocked\n");
 		nlmsvc_insert_block(block, NLM_NEVER);
+		nlmsvc_release_block(block);
 		return;
 	default:
 		printk(KERN_WARNING "lockd: unexpected error %d in %s!\n",
 				-error, __FUNCTION__);
 		nlmsvc_insert_block(block, 10 * HZ);
+		nlmsvc_release_block(block);
 		return;
 	}
 
@@ -618,7 +665,6 @@ callback:
 	nlmsvc_insert_block(block, 30 * HZ);
 
 	/* Call the client */
-	kref_get(&block->b_count);
 	if (nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG,
 						&nlmsvc_grant_ops) < 0)
 		nlmsvc_release_block(block);
@@ -693,6 +739,23 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
 	nlmsvc_release_block(block);
 }
 
+/* Helper function to handle retry of a deferred block.
+ * If it is a blocking lock, call grant_blocked.
+ * For a non-blocking lock or test lock, revisit the request.
+ */
+static void
+retry_deferred_block(struct nlm_block *block)
+{
+	if (!(block->b_flags & B_GOT_CALLBACK))
+		block->b_flags |= B_TOO_LATE;
+	nlmsvc_insert_block(block, NLM_TIMEOUT);
+	dprintk("revisit block %p flags %d\n",	block, block->b_flags);
+	if (block->b_deferred_req) {
+		block->b_deferred_req->revisit(block->b_deferred_req, 0);
+		block->b_deferred_req = NULL;
+	}
+}
+
 /*
  * Retry all blocked locks that have been notified. This is where lockd
  * picks up locks that can be granted, or grant notifications that must
@@ -716,9 +779,12 @@ nlmsvc_retry_blocked(void)
 
 		dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
 			block, block->b_when);
-		kref_get(&block->b_count);
-		nlmsvc_grant_blocked(block);
-		nlmsvc_release_block(block);
+		if (block->b_flags & B_QUEUED) {
+			dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n",
+				block, block->b_granted, block->b_flags);
+			retry_deferred_block(block);
+		} else
+			nlmsvc_grant_blocked(block);
 	}
 
 	return timeout;
-- 
1.5.0.rc1.g72fe


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

* [PATCH 10/14] lockd: pass cookie in nlmsvc_testlock
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Change NLM internal interface to pass more information for test lock; we
need this to make sure the cookie information is pushed down to the place
where we do request deferral, which is handled for testlock by the
following patch.

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svc4proc.c         |    2 +-
 fs/lockd/svclock.c          |    5 +++--
 fs/lockd/svcproc.c          |    2 +-
 include/linux/lockd/lockd.h |    4 ++--
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index f67146a..9d4067a 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -99,7 +99,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
 	/* Now check for conflicting locks */
-	resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock);
+	resp->status = nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie);
 
 	dprintk("lockd: TEST4          status %d\n", ntohl(resp->status));
 	nlm_release_host(host);
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index a558360..93f1bc8 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -443,8 +443,9 @@ out:
  * Test for presence of a conflicting lock.
  */
 __be32
-nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
-				       struct nlm_lock *conflock)
+nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
+		struct nlm_lock *lock, struct nlm_lock *conflock,
+		struct nlm_cookie *cookie)
 {
 	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
 				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 3707c3a..73b5c4f 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -127,7 +127,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
 	/* Now check for conflicting locks */
-	resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock));
+	resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie));
 
 	dprintk("lockd: TEST          status %d vers %d\n",
 		ntohl(resp->status), rqstp->rq_vers);
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 1df10d7..f79ac52 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -195,8 +195,8 @@ typedef int	  (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref)
 __be32		  nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
 					struct nlm_lock *, int, struct nlm_cookie *);
 __be32		  nlmsvc_unlock(struct nlm_file *, struct nlm_lock *);
-__be32		  nlmsvc_testlock(struct nlm_file *, struct nlm_lock *,
-					struct nlm_lock *);
+__be32		  nlmsvc_testlock(struct svc_rqst *, struct nlm_file *,
+			struct nlm_lock *, struct nlm_lock *, struct nlm_cookie *);
 __be32		  nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
 unsigned long	  nlmsvc_retry_blocked(void);
 void		  nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 10/14] lockd: pass cookie in nlmsvc_testlock
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Change NLM internal interface to pass more information for test lock; we
need this to make sure the cookie information is pushed down to the place
where we do request deferral, which is handled for testlock by the
following patch.

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svc4proc.c         |    2 +-
 fs/lockd/svclock.c          |    5 +++--
 fs/lockd/svcproc.c          |    2 +-
 include/linux/lockd/lockd.h |    4 ++--
 4 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c
index f67146a..9d4067a 100644
--- a/fs/lockd/svc4proc.c
+++ b/fs/lockd/svc4proc.c
@@ -99,7 +99,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
 	/* Now check for conflicting locks */
-	resp->status = nlmsvc_testlock(file, &argp->lock, &resp->lock);
+	resp->status = nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie);
 
 	dprintk("lockd: TEST4          status %d\n", ntohl(resp->status));
 	nlm_release_host(host);
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index a558360..93f1bc8 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -443,8 +443,9 @@ out:
  * Test for presence of a conflicting lock.
  */
 __be32
-nlmsvc_testlock(struct nlm_file *file, struct nlm_lock *lock,
-				       struct nlm_lock *conflock)
+nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
+		struct nlm_lock *lock, struct nlm_lock *conflock,
+		struct nlm_cookie *cookie)
 {
 	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
 				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c
index 3707c3a..73b5c4f 100644
--- a/fs/lockd/svcproc.c
+++ b/fs/lockd/svcproc.c
@@ -127,7 +127,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp,
 		return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success;
 
 	/* Now check for conflicting locks */
-	resp->status = cast_status(nlmsvc_testlock(file, &argp->lock, &resp->lock));
+	resp->status = cast_status(nlmsvc_testlock(rqstp, file, &argp->lock, &resp->lock, &resp->cookie));
 
 	dprintk("lockd: TEST          status %d vers %d\n",
 		ntohl(resp->status), rqstp->rq_vers);
diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h
index 1df10d7..f79ac52 100644
--- a/include/linux/lockd/lockd.h
+++ b/include/linux/lockd/lockd.h
@@ -195,8 +195,8 @@ typedef int	  (*nlm_host_match_fn_t)(struct nlm_host *cur, struct nlm_host *ref)
 __be32		  nlmsvc_lock(struct svc_rqst *, struct nlm_file *,
 					struct nlm_lock *, int, struct nlm_cookie *);
 __be32		  nlmsvc_unlock(struct nlm_file *, struct nlm_lock *);
-__be32		  nlmsvc_testlock(struct nlm_file *, struct nlm_lock *,
-					struct nlm_lock *);
+__be32		  nlmsvc_testlock(struct svc_rqst *, struct nlm_file *,
+			struct nlm_lock *, struct nlm_lock *, struct nlm_cookie *);
 __be32		  nlmsvc_cancel_blocked(struct nlm_file *, struct nlm_lock *);
 unsigned long	  nlmsvc_retry_blocked(void);
 void		  nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *,
-- 
1.5.0.rc1.g72fe


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

* [PATCH 11/14] lockd: handle test_lock deferrals
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Rewrite nlmsvc_testlock() to use the new asynchronous interface: instead of
immediately doing a posix_test_lock(), we first look for a matching block.
If the subsequent test_lock returns anything other than -EINPROGRESS, we
then remove the block we've found and return the results.

If it returns -EINPROGRESS, then we defer the lock request.

In the case where the block we find in the first step has B_QUEUED set,
we bypass the vfs_test_lock entirely, instead using the block to decide how
to respond:
	with nlm_lck_denied if B_TOO_LATE is set.
	with nlm_granted if B_GOT_CALLBACK is set.
	by dropping if neither B_TOO_LATE nor B_GOT_CALLBACK is set

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |   61 ++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 93f1bc8..91690e3 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -447,6 +447,9 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 		struct nlm_lock *lock, struct nlm_lock *conflock,
 		struct nlm_cookie *cookie)
 {
+	struct nlm_block *block = NULL;
+	int error;
+
 	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
 				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
 				file->f_file->f_path.dentry->d_inode->i_ino,
@@ -454,19 +457,55 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 				(long long)lock->fl.fl_start,
 				(long long)lock->fl.fl_end);
 
-	if (posix_test_lock(file->f_file, &lock->fl, &conflock->fl)) {
-		dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
-				conflock->fl.fl_type,
-				(long long)conflock->fl.fl_start,
-				(long long)conflock->fl.fl_end);
-		conflock->caller = "somehost";	/* FIXME */
-		conflock->len = strlen(conflock->caller);
-		conflock->oh.len = 0;		/* don't return OH info */
-		conflock->svid = conflock->fl.fl_pid;
-		return nlm_lck_denied;
+	/* Get existing block (in case client is busy-waiting) */
+	block = nlmsvc_lookup_block(file, lock);
+
+	if (block == NULL) {
+		block = nlmsvc_create_block(rqstp, file, lock, cookie);
+		if (block == NULL)
+			return nlm_granted;
+	}
+	if (block->b_flags & B_QUEUED) {
+		dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n",
+			block, block->b_flags, block->b_fl);
+		if (block->b_flags & B_TOO_LATE) {
+			nlmsvc_unlink_block(block);
+			return nlm_lck_denied;
+		}
+		if (block->b_flags & B_GOT_CALLBACK) {
+			if (block->b_fl != NULL) {
+				conflock->fl = *block->b_fl;
+				goto conf_lock;
+			}
+			else {
+				nlmsvc_unlink_block(block);
+				return nlm_granted;
+			}
+		}
+		return nlm_drop_reply;
 	}
 
-	return nlm_granted;
+	error = vfs_test_lock(file->f_file, &lock->fl, &conflock->fl);
+	if (error == -EINPROGRESS)
+		return nlmsvc_defer_lock_rqst(rqstp, block);
+	if (error)
+		return nlm_lck_denied_nolocks;
+	if (conflock->fl.fl_type == F_UNLCK) {
+		nlmsvc_unlink_block(block);
+		return nlm_granted;
+	}
+
+conf_lock:
+	dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
+		conflock->fl.fl_type, (long long)conflock->fl.fl_start,
+		(long long)conflock->fl.fl_end);
+	conflock->caller = "somehost";	/* FIXME */
+	conflock->len = strlen(conflock->caller);
+	conflock->oh.len = 0;		/* don't return OH info */
+	conflock->svid = conflock->fl.fl_pid;
+	if (block)
+		nlmsvc_unlink_block(block);
+	return nlm_lck_denied;
 }
 
 /*
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 11/14] lockd: handle test_lock deferrals
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Rewrite nlmsvc_testlock() to use the new asynchronous interface: instead of
immediately doing a posix_test_lock(), we first look for a matching block.
If the subsequent test_lock returns anything other than -EINPROGRESS, we
then remove the block we've found and return the results.

If it returns -EINPROGRESS, then we defer the lock request.

In the case where the block we find in the first step has B_QUEUED set,
we bypass the vfs_test_lock entirely, instead using the block to decide how
to respond:
	with nlm_lck_denied if B_TOO_LATE is set.
	with nlm_granted if B_GOT_CALLBACK is set.
	by dropping if neither B_TOO_LATE nor B_GOT_CALLBACK is set

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |   61 ++++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 50 insertions(+), 11 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 93f1bc8..91690e3 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -447,6 +447,9 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 		struct nlm_lock *lock, struct nlm_lock *conflock,
 		struct nlm_cookie *cookie)
 {
+	struct nlm_block *block = NULL;
+	int error;
+
 	dprintk("lockd: nlmsvc_testlock(%s/%ld, ty=%d, %Ld-%Ld)\n",
 				file->f_file->f_path.dentry->d_inode->i_sb->s_id,
 				file->f_file->f_path.dentry->d_inode->i_ino,
@@ -454,19 +457,55 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file,
 				(long long)lock->fl.fl_start,
 				(long long)lock->fl.fl_end);
 
-	if (posix_test_lock(file->f_file, &lock->fl, &conflock->fl)) {
-		dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
-				conflock->fl.fl_type,
-				(long long)conflock->fl.fl_start,
-				(long long)conflock->fl.fl_end);
-		conflock->caller = "somehost";	/* FIXME */
-		conflock->len = strlen(conflock->caller);
-		conflock->oh.len = 0;		/* don't return OH info */
-		conflock->svid = conflock->fl.fl_pid;
-		return nlm_lck_denied;
+	/* Get existing block (in case client is busy-waiting) */
+	block = nlmsvc_lookup_block(file, lock);
+
+	if (block == NULL) {
+		block = nlmsvc_create_block(rqstp, file, lock, cookie);
+		if (block == NULL)
+			return nlm_granted;
+	}
+	if (block->b_flags & B_QUEUED) {
+		dprintk("lockd: nlmsvc_testlock deferred block %p flags %d fl %p\n",
+			block, block->b_flags, block->b_fl);
+		if (block->b_flags & B_TOO_LATE) {
+			nlmsvc_unlink_block(block);
+			return nlm_lck_denied;
+		}
+		if (block->b_flags & B_GOT_CALLBACK) {
+			if (block->b_fl != NULL) {
+				conflock->fl = *block->b_fl;
+				goto conf_lock;
+			}
+			else {
+				nlmsvc_unlink_block(block);
+				return nlm_granted;
+			}
+		}
+		return nlm_drop_reply;
 	}
 
-	return nlm_granted;
+	error = vfs_test_lock(file->f_file, &lock->fl, &conflock->fl);
+	if (error == -EINPROGRESS)
+		return nlmsvc_defer_lock_rqst(rqstp, block);
+	if (error)
+		return nlm_lck_denied_nolocks;
+	if (conflock->fl.fl_type == F_UNLCK) {
+		nlmsvc_unlink_block(block);
+		return nlm_granted;
+	}
+
+conf_lock:
+	dprintk("lockd: conflicting lock(ty=%d, %Ld-%Ld)\n",
+		conflock->fl.fl_type, (long long)conflock->fl.fl_start,
+		(long long)conflock->fl.fl_end);
+	conflock->caller = "somehost";	/* FIXME */
+	conflock->len = strlen(conflock->caller);
+	conflock->oh.len = 0;		/* don't return OH info */
+	conflock->svid = conflock->fl.fl_pid;
+	if (block)
+		nlmsvc_unlink_block(block);
+	return nlm_lck_denied;
 }
 
 /*
-- 
1.5.0.rc1.g72fe


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

* [PATCH 12/14] lockd: always preallocate block in nlmsvc_lock()
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

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: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |   34 +++++++++++-----------------------
 1 files changed, 11 insertions(+), 23 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 91690e3..32202fa 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -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);
 	lock->fl.fl_flags &= ~FL_SLEEP;
@@ -414,26 +417,11 @@ again:
 		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;
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 12/14] lockd: always preallocate block in nlmsvc_lock()
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

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: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |   34 +++++++++++-----------------------
 1 files changed, 11 insertions(+), 23 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 91690e3..32202fa 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -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);
 	lock->fl.fl_flags &= ~FL_SLEEP;
@@ -414,26 +417,11 @@ again:
 		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;
-- 
1.5.0.rc1.g72fe


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

* [PATCH 13/14] lockd: add code to handle deferred lock requests
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Rewrite nlmsvc_lock() to use the asynchronous interface.

As with testlock, we answer nlm requests in nlmsvc_lock by first looking up
the block and then using the results we find in the block if B_QUEUED is
set, and calling vfs_lock_file() otherwise.

If this a new lock request and we get -EINPROGRESS return on a non-blocking
request then we defer the request.

Also modify nlmsvc_unlock() to call the filesystem method if appropriate.

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |   40 ++++++++++++++++++++++++++++++++++------
 fs/lockd/svcsubs.c |    2 +-
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 32202fa..61137b6 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -393,17 +393,44 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
 	} else
 		lock->fl.fl_flags &= ~FL_SLEEP;
 
-	error = posix_lock_file(file->f_file, &lock->fl);
-	lock->fl.fl_flags &= ~FL_SLEEP;
 
-	dprintk("lockd: posix_lock_file returned %d\n", error);
+	if (block->b_flags & B_QUEUED) {
+		dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n",
+							block, block->b_flags);
+		if (block->b_granted) {
+			nlmsvc_unlink_block(block);
+			ret = nlm_granted;
+			goto out;
+		}
+		if (block->b_flags & B_TOO_LATE) {
+			nlmsvc_unlink_block(block);
+			ret = nlm_lck_denied;
+			goto out;
+		}
+		ret = nlm_drop_reply;
+		goto out;
+	}
 
+	if (!wait)
+		lock->fl.fl_flags &= ~FL_SLEEP;
+	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl);
+	lock->fl.fl_flags &= ~FL_SLEEP;
+
+	dprintk("lockd: vfs_lock_file returned %d\n", error);
 	switch(error) {
 		case 0:
 			ret = nlm_granted;
 			goto out;
 		case -EAGAIN:
+			ret = nlm_lck_denied;
 			break;
+		case -EINPROGRESS:
+			if (wait)
+				break;
+			/* Filesystem lock operation is in progress
+			   Add it to the queue waiting for callback */
+			ret = nlmsvc_defer_lock_rqst(rqstp, block);
+			goto out;
 		case -EDEADLK:
 			ret = nlm_deadlock;
 			goto out;
@@ -519,7 +546,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
 	nlmsvc_cancel_blocked(file, lock);
 
 	lock->fl.fl_type = F_UNLCK;
-	error = posix_lock_file(file->f_file, &lock->fl);
+	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl);
 
 	return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
 }
@@ -665,14 +692,15 @@ nlmsvc_grant_blocked(struct nlm_block *block)
 
 	/* Try the lock operation again */
 	lock->fl.fl_flags |= FL_SLEEP;
-	error = posix_lock_file(file->f_file, &lock->fl);
+	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl);
 	lock->fl.fl_flags &= ~FL_SLEEP;
 
 	switch (error) {
 	case 0:
 		break;
 	case -EAGAIN:
-		dprintk("lockd: lock still blocked\n");
+	case -EINPROGRESS:
+		dprintk("lockd: lock still blocked error %d\n", error);
 		nlmsvc_insert_block(block, NLM_NEVER);
 		nlmsvc_release_block(block);
 		return;
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index c0df00c..cede998 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -182,7 +182,7 @@ again:
 			lock.fl_type  = F_UNLCK;
 			lock.fl_start = 0;
 			lock.fl_end   = OFFSET_MAX;
-			if (posix_lock_file(file->f_file, &lock) < 0) {
+			if (vfs_lock_file(file->f_file, F_SETLK, &lock) < 0) {
 				printk("lockd: unlock failure in %s:%d\n",
 						__FILE__, __LINE__);
 				return 1;
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 13/14] lockd: add code to handle deferred lock requests
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Rewrite nlmsvc_lock() to use the asynchronous interface.

As with testlock, we answer nlm requests in nlmsvc_lock by first looking up
the block and then using the results we find in the block if B_QUEUED is
set, and calling vfs_lock_file() otherwise.

If this a new lock request and we get -EINPROGRESS return on a non-blocking
request then we defer the request.

Also modify nlmsvc_unlock() to call the filesystem method if appropriate.

Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/lockd/svclock.c |   40 ++++++++++++++++++++++++++++++++++------
 fs/lockd/svcsubs.c |    2 +-
 2 files changed, 35 insertions(+), 7 deletions(-)

diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
index 32202fa..61137b6 100644
--- a/fs/lockd/svclock.c
+++ b/fs/lockd/svclock.c
@@ -393,17 +393,44 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file,
 	} else
 		lock->fl.fl_flags &= ~FL_SLEEP;
 
-	error = posix_lock_file(file->f_file, &lock->fl);
-	lock->fl.fl_flags &= ~FL_SLEEP;
 
-	dprintk("lockd: posix_lock_file returned %d\n", error);
+	if (block->b_flags & B_QUEUED) {
+		dprintk("lockd: nlmsvc_lock deferred block %p flags %d\n",
+							block, block->b_flags);
+		if (block->b_granted) {
+			nlmsvc_unlink_block(block);
+			ret = nlm_granted;
+			goto out;
+		}
+		if (block->b_flags & B_TOO_LATE) {
+			nlmsvc_unlink_block(block);
+			ret = nlm_lck_denied;
+			goto out;
+		}
+		ret = nlm_drop_reply;
+		goto out;
+	}
 
+	if (!wait)
+		lock->fl.fl_flags &= ~FL_SLEEP;
+	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl);
+	lock->fl.fl_flags &= ~FL_SLEEP;
+
+	dprintk("lockd: vfs_lock_file returned %d\n", error);
 	switch(error) {
 		case 0:
 			ret = nlm_granted;
 			goto out;
 		case -EAGAIN:
+			ret = nlm_lck_denied;
 			break;
+		case -EINPROGRESS:
+			if (wait)
+				break;
+			/* Filesystem lock operation is in progress
+			   Add it to the queue waiting for callback */
+			ret = nlmsvc_defer_lock_rqst(rqstp, block);
+			goto out;
 		case -EDEADLK:
 			ret = nlm_deadlock;
 			goto out;
@@ -519,7 +546,7 @@ nlmsvc_unlock(struct nlm_file *file, struct nlm_lock *lock)
 	nlmsvc_cancel_blocked(file, lock);
 
 	lock->fl.fl_type = F_UNLCK;
-	error = posix_lock_file(file->f_file, &lock->fl);
+	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl);
 
 	return (error < 0)? nlm_lck_denied_nolocks : nlm_granted;
 }
@@ -665,14 +692,15 @@ nlmsvc_grant_blocked(struct nlm_block *block)
 
 	/* Try the lock operation again */
 	lock->fl.fl_flags |= FL_SLEEP;
-	error = posix_lock_file(file->f_file, &lock->fl);
+	error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl);
 	lock->fl.fl_flags &= ~FL_SLEEP;
 
 	switch (error) {
 	case 0:
 		break;
 	case -EAGAIN:
-		dprintk("lockd: lock still blocked\n");
+	case -EINPROGRESS:
+		dprintk("lockd: lock still blocked error %d\n", error);
 		nlmsvc_insert_block(block, NLM_NEVER);
 		nlmsvc_release_block(block);
 		return;
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c
index c0df00c..cede998 100644
--- a/fs/lockd/svcsubs.c
+++ b/fs/lockd/svcsubs.c
@@ -182,7 +182,7 @@ again:
 			lock.fl_type  = F_UNLCK;
 			lock.fl_start = 0;
 			lock.fl_end   = OFFSET_MAX;
-			if (posix_lock_file(file->f_file, &lock) < 0) {
+			if (vfs_lock_file(file->f_file, F_SETLK, &lock) < 0) {
 				printk("lockd: unlock failure in %s:%d\n",
 						__FILE__, __LINE__);
 				return 1;
-- 
1.5.0.rc1.g72fe


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

* [PATCH 14/14] gfs2: nfs lock support for gfs2
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Add NFS lock support to GFS2.  (Untested.)

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/gfs2/locking/dlm/plock.c    |   76 +++++++++++++++++++++++++++++++++++++--
 fs/gfs2/ops_file.c             |    5 +++
 include/linux/lock_dlm_plock.h |    3 ++
 3 files changed, 80 insertions(+), 4 deletions(-)

diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c
index 3799f19..da6c01c 100644
--- a/fs/gfs2/locking/dlm/plock.c
+++ b/fs/gfs2/locking/dlm/plock.c
@@ -59,6 +59,8 @@ static void send_op(struct plock_op *op)
 	wake_up(&send_wq);
 }
 
+/* XXX: unlock? cancel? ... */
+
 int gdlm_plock(void *lockspace, struct lm_lockname *name,
 	       struct file *file, int cmd, struct file_lock *fl)
 {
@@ -79,9 +81,20 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
 	op->info.start		= fl->fl_start;
 	op->info.end		= fl->fl_end;
 	op->info.owner		= (__u64)(long) fl->fl_owner;
+	if (fl->fl_lmops && fl->fl_lmops->fl_notify) {
+		op->info.callback	= fl->fl_lmops->fl_notify;
+		/* might need to make a copy */
+		op->info.fl		= fl;
+		op->info.file		= file;
+	} else
+		op->info.callback	= NULL;
 
 	send_op(op);
-	wait_event(recv_wq, (op->done != 0));
+
+	if (op->info.callback == NULL)
+		wait_event(recv_wq, (op->done != 0));
+	else
+		return -EINPROGRESS;
 
 	spin_lock(&ops_lock);
 	if (!list_empty(&op->list)) {
@@ -103,6 +116,58 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
 	return rv;
 }
 
+/* Returns failure iff a succesful lock operation should be canceled */
+static int gdlm_plock_callback(struct plock_op *op)
+{
+	struct file *file;
+	struct file_lock *fl;
+	int (*notify)(void *, void *, int) = NULL;
+	int rv = 0;
+
+	spin_lock(&ops_lock);
+	if (!list_empty(&op->list)) {
+		printk(KERN_INFO "plock op on list\n");
+		list_del(&op->list);
+	}
+	spin_unlock(&ops_lock);
+
+	/* check if the following 2 are still valid or make a copy */
+	file = op->info.file;
+	fl = op->info.fl;
+	notify = op->info.callback;
+
+	if (op->info.rv) {
+		notify(fl, NULL, op->info.rv);
+		goto out;
+	}
+
+	/* got fs lock; bookkeep locally as well: */
+	if (posix_lock_file(file, fl)) {
+		/*
+		 * This can only happen in the case of kmalloc() failure.
+		 * The filesystem's own lock is the authoritative lock,
+		 * so a failure to get the lock locally is not a disaster.
+		 * As long as GFS cannot reliably cancel locks (especially
+		 * in a low-memory situation), we're better off ignoring
+		 * this failure than trying to recover.
+		 */
+		log_error("gdlm_plock: vfs lock error file %p fl %p",
+				file, fl);
+	}
+
+	rv = notify(fl, NULL, 0);
+	if (rv) {
+		/* XXX: We need to cancel the fs lock here: */
+		printk("gfs2 lock granted after lock request failed;"
+						" dangling lock!\n");
+		goto out;
+	}
+
+out:
+	kfree(op);
+	return rv;
+}
+
 int gdlm_punlock(void *lockspace, struct lm_lockname *name,
 		 struct file *file, struct file_lock *fl)
 {
@@ -243,9 +308,12 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
 	}
 	spin_unlock(&ops_lock);
 
-	if (found)
-		wake_up(&recv_wq);
-	else
+	if (found) {
+		if (op->info.callback)
+			count = gdlm_plock_callback(op);
+		else
+			wake_up(&recv_wq);
+	} else
 		printk(KERN_INFO "gdlm dev_write no op %x %llx\n", info.fsid,
 			(unsigned long long)info.number);
 	return count;
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index faa07e4..acf23b2 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -576,6 +576,11 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
 		}
 	}
 
+	if (cmd == F_CANCELLK) {
+		/* Hack: */
+		cmd = F_SETLK;
+		fl->fl_type = F_UNLCK;
+	}
 	if (IS_GETLK(cmd))
 		return gfs2_lm_plock_get(sdp, &name, file, fl);
 	else if (fl->fl_type == F_UNLCK)
diff --git a/include/linux/lock_dlm_plock.h b/include/linux/lock_dlm_plock.h
index fc34151..809c5b7 100644
--- a/include/linux/lock_dlm_plock.h
+++ b/include/linux/lock_dlm_plock.h
@@ -35,6 +35,9 @@ struct gdlm_plock_info {
 	__u64 start;
 	__u64 end;
 	__u64 owner;
+	void *callback;
+	void *fl;
+	void *file;
 };
 
 #endif
-- 
1.5.0.rc1.g72fe


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* [PATCH 14/14] gfs2: nfs lock support for gfs2
@ 2007-02-03  5:34     ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-03  5:34 UTC (permalink / raw)
  To: linux-fsdevel; +Cc: nfs, Marc Eshel

From: Marc Eshel <eshel@almaden.ibm.com> - unquoted

Add NFS lock support to GFS2.  (Untested.)

Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
---
 fs/gfs2/locking/dlm/plock.c    |   76 +++++++++++++++++++++++++++++++++++++--
 fs/gfs2/ops_file.c             |    5 +++
 include/linux/lock_dlm_plock.h |    3 ++
 3 files changed, 80 insertions(+), 4 deletions(-)

diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c
index 3799f19..da6c01c 100644
--- a/fs/gfs2/locking/dlm/plock.c
+++ b/fs/gfs2/locking/dlm/plock.c
@@ -59,6 +59,8 @@ static void send_op(struct plock_op *op)
 	wake_up(&send_wq);
 }
 
+/* XXX: unlock? cancel? ... */
+
 int gdlm_plock(void *lockspace, struct lm_lockname *name,
 	       struct file *file, int cmd, struct file_lock *fl)
 {
@@ -79,9 +81,20 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
 	op->info.start		= fl->fl_start;
 	op->info.end		= fl->fl_end;
 	op->info.owner		= (__u64)(long) fl->fl_owner;
+	if (fl->fl_lmops && fl->fl_lmops->fl_notify) {
+		op->info.callback	= fl->fl_lmops->fl_notify;
+		/* might need to make a copy */
+		op->info.fl		= fl;
+		op->info.file		= file;
+	} else
+		op->info.callback	= NULL;
 
 	send_op(op);
-	wait_event(recv_wq, (op->done != 0));
+
+	if (op->info.callback == NULL)
+		wait_event(recv_wq, (op->done != 0));
+	else
+		return -EINPROGRESS;
 
 	spin_lock(&ops_lock);
 	if (!list_empty(&op->list)) {
@@ -103,6 +116,58 @@ int gdlm_plock(void *lockspace, struct lm_lockname *name,
 	return rv;
 }
 
+/* Returns failure iff a succesful lock operation should be canceled */
+static int gdlm_plock_callback(struct plock_op *op)
+{
+	struct file *file;
+	struct file_lock *fl;
+	int (*notify)(void *, void *, int) = NULL;
+	int rv = 0;
+
+	spin_lock(&ops_lock);
+	if (!list_empty(&op->list)) {
+		printk(KERN_INFO "plock op on list\n");
+		list_del(&op->list);
+	}
+	spin_unlock(&ops_lock);
+
+	/* check if the following 2 are still valid or make a copy */
+	file = op->info.file;
+	fl = op->info.fl;
+	notify = op->info.callback;
+
+	if (op->info.rv) {
+		notify(fl, NULL, op->info.rv);
+		goto out;
+	}
+
+	/* got fs lock; bookkeep locally as well: */
+	if (posix_lock_file(file, fl)) {
+		/*
+		 * This can only happen in the case of kmalloc() failure.
+		 * The filesystem's own lock is the authoritative lock,
+		 * so a failure to get the lock locally is not a disaster.
+		 * As long as GFS cannot reliably cancel locks (especially
+		 * in a low-memory situation), we're better off ignoring
+		 * this failure than trying to recover.
+		 */
+		log_error("gdlm_plock: vfs lock error file %p fl %p",
+				file, fl);
+	}
+
+	rv = notify(fl, NULL, 0);
+	if (rv) {
+		/* XXX: We need to cancel the fs lock here: */
+		printk("gfs2 lock granted after lock request failed;"
+						" dangling lock!\n");
+		goto out;
+	}
+
+out:
+	kfree(op);
+	return rv;
+}
+
 int gdlm_punlock(void *lockspace, struct lm_lockname *name,
 		 struct file *file, struct file_lock *fl)
 {
@@ -243,9 +308,12 @@ static ssize_t dev_write(struct file *file, const char __user *u, size_t count,
 	}
 	spin_unlock(&ops_lock);
 
-	if (found)
-		wake_up(&recv_wq);
-	else
+	if (found) {
+		if (op->info.callback)
+			count = gdlm_plock_callback(op);
+		else
+			wake_up(&recv_wq);
+	} else
 		printk(KERN_INFO "gdlm dev_write no op %x %llx\n", info.fsid,
 			(unsigned long long)info.number);
 	return count;
diff --git a/fs/gfs2/ops_file.c b/fs/gfs2/ops_file.c
index faa07e4..acf23b2 100644
--- a/fs/gfs2/ops_file.c
+++ b/fs/gfs2/ops_file.c
@@ -576,6 +576,11 @@ static int gfs2_lock(struct file *file, int cmd, struct file_lock *fl)
 		}
 	}
 
+	if (cmd == F_CANCELLK) {
+		/* Hack: */
+		cmd = F_SETLK;
+		fl->fl_type = F_UNLCK;
+	}
 	if (IS_GETLK(cmd))
 		return gfs2_lm_plock_get(sdp, &name, file, fl);
 	else if (fl->fl_type == F_UNLCK)
diff --git a/include/linux/lock_dlm_plock.h b/include/linux/lock_dlm_plock.h
index fc34151..809c5b7 100644
--- a/include/linux/lock_dlm_plock.h
+++ b/include/linux/lock_dlm_plock.h
@@ -35,6 +35,9 @@ struct gdlm_plock_info {
 	__u64 start;
 	__u64 end;
 	__u64 owner;
+	void *callback;
+	void *fl;
+	void *file;
 };
 
 #endif
-- 
1.5.0.rc1.g72fe


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

* Re: [PATCH 2/14] locks: factor out generic/filesystem switch from test_lock
@ 2007-02-03  8:50     ` Christoph Hellwig
  2007-02-04  1:48       ` J. Bruce Fields
  0 siblings, 1 reply; 43+ messages in thread
From: Christoph Hellwig @ 2007-02-03  8:50 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-fsdevel, nfs, Marc Eshel

> +int vfs_test_lock(struct file *filp, struct file_lock *fl, struct file_lock *conf)

Please make sure to add linebreaks after at most 80 characters.

> +	error = vfs_test_lock(filp, &file_lock, &cfl);
> +	if (error)
> +		goto out;

> +	fl = (cfl.fl_type == F_UNLCK ? NULL : &cfl);
>  	flock.l_type = F_UNLCK;
>  	if (fl != NULL) {

This code snippled is more than ugly.  fl is only checked for equality
once so you should reformulate that check using the actual type check:

	if (cfl.fl_type != F_UNLCK) {

That also allows you to move the

	flock.l_type = fl->fl_type;

out of the if statement later on.  In fact that copying out should
proably move into posix_lock_to_flock and posix_lock_to_fock64
helpers similar to the flock_to_posix_lock and flock64_to_posix_lock
helpers we have for the other way around.


-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* Re: [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code
@ 2007-02-03  8:51     ` Christoph Hellwig
  2007-02-03  5:16       ` Brad Boyer
  2007-02-04  1:58       ` J. Bruce Fields
  0 siblings, 2 replies; 43+ messages in thread
From: Christoph Hellwig @ 2007-02-03  8:51 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 12:33:59AM -0500, J. Bruce Fields wrote:
> + */
> +int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
> +{
> +	if (filp->f_op && filp->f_op->lock)
> +		return filp->f_op->lock(filp, cmd, fl);
> +	else
> +		return posix_lock_file(filp, fl);
> +}
> +EXPORT_SYMBOL(vfs_lock_file);

_GPL please (and same for the last patch)

> +	for (;;) {
> +		error = vfs_lock_file(filp, cmd, file_lock);
> +		if ((error != -EAGAIN) || (cmd == F_SETLK))

No need for the inside braces here.

> +		error = vfs_lock_file(filp, cmd, file_lock);
> +		if ((error != -EAGAIN) || (cmd == F_SETLK64))

again.


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

* Re: [PATCH 4/14] locks: add locking function that returns conflicting lock
@ 2007-02-03  8:54     ` Christoph Hellwig
  2007-02-04  2:02       ` J. Bruce Fields
  0 siblings, 1 reply; 43+ messages in thread
From: Christoph Hellwig @ 2007-02-03  8:54 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 12:34:00AM -0500, J. Bruce Fields wrote:
> From: Marc Eshel <eshel@almaden.ibm.com> - unquoted
> 
> The nfsv4 protocol's lock operation, in the case of a conflict, returns
> information about the conflicting lock.
> 
> It's unclear how clients can use this, so for now we're not going so far as to
> add a filesystem method that can return a conflicting lock, but we may as well
> return something in the local case when it's easy to.
> 
> Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
> ---
>  fs/locks.c                 |   18 ++++++++++++++++++
>  include/linux/lockd/bind.h |    1 +
>  2 files changed, 19 insertions(+), 0 deletions(-)
> 
> diff --git a/fs/locks.c b/fs/locks.c
> index c88139d..1bd6418 100644
> --- a/fs/locks.c
> +++ b/fs/locks.c
> @@ -1706,6 +1706,24 @@ int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
>  }
>  EXPORT_SYMBOL(vfs_lock_file);
>  
> +/**
> + * vfs_lock_file_conf - file byte range lock
> + * @filp: The file to apply the lock to
> + * @fl: The lock to be applied
> + * @conf: Place to return a copy of the conflicting lock, if found.
> + *
> + * read comments for vfs_lock_file()
> + */
> +int vfs_lock_file_conf(struct file *filp, struct file_lock *fl, struct file_lock *conf)
> +{
> +	if (filp->f_op && filp->f_op->lock) {
> +		__locks_copy_lock(conf, fl);
> +		return filp->f_op->lock(filp, F_SETLK, fl);
> +	} else
> +		return posix_lock_file_conf(filp, fl, conf);
> +}
> +EXPORT_SYMBOL(vfs_lock_file_conf);

Is there any reason we want to have both variants?  I think vfs_lock_file
should simple get the last argument and we shouldn't have a separate
vfs_lock_file_conf (which btw doesn't have an exactly descriptive name).
The also allows you to kill __posix_lock_file_conf and only keep a single
posix_lock_file routines that gets the argument aswell.


And btw, in case you ask why I demand all these addition cleanuos:
you're touching an already more than messy codebase and make it more
complex, that needs some cleanups to counterbalance :)

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

* Re: [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code
  2007-02-04  8:37         ` Christoph Hellwig
@ 2007-02-03 21:27           ` Brad Boyer
  0 siblings, 0 replies; 43+ messages in thread
From: Brad Boyer @ 2007-02-03 21:27 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, nfs

On Sun, Feb 04, 2007 at 08:37:32AM +0000, Christoph Hellwig wrote:
> In general we want everything that's internal to be _GPL, and a symbol
> that's only for use in the lock manager falls under that category.

OK. I guess I misunderstood the purpose of the function. Thank you
for your explanation. It looked more generic than that based on a
quick read of the patch.

	Brad Boyer
	flar@allandria.com


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

* Re: [NFS] [PATCH 2/14] locks: factor out generic/filesystem switch from test_lock
@ 2007-02-04  0:32     ` Trond Myklebust
  2007-02-04  1:52       ` J. Bruce Fields
  0 siblings, 1 reply; 43+ messages in thread
From: Trond Myklebust @ 2007-02-04  0:32 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, 2007-02-03 at 00:33 -0500, J. Bruce Fields wrote:
> From: J. Bruce Fields <bfields@snoopy.citi.umich.edu> - unquoted
> 
> Factor out the code that switches between generic and filesystem-specific lock
> methods; eventually we want to call this from lock managers (lockd and nfsd)
> too; currently they only call the generic methods.
> 
> This patch does that for test_lock.
> 
> Note that this hasn't been necessary until recently, because the few
> filesystems that define ->lock() (nfs, cifs...) aren't exportable via NFS.
> However GFS (and, in the future, other cluster filesystems) need to implement
> their own locking to get cluster-coherent locking, and also want to be able to
> export locking to NFS (lockd and NFSv4).
> 
> So we accomplish this by factoring out code such as this and exporting it for
> the use of lockd and nfsd.
> 
> Signed-off-by: "J. Bruce Fields" <bfields@citi.umich.edu>
> ---
>  fs/locks.c                 |   59 ++++++++++++++++++++++++++-----------------
>  include/linux/lockd/bind.h |    2 +
>  2 files changed, 38 insertions(+), 23 deletions(-)
> 
> diff --git a/fs/locks.c b/fs/locks.c
> index 4390a95..95246dc 100644
> --- a/fs/locks.c
> +++ b/fs/locks.c
> @@ -1611,6 +1611,33 @@ asmlinkage long sys_flock(unsigned int fd, unsigned int cmd)
>  	return error;
>  }
>  
> +/**
> + * vfs_test_lock - test file byte range lock
> + * @filp: The file to test lock for
> + * @fl: The lock to test
> + * @conf: Place to return a copy of the conflicting lock, if found
> + *
> + * Returns -ERRNO on failure.  Indicates presence of conflicting lock by
> + * setting conf->fl_type to something other than F_UNLCK.
> + */
> +int vfs_test_lock(struct file *filp, struct file_lock *fl, struct file_lock *conf)
> +{
> +	int error;
> +
> +	conf->fl_type = F_UNLCK;
> +	if (filp->f_op && filp->f_op->lock) {
> +		__locks_copy_lock(conf, fl);
> +		error = filp->f_op->lock(filp, F_GETLK, conf);
> +		if (conf->fl_ops && conf->fl_ops->fl_release_private)
> +			conf->fl_ops->fl_release_private(conf);

Why are you adding in a "release" call here? Is there any reason why a
GETLK would want to return private data from the filesystem to the VFS?

> +		return error;
> +	} else {
> +		posix_test_lock(filp, fl, conf);
> +		return 0;
> +	}
> +}
> +EXPORT_SYMBOL(vfs_test_lock);
> +
>  /* Report the first existing lock that would conflict with l.
>   * This implements the F_GETLK command of fcntl().
>   */
> @@ -1631,17 +1658,10 @@ int fcntl_getlk(struct file *filp, struct flock __user *l)
>  	if (error)
>  		goto out;
>  
> -	if (filp->f_op && filp->f_op->lock) {
> -		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
> -		if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
> -			file_lock.fl_ops->fl_release_private(&file_lock);
> -		if (error < 0)
> -			goto out;
> -		else
> -		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
> -	} else {
> -		fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
> -	}
> +	error = vfs_test_lock(filp, &file_lock, &cfl);
> +	if (error)
> +		goto out;
> +	fl = (cfl.fl_type == F_UNLCK ? NULL : &cfl);
>   
>  	flock.l_type = F_UNLCK;
>  	if (fl != NULL) {
> @@ -1785,18 +1805,11 @@ int fcntl_getlk64(struct file *filp, struct flock64 __user *l)
>  	if (error)
>  		goto out;
>  
> -	if (filp->f_op && filp->f_op->lock) {
> -		error = filp->f_op->lock(filp, F_GETLK, &file_lock);
> -		if (file_lock.fl_ops && file_lock.fl_ops->fl_release_private)
> -			file_lock.fl_ops->fl_release_private(&file_lock);
> -		if (error < 0)
> -			goto out;
> -		else
> -		  fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock);
> -	} else {
> -		fl = (posix_test_lock(filp, &file_lock, &cfl) ? &cfl : NULL);
> -	}
> - 
> +	error = vfs_test_lock(filp, &file_lock, &cfl);
> +	if (error)
> +		goto out;
> +	fl = (cfl.fl_type == F_UNLCK ? NULL : &cfl);
> +
>  	flock.l_type = F_UNLCK;
>  	if (fl != NULL) {
>  		flock.l_pid = fl->fl_pid;
> diff --git a/include/linux/lockd/bind.h b/include/linux/lockd/bind.h
> index 246de1d..f78b24a 100644
> --- a/include/linux/lockd/bind.h
> +++ b/include/linux/lockd/bind.h
> @@ -38,4 +38,6 @@ extern int	nlmclnt_proc(struct inode *, int, struct file_lock *);
>  extern int	lockd_up(int proto);
>  extern void	lockd_down(void);
>  
> +extern int vfs_test_lock(struct file *, struct file_lock *, struct file_lock *);
> +
>  #endif /* LINUX_LOCKD_BIND_H */
> -- 
> 1.5.0.rc1.g72fe
> 
> 
> -------------------------------------------------------------------------
> Using Tomcat but need to do more? Need to support web services, security?
> Get stuff done quickly with pre-integrated technology to make your job easier.
> Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
> http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
> _______________________________________________
> NFS maillist  -  NFS@lists.sourceforge.net
> https://lists.sourceforge.net/lists/listinfo/nfs


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

* Re: [NFS] [PATCH 9/14] lockd: handle fl_notify callbacks
@ 2007-02-04  0:40     ` Trond Myklebust
  2007-02-04  2:10       ` J. Bruce Fields
  0 siblings, 1 reply; 43+ messages in thread
From: Trond Myklebust @ 2007-02-04  0:40 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, 2007-02-03 at 00:34 -0500, J. Bruce Fields wrote:
> From: Marc Eshel <eshel@almaden.ibm.com> - unquoted
> 
> Add code to handle file system callback when the lock is finally granted.
> 
> Signed-off-by: Marc Eshel <eshel@almaden.ibm.com>
> Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
> ---
>  fs/lockd/svclock.c |   78 ++++++++++++++++++++++++++++++++++++++++++++++++----
>  1 files changed, 72 insertions(+), 6 deletions(-)
> 
> diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c
> index 00e657a..a558360 100644
> --- a/fs/lockd/svclock.c
> +++ b/fs/lockd/svclock.c
> @@ -261,6 +261,8 @@ static void nlmsvc_free_block(struct kref *kref)
>  	nlmsvc_freegrantargs(block->b_call);
>  	nlm_release_call(block->b_call);
>  	nlm_release_file(block->b_file);
> +	if (block->b_fl)
> +		kfree(block->b_fl);
>  	kfree(block);
>  }
>  
> @@ -525,6 +527,32 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock)
>  }
>  
>  /*
> + * This is a callback from the filesystem for VFS file lock requests.
> + * It will be used if fl_notify is defined and the filesystem can not
> + * respond to the request immediately.
> + * For GETLK request it will copy the reply to the nlm_block.
> + * For SETLK or SETLKW request it will get the local posix lock.
> + * In all cases it will move the block to the head of nlm_blocked q where
> + * nlmsvc_retry_blocked() can send back a reply for SETLKW or revisit the
> + * deferred rpc for GETLK and SETLK.
> + */
> +static void
> +nlmsvc_update_deferred_block(struct nlm_block *block, struct file_lock *conf,
> +			     int result)
> +{
> +	block->b_flags |= B_GOT_CALLBACK;
> +	if (result == 0)
> +		block->b_granted = 1;
> +	else
> +		block->b_flags |= B_TOO_LATE;
> +	if (conf) {
> +		block->b_fl = kzalloc(sizeof(struct file_lock), GFP_KERNEL);
> +		if (block->b_fl)
> +			locks_copy_lock(block->b_fl, conf);
> +	}
> +}
> +
> +/*
>   * Unblock a blocked lock request. This is a callback invoked from the
>   * VFS layer when a lock on which we blocked is removed.
>   *
> @@ -535,18 +563,33 @@ static int
>  nlmsvc_notify_blocked(struct file_lock *fl, struct file_lock *conf, int result)
>  {
>  	struct nlm_block	*block;
> +	int rc = -ENOENT;
>  
>  	dprintk("lockd: nlmsvc_notify_blocked lock %p conf %p result %d\n",
>  							fl, conf, result);
> +	lock_kernel();
>  	list_for_each_entry(block, &nlm_blocked, b_list) {
>  		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
> +			dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
> +							block, block->b_flags);
> +			if (block->b_flags & B_QUEUED) {
> +				if (block->b_flags & B_TOO_LATE) {
> +					rc = -ENOLCK;
> +					break;
> +				}
> +				nlmsvc_update_deferred_block(block, conf, result);

but nlmsvc_update_deferred_block() can sleep! How are you protecting
against races with notification? Also, how are you guaranteeing that the
block queue won't change underneath you when you lose the BKL.

> +			}
>  			nlmsvc_insert_block(block, 0);
>  			svc_wake_up(block->b_daemon);
> -			return;
> +			rc = 0;
> +			break;
>  		}
>  	}
> +	unlock_kernel();
>  
> -	printk(KERN_WARNING "lockd: notification for unknown block!\n");
> +	if (rc == -ENOENT)
> +		printk(KERN_WARNING "lockd: notification for unknown block!\n");
> +	return rc;
>  }
>  
>  static int nlmsvc_same_owner(struct file_lock *fl1, struct file_lock *fl2)
> @@ -579,6 +622,8 @@ nlmsvc_grant_blocked(struct nlm_block *block)
>  
>  	dprintk("lockd: grant blocked lock %p\n", block);
>  
> +	kref_get(&block->b_count);
> +
>  	/* Unlink block request from list */
>  	nlmsvc_unlink_block(block);
>  
> @@ -601,11 +646,13 @@ nlmsvc_grant_blocked(struct nlm_block *block)
>  	case -EAGAIN:
>  		dprintk("lockd: lock still blocked\n");
>  		nlmsvc_insert_block(block, NLM_NEVER);
> +		nlmsvc_release_block(block);
>  		return;
>  	default:
>  		printk(KERN_WARNING "lockd: unexpected error %d in %s!\n",
>  				-error, __FUNCTION__);
>  		nlmsvc_insert_block(block, 10 * HZ);
> +		nlmsvc_release_block(block);
>  		return;
>  	}
>  
> @@ -618,7 +665,6 @@ callback:
>  	nlmsvc_insert_block(block, 30 * HZ);
>  
>  	/* Call the client */
> -	kref_get(&block->b_count);
>  	if (nlm_async_call(block->b_call, NLMPROC_GRANTED_MSG,
>  						&nlmsvc_grant_ops) < 0)
>  		nlmsvc_release_block(block);
> @@ -693,6 +739,23 @@ nlmsvc_grant_reply(struct nlm_cookie *cookie, __be32 status)
>  	nlmsvc_release_block(block);
>  }
>  
> +/* Helper function to handle retry of a deferred block.
> + * If it is a blocking lock, call grant_blocked.
> + * For a non-blocking lock or test lock, revisit the request.
> + */
> +static void
> +retry_deferred_block(struct nlm_block *block)
> +{
> +	if (!(block->b_flags & B_GOT_CALLBACK))
> +		block->b_flags |= B_TOO_LATE;
> +	nlmsvc_insert_block(block, NLM_TIMEOUT);
> +	dprintk("revisit block %p flags %d\n",	block, block->b_flags);
> +	if (block->b_deferred_req) {
> +		block->b_deferred_req->revisit(block->b_deferred_req, 0);
> +		block->b_deferred_req = NULL;
> +	}
> +}
> +
>  /*
>   * Retry all blocked locks that have been notified. This is where lockd
>   * picks up locks that can be granted, or grant notifications that must
> @@ -716,9 +779,12 @@ nlmsvc_retry_blocked(void)
>  
>  		dprintk("nlmsvc_retry_blocked(%p, when=%ld)\n",
>  			block, block->b_when);
> -		kref_get(&block->b_count);
> -		nlmsvc_grant_blocked(block);
> -		nlmsvc_release_block(block);
> +		if (block->b_flags & B_QUEUED) {
> +			dprintk("nlmsvc_retry_blocked delete block (%p, granted=%d, flags=%d)\n",
> +				block, block->b_granted, block->b_flags);
> +			retry_deferred_block(block);
> +		} else
> +			nlmsvc_grant_blocked(block);
>  	}
>  
>  	return timeout;


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

* Re: [PATCH 2/14] locks: factor out generic/filesystem switch from test_lock
  2007-02-03  8:50     ` Christoph Hellwig
@ 2007-02-04  1:48       ` J. Bruce Fields
  2007-02-04  8:41         ` Christoph Hellwig
  0 siblings, 1 reply; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-04  1:48 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 08:50:25AM +0000, Christoph Hellwig wrote:
> > +int vfs_test_lock(struct file *filp, struct file_lock *fl, struct file_lock *conf)
> 
> Please make sure to add linebreaks after at most 80 characters.

OK, done.

> 
> > +	error = vfs_test_lock(filp, &file_lock, &cfl);
> > +	if (error)
> > +		goto out;
> 
> > +	fl = (cfl.fl_type == F_UNLCK ? NULL : &cfl);
> >  	flock.l_type = F_UNLCK;
> >  	if (fl != NULL) {
> 
> This code snippled is more than ugly.  fl is only checked for equality
> once so you should reformulate that check using the actual type check:
> 
> 	if (cfl.fl_type != F_UNLCK) {
> 
> That also allows you to move the
> 
> 	flock.l_type = fl->fl_type;
> 
> out of the if statement later on.

That's a good idea, thanks; done.

Actually, I wonder if there's any reason we couldn't also just give
posix_test_lock() the same interface as ->lock?  (The latter uses the
same file_lock argument for the input and (in the case where it finds
a conflicting lock) the output, where the former uses an extra argument
to pass back the lock.)  That'd make this a little simpler too.

> In fact that copying out should proably move into posix_lock_to_flock
> and posix_lock_to_fock64 helpers similar to the flock_to_posix_lock
> and flock64_to_posix_lock helpers we have for the other way around.

OK!--b.

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

* Re: [NFS] [PATCH 2/14] locks: factor out generic/filesystem switch from test_lock
  2007-02-04  0:32     ` [NFS] " Trond Myklebust
@ 2007-02-04  1:52       ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-04  1:52 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 04:32:05PM -0800, Trond Myklebust wrote:
> On Sat, 2007-02-03 at 00:33 -0500, J. Bruce Fields wrote:
> > From: J. Bruce Fields <bfields@snoopy.citi.umich.edu> - unquoted
> > +int vfs_test_lock(struct file *filp, struct file_lock *fl, struct file_lock *conf)
> > +{
> > +	int error;
> > +
> > +	conf->fl_type = F_UNLCK;
> > +	if (filp->f_op && filp->f_op->lock) {
> > +		__locks_copy_lock(conf, fl);
> > +		error = filp->f_op->lock(filp, F_GETLK, conf);
> > +		if (conf->fl_ops && conf->fl_ops->fl_release_private)
> > +			conf->fl_ops->fl_release_private(conf);
> 
> Why are you adding in a "release" call here? Is there any reason why a
> GETLK would want to return private data from the filesystem to the VFS?

I'm not adding it--it's already there in the current code for
fcntl_getlk().

I looked over the nfsv4 implementation of ->lock in the getlk case, and
it looks to me like it does in fact return the lock with private data
still set, and counts on the VFS to release it.  But I was just skimming
and may have overlooked something.

--b.

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

* Re: [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code
  2007-02-03  8:51     ` Christoph Hellwig
  2007-02-03  5:16       ` Brad Boyer
@ 2007-02-04  1:58       ` J. Bruce Fields
  1 sibling, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-04  1:58 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 08:51:36AM +0000, Christoph Hellwig wrote:
> On Sat, Feb 03, 2007 at 12:33:59AM -0500, J. Bruce Fields wrote:
> > + */
> > +int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
> > +{
> > +	if (filp->f_op && filp->f_op->lock)
> > +		return filp->f_op->lock(filp, cmd, fl);
> > +	else
> > +		return posix_lock_file(filp, fl);
> > +}
> > +EXPORT_SYMBOL(vfs_lock_file);
> 
> _GPL please (and same for the last patch)

Oops, sorry--I think you asked for that before.  OK, done.

> 
> > +	for (;;) {
> > +		error = vfs_lock_file(filp, cmd, file_lock);
> > +		if ((error != -EAGAIN) || (cmd == F_SETLK))
> 
> No need for the inside braces here.
> 
> > +		error = vfs_lock_file(filp, cmd, file_lock);
> > +		if ((error != -EAGAIN) || (cmd == F_SETLK64))
> 
> again.

Got it, thanks.--b.

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

* Re: [PATCH 4/14] locks: add locking function that returns conflicting lock
  2007-02-03  8:54     ` Christoph Hellwig
@ 2007-02-04  2:02       ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-04  2:02 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 08:54:50AM +0000, Christoph Hellwig wrote:
> Is there any reason we want to have both variants?  I think vfs_lock_file
> should simple get the last argument and we shouldn't have a separate
> vfs_lock_file_conf (which btw doesn't have an exactly descriptive name).
> The also allows you to kill __posix_lock_file_conf and only keep a single
> posix_lock_file routines that gets the argument aswell.

That sounds reasonable.

> And btw, in case you ask why I demand all these addition cleanuos:
> you're touching an already more than messy codebase and make it more
> complex, that needs some cleanups to counterbalance :)

I find locks.c really hard to read, so I'm happy for any suggestions for
cleanups....

--b.

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

* Re: [PATCH 9/14] lockd: handle fl_notify callbacks
  2007-02-04  0:40     ` [NFS] " Trond Myklebust
@ 2007-02-04  2:10       ` J. Bruce Fields
  0 siblings, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-04  2:10 UTC (permalink / raw)
  To: Trond Myklebust; +Cc: linux-fsdevel, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 04:40:05PM -0800, Trond Myklebust wrote:
> On Sat, 2007-02-03 at 00:34 -0500, J. Bruce Fields wrote:
> >  nlmsvc_notify_blocked(struct file_lock *fl, struct file_lock *conf, int result)
> >  {
> >  	struct nlm_block	*block;
> > +	int rc = -ENOENT;
> >  
> >  	dprintk("lockd: nlmsvc_notify_blocked lock %p conf %p result %d\n",
> >  							fl, conf, result);
> > +	lock_kernel();
> >  	list_for_each_entry(block, &nlm_blocked, b_list) {
> >  		if (nlm_compare_locks(&block->b_call->a_args.lock.fl, fl)) {
> > +			dprintk("lockd: nlmsvc_notify_blocked block %p flags %d\n",
> > +							block, block->b_flags);
> > +			if (block->b_flags & B_QUEUED) {
> > +				if (block->b_flags & B_TOO_LATE) {
> > +					rc = -ENOLCK;
> > +					break;
> > +				}
> > +				nlmsvc_update_deferred_block(block, conf, result);
> 
> but nlmsvc_update_deferred_block() can sleep!

Yep, you're right.  Fortunately, the only reason it sleeps is a single
allocation that's probably easy enough to do elsewhere, which I believe
would fix this:

> How are you protecting against races with notification? Also, how are
> you guaranteeing that the block queue won't change underneath you when
> you lose the BKL.

--b.

-------------------------------------------------------------------------
Using Tomcat but need to do more? Need to support web services, security?
Get stuff done quickly with pre-integrated technology to make your job easier.
Download IBM WebSphere Application Server v.1.0.1 based on Apache Geronimo
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=120709&bid=263057&dat=121642
_______________________________________________
NFS maillist  -  NFS@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nfs

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

* Re: [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code
  2007-02-03  5:16       ` Brad Boyer
@ 2007-02-04  2:27         ` J. Bruce Fields
  2007-02-04  8:37         ` Christoph Hellwig
  1 sibling, 0 replies; 43+ messages in thread
From: J. Bruce Fields @ 2007-02-04  2:27 UTC (permalink / raw)
  To: Brad Boyer; +Cc: Christoph Hellwig, linux-fsdevel, nfs, Marc Eshel

On Fri, Feb 02, 2007 at 09:16:38PM -0800, Brad Boyer wrote:
> On Sat, Feb 03, 2007 at 08:51:36AM +0000, Christoph Hellwig wrote:
> > On Sat, Feb 03, 2007 at 12:33:59AM -0500, J. Bruce Fields wrote:
> > > + */
> > > +int vfs_lock_file(struct file *filp, unsigned int cmd, struct file_lock *fl)
> > > +{
> > > +	if (filp->f_op && filp->f_op->lock)
> > > +		return filp->f_op->lock(filp, cmd, fl);
> > > +	else
> > > +		return posix_lock_file(filp, fl);
> > > +}
> > > +EXPORT_SYMBOL(vfs_lock_file);
> > 
> > _GPL please (and same for the last patch)
> 
> Any particular reason? It seems like this is a function that
> would be exactly the sort of thing to be publically exported.
> I know it's not a popular opinion around here, but I think
> that the GPL exports should be primarily for things that
> aren't intended to be used by normal modules.

Actually, this is only used by the NLM and NFSv4 servers.  I doubt
there will be other users any time soon.

If you really want to argue about the EXPORT_SYMBOL_GPL stuff you'll
want to google through the archives for previous discussions first.

--b.

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

* Re: [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code
  2007-02-03  5:16       ` Brad Boyer
  2007-02-04  2:27         ` J. Bruce Fields
@ 2007-02-04  8:37         ` Christoph Hellwig
  2007-02-03 21:27           ` Brad Boyer
  1 sibling, 1 reply; 43+ messages in thread
From: Christoph Hellwig @ 2007-02-04  8:37 UTC (permalink / raw)
  To: Brad Boyer
  Cc: Christoph Hellwig, J. Bruce Fields, linux-fsdevel, nfs, Marc Eshel

On Fri, Feb 02, 2007 at 09:16:38PM -0800, Brad Boyer wrote:
> Any particular reason?

In general we want everything that's internal to be _GPL, and a symbol
that's only for use in the lock manager falls under that category.


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

* Re: [PATCH 2/14] locks: factor out generic/filesystem switch from test_lock
  2007-02-04  1:48       ` J. Bruce Fields
@ 2007-02-04  8:41         ` Christoph Hellwig
  0 siblings, 0 replies; 43+ messages in thread
From: Christoph Hellwig @ 2007-02-04  8:41 UTC (permalink / raw)
  To: J. Bruce Fields; +Cc: Christoph Hellwig, linux-fsdevel, nfs, Marc Eshel

On Sat, Feb 03, 2007 at 08:48:44PM -0500, J. Bruce Fields wrote:
> Actually, I wonder if there's any reason we couldn't also just give
> posix_test_lock() the same interface as ->lock?  (The latter uses the
> same file_lock argument for the input and (in the case where it finds
> a conflicting lock) the output, where the former uses an extra argument
> to pass back the lock.)  That'd make this a little simpler too.

yes, giving posix_test_lock the same interface as ->lock would be
even better. 


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

end of thread, other threads:[~2007-02-04 17:57 UTC | newest]

Thread overview: 43+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <11704808501171-git-send-email->
     [not found] ` <11704808502512-git-send-email->
     [not found]   ` <11704808513862-git-send-email->
     [not found]     ` <1170480851972-git-send-email->
     [not found]       ` <11704808513070-git-send-email->
     [not found]         ` <117048085185-git-send-email->
     [not found]           ` <11704808513263-git-send-email->
     [not found]             ` <11704808513185-git-send-email->
     [not found]               ` <11704808511238-git-send-email->
     [not found]                 ` <11704808513085-git-send-email->
     [not found]                   ` <11704808521765-git-send-email->
     [not found]                     ` <11704808523686-git-send-email->
2007-02-03  5:33 ` [PATCH 1/14] locks: always unlock on close J. Bruce Fields
2007-02-03  5:33   ` J. Bruce Fields
2007-02-03  5:33   ` J. Bruce Fields
2007-02-03  5:33   ` [PATCH 2/14] locks: factor out generic/filesystem switch from test_lock J. Bruce Fields
2007-02-03  5:33     ` J. Bruce Fields
2007-02-03  5:33     ` J. Bruce Fields
2007-02-03  8:50     ` Christoph Hellwig
2007-02-04  1:48       ` J. Bruce Fields
2007-02-04  8:41         ` Christoph Hellwig
2007-02-04  0:32     ` [NFS] " Trond Myklebust
2007-02-04  1:52       ` J. Bruce Fields
2007-02-03  5:33   ` [PATCH 3/14] locks: factor out generic/filesystem switch from setlock code J. Bruce Fields
2007-02-03  5:33     ` J. Bruce Fields
2007-02-03  5:33     ` J. Bruce Fields
2007-02-03  8:51     ` Christoph Hellwig
2007-02-03  5:16       ` Brad Boyer
2007-02-04  2:27         ` J. Bruce Fields
2007-02-04  8:37         ` Christoph Hellwig
2007-02-03 21:27           ` Brad Boyer
2007-02-04  1:58       ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 4/14] locks: add locking function that returns conflicting lock J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  8:54     ` Christoph Hellwig
2007-02-04  2:02       ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 5/14] locks: add fl_notify arguments for asynchronous lock return J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 6/14] locks: add lock cancel command J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 7/14] nfsd4: Convert NFSv4 to new lock interface J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 8/14] lockd: save lock state on deferral J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 9/14] lockd: handle fl_notify callbacks J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-04  0:40     ` [NFS] " Trond Myklebust
2007-02-04  2:10       ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 10/14] lockd: pass cookie in nlmsvc_testlock J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 11/14] lockd: handle test_lock deferrals J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 12/14] lockd: always preallocate block in nlmsvc_lock() J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 13/14] lockd: add code to handle deferred lock requests J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34   ` [PATCH 14/14] gfs2: nfs lock support for gfs2 J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields
2007-02-03  5:34     ` J. Bruce Fields

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.