Loading fs/nfs/super.c +528 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include <linux/inet.h> #include <linux/nfs_xdr.h> #include <linux/magic.h> #include <linux/parser.h> #include <asm/system.h> #include <asm/uaccess.h> Loading @@ -57,6 +58,164 @@ #define NFSDBG_FACILITY NFSDBG_VFS struct nfs_parsed_mount_data { int flags; int rsize, wsize; int timeo, retrans; int acregmin, acregmax, acdirmin, acdirmax; int namlen; unsigned int bsize; unsigned int auth_flavor_len; rpc_authflavor_t auth_flavors[1]; char *client_address; struct { struct sockaddr_in address; unsigned int program; unsigned int version; unsigned short port; int protocol; } mount_server; struct { struct sockaddr_in address; char *hostname; char *export_path; unsigned int program; int protocol; } nfs_server; }; enum { /* Mount options that take no arguments */ Opt_soft, Opt_hard, Opt_intr, Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp, Opt_acl, Opt_noacl, Opt_rdirplus, Opt_nordirplus, /* Mount options that take integer arguments */ Opt_port, Opt_rsize, Opt_wsize, Opt_bsize, Opt_timeo, Opt_retrans, Opt_acregmin, Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_actimeo, Opt_namelen, Opt_mountport, Opt_mountprog, Opt_mountvers, Opt_nfsprog, Opt_nfsvers, /* Mount options that take string arguments */ Opt_sec, Opt_proto, Opt_mountproto, Opt_addr, Opt_mounthost, Opt_clientaddr, /* Mount options that are ignored */ Opt_userspace, Opt_deprecated, Opt_err }; static match_table_t nfs_mount_option_tokens = { { Opt_userspace, "bg" }, { Opt_userspace, "fg" }, { Opt_soft, "soft" }, { Opt_hard, "hard" }, { Opt_intr, "intr" }, { Opt_nointr, "nointr" }, { Opt_posix, "posix" }, { Opt_noposix, "noposix" }, { Opt_cto, "cto" }, { Opt_nocto, "nocto" }, { Opt_ac, "ac" }, { Opt_noac, "noac" }, { Opt_lock, "lock" }, { Opt_nolock, "nolock" }, { Opt_v2, "v2" }, { Opt_v3, "v3" }, { Opt_udp, "udp" }, { Opt_tcp, "tcp" }, { Opt_acl, "acl" }, { Opt_noacl, "noacl" }, { Opt_rdirplus, "rdirplus" }, { Opt_nordirplus, "nordirplus" }, { Opt_port, "port=%u" }, { Opt_rsize, "rsize=%u" }, { Opt_wsize, "wsize=%u" }, { Opt_bsize, "bsize=%u" }, { Opt_timeo, "timeo=%u" }, { Opt_retrans, "retrans=%u" }, { Opt_acregmin, "acregmin=%u" }, { Opt_acregmax, "acregmax=%u" }, { Opt_acdirmin, "acdirmin=%u" }, { Opt_acdirmax, "acdirmax=%u" }, { Opt_actimeo, "actimeo=%u" }, { Opt_userspace, "retry=%u" }, { Opt_namelen, "namlen=%u" }, { Opt_mountport, "mountport=%u" }, { Opt_mountprog, "mountprog=%u" }, { Opt_mountvers, "mountvers=%u" }, { Opt_nfsprog, "nfsprog=%u" }, { Opt_nfsvers, "nfsvers=%u" }, { Opt_nfsvers, "vers=%u" }, { Opt_sec, "sec=%s" }, { Opt_proto, "proto=%s" }, { Opt_mountproto, "mountproto=%s" }, { Opt_addr, "addr=%s" }, { Opt_clientaddr, "clientaddr=%s" }, { Opt_mounthost, "mounthost=%s" }, { Opt_err, NULL } }; enum { Opt_xprt_udp, Opt_xprt_tcp, Opt_xprt_err }; static match_table_t nfs_xprt_protocol_tokens = { { Opt_xprt_udp, "udp" }, { Opt_xprt_tcp, "tcp" }, { Opt_xprt_err, NULL } }; enum { Opt_sec_none, Opt_sec_sys, Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p, Opt_sec_lkey, Opt_sec_lkeyi, Opt_sec_lkeyp, Opt_sec_spkm, Opt_sec_spkmi, Opt_sec_spkmp, Opt_sec_err }; static match_table_t nfs_secflavor_tokens = { { Opt_sec_none, "none" }, { Opt_sec_none, "null" }, { Opt_sec_sys, "sys" }, { Opt_sec_krb5, "krb5" }, { Opt_sec_krb5i, "krb5i" }, { Opt_sec_krb5p, "krb5p" }, { Opt_sec_lkey, "lkey" }, { Opt_sec_lkeyi, "lkeyi" }, { Opt_sec_lkeyp, "lkeyp" }, { Opt_sec_err, NULL } }; static void nfs_umount_begin(struct vfsmount *, int); static int nfs_statfs(struct dentry *, struct kstatfs *); static int nfs_show_options(struct seq_file *, struct vfsmount *); Loading Loading @@ -463,6 +622,375 @@ static int nfs_verify_server_address(struct sockaddr *addr) return 0; } /* * Error-check and convert a string of mount options from user space into * a data structure */ static int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) { char *p, *string; if (!raw) { dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); return 1; } dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); while ((p = strsep(&raw, ",")) != NULL) { substring_t args[MAX_OPT_ARGS]; int option, token; if (!*p) continue; dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p); token = match_token(p, nfs_mount_option_tokens, args); switch (token) { case Opt_soft: mnt->flags |= NFS_MOUNT_SOFT; break; case Opt_hard: mnt->flags &= ~NFS_MOUNT_SOFT; break; case Opt_intr: mnt->flags |= NFS_MOUNT_INTR; break; case Opt_nointr: mnt->flags &= ~NFS_MOUNT_INTR; break; case Opt_posix: mnt->flags |= NFS_MOUNT_POSIX; break; case Opt_noposix: mnt->flags &= ~NFS_MOUNT_POSIX; break; case Opt_cto: mnt->flags &= ~NFS_MOUNT_NOCTO; break; case Opt_nocto: mnt->flags |= NFS_MOUNT_NOCTO; break; case Opt_ac: mnt->flags &= ~NFS_MOUNT_NOAC; break; case Opt_noac: mnt->flags |= NFS_MOUNT_NOAC; break; case Opt_lock: mnt->flags &= ~NFS_MOUNT_NONLM; break; case Opt_nolock: mnt->flags |= NFS_MOUNT_NONLM; break; case Opt_v2: mnt->flags &= ~NFS_MOUNT_VER3; break; case Opt_v3: mnt->flags |= NFS_MOUNT_VER3; break; case Opt_udp: mnt->flags &= ~NFS_MOUNT_TCP; mnt->nfs_server.protocol = IPPROTO_UDP; mnt->timeo = 7; mnt->retrans = 5; break; case Opt_tcp: mnt->flags |= NFS_MOUNT_TCP; mnt->nfs_server.protocol = IPPROTO_TCP; mnt->timeo = 600; mnt->retrans = 2; break; case Opt_acl: mnt->flags &= ~NFS_MOUNT_NOACL; break; case Opt_noacl: mnt->flags |= NFS_MOUNT_NOACL; break; case Opt_rdirplus: mnt->flags &= ~NFS_MOUNT_NORDIRPLUS; break; case Opt_nordirplus: mnt->flags |= NFS_MOUNT_NORDIRPLUS; break; case Opt_port: if (match_int(args, &option)) return 0; if (option < 0 || option > 65535) return 0; mnt->nfs_server.address.sin_port = htonl(option); break; case Opt_rsize: if (match_int(args, &mnt->rsize)) return 0; break; case Opt_wsize: if (match_int(args, &mnt->wsize)) return 0; break; case Opt_bsize: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->bsize = option; break; case Opt_timeo: if (match_int(args, &mnt->timeo)) return 0; break; case Opt_retrans: if (match_int(args, &mnt->retrans)) return 0; break; case Opt_acregmin: if (match_int(args, &mnt->acregmin)) return 0; break; case Opt_acregmax: if (match_int(args, &mnt->acregmax)) return 0; break; case Opt_acdirmin: if (match_int(args, &mnt->acdirmin)) return 0; break; case Opt_acdirmax: if (match_int(args, &mnt->acdirmax)) return 0; break; case Opt_actimeo: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->acregmin = mnt->acregmax = mnt->acdirmin = mnt->acdirmax = option; break; case Opt_namelen: if (match_int(args, &mnt->namlen)) return 0; break; case Opt_mountport: if (match_int(args, &option)) return 0; if (option < 0 || option > 65535) return 0; mnt->mount_server.port = option; break; case Opt_mountprog: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->mount_server.program = option; break; case Opt_mountvers: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->mount_server.version = option; break; case Opt_nfsprog: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->nfs_server.program = option; break; case Opt_nfsvers: if (match_int(args, &option)) return 0; switch (option) { case 2: mnt->flags &= ~NFS_MOUNT_VER3; break; case 3: mnt->flags |= NFS_MOUNT_VER3; break; default: goto out_unrec_vers; } break; case Opt_sec: string = match_strdup(args); if (string == NULL) goto out_nomem; token = match_token(string, nfs_secflavor_tokens, args); kfree(string); /* * The flags setting is for v2/v3. The flavor_len * setting is for v4. v2/v3 also need to know the * difference between NULL and UNIX. */ switch (token) { case Opt_sec_none: mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 0; mnt->auth_flavors[0] = RPC_AUTH_NULL; break; case Opt_sec_sys: mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 0; mnt->auth_flavors[0] = RPC_AUTH_UNIX; break; case Opt_sec_krb5: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5; break; case Opt_sec_krb5i: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I; break; case Opt_sec_krb5p: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P; break; case Opt_sec_lkey: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY; break; case Opt_sec_lkeyi: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI; break; case Opt_sec_lkeyp: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP; break; case Opt_sec_spkm: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM; break; case Opt_sec_spkmi: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI; break; case Opt_sec_spkmp: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP; break; default: goto out_unrec_sec; } break; case Opt_proto: string = match_strdup(args); if (string == NULL) goto out_nomem; token = match_token(string, nfs_xprt_protocol_tokens, args); kfree(string); switch (token) { case Opt_udp: mnt->flags &= ~NFS_MOUNT_TCP; mnt->nfs_server.protocol = IPPROTO_UDP; mnt->timeo = 7; mnt->retrans = 5; break; case Opt_tcp: mnt->flags |= NFS_MOUNT_TCP; mnt->nfs_server.protocol = IPPROTO_TCP; mnt->timeo = 600; mnt->retrans = 2; break; default: goto out_unrec_xprt; } break; case Opt_mountproto: string = match_strdup(args); if (string == NULL) goto out_nomem; token = match_token(string, nfs_xprt_protocol_tokens, args); kfree(string); switch (token) { case Opt_udp: mnt->mount_server.protocol = IPPROTO_UDP; break; case Opt_tcp: mnt->mount_server.protocol = IPPROTO_TCP; break; default: goto out_unrec_xprt; } break; case Opt_addr: string = match_strdup(args); if (string == NULL) goto out_nomem; mnt->nfs_server.address.sin_family = AF_INET; mnt->nfs_server.address.sin_addr.s_addr = in_aton(string); kfree(string); break; case Opt_clientaddr: string = match_strdup(args); if (string == NULL) goto out_nomem; mnt->client_address = string; break; case Opt_mounthost: string = match_strdup(args); if (string == NULL) goto out_nomem; mnt->mount_server.address.sin_family = AF_INET; mnt->mount_server.address.sin_addr.s_addr = in_aton(string); kfree(string); break; case Opt_userspace: case Opt_deprecated: break; default: goto out_unknown; } } return 1; out_nomem: printk(KERN_INFO "NFS: not enough memory to parse option\n"); return 0; out_unrec_vers: printk(KERN_INFO "NFS: unrecognized NFS version number\n"); return 0; out_unrec_xprt: printk(KERN_INFO "NFS: unrecognized transport protocol\n"); return 0; out_unrec_sec: printk(KERN_INFO "NFS: unrecognized security flavor\n"); return 0; out_unknown: printk(KERN_INFO "NFS: unknown mount option: %s\n", p); return 0; } /* * Validate the NFS2/NFS3 mount data * - fills in the mount root filehandle Loading Loading
fs/nfs/super.c +528 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,7 @@ #include <linux/inet.h> #include <linux/nfs_xdr.h> #include <linux/magic.h> #include <linux/parser.h> #include <asm/system.h> #include <asm/uaccess.h> Loading @@ -57,6 +58,164 @@ #define NFSDBG_FACILITY NFSDBG_VFS struct nfs_parsed_mount_data { int flags; int rsize, wsize; int timeo, retrans; int acregmin, acregmax, acdirmin, acdirmax; int namlen; unsigned int bsize; unsigned int auth_flavor_len; rpc_authflavor_t auth_flavors[1]; char *client_address; struct { struct sockaddr_in address; unsigned int program; unsigned int version; unsigned short port; int protocol; } mount_server; struct { struct sockaddr_in address; char *hostname; char *export_path; unsigned int program; int protocol; } nfs_server; }; enum { /* Mount options that take no arguments */ Opt_soft, Opt_hard, Opt_intr, Opt_nointr, Opt_posix, Opt_noposix, Opt_cto, Opt_nocto, Opt_ac, Opt_noac, Opt_lock, Opt_nolock, Opt_v2, Opt_v3, Opt_udp, Opt_tcp, Opt_acl, Opt_noacl, Opt_rdirplus, Opt_nordirplus, /* Mount options that take integer arguments */ Opt_port, Opt_rsize, Opt_wsize, Opt_bsize, Opt_timeo, Opt_retrans, Opt_acregmin, Opt_acregmax, Opt_acdirmin, Opt_acdirmax, Opt_actimeo, Opt_namelen, Opt_mountport, Opt_mountprog, Opt_mountvers, Opt_nfsprog, Opt_nfsvers, /* Mount options that take string arguments */ Opt_sec, Opt_proto, Opt_mountproto, Opt_addr, Opt_mounthost, Opt_clientaddr, /* Mount options that are ignored */ Opt_userspace, Opt_deprecated, Opt_err }; static match_table_t nfs_mount_option_tokens = { { Opt_userspace, "bg" }, { Opt_userspace, "fg" }, { Opt_soft, "soft" }, { Opt_hard, "hard" }, { Opt_intr, "intr" }, { Opt_nointr, "nointr" }, { Opt_posix, "posix" }, { Opt_noposix, "noposix" }, { Opt_cto, "cto" }, { Opt_nocto, "nocto" }, { Opt_ac, "ac" }, { Opt_noac, "noac" }, { Opt_lock, "lock" }, { Opt_nolock, "nolock" }, { Opt_v2, "v2" }, { Opt_v3, "v3" }, { Opt_udp, "udp" }, { Opt_tcp, "tcp" }, { Opt_acl, "acl" }, { Opt_noacl, "noacl" }, { Opt_rdirplus, "rdirplus" }, { Opt_nordirplus, "nordirplus" }, { Opt_port, "port=%u" }, { Opt_rsize, "rsize=%u" }, { Opt_wsize, "wsize=%u" }, { Opt_bsize, "bsize=%u" }, { Opt_timeo, "timeo=%u" }, { Opt_retrans, "retrans=%u" }, { Opt_acregmin, "acregmin=%u" }, { Opt_acregmax, "acregmax=%u" }, { Opt_acdirmin, "acdirmin=%u" }, { Opt_acdirmax, "acdirmax=%u" }, { Opt_actimeo, "actimeo=%u" }, { Opt_userspace, "retry=%u" }, { Opt_namelen, "namlen=%u" }, { Opt_mountport, "mountport=%u" }, { Opt_mountprog, "mountprog=%u" }, { Opt_mountvers, "mountvers=%u" }, { Opt_nfsprog, "nfsprog=%u" }, { Opt_nfsvers, "nfsvers=%u" }, { Opt_nfsvers, "vers=%u" }, { Opt_sec, "sec=%s" }, { Opt_proto, "proto=%s" }, { Opt_mountproto, "mountproto=%s" }, { Opt_addr, "addr=%s" }, { Opt_clientaddr, "clientaddr=%s" }, { Opt_mounthost, "mounthost=%s" }, { Opt_err, NULL } }; enum { Opt_xprt_udp, Opt_xprt_tcp, Opt_xprt_err }; static match_table_t nfs_xprt_protocol_tokens = { { Opt_xprt_udp, "udp" }, { Opt_xprt_tcp, "tcp" }, { Opt_xprt_err, NULL } }; enum { Opt_sec_none, Opt_sec_sys, Opt_sec_krb5, Opt_sec_krb5i, Opt_sec_krb5p, Opt_sec_lkey, Opt_sec_lkeyi, Opt_sec_lkeyp, Opt_sec_spkm, Opt_sec_spkmi, Opt_sec_spkmp, Opt_sec_err }; static match_table_t nfs_secflavor_tokens = { { Opt_sec_none, "none" }, { Opt_sec_none, "null" }, { Opt_sec_sys, "sys" }, { Opt_sec_krb5, "krb5" }, { Opt_sec_krb5i, "krb5i" }, { Opt_sec_krb5p, "krb5p" }, { Opt_sec_lkey, "lkey" }, { Opt_sec_lkeyi, "lkeyi" }, { Opt_sec_lkeyp, "lkeyp" }, { Opt_sec_err, NULL } }; static void nfs_umount_begin(struct vfsmount *, int); static int nfs_statfs(struct dentry *, struct kstatfs *); static int nfs_show_options(struct seq_file *, struct vfsmount *); Loading Loading @@ -463,6 +622,375 @@ static int nfs_verify_server_address(struct sockaddr *addr) return 0; } /* * Error-check and convert a string of mount options from user space into * a data structure */ static int nfs_parse_mount_options(char *raw, struct nfs_parsed_mount_data *mnt) { char *p, *string; if (!raw) { dfprintk(MOUNT, "NFS: mount options string was NULL.\n"); return 1; } dfprintk(MOUNT, "NFS: nfs mount opts='%s'\n", raw); while ((p = strsep(&raw, ",")) != NULL) { substring_t args[MAX_OPT_ARGS]; int option, token; if (!*p) continue; dfprintk(MOUNT, "NFS: parsing nfs mount option '%s'\n", p); token = match_token(p, nfs_mount_option_tokens, args); switch (token) { case Opt_soft: mnt->flags |= NFS_MOUNT_SOFT; break; case Opt_hard: mnt->flags &= ~NFS_MOUNT_SOFT; break; case Opt_intr: mnt->flags |= NFS_MOUNT_INTR; break; case Opt_nointr: mnt->flags &= ~NFS_MOUNT_INTR; break; case Opt_posix: mnt->flags |= NFS_MOUNT_POSIX; break; case Opt_noposix: mnt->flags &= ~NFS_MOUNT_POSIX; break; case Opt_cto: mnt->flags &= ~NFS_MOUNT_NOCTO; break; case Opt_nocto: mnt->flags |= NFS_MOUNT_NOCTO; break; case Opt_ac: mnt->flags &= ~NFS_MOUNT_NOAC; break; case Opt_noac: mnt->flags |= NFS_MOUNT_NOAC; break; case Opt_lock: mnt->flags &= ~NFS_MOUNT_NONLM; break; case Opt_nolock: mnt->flags |= NFS_MOUNT_NONLM; break; case Opt_v2: mnt->flags &= ~NFS_MOUNT_VER3; break; case Opt_v3: mnt->flags |= NFS_MOUNT_VER3; break; case Opt_udp: mnt->flags &= ~NFS_MOUNT_TCP; mnt->nfs_server.protocol = IPPROTO_UDP; mnt->timeo = 7; mnt->retrans = 5; break; case Opt_tcp: mnt->flags |= NFS_MOUNT_TCP; mnt->nfs_server.protocol = IPPROTO_TCP; mnt->timeo = 600; mnt->retrans = 2; break; case Opt_acl: mnt->flags &= ~NFS_MOUNT_NOACL; break; case Opt_noacl: mnt->flags |= NFS_MOUNT_NOACL; break; case Opt_rdirplus: mnt->flags &= ~NFS_MOUNT_NORDIRPLUS; break; case Opt_nordirplus: mnt->flags |= NFS_MOUNT_NORDIRPLUS; break; case Opt_port: if (match_int(args, &option)) return 0; if (option < 0 || option > 65535) return 0; mnt->nfs_server.address.sin_port = htonl(option); break; case Opt_rsize: if (match_int(args, &mnt->rsize)) return 0; break; case Opt_wsize: if (match_int(args, &mnt->wsize)) return 0; break; case Opt_bsize: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->bsize = option; break; case Opt_timeo: if (match_int(args, &mnt->timeo)) return 0; break; case Opt_retrans: if (match_int(args, &mnt->retrans)) return 0; break; case Opt_acregmin: if (match_int(args, &mnt->acregmin)) return 0; break; case Opt_acregmax: if (match_int(args, &mnt->acregmax)) return 0; break; case Opt_acdirmin: if (match_int(args, &mnt->acdirmin)) return 0; break; case Opt_acdirmax: if (match_int(args, &mnt->acdirmax)) return 0; break; case Opt_actimeo: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->acregmin = mnt->acregmax = mnt->acdirmin = mnt->acdirmax = option; break; case Opt_namelen: if (match_int(args, &mnt->namlen)) return 0; break; case Opt_mountport: if (match_int(args, &option)) return 0; if (option < 0 || option > 65535) return 0; mnt->mount_server.port = option; break; case Opt_mountprog: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->mount_server.program = option; break; case Opt_mountvers: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->mount_server.version = option; break; case Opt_nfsprog: if (match_int(args, &option)) return 0; if (option < 0) return 0; mnt->nfs_server.program = option; break; case Opt_nfsvers: if (match_int(args, &option)) return 0; switch (option) { case 2: mnt->flags &= ~NFS_MOUNT_VER3; break; case 3: mnt->flags |= NFS_MOUNT_VER3; break; default: goto out_unrec_vers; } break; case Opt_sec: string = match_strdup(args); if (string == NULL) goto out_nomem; token = match_token(string, nfs_secflavor_tokens, args); kfree(string); /* * The flags setting is for v2/v3. The flavor_len * setting is for v4. v2/v3 also need to know the * difference between NULL and UNIX. */ switch (token) { case Opt_sec_none: mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 0; mnt->auth_flavors[0] = RPC_AUTH_NULL; break; case Opt_sec_sys: mnt->flags &= ~NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 0; mnt->auth_flavors[0] = RPC_AUTH_UNIX; break; case Opt_sec_krb5: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5; break; case Opt_sec_krb5i: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5I; break; case Opt_sec_krb5p: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_KRB5P; break; case Opt_sec_lkey: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEY; break; case Opt_sec_lkeyi: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYI; break; case Opt_sec_lkeyp: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_LKEYP; break; case Opt_sec_spkm: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKM; break; case Opt_sec_spkmi: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMI; break; case Opt_sec_spkmp: mnt->flags |= NFS_MOUNT_SECFLAVOUR; mnt->auth_flavor_len = 1; mnt->auth_flavors[0] = RPC_AUTH_GSS_SPKMP; break; default: goto out_unrec_sec; } break; case Opt_proto: string = match_strdup(args); if (string == NULL) goto out_nomem; token = match_token(string, nfs_xprt_protocol_tokens, args); kfree(string); switch (token) { case Opt_udp: mnt->flags &= ~NFS_MOUNT_TCP; mnt->nfs_server.protocol = IPPROTO_UDP; mnt->timeo = 7; mnt->retrans = 5; break; case Opt_tcp: mnt->flags |= NFS_MOUNT_TCP; mnt->nfs_server.protocol = IPPROTO_TCP; mnt->timeo = 600; mnt->retrans = 2; break; default: goto out_unrec_xprt; } break; case Opt_mountproto: string = match_strdup(args); if (string == NULL) goto out_nomem; token = match_token(string, nfs_xprt_protocol_tokens, args); kfree(string); switch (token) { case Opt_udp: mnt->mount_server.protocol = IPPROTO_UDP; break; case Opt_tcp: mnt->mount_server.protocol = IPPROTO_TCP; break; default: goto out_unrec_xprt; } break; case Opt_addr: string = match_strdup(args); if (string == NULL) goto out_nomem; mnt->nfs_server.address.sin_family = AF_INET; mnt->nfs_server.address.sin_addr.s_addr = in_aton(string); kfree(string); break; case Opt_clientaddr: string = match_strdup(args); if (string == NULL) goto out_nomem; mnt->client_address = string; break; case Opt_mounthost: string = match_strdup(args); if (string == NULL) goto out_nomem; mnt->mount_server.address.sin_family = AF_INET; mnt->mount_server.address.sin_addr.s_addr = in_aton(string); kfree(string); break; case Opt_userspace: case Opt_deprecated: break; default: goto out_unknown; } } return 1; out_nomem: printk(KERN_INFO "NFS: not enough memory to parse option\n"); return 0; out_unrec_vers: printk(KERN_INFO "NFS: unrecognized NFS version number\n"); return 0; out_unrec_xprt: printk(KERN_INFO "NFS: unrecognized transport protocol\n"); return 0; out_unrec_sec: printk(KERN_INFO "NFS: unrecognized security flavor\n"); return 0; out_unknown: printk(KERN_INFO "NFS: unknown mount option: %s\n", p); return 0; } /* * Validate the NFS2/NFS3 mount data * - fills in the mount root filehandle Loading