]> Pileus Git - ~andy/linux/commitdiff
Merge tag 'nfs-for-3.10-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
authorLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 May 2013 17:24:54 +0000 (10:24 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 9 May 2013 17:24:54 +0000 (10:24 -0700)
Pull more NFS client bugfixes from Trond Myklebust:

 - Ensure that we match the 'sec=' mount flavour against the server list

 - Fix the NFSv4 byte range locking in the presence of delegations

 - Ensure that we conform to the NFSv4.1 spec w.r.t.  freeing lock
   stateids

 - Fix a pNFS data server connection race

* tag 'nfs-for-3.10-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs:
  NFS4.1 Fix data server connection race
  NFSv3: match sec= flavor against server list
  NFSv4.1: Ensure that we free the lock stateid on the server
  NFSv4: Convert nfs41_free_stateid to use an asynchronous RPC call
  SUNRPC: Don't spam syslog with "Pseudoflavor not found" messages
  NFSv4.x: Fix handling of partially delegated locks

1  2 
fs/nfs/super.c
net/sunrpc/auth_gss/auth_gss.c
net/sunrpc/clnt.c

diff --combined fs/nfs/super.c
index 1bb071dca9ab1349deecd44e19ec7e0531b737ea,b65001c0a11974b18e3bf2f86be90d7e2ca20107..a366107a7331ad36864ba81b8b14ba940756ac70
@@@ -294,7 -294,6 +294,7 @@@ struct file_system_type nfs_fs_type = 
        .kill_sb        = nfs_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
  };
 +MODULE_ALIAS_FS("nfs");
  EXPORT_SYMBOL_GPL(nfs_fs_type);
  
  struct file_system_type nfs_xdev_fs_type = {
@@@ -334,8 -333,6 +334,8 @@@ struct file_system_type nfs4_fs_type = 
        .kill_sb        = nfs_kill_super,
        .fs_flags       = FS_RENAME_DOES_D_MOVE|FS_BINARY_MOUNTDATA,
  };
 +MODULE_ALIAS_FS("nfs4");
 +MODULE_ALIAS("nfs4");
  EXPORT_SYMBOL_GPL(nfs4_fs_type);
  
  static int __init register_nfs4_fs(void)
@@@ -1610,16 -1607,15 +1610,15 @@@ out_security_failure
  /*
   * Select a security flavor for this mount.  The selected flavor
   * is planted in args->auth_flavors[0].
+  *
+  * Returns 0 on success, -EACCES on failure.
   */
- static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
+ static int nfs_select_flavor(struct nfs_parsed_mount_data *args,
                              struct nfs_mount_request *request)
  {
        unsigned int i, count = *(request->auth_flav_len);
        rpc_authflavor_t flavor;
  
-       if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR)
-               goto out;
        /*
         * The NFSv2 MNT operation does not return a flavor list.
         */
        if (count == 0)
                goto out_default;
  
+       /*
+        * If the sec= mount option is used, the specified flavor or AUTH_NULL
+        * must be in the list returned by the server.
+        *
+        * AUTH_NULL has a special meaning when it's in the server list - it
+        * means that the server will ignore the rpc creds, so any flavor
+        * can be used.
+        */
+       if (args->auth_flavors[0] != RPC_AUTH_MAXFLAVOR) {
+               for (i = 0; i < count; i++) {
+                       if (args->auth_flavors[0] == request->auth_flavs[i] ||
+                           request->auth_flavs[i] == RPC_AUTH_NULL)
+                               goto out;
+               }
+               dfprintk(MOUNT, "NFS: auth flavor %d not supported by server\n",
+                       args->auth_flavors[0]);
+               goto out_err;
+       }
        /*
         * RFC 2623, section 2.7 suggests we SHOULD prefer the
         * flavor listed first.  However, some servers list
                }
        }
  
+       /*
+        * As a last chance, see if the server list contains AUTH_NULL -
+        * if it does, use the default flavor.
+        */
+       for (i = 0; i < count; i++) {
+               if (request->auth_flavs[i] == RPC_AUTH_NULL)
+                       goto out_default;
+       }
+       dfprintk(MOUNT, "NFS: no auth flavors in common with server\n");
+       goto out_err;
  out_default:
-       flavor = RPC_AUTH_UNIX;
+       /* use default if flavor not already set */
+       flavor = (args->auth_flavors[0] == RPC_AUTH_MAXFLAVOR) ?
+               RPC_AUTH_UNIX : args->auth_flavors[0];
  out_set:
        args->auth_flavors[0] = flavor;
  out:
        dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]);
