PATCH: 2.2.2 NFS fnctl F_GETLK and NFS lock behaviour with nolock selected.

Matthew Grant (grantma@anathoth.gen.nz)
Mon, 01 Mar 1999 08:50:18 +1300


This is a multi-part message in MIME format.
--------------E6175EBE7D6A3FB82D28A035
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Alan,

Could you please tell me what to do with this patch. I want to get this
into 2.2.3 as it fixes a few bugs with the new NFS lock code
behaviourwith fcntl F_GETLK. I am repeating this post as I believe the
original subject I filed it under was wrong.

(For those repsonding to this on the kernel-list, please CC me as I am
not subscribed.)

The 2.2.2 fcntl F_GETLK and nolock locking fixes
------------------------------------------------

While converting my setup to kernel 2.2.2 I found that ypbind on my
Xterm machine was failing with a wierd log message saying that it was
alredy running. I tracked this down to some wierd fnctl F_GETLK returns
when the /var/run/ypbind.pid file was on an NFS file system. The point
where the
nfs_lock function ties into the fcntl_getlk function in fs/locks.c was
incorrect and I also found by inspecting nfs_lock in fs/nfs/file.c that
this was compounded because in this case posix_test_lock was never
called for a mount with an option of 'nolock'. This patch fixes this
bug and makes fnctl return the same struct flock as it would on doing
the operation on an ext2fs file system. There is also a fix for a bug
in lockd related to the F_GETLK testing that actually the correct
result!

I also changed the ordering of the checks in nfs_lock so that an NFS
mount with the nolock option should hopefully now behave the same as
under 2.0.x when it comes to locking matters. Please correct this if I
got it wrong.

The patch is MIME attached as I am writing this in Netscape....DUH! I am
planning to go to GNUS ASAP...

The patch applies cleanly to vanilla 2.2.2 and 2.2.2 + ac4.

For those who are reading the message here is a cut and paste version:

-----------Cut here-----------------
--- linux-2.2.2.orig/include/linux/fs.h Tue Feb 23 11:50:24 1999
+++ linux/include/linux/fs.h Sat Feb 27 22:28:10 1999
@@ -650,6 +650,10 @@
extern int register_filesystem(struct file_system_type *);
extern int unregister_filesystem(struct file_system_type *);

+/* Return value for VFS lock functions - tells locks.c to lock
conventionally
+ * REALLY kosha for root NFS and nfs_lock
+ */
+#define LOCK_USE_CLNT 1

#define FLOCK_VERIFY_READ 1
#define FLOCK_VERIFY_WRITE 2
--- linux-2.2.2.orig/fs/locks.c Thu Dec 24 09:11:45 1998
+++ linux/fs/locks.c Sat Feb 27 22:49:17 1999
@@ -339,7 +339,11 @@
error = filp->f_op->lock(filp, F_GETLK, &file_lock);
if (error < 0)
goto out_putf;
- fl = &file_lock;
+ else if (error == LOCK_USE_CLNT)
+ /* Bypass for NFS with no locking - 2.0.36 compat */
+ fl = posix_test_lock(filp, &file_lock);
+ else
+ fl = (file_lock.fl_type == F_UNLCK ? NULL :
&file_lock);
} else {
fl = posix_test_lock(filp, &file_lock);
}
@@ -450,6 +454,10 @@

if (filp->f_op->lock != NULL) {
error = filp->f_op->lock(filp, cmd, &file_lock);
+ /*
+ * FUTURE: Watch out for return of LOCK_USE_CLNT here!
+ * See nfs_lock in fs/nfs/file.c
+ */
if (error < 0)
goto out_putf;
}
--- linux-2.2.2.orig/fs/nfs/file.c Wed Dec 2 10:34:51 1998
+++ linux/fs/nfs/file.c Sat Feb 27 23:10:41 1999
@@ -214,6 +214,18 @@
struct inode * inode = filp->f_dentry->d_inode;
int status;

+ /*
+ * Do something for a FS mounted without NLM support
+ * Tell code in locks.c to lock in client-side kernel.
+ * This is here so that the nolock option to the NFS
+ * mount causes behaviour as in 2.0.x for compatibility
+ * and less FRIGHT.
+ * This REALLY helps with root NFS mounts.
+ */
+ if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) {
+ return LOCK_USE_CLNT;
+ }
+
dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%ld:%ld)\n",
inode->i_dev, inode->i_ino,
fl->fl_type, fl->fl_flags,
@@ -225,10 +237,6 @@
/* No mandatory locks over NFS */
if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID)
return -ENOLCK;
-
- /* Fake OK code if mounted without NLM support */
- if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM)
- return 0;

