NFSv4: Don't allow posix locking against servers that don't support it
authorTrond Myklebust <Trond.Myklebust@netapp.com>
Tue, 26 Jan 2010 20:42:30 +0000 (15:42 -0500)
committerGreg Kroah-Hartman <gregkh@suse.de>
Tue, 23 Feb 2010 15:37:50 +0000 (07:37 -0800)
commit 8e469ebd6dc32cbaf620e134d79f740bf0ebab79 upstream.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Reviewed-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
fs/nfs/nfs4_fs.h
fs/nfs/nfs4proc.c

index 6ea07a3c75d4942f6197e54791b7504502d3f54c..b4a6b1a586d6ba182eb9924a1153eb5cee329e57 100644 (file)
@@ -141,6 +141,7 @@ enum {
        NFS_O_RDWR_STATE,               /* OPEN stateid has read/write state */
        NFS_STATE_RECLAIM_REBOOT,       /* OPEN stateid server rebooted */
        NFS_STATE_RECLAIM_NOGRACE,      /* OPEN stateid needs to recover state */
+       NFS_STATE_POSIX_LOCKS,          /* Posix locks are supported */
 };
 
 struct nfs4_state {
index 741a562177fc3f587dcd1e1019f3cfe53c367de8..8dbee6291284bcd8aae602d3d056f7564aa21453 100644 (file)
@@ -1573,6 +1573,8 @@ static int _nfs4_do_open(struct inode *dir, struct path *path, fmode_t fmode, in
        status = PTR_ERR(state);
        if (IS_ERR(state))
                goto err_opendata_put;
+       if ((opendata->o_res.rflags & NFS4_OPEN_RESULT_LOCKTYPE_POSIX) != 0)
+               set_bit(NFS_STATE_POSIX_LOCKS, &state->flags);
        nfs4_opendata_put(opendata);
        nfs4_put_state_owner(sp);
        *res = state;
@@ -4060,8 +4062,11 @@ static int _nfs4_proc_setlk(struct nfs4_state *state, int cmd, struct file_lock
 {
        struct nfs_inode *nfsi = NFS_I(state->inode);
        unsigned char fl_flags = request->fl_flags;
-       int status;
+       int status = -ENOLCK;
 
+       if ((fl_flags & FL_POSIX) &&
+                       !test_bit(NFS_STATE_POSIX_LOCKS, &state->flags))
+               goto out;
        /* Is this a delegated open? */
        status = nfs4_set_lock_state(state, request);
        if (status != 0)