+       return 0;
+ out_err:
+       return -EACCES;
  }
  
  /*
@@@ -1721,8 -1753,7 +1756,7 @@@ static int nfs_request_mount(struct nfs
                return status;
        }
  
-       nfs_select_flavor(args, &request);
-       return 0;
+       return nfs_select_flavor(args, &request);
  }
  
  struct dentry *nfs_try_mount(int flags, const char *dev_name,
@@@ -2385,9 -2416,10 +2419,9 @@@ int nfs_clone_sb_security(struct super_
                          struct nfs_mount_info *mount_info)
  {
        /* clone any lsm security options from the parent to the new sb */
 -      security_sb_clone_mnt_opts(mount_info->cloned->sb, s);
        if (mntroot->d_inode->i_op != NFS_SB(s)->nfs_client->rpc_ops->dir_inode_ops)
                return -ESTALE;
 -      return 0;
 +      return security_sb_clone_mnt_opts(mount_info->cloned->sb, s);
  }
  EXPORT_SYMBOL_GPL(nfs_clone_sb_security);
  
@@@ -2723,5 -2755,6 +2757,5 @@@ module_param(send_implementation_id, us
  MODULE_PARM_DESC(send_implementation_id,
                "Send implementation ID with NFSv4.1 exchange_id");
  MODULE_PARM_DESC(nfs4_unique_id, "nfs_client_id4 uniquifier string");
 -MODULE_ALIAS("nfs4");
  
  #endif /* CONFIG_NFS_V4 */
index a764e227fddeb06955226e7a7d622282e168b481,b5dd6922493a92d9757e0448384f07702b02ecf3..7da6b457f66abfab016fd8b21aeedcb14d5e7ff0
@@@ -238,7 -238,7 +238,7 @@@ gss_fill_context(const void *p, const v
                p = ERR_PTR(-EFAULT);
                goto err;
        }
 -      ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, GFP_NOFS);
 +      ret = gss_import_sec_context(p, seclen, gm, &ctx->gc_gss_ctx, NULL, GFP_NOFS);
        if (ret < 0) {
                p = ERR_PTR(ret);
                goto err;
@@@ -867,8 -867,7 +867,7 @@@ gss_create(struct rpc_clnt *clnt, rpc_a
        err = -EINVAL;
        gss_auth->mech = gss_mech_get_by_pseudoflavor(flavor);
        if (!gss_auth->mech) {
-               printk(KERN_WARNING "%s: Pseudoflavor %d not found!\n",
-                               __func__, flavor);
+               dprintk("RPC:       Pseudoflavor %d not found!\n", flavor);
                goto err_free;
        }
        gss_auth->service = gss_pseudoflavor_to_service(gss_auth->mech, flavor);
diff --combined net/sunrpc/clnt.c
index 3f7930f938cc295c79cdec097c1db4a9109a6086,e9143edcb23b72a52f8a5833014393ca0b62e820..5a750b9c36404b34a3b41bd0e2d38628f881a5f2
@@@ -360,7 -360,7 +360,7 @@@ static struct rpc_clnt * rpc_new_client
  
        auth = rpcauth_create(args->authflavor, clnt);
        if (IS_ERR(auth)) {
-               printk(KERN_INFO "RPC: Couldn't create auth handle (flavor %u)\n",
+               dprintk("RPC:       Couldn't create auth handle (flavor %u)\n",
                                args->authflavor);
                err = PTR_ERR(auth);
                goto out_no_auth;
@@@ -413,8 -413,6 +413,8 @@@ struct rpc_clnt *rpc_create(struct rpc_
  
        if (args->flags & RPC_CLNT_CREATE_INFINITE_SLOTS)
                xprtargs.flags |= XPRT_CREATE_INFINITE_SLOTS;
 +      if (args->flags & RPC_CLNT_CREATE_NO_IDLE_TIMEOUT)
 +              xprtargs.flags |= XPRT_CREATE_NO_IDLE_TIMEOUT;
        /*
         * If the caller chooses not to specify a hostname, whip
         * up a string representation of the passed-in address.
@@@ -683,7 -681,6 +683,7 @@@ rpc_release_client(struct rpc_clnt *cln
        if (atomic_dec_and_test(&clnt->cl_count))
                rpc_free_auth(clnt);
  }
 +EXPORT_SYMBOL_GPL(rpc_release_client);
  
  /**
   * rpc_bind_new_program - bind a new RPC program to an existing client