Loading fs/lockd/clntlock.c +16 −7 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/sunrpc/svc.h> #include <linux/lockd/lockd.h> #include <linux/smp_lock.h> #include <linux/kthread.h> #define NLMDBG_FACILITY NLMDBG_CLIENT Loading Loading @@ -60,7 +61,7 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init) host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, nlm_init->protocol, nlm_version, nlm_init->hostname); nlm_init->hostname, nlm_init->noresvport); if (host == NULL) { lockd_down(); return ERR_PTR(-ENOLCK); Loading Loading @@ -191,11 +192,15 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) void nlmclnt_recovery(struct nlm_host *host) { struct task_struct *task; if (!host->h_reclaiming++) { nlm_get_host(host); __module_get(THIS_MODULE); if (kernel_thread(reclaimer, host, CLONE_FS | CLONE_FILES) < 0) module_put(THIS_MODULE); task = kthread_run(reclaimer, host, "%s-reclaim", host->h_name); if (IS_ERR(task)) printk(KERN_ERR "lockd: unable to spawn reclaimer " "thread. Locks for %s won't be reclaimed! " "(%ld)\n", host->h_name, PTR_ERR(task)); } } Loading @@ -207,7 +212,6 @@ reclaimer(void *ptr) struct file_lock *fl, *next; u32 nsmstate; daemonize("%s-reclaim", host->h_name); allow_signal(SIGKILL); down_write(&host->h_rwsem); Loading @@ -233,7 +237,12 @@ restart: list_for_each_entry_safe(fl, next, &host->h_reclaim, fl_u.nfs_fl.list) { list_del_init(&fl->fl_u.nfs_fl.list); /* Why are we leaking memory here? --okir */ /* * sending this thread a SIGKILL will result in any unreclaimed * locks being removed from the h_granted list. This means that * the kernel will not attempt to reclaim them again if a new * reclaimer thread is spawned for this host. */ if (signalled()) continue; if (nlmclnt_reclaim(host, fl) != 0) Loading Loading @@ -261,5 +270,5 @@ restart: nlm_release_host(host); lockd_down(); unlock_kernel(); module_put_and_exit(0); return 0; } fs/lockd/host.c +9 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ struct nlm_lookup_host_info { const size_t hostname_len; /* it's length */ const struct sockaddr *src_sap; /* our address (optional) */ const size_t src_len; /* it's length */ const int noresvport; /* use non-priv port */ }; /* Loading Loading @@ -222,6 +223,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni) host->h_nsmstate = 0; /* real NSM state */ host->h_nsmhandle = nsm; host->h_server = ni->server; host->h_noresvport = ni->noresvport; hlist_add_head(&host->h_hash, chain); INIT_LIST_HEAD(&host->h_lockowners); spin_lock_init(&host->h_lock); Loading Loading @@ -272,6 +274,7 @@ nlm_destroy_host(struct nlm_host *host) * @protocol: transport protocol to use * @version: NLM protocol version * @hostname: '\0'-terminated hostname of server * @noresvport: 1 if non-privileged port should be used * * Returns an nlm_host structure that matches the passed-in * [server address, transport protocol, NLM version, server hostname]. Loading @@ -281,7 +284,9 @@ nlm_destroy_host(struct nlm_host *host) struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, const size_t salen, const unsigned short protocol, const u32 version, const char *hostname) const u32 version, const char *hostname, int noresvport) { const struct sockaddr source = { .sa_family = AF_UNSPEC, Loading @@ -296,6 +301,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, .hostname_len = strlen(hostname), .src_sap = &source, .src_len = sizeof(source), .noresvport = noresvport, }; dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, Loading Loading @@ -417,6 +423,8 @@ nlm_bind_host(struct nlm_host *host) */ if (!host->h_server) args.flags |= RPC_CLNT_CREATE_HARDRTRY; if (host->h_noresvport) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; clnt = rpc_create(&args); if (!IS_ERR(clnt)) Loading fs/lockd/svc.c +3 −3 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ static struct svc_program nlmsvc_program; struct nlmsvc_binding * nlmsvc_ops; EXPORT_SYMBOL(nlmsvc_ops); EXPORT_SYMBOL_GPL(nlmsvc_ops); static DEFINE_MUTEX(nlmsvc_mutex); static unsigned int nlmsvc_users; Loading Loading @@ -300,7 +300,7 @@ out: mutex_unlock(&nlmsvc_mutex); return error; } EXPORT_SYMBOL(lockd_up); EXPORT_SYMBOL_GPL(lockd_up); /* * Decrement the user count and bring down lockd if we're the last. Loading Loading @@ -329,7 +329,7 @@ lockd_down(void) out: mutex_unlock(&nlmsvc_mutex); } EXPORT_SYMBOL(lockd_down); EXPORT_SYMBOL_GPL(lockd_down); #ifdef CONFIG_SYSCTL Loading fs/nfs/callback.c +31 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/mutex.h> #include <linux/freezer.h> #include <linux/kthread.h> #include <linux/sunrpc/svcauth_gss.h> #include <net/inet_sock.h> Loading Loading @@ -182,10 +183,34 @@ void nfs_callback_down(void) mutex_unlock(&nfs_callback_mutex); } static int check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) { struct rpc_clnt *r = clp->cl_rpcclient; char *p = svc_gss_principal(rqstp); /* * It might just be a normal user principal, in which case * userspace won't bother to tell us the name at all. */ if (p == NULL) return SVC_DENIED; /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ if (memcmp(p, "nfs@", 4) != 0) return SVC_DENIED; p += 4; if (strcmp(p, r->cl_server) != 0) return SVC_DENIED; return SVC_OK; } static int nfs_callback_authenticate(struct svc_rqst *rqstp) { struct nfs_client *clp; RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); int ret = SVC_OK; /* Don't talk to strangers */ clp = nfs_find_client(svc_addr(rqstp), 4); Loading @@ -194,21 +219,22 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp) dprintk("%s: %s NFSv4 callback!\n", __func__, svc_print_addr(rqstp, buf, sizeof(buf))); nfs_put_client(clp); switch (rqstp->rq_authop->flavour) { case RPC_AUTH_NULL: if (rqstp->rq_proc != CB_NULL) return SVC_DENIED; ret = SVC_DENIED; break; case RPC_AUTH_UNIX: break; case RPC_AUTH_GSS: /* FIXME: RPCSEC_GSS handling? */ ret = check_gss_callback_principal(clp, rqstp); break; default: return SVC_DENIED; ret = SVC_DENIED; } return SVC_OK; nfs_put_client(clp); return ret; } /* Loading fs/nfs/client.c +61 −34 Original line number Diff line number Diff line Loading @@ -143,7 +143,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ clp->cl_proto = cl_init->proto; #ifdef CONFIG_NFS_V4 init_rwsem(&clp->cl_sem); INIT_LIST_HEAD(&clp->cl_delegations); spin_lock_init(&clp->cl_lock); INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); Loading Loading @@ -224,31 +223,54 @@ void nfs_put_client(struct nfs_client *clp) } } static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, const struct sockaddr_in *sa2) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static const struct in6_addr *nfs_map_ipv4_addr(const struct sockaddr *sa, struct in6_addr *addr_mapped) { return sa1->sin_addr.s_addr == sa2->sin_addr.s_addr; switch (sa->sa_family) { default: return NULL; case AF_INET6: return &((const struct sockaddr_in6 *)sa)->sin6_addr; break; case AF_INET: ipv6_addr_set_v4mapped(((const struct sockaddr_in *)sa)->sin_addr.s_addr, addr_mapped); return addr_mapped; } } static int nfs_sockaddr_match_ipaddr6(const struct sockaddr_in6 *sa1, const struct sockaddr_in6 *sa2) static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, const struct sockaddr *sa2) { const struct in6_addr *addr1; const struct in6_addr *addr2; struct in6_addr addr1_mapped; struct in6_addr addr2_mapped; addr1 = nfs_map_ipv4_addr(sa1, &addr1_mapped); if (likely(addr1 != NULL)) { addr2 = nfs_map_ipv4_addr(sa2, &addr2_mapped); if (likely(addr2 != NULL)) return ipv6_addr_equal(addr1, addr2); } return 0; } #else static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, const struct sockaddr_in *sa2) { return ipv6_addr_equal(&sa1->sin6_addr, &sa2->sin6_addr); return sa1->sin_addr.s_addr == sa2->sin_addr.s_addr; } static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, const struct sockaddr *sa2) { switch (sa1->sa_family) { case AF_INET: if (unlikely(sa1->sa_family != AF_INET || sa2->sa_family != AF_INET)) return 0; return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, (const struct sockaddr_in *)sa2); case AF_INET6: return nfs_sockaddr_match_ipaddr6((const struct sockaddr_in6 *)sa1, (const struct sockaddr_in6 *)sa2); } BUG(); } #endif /* * Find a client by IP address and protocol version Loading @@ -270,8 +292,6 @@ struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion) if (clp->rpc_ops->version != nfsversion) continue; if (addr->sa_family != clap->sa_family) continue; /* Match only the IP address, not the port number */ if (!nfs_sockaddr_match_ipaddr(addr, clap)) continue; Loading Loading @@ -305,8 +325,6 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp) if (clp->rpc_ops->version != nfsvers) continue; if (sap->sa_family != clap->sa_family) continue; /* Match only the IP address, not the port number */ if (!nfs_sockaddr_match_ipaddr(sap, clap)) continue; Loading Loading @@ -470,7 +488,7 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, static int nfs_create_rpc_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, rpc_authflavor_t flavor, int flags) int discrtry, int noresvport) { struct rpc_clnt *clnt = NULL; struct rpc_create_args args = { Loading @@ -482,9 +500,13 @@ static int nfs_create_rpc_client(struct nfs_client *clp, .program = &nfs_program, .version = clp->rpc_ops->version, .authflavor = flavor, .flags = flags, }; if (discrtry) args.flags |= RPC_CLNT_CREATE_DISCRTRY; if (noresvport) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; if (!IS_ERR(clp->cl_rpcclient)) return 0; Loading Loading @@ -522,6 +544,8 @@ static int nfs_start_lockd(struct nfs_server *server) .protocol = server->flags & NFS_MOUNT_TCP ? IPPROTO_TCP : IPPROTO_UDP, .nfs_version = clp->rpc_ops->version, .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? 1 : 0, }; if (nlm_init.nfs_version > 3) Loading Loading @@ -623,7 +647,8 @@ static int nfs_init_client(struct nfs_client *clp, * Create a client RPC handle for doing FSSTAT with UNIX auth only * - RFC 2623, sec 2.3.2 */ error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, 0); error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, 0, data->flags & NFS_MOUNT_NORESVPORT); if (error < 0) goto error; nfs_mark_client_ready(clp, NFS_CS_READY); Loading Loading @@ -965,7 +990,8 @@ error: static int nfs4_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, const char *ip_addr, rpc_authflavor_t authflavour) rpc_authflavor_t authflavour, int flags) { int error; Loading @@ -979,7 +1005,7 @@ static int nfs4_init_client(struct nfs_client *clp, clp->rpc_ops = &nfs_v4_clientops; error = nfs_create_rpc_client(clp, timeparms, authflavour, RPC_CLNT_CREATE_DISCRTRY); 1, flags & NFS_MOUNT_NORESVPORT); if (error < 0) goto error; memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); Loading Loading @@ -1030,7 +1056,8 @@ static int nfs4_set_client(struct nfs_server *server, error = PTR_ERR(clp); goto error; } error = nfs4_init_client(clp, timeparms, ip_addr, authflavour); error = nfs4_init_client(clp, timeparms, ip_addr, authflavour, server->flags); if (error < 0) goto error_put; Loading Loading @@ -1059,6 +1086,10 @@ static int nfs4_init_server(struct nfs_server *server, nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, data->timeo, data->retrans); /* Initialise the client representation from the mount data */ server->flags = data->flags; server->caps |= NFS_CAP_ATOMIC_OPEN; /* Get a client record */ error = nfs4_set_client(server, data->nfs_server.hostname, Loading @@ -1071,10 +1102,6 @@ static int nfs4_init_server(struct nfs_server *server, if (error < 0) goto error; /* Initialise the client representation from the mount data */ server->flags = data->flags; server->caps |= NFS_CAP_ATOMIC_OPEN; if (data->rsize) server->rsize = nfs_block_size(data->rsize, NULL); if (data->wsize) Loading Loading @@ -1177,6 +1204,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, parent_server = NFS_SB(data->sb); parent_client = parent_server->nfs_client; /* Initialise the client representation from the parent server */ nfs_server_copy_userdata(server, parent_server); server->caps |= NFS_CAP_ATOMIC_OPEN; /* Get a client representation. * Note: NFSv4 always uses TCP, */ error = nfs4_set_client(server, data->hostname, Loading @@ -1189,10 +1220,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, if (error < 0) goto error; /* Initialise the client representation from the parent server */ nfs_server_copy_userdata(server, parent_server); server->caps |= NFS_CAP_ATOMIC_OPEN; error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor); if (error < 0) goto error; Loading Loading
fs/lockd/clntlock.c +16 −7 Original line number Diff line number Diff line Loading @@ -14,6 +14,7 @@ #include <linux/sunrpc/svc.h> #include <linux/lockd/lockd.h> #include <linux/smp_lock.h> #include <linux/kthread.h> #define NLMDBG_FACILITY NLMDBG_CLIENT Loading Loading @@ -60,7 +61,7 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init) host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, nlm_init->protocol, nlm_version, nlm_init->hostname); nlm_init->hostname, nlm_init->noresvport); if (host == NULL) { lockd_down(); return ERR_PTR(-ENOLCK); Loading Loading @@ -191,11 +192,15 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) void nlmclnt_recovery(struct nlm_host *host) { struct task_struct *task; if (!host->h_reclaiming++) { nlm_get_host(host); __module_get(THIS_MODULE); if (kernel_thread(reclaimer, host, CLONE_FS | CLONE_FILES) < 0) module_put(THIS_MODULE); task = kthread_run(reclaimer, host, "%s-reclaim", host->h_name); if (IS_ERR(task)) printk(KERN_ERR "lockd: unable to spawn reclaimer " "thread. Locks for %s won't be reclaimed! " "(%ld)\n", host->h_name, PTR_ERR(task)); } } Loading @@ -207,7 +212,6 @@ reclaimer(void *ptr) struct file_lock *fl, *next; u32 nsmstate; daemonize("%s-reclaim", host->h_name); allow_signal(SIGKILL); down_write(&host->h_rwsem); Loading @@ -233,7 +237,12 @@ restart: list_for_each_entry_safe(fl, next, &host->h_reclaim, fl_u.nfs_fl.list) { list_del_init(&fl->fl_u.nfs_fl.list); /* Why are we leaking memory here? --okir */ /* * sending this thread a SIGKILL will result in any unreclaimed * locks being removed from the h_granted list. This means that * the kernel will not attempt to reclaim them again if a new * reclaimer thread is spawned for this host. */ if (signalled()) continue; if (nlmclnt_reclaim(host, fl) != 0) Loading Loading @@ -261,5 +270,5 @@ restart: nlm_release_host(host); lockd_down(); unlock_kernel(); module_put_and_exit(0); return 0; }
fs/lockd/host.c +9 −1 Original line number Diff line number Diff line Loading @@ -48,6 +48,7 @@ struct nlm_lookup_host_info { const size_t hostname_len; /* it's length */ const struct sockaddr *src_sap; /* our address (optional) */ const size_t src_len; /* it's length */ const int noresvport; /* use non-priv port */ }; /* Loading Loading @@ -222,6 +223,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni) host->h_nsmstate = 0; /* real NSM state */ host->h_nsmhandle = nsm; host->h_server = ni->server; host->h_noresvport = ni->noresvport; hlist_add_head(&host->h_hash, chain); INIT_LIST_HEAD(&host->h_lockowners); spin_lock_init(&host->h_lock); Loading Loading @@ -272,6 +274,7 @@ nlm_destroy_host(struct nlm_host *host) * @protocol: transport protocol to use * @version: NLM protocol version * @hostname: '\0'-terminated hostname of server * @noresvport: 1 if non-privileged port should be used * * Returns an nlm_host structure that matches the passed-in * [server address, transport protocol, NLM version, server hostname]. Loading @@ -281,7 +284,9 @@ nlm_destroy_host(struct nlm_host *host) struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, const size_t salen, const unsigned short protocol, const u32 version, const char *hostname) const u32 version, const char *hostname, int noresvport) { const struct sockaddr source = { .sa_family = AF_UNSPEC, Loading @@ -296,6 +301,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, .hostname_len = strlen(hostname), .src_sap = &source, .src_len = sizeof(source), .noresvport = noresvport, }; dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, Loading Loading @@ -417,6 +423,8 @@ nlm_bind_host(struct nlm_host *host) */ if (!host->h_server) args.flags |= RPC_CLNT_CREATE_HARDRTRY; if (host->h_noresvport) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; clnt = rpc_create(&args); if (!IS_ERR(clnt)) Loading
fs/lockd/svc.c +3 −3 Original line number Diff line number Diff line Loading @@ -45,7 +45,7 @@ static struct svc_program nlmsvc_program; struct nlmsvc_binding * nlmsvc_ops; EXPORT_SYMBOL(nlmsvc_ops); EXPORT_SYMBOL_GPL(nlmsvc_ops); static DEFINE_MUTEX(nlmsvc_mutex); static unsigned int nlmsvc_users; Loading Loading @@ -300,7 +300,7 @@ out: mutex_unlock(&nlmsvc_mutex); return error; } EXPORT_SYMBOL(lockd_up); EXPORT_SYMBOL_GPL(lockd_up); /* * Decrement the user count and bring down lockd if we're the last. Loading Loading @@ -329,7 +329,7 @@ lockd_down(void) out: mutex_unlock(&nlmsvc_mutex); } EXPORT_SYMBOL(lockd_down); EXPORT_SYMBOL_GPL(lockd_down); #ifdef CONFIG_SYSCTL Loading
fs/nfs/callback.c +31 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ #include <linux/mutex.h> #include <linux/freezer.h> #include <linux/kthread.h> #include <linux/sunrpc/svcauth_gss.h> #include <net/inet_sock.h> Loading Loading @@ -182,10 +183,34 @@ void nfs_callback_down(void) mutex_unlock(&nfs_callback_mutex); } static int check_gss_callback_principal(struct nfs_client *clp, struct svc_rqst *rqstp) { struct rpc_clnt *r = clp->cl_rpcclient; char *p = svc_gss_principal(rqstp); /* * It might just be a normal user principal, in which case * userspace won't bother to tell us the name at all. */ if (p == NULL) return SVC_DENIED; /* Expect a GSS_C_NT_HOSTBASED_NAME like "nfs@serverhostname" */ if (memcmp(p, "nfs@", 4) != 0) return SVC_DENIED; p += 4; if (strcmp(p, r->cl_server) != 0) return SVC_DENIED; return SVC_OK; } static int nfs_callback_authenticate(struct svc_rqst *rqstp) { struct nfs_client *clp; RPC_IFDEBUG(char buf[RPC_MAX_ADDRBUFLEN]); int ret = SVC_OK; /* Don't talk to strangers */ clp = nfs_find_client(svc_addr(rqstp), 4); Loading @@ -194,21 +219,22 @@ static int nfs_callback_authenticate(struct svc_rqst *rqstp) dprintk("%s: %s NFSv4 callback!\n", __func__, svc_print_addr(rqstp, buf, sizeof(buf))); nfs_put_client(clp); switch (rqstp->rq_authop->flavour) { case RPC_AUTH_NULL: if (rqstp->rq_proc != CB_NULL) return SVC_DENIED; ret = SVC_DENIED; break; case RPC_AUTH_UNIX: break; case RPC_AUTH_GSS: /* FIXME: RPCSEC_GSS handling? */ ret = check_gss_callback_principal(clp, rqstp); break; default: return SVC_DENIED; ret = SVC_DENIED; } return SVC_OK; nfs_put_client(clp); return ret; } /* Loading
fs/nfs/client.c +61 −34 Original line number Diff line number Diff line Loading @@ -143,7 +143,6 @@ static struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *cl_ clp->cl_proto = cl_init->proto; #ifdef CONFIG_NFS_V4 init_rwsem(&clp->cl_sem); INIT_LIST_HEAD(&clp->cl_delegations); spin_lock_init(&clp->cl_lock); INIT_DELAYED_WORK(&clp->cl_renewd, nfs4_renew_state); Loading Loading @@ -224,31 +223,54 @@ void nfs_put_client(struct nfs_client *clp) } } static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, const struct sockaddr_in *sa2) #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) static const struct in6_addr *nfs_map_ipv4_addr(const struct sockaddr *sa, struct in6_addr *addr_mapped) { return sa1->sin_addr.s_addr == sa2->sin_addr.s_addr; switch (sa->sa_family) { default: return NULL; case AF_INET6: return &((const struct sockaddr_in6 *)sa)->sin6_addr; break; case AF_INET: ipv6_addr_set_v4mapped(((const struct sockaddr_in *)sa)->sin_addr.s_addr, addr_mapped); return addr_mapped; } } static int nfs_sockaddr_match_ipaddr6(const struct sockaddr_in6 *sa1, const struct sockaddr_in6 *sa2) static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, const struct sockaddr *sa2) { const struct in6_addr *addr1; const struct in6_addr *addr2; struct in6_addr addr1_mapped; struct in6_addr addr2_mapped; addr1 = nfs_map_ipv4_addr(sa1, &addr1_mapped); if (likely(addr1 != NULL)) { addr2 = nfs_map_ipv4_addr(sa2, &addr2_mapped); if (likely(addr2 != NULL)) return ipv6_addr_equal(addr1, addr2); } return 0; } #else static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, const struct sockaddr_in *sa2) { return ipv6_addr_equal(&sa1->sin6_addr, &sa2->sin6_addr); return sa1->sin_addr.s_addr == sa2->sin_addr.s_addr; } static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, const struct sockaddr *sa2) { switch (sa1->sa_family) { case AF_INET: if (unlikely(sa1->sa_family != AF_INET || sa2->sa_family != AF_INET)) return 0; return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, (const struct sockaddr_in *)sa2); case AF_INET6: return nfs_sockaddr_match_ipaddr6((const struct sockaddr_in6 *)sa1, (const struct sockaddr_in6 *)sa2); } BUG(); } #endif /* * Find a client by IP address and protocol version Loading @@ -270,8 +292,6 @@ struct nfs_client *nfs_find_client(const struct sockaddr *addr, u32 nfsversion) if (clp->rpc_ops->version != nfsversion) continue; if (addr->sa_family != clap->sa_family) continue; /* Match only the IP address, not the port number */ if (!nfs_sockaddr_match_ipaddr(addr, clap)) continue; Loading Loading @@ -305,8 +325,6 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp) if (clp->rpc_ops->version != nfsvers) continue; if (sap->sa_family != clap->sa_family) continue; /* Match only the IP address, not the port number */ if (!nfs_sockaddr_match_ipaddr(sap, clap)) continue; Loading Loading @@ -470,7 +488,7 @@ static void nfs_init_timeout_values(struct rpc_timeout *to, int proto, static int nfs_create_rpc_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, rpc_authflavor_t flavor, int flags) int discrtry, int noresvport) { struct rpc_clnt *clnt = NULL; struct rpc_create_args args = { Loading @@ -482,9 +500,13 @@ static int nfs_create_rpc_client(struct nfs_client *clp, .program = &nfs_program, .version = clp->rpc_ops->version, .authflavor = flavor, .flags = flags, }; if (discrtry) args.flags |= RPC_CLNT_CREATE_DISCRTRY; if (noresvport) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; if (!IS_ERR(clp->cl_rpcclient)) return 0; Loading Loading @@ -522,6 +544,8 @@ static int nfs_start_lockd(struct nfs_server *server) .protocol = server->flags & NFS_MOUNT_TCP ? IPPROTO_TCP : IPPROTO_UDP, .nfs_version = clp->rpc_ops->version, .noresvport = server->flags & NFS_MOUNT_NORESVPORT ? 1 : 0, }; if (nlm_init.nfs_version > 3) Loading Loading @@ -623,7 +647,8 @@ static int nfs_init_client(struct nfs_client *clp, * Create a client RPC handle for doing FSSTAT with UNIX auth only * - RFC 2623, sec 2.3.2 */ error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, 0); error = nfs_create_rpc_client(clp, timeparms, RPC_AUTH_UNIX, 0, data->flags & NFS_MOUNT_NORESVPORT); if (error < 0) goto error; nfs_mark_client_ready(clp, NFS_CS_READY); Loading Loading @@ -965,7 +990,8 @@ error: static int nfs4_init_client(struct nfs_client *clp, const struct rpc_timeout *timeparms, const char *ip_addr, rpc_authflavor_t authflavour) rpc_authflavor_t authflavour, int flags) { int error; Loading @@ -979,7 +1005,7 @@ static int nfs4_init_client(struct nfs_client *clp, clp->rpc_ops = &nfs_v4_clientops; error = nfs_create_rpc_client(clp, timeparms, authflavour, RPC_CLNT_CREATE_DISCRTRY); 1, flags & NFS_MOUNT_NORESVPORT); if (error < 0) goto error; memcpy(clp->cl_ipaddr, ip_addr, sizeof(clp->cl_ipaddr)); Loading Loading @@ -1030,7 +1056,8 @@ static int nfs4_set_client(struct nfs_server *server, error = PTR_ERR(clp); goto error; } error = nfs4_init_client(clp, timeparms, ip_addr, authflavour); error = nfs4_init_client(clp, timeparms, ip_addr, authflavour, server->flags); if (error < 0) goto error_put; Loading Loading @@ -1059,6 +1086,10 @@ static int nfs4_init_server(struct nfs_server *server, nfs_init_timeout_values(&timeparms, data->nfs_server.protocol, data->timeo, data->retrans); /* Initialise the client representation from the mount data */ server->flags = data->flags; server->caps |= NFS_CAP_ATOMIC_OPEN; /* Get a client record */ error = nfs4_set_client(server, data->nfs_server.hostname, Loading @@ -1071,10 +1102,6 @@ static int nfs4_init_server(struct nfs_server *server, if (error < 0) goto error; /* Initialise the client representation from the mount data */ server->flags = data->flags; server->caps |= NFS_CAP_ATOMIC_OPEN; if (data->rsize) server->rsize = nfs_block_size(data->rsize, NULL); if (data->wsize) Loading Loading @@ -1177,6 +1204,10 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, parent_server = NFS_SB(data->sb); parent_client = parent_server->nfs_client; /* Initialise the client representation from the parent server */ nfs_server_copy_userdata(server, parent_server); server->caps |= NFS_CAP_ATOMIC_OPEN; /* Get a client representation. * Note: NFSv4 always uses TCP, */ error = nfs4_set_client(server, data->hostname, Loading @@ -1189,10 +1220,6 @@ struct nfs_server *nfs4_create_referral_server(struct nfs_clone_mount *data, if (error < 0) goto error; /* Initialise the client representation from the parent server */ nfs_server_copy_userdata(server, parent_server); server->caps |= NFS_CAP_ATOMIC_OPEN; error = nfs_init_server_rpcclient(server, parent_server->client->cl_timeout, data->authflavor); if (error < 0) goto error; Loading