diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-14 15:31:14 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-10-14 15:31:14 -0400 |
| commit | 8acd3a60bcca17c6d89c73cee3ad6057eb83ba1e (patch) | |
| tree | d610c8d39246c33c499ee9d92d302d3ca9e89ae3 /fs/lockd | |
| parent | c269bc00fcb876ae3b85f178f1e34601185c8ccc (diff) | |
| parent | 107e0008dfb8bd6366bc8827f5bbbc0c1f795d2d (diff) | |
Merge branch 'for-2.6.28' of git://linux-nfs.org/~bfields/linux
* 'for-2.6.28' of git://linux-nfs.org/~bfields/linux: (59 commits)
svcrdma: Fix IRD/ORD polarity
svcrdma: Update svc_rdma_send_error to use DMA LKEY
svcrdma: Modify the RPC reply path to use FRMR when available
svcrdma: Modify the RPC recv path to use FRMR when available
svcrdma: Add support to svc_rdma_send to handle chained WR
svcrdma: Modify post recv path to use local dma key
svcrdma: Add a service to register a Fast Reg MR with the device
svcrdma: Query device for Fast Reg support during connection setup
svcrdma: Add FRMR get/put services
NLM: Remove unused argument from svc_addsock() function
NLM: Remove "proto" argument from lockd_up()
NLM: Always start both UDP and TCP listeners
lockd: Remove unused fields in the nlm_reboot structure
lockd: Add helper to sanity check incoming NOTIFY requests
lockd: change nlmclnt_grant() to take a "struct sockaddr *"
lockd: Adjust nlmsvc_lookup_host() to accomodate AF_INET6 addresses
lockd: Adjust nlmclnt_lookup_host() signature to accomodate non-AF_INET
lockd: Support non-AF_INET addresses in nlm_lookup_host()
NLM: Convert nlm_lookup_host() to use a single argument
svcrdma: Add Fast Reg MR Data Types
...
Diffstat (limited to 'fs/lockd')
| -rw-r--r-- | fs/lockd/Makefile | 2 | ||||
| -rw-r--r-- | fs/lockd/clntlock.c | 13 | ||||
| -rw-r--r-- | fs/lockd/grace.c | 59 | ||||
| -rw-r--r-- | fs/lockd/host.c | 350 | ||||
| -rw-r--r-- | fs/lockd/mon.c | 2 | ||||
| -rw-r--r-- | fs/lockd/svc.c | 88 | ||||
| -rw-r--r-- | fs/lockd/svc4proc.c | 31 | ||||
| -rw-r--r-- | fs/lockd/svclock.c | 18 | ||||
| -rw-r--r-- | fs/lockd/svcproc.c | 31 | ||||
| -rw-r--r-- | fs/lockd/svcsubs.c | 2 | ||||
| -rw-r--r-- | fs/lockd/xdr.c | 2 | ||||
| -rw-r--r-- | fs/lockd/xdr4.c | 2 |
12 files changed, 397 insertions, 203 deletions
diff --git a/fs/lockd/Makefile b/fs/lockd/Makefile index 7725a0a9a555..97f6073ab339 100644 --- a/fs/lockd/Makefile +++ b/fs/lockd/Makefile | |||
| @@ -5,6 +5,6 @@ | |||
| 5 | obj-$(CONFIG_LOCKD) += lockd.o | 5 | obj-$(CONFIG_LOCKD) += lockd.o |
| 6 | 6 | ||
| 7 | lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \ | 7 | lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \ |
| 8 | svcproc.o svcsubs.o mon.o xdr.o | 8 | svcproc.o svcsubs.o mon.o xdr.o grace.o |
| 9 | lockd-objs-$(CONFIG_LOCKD_V4) += xdr4.o svc4proc.o | 9 | lockd-objs-$(CONFIG_LOCKD_V4) += xdr4.o svc4proc.o |
| 10 | lockd-objs := $(lockd-objs-y) | 10 | lockd-objs := $(lockd-objs-y) |
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 0b45fd3a4bfd..8307dd64bf46 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
| @@ -54,14 +54,13 @@ struct nlm_host *nlmclnt_init(const struct nlmclnt_initdata *nlm_init) | |||
| 54 | u32 nlm_version = (nlm_init->nfs_version == 2) ? 1 : 4; | 54 | u32 nlm_version = (nlm_init->nfs_version == 2) ? 1 : 4; |
| 55 | int status; | 55 | int status; |
| 56 | 56 | ||
| 57 | status = lockd_up(nlm_init->protocol); | 57 | status = lockd_up(); |
| 58 | if (status < 0) | 58 | if (status < 0) |
| 59 | return ERR_PTR(status); | 59 | return ERR_PTR(status); |
| 60 | 60 | ||
| 61 | host = nlmclnt_lookup_host((struct sockaddr_in *)nlm_init->address, | 61 | host = nlmclnt_lookup_host(nlm_init->address, nlm_init->addrlen, |
| 62 | nlm_init->protocol, nlm_version, | 62 | nlm_init->protocol, nlm_version, |
| 63 | nlm_init->hostname, | 63 | nlm_init->hostname); |
| 64 | strlen(nlm_init->hostname)); | ||
| 65 | if (host == NULL) { | 64 | if (host == NULL) { |
| 66 | lockd_down(); | 65 | lockd_down(); |
| 67 | return ERR_PTR(-ENOLCK); | 66 | return ERR_PTR(-ENOLCK); |
| @@ -142,7 +141,7 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) | |||
| 142 | /* | 141 | /* |
| 143 | * The server lockd has called us back to tell us the lock was granted | 142 | * The server lockd has called us back to tell us the lock was granted |
| 144 | */ | 143 | */ |
| 145 | __be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock) | 144 | __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) |
| 146 | { | 145 | { |
| 147 | const struct file_lock *fl = &lock->fl; | 146 | const struct file_lock *fl = &lock->fl; |
| 148 | const struct nfs_fh *fh = &lock->fh; | 147 | const struct nfs_fh *fh = &lock->fh; |
| @@ -166,7 +165,7 @@ __be32 nlmclnt_grant(const struct sockaddr_in *addr, const struct nlm_lock *lock | |||
| 166 | */ | 165 | */ |
| 167 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) | 166 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) |
| 168 | continue; | 167 | continue; |
| 169 | if (!nlm_cmp_addr(&block->b_host->h_addr, addr)) | 168 | if (!nlm_cmp_addr(nlm_addr(block->b_host), addr)) |
| 170 | continue; | 169 | continue; |
| 171 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) | 170 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) |
| 172 | continue; | 171 | continue; |
| @@ -216,7 +215,7 @@ reclaimer(void *ptr) | |||
| 216 | /* This one ensures that our parent doesn't terminate while the | 215 | /* This one ensures that our parent doesn't terminate while the |
| 217 | * reclaim is in progress */ | 216 | * reclaim is in progress */ |
| 218 | lock_kernel(); | 217 | lock_kernel(); |
| 219 | lockd_up(0); /* note: this cannot fail as lockd is already running */ | 218 | lockd_up(); /* note: this cannot fail as lockd is already running */ |
| 220 | 219 | ||
| 221 | dprintk("lockd: reclaiming locks for host %s\n", host->h_name); | 220 | dprintk("lockd: reclaiming locks for host %s\n", host->h_name); |
| 222 | 221 | ||
diff --git a/fs/lockd/grace.c b/fs/lockd/grace.c new file mode 100644 index 000000000000..183cc1f0af1c --- /dev/null +++ b/fs/lockd/grace.c | |||
| @@ -0,0 +1,59 @@ | |||
| 1 | /* | ||
| 2 | * Common code for control of lockd and nfsv4 grace periods. | ||
| 3 | */ | ||
| 4 | |||
| 5 | #include <linux/module.h> | ||
| 6 | #include <linux/lockd/bind.h> | ||
| 7 | |||
| 8 | static LIST_HEAD(grace_list); | ||
| 9 | static DEFINE_SPINLOCK(grace_lock); | ||
| 10 | |||
| 11 | /** | ||
| 12 | * locks_start_grace | ||
| 13 | * @lm: who this grace period is for | ||
| 14 | * | ||
| 15 | * A grace period is a period during which locks should not be given | ||
| 16 | * out. Currently grace periods are only enforced by the two lock | ||
| 17 | * managers (lockd and nfsd), using the locks_in_grace() function to | ||
| 18 | * check when they are in a grace period. | ||
| 19 | * | ||
| 20 | * This function is called to start a grace period. | ||
| 21 | */ | ||
| 22 | void locks_start_grace(struct lock_manager *lm) | ||
| 23 | { | ||
| 24 | spin_lock(&grace_lock); | ||
| 25 | list_add(&lm->list, &grace_list); | ||
| 26 | spin_unlock(&grace_lock); | ||
| 27 | } | ||
| 28 | EXPORT_SYMBOL_GPL(locks_start_grace); | ||
| 29 | |||
| 30 | /** | ||
| 31 | * locks_end_grace | ||
| 32 | * @lm: who this grace period is for | ||
| 33 | * | ||
| 34 | * Call this function to state that the given lock manager is ready to | ||
| 35 | * resume regular locking. The grace period will not end until all lock | ||
| 36 | * managers that called locks_start_grace() also call locks_end_grace(). | ||
| 37 | * Note that callers count on it being safe to call this more than once, | ||
| 38 | * and the second call should be a no-op. | ||
| 39 | */ | ||
| 40 | void locks_end_grace(struct lock_manager *lm) | ||
| 41 | { | ||
| 42 | spin_lock(&grace_lock); | ||
| 43 | list_del_init(&lm->list); | ||
| 44 | spin_unlock(&grace_lock); | ||
| 45 | } | ||
| 46 | EXPORT_SYMBOL_GPL(locks_end_grace); | ||
| 47 | |||
| 48 | /** | ||
| 49 | * locks_in_grace | ||
| 50 | * | ||
| 51 | * Lock managers call this function to determine when it is OK for them | ||
| 52 | * to answer ordinary lock requests, and when they should accept only | ||
| 53 | * lock reclaims. | ||
| 54 | */ | ||
| 55 | int locks_in_grace(void) | ||
| 56 | { | ||
| 57 | return !list_empty(&grace_list); | ||
| 58 | } | ||
| 59 | EXPORT_SYMBOL_GPL(locks_in_grace); | ||
diff --git a/fs/lockd/host.c b/fs/lockd/host.c index a17664c7eacc..9fd8889097b7 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c | |||
| @@ -11,16 +11,17 @@ | |||
| 11 | #include <linux/types.h> | 11 | #include <linux/types.h> |
| 12 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
| 13 | #include <linux/in.h> | 13 | #include <linux/in.h> |
| 14 | #include <linux/in6.h> | ||
| 14 | #include <linux/sunrpc/clnt.h> | 15 | #include <linux/sunrpc/clnt.h> |
| 15 | #include <linux/sunrpc/svc.h> | 16 | #include <linux/sunrpc/svc.h> |
| 16 | #include <linux/lockd/lockd.h> | 17 | #include <linux/lockd/lockd.h> |
| 17 | #include <linux/lockd/sm_inter.h> | 18 | #include <linux/lockd/sm_inter.h> |
| 18 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
| 19 | 20 | ||
| 21 | #include <net/ipv6.h> | ||
| 20 | 22 | ||
| 21 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE | 23 | #define NLMDBG_FACILITY NLMDBG_HOSTCACHE |
| 22 | #define NLM_HOST_NRHASH 32 | 24 | #define NLM_HOST_NRHASH 32 |
| 23 | #define NLM_ADDRHASH(addr) (ntohl(addr) & (NLM_HOST_NRHASH-1)) | ||
| 24 | #define NLM_HOST_REBIND (60 * HZ) | 25 | #define NLM_HOST_REBIND (60 * HZ) |
| 25 | #define NLM_HOST_EXPIRE (300 * HZ) | 26 | #define NLM_HOST_EXPIRE (300 * HZ) |
| 26 | #define NLM_HOST_COLLECT (120 * HZ) | 27 | #define NLM_HOST_COLLECT (120 * HZ) |
| @@ -30,42 +31,115 @@ static unsigned long next_gc; | |||
| 30 | static int nrhosts; | 31 | static int nrhosts; |
| 31 | static DEFINE_MUTEX(nlm_host_mutex); | 32 | static DEFINE_MUTEX(nlm_host_mutex); |
| 32 | 33 | ||
| 33 | |||
| 34 | static void nlm_gc_hosts(void); | 34 | static void nlm_gc_hosts(void); |
| 35 | static struct nsm_handle * __nsm_find(const struct sockaddr_in *, | 35 | static struct nsm_handle *nsm_find(const struct sockaddr *sap, |
| 36 | const char *, unsigned int, int); | 36 | const size_t salen, |
| 37 | static struct nsm_handle * nsm_find(const struct sockaddr_in *sin, | 37 | const char *hostname, |
| 38 | const char *hostname, | 38 | const size_t hostname_len, |
| 39 | unsigned int hostname_len); | 39 | const int create); |
| 40 | |||
| 41 | struct nlm_lookup_host_info { | ||
| 42 | const int server; /* search for server|client */ | ||
| 43 | const struct sockaddr *sap; /* address to search for */ | ||
| 44 | const size_t salen; /* it's length */ | ||
| 45 | const unsigned short protocol; /* transport to search for*/ | ||
| 46 | const u32 version; /* NLM version to search for */ | ||
| 47 | const char *hostname; /* remote's hostname */ | ||
| 48 | const size_t hostname_len; /* it's length */ | ||
| 49 | const struct sockaddr *src_sap; /* our address (optional) */ | ||
| 50 | const size_t src_len; /* it's length */ | ||
| 51 | }; | ||
| 52 | |||
| 53 | /* | ||
| 54 | * Hash function must work well on big- and little-endian platforms | ||
| 55 | */ | ||
| 56 | static unsigned int __nlm_hash32(const __be32 n) | ||
| 57 | { | ||
| 58 | unsigned int hash = (__force u32)n ^ ((__force u32)n >> 16); | ||
| 59 | return hash ^ (hash >> 8); | ||
| 60 | } | ||
| 61 | |||
| 62 | static unsigned int __nlm_hash_addr4(const struct sockaddr *sap) | ||
| 63 | { | ||
| 64 | const struct sockaddr_in *sin = (struct sockaddr_in *)sap; | ||
| 65 | return __nlm_hash32(sin->sin_addr.s_addr); | ||
| 66 | } | ||
| 67 | |||
| 68 | static unsigned int __nlm_hash_addr6(const struct sockaddr *sap) | ||
| 69 | { | ||
| 70 | const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; | ||
| 71 | const struct in6_addr addr = sin6->sin6_addr; | ||
| 72 | return __nlm_hash32(addr.s6_addr32[0]) ^ | ||
| 73 | __nlm_hash32(addr.s6_addr32[1]) ^ | ||
| 74 | __nlm_hash32(addr.s6_addr32[2]) ^ | ||
| 75 | __nlm_hash32(addr.s6_addr32[3]); | ||
| 76 | } | ||
| 77 | |||
| 78 | static unsigned int nlm_hash_address(const struct sockaddr *sap) | ||
| 79 | { | ||
| 80 | unsigned int hash; | ||
| 81 | |||
| 82 | switch (sap->sa_family) { | ||
| 83 | case AF_INET: | ||
| 84 | hash = __nlm_hash_addr4(sap); | ||
| 85 | break; | ||
| 86 | case AF_INET6: | ||
| 87 | hash = __nlm_hash_addr6(sap); | ||
| 88 | break; | ||
| 89 | default: | ||
| 90 | hash = 0; | ||
| 91 | } | ||
| 92 | return hash & (NLM_HOST_NRHASH - 1); | ||
| 93 | } | ||
| 94 | |||
| 95 | static void nlm_clear_port(struct sockaddr *sap) | ||
| 96 | { | ||
| 97 | switch (sap->sa_family) { | ||
| 98 | case AF_INET: | ||
| 99 | ((struct sockaddr_in *)sap)->sin_port = 0; | ||
| 100 | break; | ||
| 101 | case AF_INET6: | ||
| 102 | ((struct sockaddr_in6 *)sap)->sin6_port = 0; | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | |||
| 107 | static void nlm_display_address(const struct sockaddr *sap, | ||
| 108 | char *buf, const size_t len) | ||
| 109 | { | ||
| 110 | const struct sockaddr_in *sin = (struct sockaddr_in *)sap; | ||
| 111 | const struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap; | ||
| 112 | |||
| 113 | switch (sap->sa_family) { | ||
| 114 | case AF_UNSPEC: | ||
| 115 | snprintf(buf, len, "unspecified"); | ||
| 116 | break; | ||
| 117 | case AF_INET: | ||
| 118 | snprintf(buf, len, NIPQUAD_FMT, NIPQUAD(sin->sin_addr.s_addr)); | ||
| 119 | break; | ||
| 120 | case AF_INET6: | ||
| 121 | if (ipv6_addr_v4mapped(&sin6->sin6_addr)) | ||
| 122 | snprintf(buf, len, NIPQUAD_FMT, | ||
| 123 | NIPQUAD(sin6->sin6_addr.s6_addr32[3])); | ||
| 124 | else | ||
| 125 | snprintf(buf, len, NIP6_FMT, NIP6(sin6->sin6_addr)); | ||
| 126 | break; | ||
| 127 | default: | ||
| 128 | snprintf(buf, len, "unsupported address family"); | ||
| 129 | break; | ||
| 130 | } | ||
| 131 | } | ||
| 40 | 132 | ||
| 41 | /* | 133 | /* |
| 42 | * Common host lookup routine for server & client | 134 | * Common host lookup routine for server & client |
| 43 | */ | 135 | */ |
| 44 | static struct nlm_host *nlm_lookup_host(int server, | 136 | static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni) |
| 45 | const struct sockaddr_in *sin, | ||
| 46 | int proto, u32 version, | ||
| 47 | const char *hostname, | ||
| 48 | unsigned int hostname_len, | ||
| 49 | const struct sockaddr_in *ssin) | ||
| 50 | { | 137 | { |
| 51 | struct hlist_head *chain; | 138 | struct hlist_head *chain; |
| 52 | struct hlist_node *pos; | 139 | struct hlist_node *pos; |
| 53 | struct nlm_host *host; | 140 | struct nlm_host *host; |
| 54 | struct nsm_handle *nsm = NULL; | 141 | struct nsm_handle *nsm = NULL; |
| 55 | int hash; | ||
| 56 | |||
| 57 | dprintk("lockd: nlm_lookup_host("NIPQUAD_FMT"->"NIPQUAD_FMT | ||
| 58 | ", p=%d, v=%u, my role=%s, name=%.*s)\n", | ||
| 59 | NIPQUAD(ssin->sin_addr.s_addr), | ||
| 60 | NIPQUAD(sin->sin_addr.s_addr), proto, version, | ||
| 61 | server? "server" : "client", | ||
| 62 | hostname_len, | ||
| 63 | hostname? hostname : "<none>"); | ||
| 64 | 142 | ||
| 65 | |||
| 66 | hash = NLM_ADDRHASH(sin->sin_addr.s_addr); | ||
| 67 | |||
| 68 | /* Lock hash table */ | ||
| 69 | mutex_lock(&nlm_host_mutex); | 143 | mutex_lock(&nlm_host_mutex); |
| 70 | 144 | ||
| 71 | if (time_after_eq(jiffies, next_gc)) | 145 | if (time_after_eq(jiffies, next_gc)) |
| @@ -78,22 +152,22 @@ static struct nlm_host *nlm_lookup_host(int server, | |||
| 78 | * different NLM rpc_clients into one single nlm_host object. | 152 | * different NLM rpc_clients into one single nlm_host object. |
| 79 | * This would allow us to have one nlm_host per address. | 153 | * This would allow us to have one nlm_host per address. |
| 80 | */ | 154 | */ |
| 81 | chain = &nlm_hosts[hash]; | 155 | chain = &nlm_hosts[nlm_hash_address(ni->sap)]; |
| 82 | hlist_for_each_entry(host, pos, chain, h_hash) { | 156 | hlist_for_each_entry(host, pos, chain, h_hash) { |
| 83 | if (!nlm_cmp_addr(&host->h_addr, sin)) | 157 | if (!nlm_cmp_addr(nlm_addr(host), ni->sap)) |
| 84 | continue; | 158 | continue; |
| 85 | 159 | ||
| 86 | /* See if we have an NSM handle for this client */ | 160 | /* See if we have an NSM handle for this client */ |
| 87 | if (!nsm) | 161 | if (!nsm) |
| 88 | nsm = host->h_nsmhandle; | 162 | nsm = host->h_nsmhandle; |
| 89 | 163 | ||
| 90 | if (host->h_proto != proto) | 164 | if (host->h_proto != ni->protocol) |
| 91 | continue; | 165 | continue; |
| 92 | if (host->h_version != version) | 166 | if (host->h_version != ni->version) |
| 93 | continue; | 167 | continue; |
| 94 | if (host->h_server != server) | 168 | if (host->h_server != ni->server) |
| 95 | continue; | 169 | continue; |
| 96 | if (!nlm_cmp_addr(&host->h_saddr, ssin)) | 170 | if (!nlm_cmp_addr(nlm_srcaddr(host), ni->src_sap)) |
| 97 | continue; | 171 | continue; |
| 98 | 172 | ||
| 99 | /* Move to head of hash chain. */ | 173 | /* Move to head of hash chain. */ |
| @@ -101,30 +175,41 @@ static struct nlm_host *nlm_lookup_host(int server, | |||
| 101 | hlist_add_head(&host->h_hash, chain); | 175 | hlist_add_head(&host->h_hash, chain); |
| 102 | 176 | ||
| 103 | nlm_get_host(host); | 177 | nlm_get_host(host); |
| 178 | dprintk("lockd: nlm_lookup_host found host %s (%s)\n", | ||
| 179 | host->h_name, host->h_addrbuf); | ||
| 104 | goto out; | 180 | goto out; |
| 105 | } | 181 | } |
| 106 | if (nsm) | ||
| 107 | atomic_inc(&nsm->sm_count); | ||
| 108 | |||
| 109 | host = NULL; | ||
| 110 | 182 | ||
| 111 | /* Sadly, the host isn't in our hash table yet. See if | 183 | /* |
| 112 | * we have an NSM handle for it. If not, create one. | 184 | * The host wasn't in our hash table. If we don't |
| 185 | * have an NSM handle for it yet, create one. | ||
| 113 | */ | 186 | */ |
| 114 | if (!nsm && !(nsm = nsm_find(sin, hostname, hostname_len))) | 187 | if (nsm) |
| 115 | goto out; | 188 | atomic_inc(&nsm->sm_count); |
| 189 | else { | ||
| 190 | host = NULL; | ||
| 191 | nsm = nsm_find(ni->sap, ni->salen, | ||
| 192 | ni->hostname, ni->hostname_len, 1); | ||
| 193 | if (!nsm) { | ||
| 194 | dprintk("lockd: nlm_lookup_host failed; " | ||
| 195 | "no nsm handle\n"); | ||
| 196 | goto out; | ||
| 197 | } | ||
| 198 | } | ||
| 116 | 199 | ||
| 117 | host = kzalloc(sizeof(*host), GFP_KERNEL); | 200 | host = kzalloc(sizeof(*host), GFP_KERNEL); |
| 118 | if (!host) { | 201 | if (!host) { |
| 119 | nsm_release(nsm); | 202 | nsm_release(nsm); |
| 203 | dprintk("lockd: nlm_lookup_host failed; no memory\n"); | ||
| 120 | goto out; | 204 | goto out; |
| 121 | } | 205 | } |
| 122 | host->h_name = nsm->sm_name; | 206 | host->h_name = nsm->sm_name; |
| 123 | host->h_addr = *sin; | 207 | memcpy(nlm_addr(host), ni->sap, ni->salen); |
| 124 | host->h_addr.sin_port = 0; /* ouch! */ | 208 | host->h_addrlen = ni->salen; |
| 125 | host->h_saddr = *ssin; | 209 | nlm_clear_port(nlm_addr(host)); |
| 126 | host->h_version = version; | 210 | memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len); |
| 127 | host->h_proto = proto; | 211 | host->h_version = ni->version; |
| 212 | host->h_proto = ni->protocol; | ||
| 128 | host->h_rpcclnt = NULL; | 213 | host->h_rpcclnt = NULL; |
| 129 | mutex_init(&host->h_mutex); | 214 | mutex_init(&host->h_mutex); |
| 130 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; | 215 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; |
| @@ -135,7 +220,7 @@ static struct nlm_host *nlm_lookup_host(int server, | |||
| 135 | host->h_state = 0; /* pseudo NSM state */ | 220 | host->h_state = 0; /* pseudo NSM state */ |
| 136 | host->h_nsmstate = 0; /* real NSM state */ | 221 | host->h_nsmstate = 0; /* real NSM state */ |
| 137 | host->h_nsmhandle = nsm; | 222 | host->h_nsmhandle = nsm; |
| 138 | host->h_server = server; | 223 | host->h_server = ni->server; |
| 139 | hlist_add_head(&host->h_hash, chain); | 224 | hlist_add_head(&host->h_hash, chain); |
| 140 | INIT_LIST_HEAD(&host->h_lockowners); | 225 | INIT_LIST_HEAD(&host->h_lockowners); |
| 141 | spin_lock_init(&host->h_lock); | 226 | spin_lock_init(&host->h_lock); |
| @@ -143,6 +228,15 @@ static struct nlm_host *nlm_lookup_host(int server, | |||
| 143 | INIT_LIST_HEAD(&host->h_reclaim); | 228 | INIT_LIST_HEAD(&host->h_reclaim); |
| 144 | 229 | ||
| 145 | nrhosts++; | 230 | nrhosts++; |
| 231 | |||
| 232 | nlm_display_address((struct sockaddr *)&host->h_addr, | ||
| 233 | host->h_addrbuf, sizeof(host->h_addrbuf)); | ||
| 234 | nlm_display_address((struct sockaddr *)&host->h_srcaddr, | ||
| 235 | host->h_srcaddrbuf, sizeof(host->h_srcaddrbuf)); | ||
| 236 | |||
| 237 | dprintk("lockd: nlm_lookup_host created host %s\n", | ||
| 238 | host->h_name); | ||
| 239 | |||
| 146 | out: | 240 | out: |
| 147 | mutex_unlock(&nlm_host_mutex); | 241 | mutex_unlock(&nlm_host_mutex); |
| 148 | return host; | 242 | return host; |
| @@ -170,33 +264,103 @@ nlm_destroy_host(struct nlm_host *host) | |||
| 170 | kfree(host); | 264 | kfree(host); |
| 171 | } | 265 | } |
| 172 | 266 | ||
| 173 | /* | 267 | /** |
| 174 | * Find an NLM server handle in the cache. If there is none, create it. | 268 | * nlmclnt_lookup_host - Find an NLM host handle matching a remote server |
| 269 | * @sap: network address of server | ||
| 270 | * @salen: length of server address | ||
| 271 | * @protocol: transport protocol to use | ||
| 272 | * @version: NLM protocol version | ||
| 273 | * @hostname: '\0'-terminated hostname of server | ||
| 274 | * | ||
| 275 | * Returns an nlm_host structure that matches the passed-in | ||
| 276 | * [server address, transport protocol, NLM version, server hostname]. | ||
| 277 | * If one doesn't already exist in the host cache, a new handle is | ||
| 278 | * created and returned. | ||
| 175 | */ | 279 | */ |
| 176 | struct nlm_host *nlmclnt_lookup_host(const struct sockaddr_in *sin, | 280 | struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, |
| 177 | int proto, u32 version, | 281 | const size_t salen, |
| 178 | const char *hostname, | 282 | const unsigned short protocol, |
| 179 | unsigned int hostname_len) | 283 | const u32 version, const char *hostname) |
| 180 | { | 284 | { |
| 181 | struct sockaddr_in ssin = {0}; | 285 | const struct sockaddr source = { |
| 182 | 286 | .sa_family = AF_UNSPEC, | |
| 183 | return nlm_lookup_host(0, sin, proto, version, | 287 | }; |
| 184 | hostname, hostname_len, &ssin); | 288 | struct nlm_lookup_host_info ni = { |
| 289 | .server = 0, | ||
| 290 | .sap = sap, | ||
| 291 | .salen = salen, | ||
| 292 | .protocol = protocol, | ||
| 293 | .version = version, | ||
| 294 | .hostname = hostname, | ||
| 295 | .hostname_len = strlen(hostname), | ||
| 296 | .src_sap = &source, | ||
| 297 | .src_len = sizeof(source), | ||
| 298 | }; | ||
| 299 | |||
| 300 | dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, | ||
| 301 | (hostname ? hostname : "<none>"), version, | ||
| 302 | (protocol == IPPROTO_UDP ? "udp" : "tcp")); | ||
| 303 | |||
| 304 | return nlm_lookup_host(&ni); | ||
| 185 | } | 305 | } |
| 186 | 306 | ||
| 187 | /* | 307 | /** |
| 188 | * Find an NLM client handle in the cache. If there is none, create it. | 308 | * nlmsvc_lookup_host - Find an NLM host handle matching a remote client |
| 309 | * @rqstp: incoming NLM request | ||
| 310 | * @hostname: name of client host | ||
| 311 | * @hostname_len: length of client hostname | ||
| 312 | * | ||
| 313 | * Returns an nlm_host structure that matches the [client address, | ||
| 314 | * transport protocol, NLM version, client hostname] of the passed-in | ||
| 315 | * NLM request. If one doesn't already exist in the host cache, a | ||
| 316 | * new handle is created and returned. | ||
| 317 | * | ||
| 318 | * Before possibly creating a new nlm_host, construct a sockaddr | ||
| 319 | * for a specific source address in case the local system has | ||
| 320 | * multiple network addresses. The family of the address in | ||
| 321 | * rq_daddr is guaranteed to be the same as the family of the | ||
| 322 | * address in rq_addr, so it's safe to use the same family for | ||
| 323 | * the source address. | ||
| 189 | */ | 324 | */ |
| 190 | struct nlm_host * | 325 | struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, |
| 191 | nlmsvc_lookup_host(struct svc_rqst *rqstp, | 326 | const char *hostname, |
| 192 | const char *hostname, unsigned int hostname_len) | 327 | const size_t hostname_len) |
| 193 | { | 328 | { |
| 194 | struct sockaddr_in ssin = {0}; | 329 | struct sockaddr_in sin = { |
| 330 | .sin_family = AF_INET, | ||
| 331 | }; | ||
| 332 | struct sockaddr_in6 sin6 = { | ||
| 333 | .sin6_family = AF_INET6, | ||
| 334 | }; | ||
| 335 | struct nlm_lookup_host_info ni = { | ||
| 336 | .server = 1, | ||
| 337 | .sap = svc_addr(rqstp), | ||
| 338 | .salen = rqstp->rq_addrlen, | ||
| 339 | .protocol = rqstp->rq_prot, | ||
| 340 | .version = rqstp->rq_vers, | ||
| 341 | .hostname = hostname, | ||
| 342 | .hostname_len = hostname_len, | ||
| 343 | .src_len = rqstp->rq_addrlen, | ||
| 344 | }; | ||
| 345 | |||
| 346 | dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, | ||
| 347 | (int)hostname_len, hostname, rqstp->rq_vers, | ||
| 348 | (rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp")); | ||
| 349 | |||
| 350 | switch (ni.sap->sa_family) { | ||
| 351 | case AF_INET: | ||
| 352 | sin.sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr; | ||
| 353 | ni.src_sap = (struct sockaddr *)&sin; | ||
| 354 | break; | ||
| 355 | case AF_INET6: | ||
| 356 | ipv6_addr_copy(&sin6.sin6_addr, &rqstp->rq_daddr.addr6); | ||
| 357 | ni.src_sap = (struct sockaddr *)&sin6; | ||
| 358 | break; | ||
| 359 | default: | ||
| 360 | return NULL; | ||
| 361 | } | ||
| 195 | 362 | ||
| 196 | ssin.sin_addr = rqstp->rq_daddr.addr; | 363 | return nlm_lookup_host(&ni); |
| 197 | return nlm_lookup_host(1, svc_addr_in(rqstp), | ||
| 198 | rqstp->rq_prot, rqstp->rq_vers, | ||
| 199 | hostname, hostname_len, &ssin); | ||
| 200 | } | 364 | } |
| 201 | 365 | ||
| 202 | /* | 366 | /* |
| @@ -207,9 +371,8 @@ nlm_bind_host(struct nlm_host *host) | |||
| 207 | { | 371 | { |
| 208 | struct rpc_clnt *clnt; | 372 | struct rpc_clnt *clnt; |
| 209 | 373 | ||
| 210 | dprintk("lockd: nlm_bind_host("NIPQUAD_FMT"->"NIPQUAD_FMT")\n", | 374 | dprintk("lockd: nlm_bind_host %s (%s), my addr=%s\n", |
| 211 | NIPQUAD(host->h_saddr.sin_addr), | 375 | host->h_name, host->h_addrbuf, host->h_srcaddrbuf); |
| 212 | NIPQUAD(host->h_addr.sin_addr)); | ||
| 213 | 376 | ||
| 214 | /* Lock host handle */ | 377 | /* Lock host handle */ |
| 215 | mutex_lock(&host->h_mutex); | 378 | mutex_lock(&host->h_mutex); |
| @@ -221,7 +384,7 @@ nlm_bind_host(struct nlm_host *host) | |||
| 221 | if (time_after_eq(jiffies, host->h_nextrebind)) { | 384 | if (time_after_eq(jiffies, host->h_nextrebind)) { |
| 222 | rpc_force_rebind(clnt); | 385 | rpc_force_rebind(clnt); |
| 223 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; | 386 | host->h_nextrebind = jiffies + NLM_HOST_REBIND; |
| 224 | dprintk("lockd: next rebind in %ld jiffies\n", | 387 | dprintk("lockd: next rebind in %lu jiffies\n", |
| 225 | host->h_nextrebind - jiffies); | 388 | host->h_nextrebind - jiffies); |
| 226 | } | 389 | } |
| 227 | } else { | 390 | } else { |
| @@ -234,9 +397,9 @@ nlm_bind_host(struct nlm_host *host) | |||
| 234 | }; | 397 | }; |
| 235 | struct rpc_create_args args = { | 398 | struct rpc_create_args args = { |
| 236 | .protocol = host->h_proto, | 399 | .protocol = host->h_proto, |
| 237 | .address = (struct sockaddr *)&host->h_addr, | 400 | .address = nlm_addr(host), |
| 238 | .addrsize = sizeof(host->h_addr), | 401 | .addrsize = host->h_addrlen, |
| 239 | .saddress = (struct sockaddr *)&host->h_saddr, | 402 | .saddress = nlm_srcaddr(host), |
| 240 | .timeout = &timeparms, | 403 | .timeout = &timeparms, |
| 241 | .servername = host->h_name, | 404 | .servername = host->h_name, |
| 242 | .program = &nlm_program, | 405 | .program = &nlm_program, |
| @@ -324,12 +487,16 @@ void nlm_host_rebooted(const struct sockaddr_in *sin, | |||
| 324 | struct nsm_handle *nsm; | 487 | struct nsm_handle *nsm; |
| 325 | struct nlm_host *host; | 488 | struct nlm_host *host; |
| 326 | 489 | ||
| 327 | dprintk("lockd: nlm_host_rebooted(%s, %u.%u.%u.%u)\n", | 490 | nsm = nsm_find((struct sockaddr *)sin, sizeof(*sin), |
| 328 | hostname, NIPQUAD(sin->sin_addr)); | 491 | hostname, hostname_len, 0); |
| 329 | 492 | if (nsm == NULL) { | |
| 330 | /* Find the NSM handle for this peer */ | 493 | dprintk("lockd: never saw rebooted peer '%.*s' before\n", |
| 331 | if (!(nsm = __nsm_find(sin, hostname, hostname_len, 0))) | 494 | hostname_len, hostname); |
| 332 | return; | 495 | return; |
| 496 | } | ||
| 497 | |||
| 498 | dprintk("lockd: nlm_host_rebooted(%.*s, %s)\n", | ||
| 499 | hostname_len, hostname, nsm->sm_addrbuf); | ||
| 333 | 500 | ||
| 334 | /* When reclaiming locks on this peer, make sure that | 501 | /* When reclaiming locks on this peer, make sure that |
| 335 | * we set up a new notification */ | 502 | * we set up a new notification */ |
| @@ -461,22 +628,23 @@ nlm_gc_hosts(void) | |||
| 461 | static LIST_HEAD(nsm_handles); | 628 | static LIST_HEAD(nsm_handles); |
| 462 | static DEFINE_SPINLOCK(nsm_lock); | 629 | static DEFINE_SPINLOCK(nsm_lock); |
| 463 | 630 | ||
| 464 | static struct nsm_handle * | 631 | static struct nsm_handle *nsm_find(const struct sockaddr *sap, |
| 465 | __nsm_find(const struct sockaddr_in *sin, | 632 | const size_t salen, |
| 466 | const char *hostname, unsigned int hostname_len, | 633 | const char *hostname, |
| 467 | int create) | 634 | const size_t hostname_len, |
| 635 | const int create) | ||
| 468 | { | 636 | { |
| 469 | struct nsm_handle *nsm = NULL; | 637 | struct nsm_handle *nsm = NULL; |
| 470 | struct nsm_handle *pos; | 638 | struct nsm_handle *pos; |
| 471 | 639 | ||
| 472 | if (!sin) | 640 | if (!sap) |
| 473 | return NULL; | 641 | return NULL; |
| 474 | 642 | ||
| 475 | if (hostname && memchr(hostname, '/', hostname_len) != NULL) { | 643 | if (hostname && memchr(hostname, '/', hostname_len) != NULL) { |
| 476 | if (printk_ratelimit()) { | 644 | if (printk_ratelimit()) { |
| 477 | printk(KERN_WARNING "Invalid hostname \"%.*s\" " | 645 | printk(KERN_WARNING "Invalid hostname \"%.*s\" " |
| 478 | "in NFS lock request\n", | 646 | "in NFS lock request\n", |
| 479 | hostname_len, hostname); | 647 | (int)hostname_len, hostname); |
| 480 | } | 648 | } |
| 481 | return NULL; | 649 | return NULL; |
| 482 | } | 650 | } |
| @@ -489,7 +657,7 @@ retry: | |||
| 489 | if (strlen(pos->sm_name) != hostname_len | 657 | if (strlen(pos->sm_name) != hostname_len |
| 490 | || memcmp(pos->sm_name, hostname, hostname_len)) | 658 | || memcmp(pos->sm_name, hostname, hostname_len)) |
| 491 | continue; | 659 | continue; |
| 492 | } else if (!nlm_cmp_addr(&pos->sm_addr, sin)) | 660 | } else if (!nlm_cmp_addr(nsm_addr(pos), sap)) |
| 493 | continue; | 661 | continue; |
| 494 | atomic_inc(&pos->sm_count); | 662 | atomic_inc(&pos->sm_count); |
| 495 | kfree(nsm); | 663 | kfree(nsm); |
| @@ -509,10 +677,13 @@ retry: | |||
| 509 | if (nsm == NULL) | 677 | if (nsm == NULL) |
| 510 | return NULL; | 678 | return NULL; |
| 511 | 679 | ||
| 512 | nsm->sm_addr = *sin; | 680 | memcpy(nsm_addr(nsm), sap, salen); |
| 681 | nsm->sm_addrlen = salen; | ||
| 513 | nsm->sm_name = (char *) (nsm + 1); | 682 | nsm->sm_name = (char *) (nsm + 1); |
| 514 | memcpy(nsm->sm_name, hostname, hostname_len); | 683 | memcpy(nsm->sm_name, hostname, hostname_len); |
| 515 | nsm->sm_name[hostname_len] = '\0'; | 684 | nsm->sm_name[hostname_len] = '\0'; |
| 685 | nlm_display_address((struct sockaddr *)&nsm->sm_addr, | ||
| 686 | nsm->sm_addrbuf, sizeof(nsm->sm_addrbuf)); | ||
| 516 | atomic_set(&nsm->sm_count, 1); | 687 | atomic_set(&nsm->sm_count, 1); |
| 517 | goto retry; | 688 | goto retry; |
| 518 | 689 | ||
| @@ -521,13 +692,6 @@ found: | |||
| 521 | return nsm; | 692 | return nsm; |
| 522 | } | 693 | } |
| 523 | 694 | ||
| 524 | static struct nsm_handle * | ||
| 525 | nsm_find(const struct sockaddr_in *sin, const char *hostname, | ||
| 526 | unsigned int hostname_len) | ||
| 527 | { | ||
| 528 | return __nsm_find(sin, hostname, hostname_len, 1); | ||
| 529 | } | ||
| 530 | |||
| 531 | /* | 695 | /* |
| 532 | * Release an NSM handle | 696 | * Release an NSM handle |
| 533 | */ | 697 | */ |
diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index e4d563543b11..4e7e958e8f67 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c | |||
| @@ -51,7 +51,7 @@ nsm_mon_unmon(struct nsm_handle *nsm, u32 proc, struct nsm_res *res) | |||
| 51 | 51 | ||
| 52 | memset(&args, 0, sizeof(args)); | 52 | memset(&args, 0, sizeof(args)); |
| 53 | args.mon_name = nsm->sm_name; | 53 | args.mon_name = nsm->sm_name; |
| 54 | args.addr = nsm->sm_addr.sin_addr.s_addr; | 54 | args.addr = nsm_addr_in(nsm)->sin_addr.s_addr; |
| 55 | args.prog = NLM_PROGRAM; | 55 | args.prog = NLM_PROGRAM; |
| 56 | args.vers = 3; | 56 | args.vers = 3; |
| 57 | args.proc = NLMPROC_NSM_NOTIFY; | 57 | args.proc = NLMPROC_NSM_NOTIFY; |
diff --git a/fs/lockd/svc.c b/fs/lockd/svc.c index 5bd9bf0fa9df..c631a83931ce 100644 --- a/fs/lockd/svc.c +++ b/fs/lockd/svc.c | |||
| @@ -51,7 +51,6 @@ static DEFINE_MUTEX(nlmsvc_mutex); | |||
| 51 | static unsigned int nlmsvc_users; | 51 | static unsigned int nlmsvc_users; |
| 52 | static struct task_struct *nlmsvc_task; | 52 | static struct task_struct *nlmsvc_task; |
| 53 | static struct svc_rqst *nlmsvc_rqst; | 53 | static struct svc_rqst *nlmsvc_rqst; |
| 54 | int nlmsvc_grace_period; | ||
| 55 | unsigned long nlmsvc_timeout; | 54 | unsigned long nlmsvc_timeout; |
| 56 | 55 | ||
| 57 | /* | 56 | /* |
| @@ -85,27 +84,23 @@ static unsigned long get_lockd_grace_period(void) | |||
| 85 | return nlm_timeout * 5 * HZ; | 84 | return nlm_timeout * 5 * HZ; |
| 86 | } | 85 | } |
| 87 | 86 | ||
| 88 | unsigned long get_nfs_grace_period(void) | 87 | static struct lock_manager lockd_manager = { |
| 89 | { | 88 | }; |
| 90 | unsigned long lockdgrace = get_lockd_grace_period(); | ||
| 91 | unsigned long nfsdgrace = 0; | ||
| 92 | |||
| 93 | if (nlmsvc_ops) | ||
| 94 | nfsdgrace = nlmsvc_ops->get_grace_period(); | ||
| 95 | |||
| 96 | return max(lockdgrace, nfsdgrace); | ||
| 97 | } | ||
| 98 | EXPORT_SYMBOL(get_nfs_grace_period); | ||
| 99 | 89 | ||
| 100 | static unsigned long set_grace_period(void) | 90 | static void grace_ender(struct work_struct *not_used) |
| 101 | { | 91 | { |
| 102 | nlmsvc_grace_period = 1; | 92 | locks_end_grace(&lockd_manager); |
| 103 | return get_nfs_grace_period() + jiffies; | ||
| 104 | } | 93 | } |
| 105 | 94 | ||
| 106 | static inline void clear_grace_period(void) | 95 | static DECLARE_DELAYED_WORK(grace_period_end, grace_ender); |
| 96 | |||
| 97 | static void set_grace_period(void) | ||
| 107 | { | 98 | { |
| 108 | nlmsvc_grace_period = 0; | 99 | unsigned long grace_period = get_lockd_grace_period(); |
| 100 | |||
| 101 | locks_start_grace(&lockd_manager); | ||
| 102 | cancel_delayed_work_sync(&grace_period_end); | ||
| 103 | schedule_delayed_work(&grace_period_end, grace_period); | ||
| 109 | } | 104 | } |
| 110 | 105 | ||
| 111 | /* | 106 | /* |
| @@ -116,7 +111,6 @@ lockd(void *vrqstp) | |||
| 116 | { | 111 | { |
| 117 | int err = 0, preverr = 0; | 112 | int err = 0, preverr = 0; |
| 118 | struct svc_rqst *rqstp = vrqstp; | 113 | struct svc_rqst *rqstp = vrqstp; |
| 119 | unsigned long grace_period_expire; | ||
| 120 | 114 | ||
| 121 | /* try_to_freeze() is called from svc_recv() */ | 115 | /* try_to_freeze() is called from svc_recv() */ |
| 122 | set_freezable(); | 116 | set_freezable(); |
| @@ -139,7 +133,7 @@ lockd(void *vrqstp) | |||
| 139 | nlm_timeout = LOCKD_DFLT_TIMEO; | 133 | nlm_timeout = LOCKD_DFLT_TIMEO; |
| 140 | nlmsvc_timeout = nlm_timeout * HZ; | 134 | nlmsvc_timeout = nlm_timeout * HZ; |
| 141 | 135 | ||
| 142 | grace_period_expire = set_grace_period(); | 136 | set_grace_period(); |
| 143 | 137 | ||
| 144 | /* | 138 | /* |
| 145 | * The main request loop. We don't terminate until the last | 139 | * The main request loop. We don't terminate until the last |
| @@ -153,21 +147,12 @@ lockd(void *vrqstp) | |||
| 153 | flush_signals(current); | 147 | flush_signals(current); |
| 154 | if (nlmsvc_ops) { | 148 | if (nlmsvc_ops) { |
| 155 | nlmsvc_invalidate_all(); | 149 | nlmsvc_invalidate_all(); |
| 156 | grace_period_expire = set_grace_period(); | 150 | set_grace_period(); |
| 157 | } | 151 | } |
| 158 | continue; | 152 | continue; |
| 159 | } | 153 | } |
| 160 | 154 | ||
| 161 | /* | 155 | timeout = nlmsvc_retry_blocked(); |
| 162 | * Retry any blocked locks that have been notified by | ||
| 163 | * the VFS. Don't do this during grace period. | ||
| 164 | * (Theoretically, there shouldn't even be blocked locks | ||
| 165 | * during grace period). | ||
| 166 | */ | ||
| 167 | if (!nlmsvc_grace_period) { | ||
| 168 | timeout = nlmsvc_retry_blocked(); | ||
| 169 | } else if (time_before(grace_period_expire, jiffies)) | ||
| 170 | clear_grace_period(); | ||
| 171 | 156 | ||
| 172 | /* | 157 | /* |
| 173 | * Find a socket with data available and call its | 158 | * Find a socket with data available and call its |
| @@ -195,6 +180,7 @@ lockd(void *vrqstp) | |||
| 195 | svc_process(rqstp); | 180 | svc_process(rqstp); |
| 196 | } | 181 | } |
| 197 | flush_signals(current); | 182 | flush_signals(current); |
| 183 | cancel_delayed_work_sync(&grace_period_end); | ||
| 198 | if (nlmsvc_ops) | 184 | if (nlmsvc_ops) |
| 199 | nlmsvc_invalidate_all(); | 185 | nlmsvc_invalidate_all(); |
| 200 | nlm_shutdown_hosts(); | 186 | nlm_shutdown_hosts(); |
| @@ -203,25 +189,28 @@ lockd(void *vrqstp) | |||
| 203 | } | 189 | } |
| 204 | 190 | ||
| 205 | /* | 191 | /* |
| 206 | * Make any sockets that are needed but not present. | 192 | * Ensure there are active UDP and TCP listeners for lockd. |
| 207 | * If nlm_udpport or nlm_tcpport were set as module | 193 | * |
| 208 | * options, make those sockets unconditionally | 194 | * Even if we have only TCP NFS mounts and/or TCP NFSDs, some |
| 195 | * local services (such as rpc.statd) still require UDP, and | ||
| 196 | * some NFS servers do not yet support NLM over TCP. | ||
| 197 | * | ||
| 198 | * Returns zero if all listeners are available; otherwise a | ||
| 199 | * negative errno value is returned. | ||
| 209 | */ | 200 | */ |
| 210 | static int make_socks(struct svc_serv *serv, int proto) | 201 | static int make_socks(struct svc_serv *serv) |
| 211 | { | 202 | { |
| 212 | static int warned; | 203 | static int warned; |
| 213 | struct svc_xprt *xprt; | 204 | struct svc_xprt *xprt; |
| 214 | int err = 0; | 205 | int err = 0; |
| 215 | 206 | ||
| 216 | if (proto == IPPROTO_UDP || nlm_udpport) { | 207 | xprt = svc_find_xprt(serv, "udp", 0, 0); |
| 217 | xprt = svc_find_xprt(serv, "udp", 0, 0); | 208 | if (!xprt) |
| 218 | if (!xprt) | 209 | err = svc_create_xprt(serv, "udp", nlm_udpport, |
| 219 | err = svc_create_xprt(serv, "udp", nlm_udpport, | 210 | SVC_SOCK_DEFAULTS); |
| 220 | SVC_SOCK_DEFAULTS); | 211 | else |
| 221 | else | 212 | svc_xprt_put(xprt); |
| 222 | svc_xprt_put(xprt); | 213 | if (err >= 0) { |
| 223 | } | ||
| 224 | if (err >= 0 && (proto == IPPROTO_TCP || nlm_tcpport)) { | ||
| 225 | xprt = svc_find_xprt(serv, "tcp", 0, 0); | 214 | xprt = svc_find_xprt(serv, "tcp", 0, 0); |
| 226 | if (!xprt) | 215 | if (!xprt) |
| 227 | err = svc_create_xprt(serv, "tcp", nlm_tcpport, | 216 | err = svc_create_xprt(serv, "tcp", nlm_tcpport, |
| @@ -241,8 +230,7 @@ static int make_socks(struct svc_serv *serv, int proto) | |||
| 241 | /* | 230 | /* |
| 242 | * Bring up the lockd process if it's not already up. | 231 | * Bring up the lockd process if it's not already up. |
| 243 | */ | 232 | */ |
| 244 | int | 233 | int lockd_up(void) |
| 245 | lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | ||
| 246 | { | 234 | { |
| 247 | struct svc_serv *serv; | 235 | struct svc_serv *serv; |
| 248 | int error = 0; | 236 | int error = 0; |
| @@ -251,11 +239,8 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | |||
| 251 | /* | 239 | /* |
| 252 | * Check whether we're already up and running. | 240 | * Check whether we're already up and running. |
| 253 | */ | 241 | */ |
| 254 | if (nlmsvc_rqst) { | 242 | if (nlmsvc_rqst) |
| 255 | if (proto) | ||
| 256 | error = make_socks(nlmsvc_rqst->rq_server, proto); | ||
| 257 | goto out; | 243 | goto out; |
| 258 | } | ||
| 259 | 244 | ||
| 260 | /* | 245 | /* |
| 261 | * Sanity check: if there's no pid, | 246 | * Sanity check: if there's no pid, |
| @@ -266,13 +251,14 @@ lockd_up(int proto) /* Maybe add a 'family' option when IPv6 is supported ?? */ | |||
| 266 | "lockd_up: no pid, %d users??\n", nlmsvc_users); | 251 | "lockd_up: no pid, %d users??\n", nlmsvc_users); |
| 267 | 252 | ||
| 268 | error = -ENOMEM; | 253 | error = -ENOMEM; |
| 269 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, NULL); | 254 | serv = svc_create(&nlmsvc_program, LOCKD_BUFSIZE, AF_INET, NULL); |
| 270 | if (!serv) { | 255 | if (!serv) { |
| 271 | printk(KERN_WARNING "lockd_up: create service failed\n"); | 256 | printk(KERN_WARNING "lockd_up: create service failed\n"); |
| 272 | goto out; | 257 | goto out; |
| 273 | } | 258 | } |
| 274 | 259 | ||
| 275 | if ((error = make_socks(serv, proto)) < 0) | 260 | error = make_socks(serv); |
| 261 | if (error < 0) | ||
| 276 | goto destroy_and_out; | 262 | goto destroy_and_out; |
| 277 | 263 | ||
| 278 | /* | 264 | /* |
diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 4a714f64515b..014f6ce48172 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c | |||
| @@ -88,12 +88,6 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 88 | dprintk("lockd: TEST4 called\n"); | 88 | dprintk("lockd: TEST4 called\n"); |
| 89 | resp->cookie = argp->cookie; | 89 | resp->cookie = argp->cookie; |
| 90 | 90 | ||
| 91 | /* Don't accept test requests during grace period */ | ||
| 92 | if (nlmsvc_grace_period) { | ||
| 93 | resp->status = nlm_lck_denied_grace_period; | ||
| 94 | return rc; | ||
| 95 | } | ||
| 96 | |||
| 97 | /* Obtain client and file */ | 91 | /* Obtain client and file */ |
| 98 | if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) | 92 | if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) |
| 99 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 93 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
| @@ -122,12 +116,6 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 122 | 116 | ||
| 123 | resp->cookie = argp->cookie; | 117 | resp->cookie = argp->cookie; |
| 124 | 118 | ||
| 125 | /* Don't accept new lock requests during grace period */ | ||
| 126 | if (nlmsvc_grace_period && !argp->reclaim) { | ||
| 127 | resp->status = nlm_lck_denied_grace_period; | ||
| 128 | return rc; | ||
| 129 | } | ||
| 130 | |||
| 131 | /* Obtain client and file */ | 119 | /* Obtain client and file */ |
| 132 | if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) | 120 | if ((resp->status = nlm4svc_retrieve_args(rqstp, argp, &host, &file))) |
| 133 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 121 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
| @@ -146,7 +134,8 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 146 | 134 | ||
| 147 | /* Now try to lock the file */ | 135 | /* Now try to lock the file */ |
| 148 | resp->status = nlmsvc_lock(rqstp, file, host, &argp->lock, | 136 | resp->status = nlmsvc_lock(rqstp, file, host, &argp->lock, |
| 149 | argp->block, &argp->cookie); | 137 | argp->block, &argp->cookie, |
| 138 | argp->reclaim); | ||
| 150 | if (resp->status == nlm_drop_reply) | 139 | if (resp->status == nlm_drop_reply) |
| 151 | rc = rpc_drop_reply; | 140 | rc = rpc_drop_reply; |
| 152 | else | 141 | else |
| @@ -169,7 +158,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 169 | resp->cookie = argp->cookie; | 158 | resp->cookie = argp->cookie; |
| 170 | 159 | ||
| 171 | /* Don't accept requests during grace period */ | 160 | /* Don't accept requests during grace period */ |
| 172 | if (nlmsvc_grace_period) { | 161 | if (locks_in_grace()) { |
| 173 | resp->status = nlm_lck_denied_grace_period; | 162 | resp->status = nlm_lck_denied_grace_period; |
| 174 | return rpc_success; | 163 | return rpc_success; |
| 175 | } | 164 | } |
| @@ -202,7 +191,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 202 | resp->cookie = argp->cookie; | 191 | resp->cookie = argp->cookie; |
| 203 | 192 | ||
| 204 | /* Don't accept new lock requests during grace period */ | 193 | /* Don't accept new lock requests during grace period */ |
| 205 | if (nlmsvc_grace_period) { | 194 | if (locks_in_grace()) { |
| 206 | resp->status = nlm_lck_denied_grace_period; | 195 | resp->status = nlm_lck_denied_grace_period; |
| 207 | return rpc_success; | 196 | return rpc_success; |
| 208 | } | 197 | } |
| @@ -231,7 +220,7 @@ nlm4svc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 231 | resp->cookie = argp->cookie; | 220 | resp->cookie = argp->cookie; |
| 232 | 221 | ||
| 233 | dprintk("lockd: GRANTED called\n"); | 222 | dprintk("lockd: GRANTED called\n"); |
| 234 | resp->status = nlmclnt_grant(svc_addr_in(rqstp), &argp->lock); | 223 | resp->status = nlmclnt_grant(svc_addr(rqstp), &argp->lock); |
| 235 | dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); | 224 | dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); |
| 236 | return rpc_success; | 225 | return rpc_success; |
| 237 | } | 226 | } |
| @@ -341,7 +330,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 341 | resp->cookie = argp->cookie; | 330 | resp->cookie = argp->cookie; |
| 342 | 331 | ||
| 343 | /* Don't accept new lock requests during grace period */ | 332 | /* Don't accept new lock requests during grace period */ |
| 344 | if (nlmsvc_grace_period && !argp->reclaim) { | 333 | if (locks_in_grace() && !argp->reclaim) { |
| 345 | resp->status = nlm_lck_denied_grace_period; | 334 | resp->status = nlm_lck_denied_grace_period; |
| 346 | return rpc_success; | 335 | return rpc_success; |
| 347 | } | 336 | } |
| @@ -374,7 +363,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 374 | resp->cookie = argp->cookie; | 363 | resp->cookie = argp->cookie; |
| 375 | 364 | ||
| 376 | /* Don't accept requests during grace period */ | 365 | /* Don't accept requests during grace period */ |
| 377 | if (nlmsvc_grace_period) { | 366 | if (locks_in_grace()) { |
| 378 | resp->status = nlm_lck_denied_grace_period; | 367 | resp->status = nlm_lck_denied_grace_period; |
| 379 | return rpc_success; | 368 | return rpc_success; |
| 380 | } | 369 | } |
| @@ -432,11 +421,9 @@ nlm4svc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | |||
| 432 | { | 421 | { |
| 433 | struct sockaddr_in saddr; | 422 | struct sockaddr_in saddr; |
| 434 | 423 | ||
| 435 | memcpy(&saddr, svc_addr_in(rqstp), sizeof(saddr)); | ||
| 436 | |||
| 437 | dprintk("lockd: SM_NOTIFY called\n"); | 424 | dprintk("lockd: SM_NOTIFY called\n"); |
| 438 | if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) | 425 | |
| 439 | || ntohs(saddr.sin_port) >= 1024) { | 426 | if (!nlm_privileged_requester(rqstp)) { |
| 440 | char buf[RPC_MAX_ADDRBUFLEN]; | 427 | char buf[RPC_MAX_ADDRBUFLEN]; |
| 441 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", | 428 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", |
| 442 | svc_print_addr(rqstp, buf, sizeof(buf))); | 429 | svc_print_addr(rqstp, buf, sizeof(buf))); |
diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index cf0d5c2c318d..6063a8e4b9f3 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c | |||
| @@ -360,7 +360,7 @@ nlmsvc_defer_lock_rqst(struct svc_rqst *rqstp, struct nlm_block *block) | |||
| 360 | __be32 | 360 | __be32 |
| 361 | nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, | 361 | nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, |
| 362 | struct nlm_host *host, struct nlm_lock *lock, int wait, | 362 | struct nlm_host *host, struct nlm_lock *lock, int wait, |
| 363 | struct nlm_cookie *cookie) | 363 | struct nlm_cookie *cookie, int reclaim) |
| 364 | { | 364 | { |
| 365 | struct nlm_block *block = NULL; | 365 | struct nlm_block *block = NULL; |
| 366 | int error; | 366 | int error; |
| @@ -406,6 +406,15 @@ nlmsvc_lock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
| 406 | goto out; | 406 | goto out; |
| 407 | } | 407 | } |
| 408 | 408 | ||
| 409 | if (locks_in_grace() && !reclaim) { | ||
| 410 | ret = nlm_lck_denied_grace_period; | ||
| 411 | goto out; | ||
| 412 | } | ||
| 413 | if (reclaim && !locks_in_grace()) { | ||
| 414 | ret = nlm_lck_denied_grace_period; | ||
| 415 | goto out; | ||
| 416 | } | ||
| 417 | |||
| 409 | if (!wait) | 418 | if (!wait) |
| 410 | lock->fl.fl_flags &= ~FL_SLEEP; | 419 | lock->fl.fl_flags &= ~FL_SLEEP; |
| 411 | error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); | 420 | error = vfs_lock_file(file->f_file, F_SETLK, &lock->fl, NULL); |
| @@ -502,6 +511,10 @@ nlmsvc_testlock(struct svc_rqst *rqstp, struct nlm_file *file, | |||
| 502 | goto out; | 511 | goto out; |
| 503 | } | 512 | } |
| 504 | 513 | ||
| 514 | if (locks_in_grace()) { | ||
| 515 | ret = nlm_lck_denied_grace_period; | ||
| 516 | goto out; | ||
| 517 | } | ||
| 505 | error = vfs_test_lock(file->f_file, &lock->fl); | 518 | error = vfs_test_lock(file->f_file, &lock->fl); |
| 506 | if (error == FILE_LOCK_DEFERRED) { | 519 | if (error == FILE_LOCK_DEFERRED) { |
| 507 | ret = nlmsvc_defer_lock_rqst(rqstp, block); | 520 | ret = nlmsvc_defer_lock_rqst(rqstp, block); |
| @@ -582,6 +595,9 @@ nlmsvc_cancel_blocked(struct nlm_file *file, struct nlm_lock *lock) | |||
| 582 | (long long)lock->fl.fl_start, | 595 | (long long)lock->fl.fl_start, |
| 583 | (long long)lock->fl.fl_end); | 596 | (long long)lock->fl.fl_end); |
| 584 | 597 | ||
| 598 | if (locks_in_grace()) | ||
| 599 | return nlm_lck_denied_grace_period; | ||
| 600 | |||
| 585 | mutex_lock(&file->f_mutex); | 601 | mutex_lock(&file->f_mutex); |
| 586 | block = nlmsvc_lookup_block(file, lock); | 602 | block = nlmsvc_lookup_block(file, lock); |
| 587 | mutex_unlock(&file->f_mutex); | 603 | mutex_unlock(&file->f_mutex); |
diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 76262c1986f2..548b0bb2b84d 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c | |||
| @@ -117,12 +117,6 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 117 | dprintk("lockd: TEST called\n"); | 117 | dprintk("lockd: TEST called\n"); |
| 118 | resp->cookie = argp->cookie; | 118 | resp->cookie = argp->cookie; |
| 119 | 119 | ||
| 120 | /* Don't accept test requests during grace period */ | ||
| 121 | if (nlmsvc_grace_period) { | ||
| 122 | resp->status = nlm_lck_denied_grace_period; | ||
| 123 | return rc; | ||
| 124 | } | ||
| 125 | |||
| 126 | /* Obtain client and file */ | 120 | /* Obtain client and file */ |
| 127 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) | 121 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) |
| 128 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 122 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
| @@ -152,12 +146,6 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 152 | 146 | ||
| 153 | resp->cookie = argp->cookie; | 147 | resp->cookie = argp->cookie; |
| 154 | 148 | ||
| 155 | /* Don't accept new lock requests during grace period */ | ||
| 156 | if (nlmsvc_grace_period && !argp->reclaim) { | ||
| 157 | resp->status = nlm_lck_denied_grace_period; | ||
| 158 | return rc; | ||
| 159 | } | ||
| 160 | |||
| 161 | /* Obtain client and file */ | 149 | /* Obtain client and file */ |
| 162 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) | 150 | if ((resp->status = nlmsvc_retrieve_args(rqstp, argp, &host, &file))) |
| 163 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; | 151 | return resp->status == nlm_drop_reply ? rpc_drop_reply :rpc_success; |
| @@ -176,7 +164,8 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 176 | 164 | ||
| 177 | /* Now try to lock the file */ | 165 | /* Now try to lock the file */ |
| 178 | resp->status = cast_status(nlmsvc_lock(rqstp, file, host, &argp->lock, | 166 | resp->status = cast_status(nlmsvc_lock(rqstp, file, host, &argp->lock, |
| 179 | argp->block, &argp->cookie)); | 167 | argp->block, &argp->cookie, |
| 168 | argp->reclaim)); | ||
| 180 | if (resp->status == nlm_drop_reply) | 169 | if (resp->status == nlm_drop_reply) |
| 181 | rc = rpc_drop_reply; | 170 | rc = rpc_drop_reply; |
| 182 | else | 171 | else |
| @@ -199,7 +188,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 199 | resp->cookie = argp->cookie; | 188 | resp->cookie = argp->cookie; |
| 200 | 189 | ||
| 201 | /* Don't accept requests during grace period */ | 190 | /* Don't accept requests during grace period */ |
| 202 | if (nlmsvc_grace_period) { | 191 | if (locks_in_grace()) { |
| 203 | resp->status = nlm_lck_denied_grace_period; | 192 | resp->status = nlm_lck_denied_grace_period; |
| 204 | return rpc_success; | 193 | return rpc_success; |
| 205 | } | 194 | } |
| @@ -232,7 +221,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 232 | resp->cookie = argp->cookie; | 221 | resp->cookie = argp->cookie; |
| 233 | 222 | ||
| 234 | /* Don't accept new lock requests during grace period */ | 223 | /* Don't accept new lock requests during grace period */ |
| 235 | if (nlmsvc_grace_period) { | 224 | if (locks_in_grace()) { |
| 236 | resp->status = nlm_lck_denied_grace_period; | 225 | resp->status = nlm_lck_denied_grace_period; |
| 237 | return rpc_success; | 226 | return rpc_success; |
| 238 | } | 227 | } |
| @@ -261,7 +250,7 @@ nlmsvc_proc_granted(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 261 | resp->cookie = argp->cookie; | 250 | resp->cookie = argp->cookie; |
| 262 | 251 | ||
| 263 | dprintk("lockd: GRANTED called\n"); | 252 | dprintk("lockd: GRANTED called\n"); |
| 264 | resp->status = nlmclnt_grant(svc_addr_in(rqstp), &argp->lock); | 253 | resp->status = nlmclnt_grant(svc_addr(rqstp), &argp->lock); |
| 265 | dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); | 254 | dprintk("lockd: GRANTED status %d\n", ntohl(resp->status)); |
| 266 | return rpc_success; | 255 | return rpc_success; |
| 267 | } | 256 | } |
| @@ -373,7 +362,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 373 | resp->cookie = argp->cookie; | 362 | resp->cookie = argp->cookie; |
| 374 | 363 | ||
| 375 | /* Don't accept new lock requests during grace period */ | 364 | /* Don't accept new lock requests during grace period */ |
| 376 | if (nlmsvc_grace_period && !argp->reclaim) { | 365 | if (locks_in_grace() && !argp->reclaim) { |
| 377 | resp->status = nlm_lck_denied_grace_period; | 366 | resp->status = nlm_lck_denied_grace_period; |
| 378 | return rpc_success; | 367 | return rpc_success; |
| 379 | } | 368 | } |
| @@ -406,7 +395,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, | |||
| 406 | resp->cookie = argp->cookie; | 395 | resp->cookie = argp->cookie; |
| 407 | 396 | ||
| 408 | /* Don't accept requests during grace period */ | 397 | /* Don't accept requests during grace period */ |
| 409 | if (nlmsvc_grace_period) { | 398 | if (locks_in_grace()) { |
| 410 | resp->status = nlm_lck_denied_grace_period; | 399 | resp->status = nlm_lck_denied_grace_period; |
| 411 | return rpc_success; | 400 | return rpc_success; |
| 412 | } | 401 | } |
| @@ -464,11 +453,9 @@ nlmsvc_proc_sm_notify(struct svc_rqst *rqstp, struct nlm_reboot *argp, | |||
| 464 | { | 453 | { |
| 465 | struct sockaddr_in saddr; | 454 | struct sockaddr_in saddr; |
| 466 | 455 | ||
| 467 | memcpy(&saddr, svc_addr_in(rqstp), sizeof(saddr)); | ||
| 468 | |||
| 469 | dprintk("lockd: SM_NOTIFY called\n"); | 456 | dprintk("lockd: SM_NOTIFY called\n"); |
| 470 | if (saddr.sin_addr.s_addr != htonl(INADDR_LOOPBACK) | 457 | |
| 471 | || ntohs(saddr.sin_port) >= 1024) { | 458 | if (!nlm_privileged_requester(rqstp)) { |
| 472 | char buf[RPC_MAX_ADDRBUFLEN]; | 459 | char buf[RPC_MAX_ADDRBUFLEN]; |
| 473 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", | 460 | printk(KERN_WARNING "lockd: rejected NSM callback from %s\n", |
| 474 | svc_print_addr(rqstp, buf, sizeof(buf))); | 461 | svc_print_addr(rqstp, buf, sizeof(buf))); |
diff --git a/fs/lockd/svcsubs.c b/fs/lockd/svcsubs.c index 198b4e55b373..34c2766e27c7 100644 --- a/fs/lockd/svcsubs.c +++ b/fs/lockd/svcsubs.c | |||
| @@ -418,7 +418,7 @@ EXPORT_SYMBOL_GPL(nlmsvc_unlock_all_by_sb); | |||
| 418 | static int | 418 | static int |
| 419 | nlmsvc_match_ip(void *datap, struct nlm_host *host) | 419 | nlmsvc_match_ip(void *datap, struct nlm_host *host) |
| 420 | { | 420 | { |
| 421 | return nlm_cmp_addr(&host->h_saddr, datap); | 421 | return nlm_cmp_addr(nlm_srcaddr(host), datap); |
| 422 | } | 422 | } |
| 423 | 423 | ||
| 424 | /** | 424 | /** |
diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 3e459e18cc31..1f226290c67c 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c | |||
| @@ -351,8 +351,6 @@ nlmsvc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp) | |||
| 351 | argp->state = ntohl(*p++); | 351 | argp->state = ntohl(*p++); |
| 352 | /* Preserve the address in network byte order */ | 352 | /* Preserve the address in network byte order */ |
| 353 | argp->addr = *p++; | 353 | argp->addr = *p++; |
| 354 | argp->vers = *p++; | ||
| 355 | argp->proto = *p++; | ||
| 356 | return xdr_argsize_check(rqstp, p); | 354 | return xdr_argsize_check(rqstp, p); |
| 357 | } | 355 | } |
| 358 | 356 | ||
diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index 43ff9397e6c6..50c493a8ad8e 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c | |||
| @@ -358,8 +358,6 @@ nlm4svc_decode_reboot(struct svc_rqst *rqstp, __be32 *p, struct nlm_reboot *argp | |||
| 358 | argp->state = ntohl(*p++); | 358 | argp->state = ntohl(*p++); |
| 359 | /* Preserve the address in network byte order */ | 359 | /* Preserve the address in network byte order */ |
| 360 | argp->addr = *p++; | 360 | argp->addr = *p++; |
| 361 | argp->vers = *p++; | ||
| 362 | argp->proto = *p++; | ||
| 363 | return xdr_argsize_check(rqstp, p); | 361 | return xdr_argsize_check(rqstp, p); |
| 364 | } | 362 | } |
| 365 | 363 | ||
