diff options
-rw-r--r-- | Documentation/kernel-parameters.txt | 8 | ||||
-rw-r--r-- | fs/nfs/client.c | 16 | ||||
-rw-r--r-- | fs/nfs/idmap.c | 24 | ||||
-rw-r--r-- | fs/nfs/nfs4proc.c | 15 | ||||
-rw-r--r-- | include/linux/nfs_fs_sb.h | 1 |
5 files changed, 55 insertions, 9 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index f4a04c0c7ed..14dcf1b7dd9 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
@@ -1580,6 +1580,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. | |||
1580 | of returning the full 64-bit number. | 1580 | of returning the full 64-bit number. |
1581 | The default is to return 64-bit inode numbers. | 1581 | The default is to return 64-bit inode numbers. |
1582 | 1582 | ||
1583 | nfs.nfs4_disable_idmapping= | ||
1584 | [NFSv4] When set, this option disables the NFSv4 | ||
1585 | idmapper on the client, but only if the mount | ||
1586 | is using the 'sec=sys' security flavour. This may | ||
1587 | make migration from legacy NFSv2/v3 systems easier | ||
1588 | provided that the server has the appropriate support. | ||
1589 | The default is to always enable NFSv4 idmapping. | ||
1590 | |||
1583 | nmi_debug= [KNL,AVR32,SH] Specify one or more actions to take | 1591 | nmi_debug= [KNL,AVR32,SH] Specify one or more actions to take |
1584 | when a NMI is triggered. | 1592 | when a NMI is triggered. |
1585 | Format: [state][,regs][,debounce][,die] | 1593 | Format: [state][,regs][,debounce][,die] |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 6dd50ac5b54..139be9647d8 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -82,6 +82,11 @@ retry: | |||
82 | #endif /* CONFIG_NFS_V4 */ | 82 | #endif /* CONFIG_NFS_V4 */ |
83 | 83 | ||
84 | /* | 84 | /* |
85 | * Turn off NFSv4 uid/gid mapping when using AUTH_SYS | ||
86 | */ | ||
87 | static int nfs4_disable_idmapping = 0; | ||
88 | |||
89 | /* | ||
85 | * RPC cruft for NFS | 90 | * RPC cruft for NFS |
86 | */ | 91 | */ |
87 | static struct rpc_version *nfs_version[5] = { | 92 | static struct rpc_version *nfs_version[5] = { |
@@ -1567,6 +1572,13 @@ static int nfs4_init_server(struct nfs_server *server, | |||
1567 | if (error < 0) | 1572 | if (error < 0) |
1568 | goto error; | 1573 | goto error; |
1569 | 1574 | ||
1575 | /* | ||
1576 | * Don't use NFS uid/gid mapping if we're using AUTH_SYS or lower | ||
1577 | * authentication. | ||
1578 | */ | ||
1579 | if (nfs4_disable_idmapping && data->auth_flavors[0] == RPC_AUTH_UNIX) | ||
1580 | server->caps |= NFS_CAP_UIDGID_NOMAP; | ||
1581 | |||
1570 | if (data->rsize) | 1582 | if (data->rsize) |
1571 | server->rsize = nfs_block_size(data->rsize, NULL); | 1583 | server->rsize = nfs_block_size(data->rsize, NULL); |
1572 | if (data->wsize) | 1584 | if (data->wsize) |
@@ -1984,3 +1996,7 @@ void nfs_fs_proc_exit(void) | |||
1984 | } | 1996 | } |
1985 | 1997 | ||
1986 | #endif /* CONFIG_PROC_FS */ | 1998 | #endif /* CONFIG_PROC_FS */ |
1999 | |||
2000 | module_param(nfs4_disable_idmapping, bool, 0644); | ||
2001 | MODULE_PARM_DESC(nfs4_disable_idmapping, | ||
2002 | "Turn off NFSv4 idmapping when using 'sec=sys'"); | ||
diff --git a/fs/nfs/idmap.c b/fs/nfs/idmap.c index e2d579d458f..79664a1025a 100644 --- a/fs/nfs/idmap.c +++ b/fs/nfs/idmap.c | |||
@@ -61,6 +61,9 @@ static int nfs_map_numeric_to_string(__u32 id, char *buf, size_t buflen) | |||
61 | 61 | ||
62 | #include <linux/slab.h> | 62 | #include <linux/slab.h> |
63 | #include <linux/cred.h> | 63 | #include <linux/cred.h> |
64 | #include <linux/sunrpc/sched.h> | ||
65 | #include <linux/nfs4.h> | ||
66 | #include <linux/nfs_fs_sb.h> | ||
64 | #include <linux/nfs_idmap.h> | 67 | #include <linux/nfs_idmap.h> |
65 | #include <linux/keyctl.h> | 68 | #include <linux/keyctl.h> |
66 | #include <linux/key-type.h> | 69 | #include <linux/key-type.h> |
@@ -257,17 +260,20 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size | |||
257 | 260 | ||
258 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) | 261 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) |
259 | { | 262 | { |
260 | int ret; | 263 | int ret = -EINVAL; |
261 | ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); | 264 | |
265 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) | ||
266 | ret = nfs_idmap_lookup_name(uid, "user", buf, buflen); | ||
262 | if (ret < 0) | 267 | if (ret < 0) |
263 | ret = nfs_map_numeric_to_string(uid, buf, buflen); | 268 | ret = nfs_map_numeric_to_string(uid, buf, buflen); |
264 | return ret; | 269 | return ret; |
265 | } | 270 | } |
266 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) | 271 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 gid, char *buf, size_t buflen) |
267 | { | 272 | { |
268 | int ret; | 273 | int ret = -EINVAL; |
269 | 274 | ||
270 | ret = nfs_idmap_lookup_name(gid, "group", buf, buflen); | 275 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) |
276 | ret = nfs_idmap_lookup_name(gid, "group", buf, buflen); | ||
271 | if (ret < 0) | 277 | if (ret < 0) |
272 | ret = nfs_map_numeric_to_string(gid, buf, buflen); | 278 | ret = nfs_map_numeric_to_string(gid, buf, buflen); |
273 | return ret; | 279 | return ret; |
@@ -750,9 +756,10 @@ int nfs_map_group_to_gid(const struct nfs_server *server, const char *name, size | |||
750 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) | 756 | int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) |
751 | { | 757 | { |
752 | struct idmap *idmap = server->nfs_client->cl_idmap; | 758 | struct idmap *idmap = server->nfs_client->cl_idmap; |
753 | int ret; | 759 | int ret = -EINVAL; |
754 | 760 | ||
755 | ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); | 761 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) |
762 | ret = nfs_idmap_name(idmap, &idmap->idmap_user_hash, uid, buf); | ||
756 | if (ret < 0) | 763 | if (ret < 0) |
757 | ret = nfs_map_numeric_to_string(uid, buf, buflen); | 764 | ret = nfs_map_numeric_to_string(uid, buf, buflen); |
758 | return ret; | 765 | return ret; |
@@ -760,9 +767,10 @@ int nfs_map_uid_to_name(const struct nfs_server *server, __u32 uid, char *buf, s | |||
760 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) | 767 | int nfs_map_gid_to_group(const struct nfs_server *server, __u32 uid, char *buf, size_t buflen) |
761 | { | 768 | { |
762 | struct idmap *idmap = server->nfs_client->cl_idmap; | 769 | struct idmap *idmap = server->nfs_client->cl_idmap; |
763 | int ret; | 770 | int ret = -EINVAL; |
764 | 771 | ||
765 | ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); | 772 | if (!(server->caps & NFS_CAP_UIDGID_NOMAP)) |
773 | ret = nfs_idmap_name(idmap, &idmap->idmap_group_hash, uid, buf); | ||
766 | if (ret < 0) | 774 | if (ret < 0) |
767 | ret = nfs_map_numeric_to_string(uid, buf, buflen); | 775 | ret = nfs_map_numeric_to_string(uid, buf, buflen); |
768 | return ret; | 776 | return ret; |
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 8f3ada04ea1..1d84e7088af 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -244,7 +244,7 @@ static int nfs4_delay(struct rpc_clnt *clnt, long *timeout) | |||
244 | /* This is the error handling routine for processes that are allowed | 244 | /* This is the error handling routine for processes that are allowed |
245 | * to sleep. | 245 | * to sleep. |
246 | */ | 246 | */ |
247 | static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, struct nfs4_exception *exception) | 247 | static int nfs4_handle_exception(struct nfs_server *server, int errorcode, struct nfs4_exception *exception) |
248 | { | 248 | { |
249 | struct nfs_client *clp = server->nfs_client; | 249 | struct nfs_client *clp = server->nfs_client; |
250 | struct nfs4_state *state = exception->state; | 250 | struct nfs4_state *state = exception->state; |
@@ -296,6 +296,19 @@ static int nfs4_handle_exception(const struct nfs_server *server, int errorcode, | |||
296 | break; | 296 | break; |
297 | case -NFS4ERR_OLD_STATEID: | 297 | case -NFS4ERR_OLD_STATEID: |
298 | exception->retry = 1; | 298 | exception->retry = 1; |
299 | break; | ||
300 | case -NFS4ERR_BADOWNER: | ||
301 | /* The following works around a Linux server bug! */ | ||
302 | case -NFS4ERR_BADNAME: | ||
303 | if (server->caps & NFS_CAP_UIDGID_NOMAP) { | ||
304 | server->caps &= ~NFS_CAP_UIDGID_NOMAP; | ||
305 | exception->retry = 1; | ||
306 | printk(KERN_WARNING "NFS: v4 server %s " | ||
307 | "does not accept raw " | ||
308 | "uid/gids. " | ||
309 | "Reenabling the idmapper.\n", | ||
310 | server->nfs_client->cl_hostname); | ||
311 | } | ||
299 | } | 312 | } |
300 | /* We failed to handle the error */ | 313 | /* We failed to handle the error */ |
301 | return nfs4_map_errors(ret); | 314 | return nfs4_map_errors(ret); |
diff --git a/include/linux/nfs_fs_sb.h b/include/linux/nfs_fs_sb.h index 0cbf109a405..216cea5db0a 100644 --- a/include/linux/nfs_fs_sb.h +++ b/include/linux/nfs_fs_sb.h | |||
@@ -177,6 +177,7 @@ struct nfs_server { | |||
177 | #define NFS_CAP_CTIME (1U << 12) | 177 | #define NFS_CAP_CTIME (1U << 12) |
178 | #define NFS_CAP_MTIME (1U << 13) | 178 | #define NFS_CAP_MTIME (1U << 13) |
179 | #define NFS_CAP_POSIX_LOCK (1U << 14) | 179 | #define NFS_CAP_POSIX_LOCK (1U << 14) |
180 | #define NFS_CAP_UIDGID_NOMAP (1U << 15) | ||
180 | 181 | ||
181 | 182 | ||
182 | /* maximum number of slots to use */ | 183 | /* maximum number of slots to use */ |