.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 = {
.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)
data->mount_server.port = NFS_UNSPEC_PORT;
data->nfs_server.port = NFS_UNSPEC_PORT;
data->nfs_server.protocol = XPRT_TRANSPORT_TCP;
- data->auth_flavors[0] = RPC_AUTH_UNIX;
+ data->auth_flavors[0] = RPC_AUTH_MAXFLAVOR;
data->auth_flavor_len = 1;
data->minorversion = 0;
data->need_mount = true;
}
/*
- * Match the requested auth flavors with the list returned by
- * the server. Returns zero and sets the mount's authentication
- * flavor on success; returns -EACCES if server does not support
- * the requested flavor.
+ * Select a security flavor for this mount. The selected flavor
+ * is planted in args->auth_flavors[0].
*/
- static int nfs_walk_authlist(struct nfs_parsed_mount_data *args,
- struct nfs_mount_request *request)
+ static void nfs_select_flavor(struct nfs_parsed_mount_data *args,
+ struct nfs_mount_request *request)
{
- unsigned int i, j, server_authlist_len = *(request->auth_flav_len);
+ 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 (args->mount_server.version != NFS_MNT3_VERSION)
+ goto out_default;
/*
* Certain releases of Linux's mountd return an empty
- * flavor list. To prevent behavioral regression with
- * these servers (ie. rejecting mounts that used to
- * succeed), revert to pre-2.6.32 behavior (no checking)
- * if the returned flavor list is empty.
+ * flavor list in some cases.
*/
- if (server_authlist_len == 0)
- return 0;
+ if (count == 0)
+ goto out_default;
/*
- * We avoid sophisticated negotiating here, as there are
- * plenty of cases where we can get it wrong, providing
- * either too little or too much security.
- *
* RFC 2623, section 2.7 suggests we SHOULD prefer the
* flavor listed first. However, some servers list
- * AUTH_NULL first. Our caller plants AUTH_SYS, the
- * preferred default, in args->auth_flavors[0] if user
- * didn't specify sec= mount option.
+ * AUTH_NULL first. Avoid ever choosing AUTH_NULL.
*/
- for (i = 0; i < args->auth_flavor_len; i++)
- for (j = 0; j < server_authlist_len; j++)
- if (args->auth_flavors[i] == request->auth_flavs[j]) {
- dfprintk(MOUNT, "NFS: using auth flavor %d\n",
- request->auth_flavs[j]);
- args->auth_flavors[0] = request->auth_flavs[j];
- return 0;
- }
+ for (i = 0; i < count; i++) {
+ struct rpcsec_gss_info info;
+
+ flavor = request->auth_flavs[i];
+ switch (flavor) {
+ case RPC_AUTH_UNIX:
+ goto out_set;
+ case RPC_AUTH_NULL:
+ continue;
+ default:
+ if (rpcauth_get_gssinfo(flavor, &info) == 0)
+ goto out_set;
+ }
+ }
- dfprintk(MOUNT, "NFS: server does not support requested auth flavor\n");
- nfs_umount(request);
- return -EACCES;
+ out_default:
+ flavor = RPC_AUTH_UNIX;
+ out_set:
+ args->auth_flavors[0] = flavor;
+ out:
+ dfprintk(MOUNT, "NFS: using auth flavor %d\n", args->auth_flavors[0]);
}
/*
return status;
}
- /*
- * MNTv1 (NFSv2) does not support auth flavor negotiation.
- */
- if (args->mount_server.version != NFS_MNT3_VERSION)
- return 0;
- return nfs_walk_authlist(args, &request);
+ nfs_select_flavor(args, &request);
+ return 0;
}
struct dentry *nfs_try_mount(int flags, const char *dev_name,
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 */
iattr->ia_valid |= ATTR_SIZE;
}
if (bmval[0] & FATTR4_WORD0_ACL) {
- int nace;
+ u32 nace;
struct nfs4_ace *ace;
READ_BUF(4); len += 4;
static __be32
nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp,
- __be32 nfserr,struct svc_export *exp)
+ __be32 nfserr, struct svc_export *exp)
{
- int i = 0;
- u32 nflavs;
+ u32 i, nflavs;
struct exp_flavor_info *flavs;
struct exp_flavor_info def_flavs[2];
__be32 *p;
WRITE32(nflavs);
ADJUST_ARGS();
for (i = 0; i < nflavs; i++) {
- u32 flav = flavs[i].pseudoflavor;
- struct gss_api_mech *gm = gss_mech_get_by_pseudoflavor(flav);
+ struct rpcsec_gss_info info;
- if (gm) {
+ if (rpcauth_get_gssinfo(flavs[i].pseudoflavor, &info) == 0) {
RESERVE_SPACE(4);
WRITE32(RPC_AUTH_GSS);
ADJUST_ARGS();
- RESERVE_SPACE(4 + gm->gm_oid.len);
- WRITE32(gm->gm_oid.len);
- WRITEMEM(gm->gm_oid.data, gm->gm_oid.len);
+ RESERVE_SPACE(4 + info.oid.len);
+ WRITE32(info.oid.len);
+ WRITEMEM(info.oid.data, info.oid.len);
ADJUST_ARGS();
RESERVE_SPACE(4);
- WRITE32(0); /* qop */
+ WRITE32(info.qop);
ADJUST_ARGS();
RESERVE_SPACE(4);
- WRITE32(gss_pseudoflavor_to_service(gm, flav));
+ WRITE32(info.service);
ADJUST_ARGS();
- gss_mech_put(gm);
} else {
RESERVE_SPACE(4);
- WRITE32(flav);
+ WRITE32(flavs[i].pseudoflavor);
ADJUST_ARGS();
}
}
+
out:
if (exp)
exp_put(exp);
xs_tcp_shutdown(xprt);
}
+static void xs_local_destroy(struct rpc_xprt *xprt)
+{
+ xs_close(xprt);
+ xs_free_peer_addresses(xprt);
+ xprt_free(xprt);
+ module_put(THIS_MODULE);
+}
+
/**
* xs_destroy - prepare to shutdown a transport
* @xprt: doomed transport
cancel_delayed_work_sync(&transport->connect_worker);
- xs_close(xprt);
- xs_free_peer_addresses(xprt);
- xprt_free(xprt);
- module_put(THIS_MODULE);
+ xs_local_destroy(xprt);
}
static inline struct rpc_xprt *xprt_from_sock(struct sock *sk)
*/
xs_tcp_force_close(xprt);
break;
- case -ECONNREFUSED:
- case -ECONNRESET:
- case -ENETUNREACH:
- /* retry with existing socket, after a delay */
case 0:
case -EINPROGRESS:
case -EALREADY:
/* Happens, for instance, if the user specified a link
* local IPv6 address without a scope-id.
*/
+ case -ECONNREFUSED:
+ case -ECONNRESET:
+ case -ENETUNREACH:
+ /* retry with existing socket, after a delay */
goto out;
}
out_eagain:
.send_request = xs_local_send_request,
.set_retrans_timeout = xprt_set_retrans_timeout_def,
.close = xs_close,
- .destroy = xs_destroy,
+ .destroy = xs_local_destroy,
.print_stats = xs_local_print_stats,
};
struct rpc_xprt *xprt;
struct sock_xprt *transport;
struct rpc_xprt *ret;
+ unsigned int max_slot_table_size = xprt_max_tcp_slot_table_entries;
+
+ if (args->flags & XPRT_CREATE_INFINITE_SLOTS)
+ max_slot_table_size = RPC_MAX_SLOT_TABLE_LIMIT;
xprt = xs_setup_xprt(args, xprt_tcp_slot_table_entries,
- xprt_max_tcp_slot_table_entries);
+ max_slot_table_size);
if (IS_ERR(xprt))
return xprt;
transport = container_of(xprt, struct sock_xprt, xprt);