/*
* No BSD flocks over NFS allowed.
--- linux-2.2.2.orig/fs/lockd/clntproc.c Thu Feb 18 06:44:33 1999
+++ linux/fs/lockd/clntproc.c Sat Feb 27 19:41:24 1999
@@ -328,7 +328,7 @@
status = req->a_res.status;
if (status == NLM_LCK_GRANTED) {
fl->fl_type = F_UNLCK;
- } if (status == NLM_LCK_DENIED) {
+ } else if (status == NLM_LCK_DENIED) {
/*
* Report the conflicting lock back to the application.
* FIXME: Is it OK to report the pid back as well?
-----------Cut here-----------------

Cheers,

Matthew Grant

-- 
-----------------------------------------------------------------------
Matthew Grant                        Email: grantma@anathoth.gen.nz
                                     Phone: +64 3 338-6287
--------------E6175EBE7D6A3FB82D28A035
Content-Type: text/plain; charset=us-ascii; name="linux-2.2.2-nfslck2.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="linux-2.2.2-nfslck2.patch"

--- linux-2.2.2.orig/include/linux/fs.h Tue Feb 23 11:50:24 1999 +++ linux/include/linux/fs.h Sat Feb 27 22:28:10 1999 @@ -650,6 +650,10 @@ extern int register_filesystem(struct file_system_type *); extern int unregister_filesystem(struct file_system_type *); +/* Return value for VFS lock functions - tells locks.c to lock conventionally + * REALLY kosha for root NFS and nfs_lock + */ +#define LOCK_USE_CLNT 1 #define FLOCK_VERIFY_READ 1 #define FLOCK_VERIFY_WRITE 2 --- linux-2.2.2.orig/fs/locks.c Thu Dec 24 09:11:45 1998 +++ linux/fs/locks.c Sat Feb 27 22:49:17 1999 @@ -339,7 +339,11 @@ error = filp->f_op->lock(filp, F_GETLK, &file_lock); if (error < 0) goto out_putf; - fl = &file_lock; + else if (error == LOCK_USE_CLNT) + /* Bypass for NFS with no locking - 2.0.36 compat */ + fl = posix_test_lock(filp, &file_lock); + else + fl = (file_lock.fl_type == F_UNLCK ? NULL : &file_lock); } else { fl = posix_test_lock(filp, &file_lock); } @@ -450,6 +454,10 @@ if (filp->f_op->lock != NULL) { error = filp->f_op->lock(filp, cmd, &file_lock); + /* + * FUTURE: Watch out for return of LOCK_USE_CLNT here! + * See nfs_lock in fs/nfs/file.c + */ if (error < 0) goto out_putf; } --- linux-2.2.2.orig/fs/nfs/file.c Wed Dec 2 10:34:51 1998 +++ linux/fs/nfs/file.c Sat Feb 27 23:10:41 1999 @@ -214,6 +214,18 @@ struct inode * inode = filp->f_dentry->d_inode; int status; + /* + * Do something for a FS mounted without NLM support + * Tell code in locks.c to lock in client-side kernel. + * This is here so that the nolock option to the NFS + * mount causes behaviour as in 2.0.x for compatibility + * and less FRIGHT. + * This REALLY helps with root NFS mounts. + */ + if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) { + return LOCK_USE_CLNT; + } + dprintk("NFS: nfs_lock(f=%4x/%ld, t=%x, fl=%x, r=%ld:%ld)\n", inode->i_dev, inode->i_ino, fl->fl_type, fl->fl_flags, @@ -225,10 +237,6 @@ /* No mandatory locks over NFS */ if ((inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID) return -ENOLCK; - - /* Fake OK code if mounted without NLM support */ - if (NFS_SERVER(inode)->flags & NFS_MOUNT_NONLM) - return 0; /* * No BSD flocks over NFS allowed. --- linux-2.2.2.orig/fs/lockd/clntproc.c Thu Feb 18 06:44:33 1999 +++ linux/fs/lockd/clntproc.c Sat Feb 27 19:41:24 1999 @@ -328,7 +328,7 @@ status = req->a_res.status; if (status == NLM_LCK_GRANTED) { fl->fl_type = F_UNLCK; - } if (status == NLM_LCK_DENIED) { + } else if (status == NLM_LCK_DENIED) { /* * Report the conflicting lock back to the application. * FIXME: Is it OK to report the pid back as well?

--------------E6175EBE7D6A3FB82D28A035--

- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.rutgers.edu Please read the FAQ at http://www.tux.org/lkml/