diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-14 15:00:18 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-03-14 15:00:18 -0400 |
commit | f1823acfbcc7d29029d6db757644bc820664af37 (patch) | |
tree | bf7839d0976f90c638b4f7806be8ee16f3b786a7 /fs | |
parent | ff9cb43ce09a9069f0ec95375d2f403578ec4977 (diff) | |
parent | 9f4c899c0d90e1b51b6864834f3877b47c161a0e (diff) |
Merge branch 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6
* 'bugfixes' of git://git.linux-nfs.org/projects/trondmy/nfs-2.6:
NFS: Fix the fix to Bugzilla #11061, when IPv6 isn't defined...
SUNRPC: xprt_connect() don't abort the task if the transport isn't bound
SUNRPC: Fix an Oops due to socket not set up yet...
Bug 11061, NFS mounts dropped
NFS: Handle -ESTALE error in access()
NLM: Fix GRANT callback address comparison when IPv6 is enabled
NLM: Shrink the IPv4-only version of nlm_cmp_addr()
NFSv3: Fix posix ACL code
NFS: Fix misparsing of nfsv4 fs_locations attribute (take 2)
SUNRPC: Tighten up the task locking rules in __rpc_execute()
Diffstat (limited to 'fs')
-rw-r--r-- | fs/lockd/clntlock.c | 51 | ||||
-rw-r--r-- | fs/nfs/client.c | 73 | ||||
-rw-r--r-- | fs/nfs/dir.c | 8 | ||||
-rw-r--r-- | fs/nfs/nfs3acl.c | 27 | ||||
-rw-r--r-- | fs/nfs/nfs3xdr.c | 34 | ||||
-rw-r--r-- | fs/nfs/nfs4namespace.c | 15 |
6 files changed, 171 insertions, 37 deletions
diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 1f3b0fc0d351..aedc47a264c1 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c | |||
@@ -139,6 +139,55 @@ int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout) | |||
139 | return 0; | 139 | return 0; |
140 | } | 140 | } |
141 | 141 | ||
142 | #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) | ||
143 | static const struct in6_addr *nlmclnt_map_v4addr(const struct sockaddr *sap, | ||
144 | struct in6_addr *addr_mapped) | ||
145 | { | ||
146 | const struct sockaddr_in *sin = (const struct sockaddr_in *)sap; | ||
147 | |||
148 | switch (sap->sa_family) { | ||
149 | case AF_INET6: | ||
150 | return &((const struct sockaddr_in6 *)sap)->sin6_addr; | ||
151 | case AF_INET: | ||
152 | ipv6_addr_set_v4mapped(sin->sin_addr.s_addr, addr_mapped); | ||
153 | return addr_mapped; | ||
154 | } | ||
155 | |||
156 | return NULL; | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * If lockd is using a PF_INET6 listener, all incoming requests appear | ||
161 | * to come from AF_INET6 remotes. The address of AF_INET remotes are | ||
162 | * mapped to AF_INET6 automatically by the network layer. In case the | ||
163 | * user passed an AF_INET server address at mount time, ensure both | ||
164 | * addresses are AF_INET6 before comparing them. | ||
165 | */ | ||
166 | static int nlmclnt_cmp_addr(const struct nlm_host *host, | ||
167 | const struct sockaddr *sap) | ||
168 | { | ||
169 | const struct in6_addr *addr1; | ||
170 | const struct in6_addr *addr2; | ||
171 | struct in6_addr addr1_mapped; | ||
172 | struct in6_addr addr2_mapped; | ||
173 | |||
174 | addr1 = nlmclnt_map_v4addr(nlm_addr(host), &addr1_mapped); | ||
175 | if (likely(addr1 != NULL)) { | ||
176 | addr2 = nlmclnt_map_v4addr(sap, &addr2_mapped); | ||
177 | if (likely(addr2 != NULL)) | ||
178 | return ipv6_addr_equal(addr1, addr2); | ||
179 | } | ||
180 | |||
181 | return 0; | ||
182 | } | ||
183 | #else /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | ||
184 | static int nlmclnt_cmp_addr(const struct nlm_host *host, | ||
185 | const struct sockaddr *sap) | ||
186 | { | ||
187 | return nlm_cmp_addr(nlm_addr(host), sap); | ||
188 | } | ||
189 | #endif /* !(CONFIG_IPV6 || CONFIG_IPV6_MODULE) */ | ||
190 | |||
142 | /* | 191 | /* |
143 | * The server lockd has called us back to tell us the lock was granted | 192 | * The server lockd has called us back to tell us the lock was granted |
144 | */ | 193 | */ |
@@ -166,7 +215,7 @@ __be32 nlmclnt_grant(const struct sockaddr *addr, const struct nlm_lock *lock) | |||
166 | */ | 215 | */ |
167 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) | 216 | if (fl_blocked->fl_u.nfs_fl.owner->pid != lock->svid) |
168 | continue; | 217 | continue; |
169 | if (!nlm_cmp_addr(nlm_addr(block->b_host), addr)) | 218 | if (!nlmclnt_cmp_addr(block->b_host, addr)) |
170 | continue; | 219 | continue; |
171 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) | 220 | if (nfs_compare_fh(NFS_FH(fl_blocked->fl_file->f_path.dentry->d_inode) ,fh) != 0) |
172 | continue; | 221 | continue; |
diff --git a/fs/nfs/client.c b/fs/nfs/client.c index 9b728f3565a1..574158ae2398 100644 --- a/fs/nfs/client.c +++ b/fs/nfs/client.c | |||
@@ -255,6 +255,32 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, | |||
255 | } | 255 | } |
256 | return 0; | 256 | return 0; |
257 | } | 257 | } |
258 | |||
259 | /* | ||
260 | * Test if two ip6 socket addresses refer to the same socket by | ||
261 | * comparing relevant fields. The padding bytes specifically, are not | ||
262 | * compared. sin6_flowinfo is not compared because it only affects QoS | ||
263 | * and sin6_scope_id is only compared if the address is "link local" | ||
264 | * because "link local" addresses need only be unique to a specific | ||
265 | * link. Conversely, ordinary unicast addresses might have different | ||
266 | * sin6_scope_id. | ||
267 | * | ||
268 | * The caller should ensure both socket addresses are AF_INET6. | ||
269 | */ | ||
270 | static int nfs_sockaddr_cmp_ip6(const struct sockaddr *sa1, | ||
271 | const struct sockaddr *sa2) | ||
272 | { | ||
273 | const struct sockaddr_in6 *saddr1 = (const struct sockaddr_in6 *)sa1; | ||
274 | const struct sockaddr_in6 *saddr2 = (const struct sockaddr_in6 *)sa2; | ||
275 | |||
276 | if (!ipv6_addr_equal(&saddr1->sin6_addr, | ||
277 | &saddr1->sin6_addr)) | ||
278 | return 0; | ||
279 | if (ipv6_addr_scope(&saddr1->sin6_addr) == IPV6_ADDR_SCOPE_LINKLOCAL && | ||
280 | saddr1->sin6_scope_id != saddr2->sin6_scope_id) | ||
281 | return 0; | ||
282 | return saddr1->sin6_port == saddr2->sin6_port; | ||
283 | } | ||
258 | #else | 284 | #else |
259 | static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, | 285 | static int nfs_sockaddr_match_ipaddr4(const struct sockaddr_in *sa1, |
260 | const struct sockaddr_in *sa2) | 286 | const struct sockaddr_in *sa2) |
@@ -270,9 +296,52 @@ static int nfs_sockaddr_match_ipaddr(const struct sockaddr *sa1, | |||
270 | return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, | 296 | return nfs_sockaddr_match_ipaddr4((const struct sockaddr_in *)sa1, |
271 | (const struct sockaddr_in *)sa2); | 297 | (const struct sockaddr_in *)sa2); |
272 | } | 298 | } |
299 | |||
300 | static int nfs_sockaddr_cmp_ip6(const struct sockaddr * sa1, | ||
301 | const struct sockaddr * sa2) | ||
302 | { | ||
303 | return 0; | ||
304 | } | ||
273 | #endif | 305 | #endif |
274 | 306 | ||
275 | /* | 307 | /* |
308 | * Test if two ip4 socket addresses refer to the same socket, by | ||
309 | * comparing relevant fields. The padding bytes specifically, are | ||
310 | * not compared. | ||
311 | * | ||
312 | * The caller should ensure both socket addresses are AF_INET. | ||
313 | */ | ||
314 | static int nfs_sockaddr_cmp_ip4(const struct sockaddr *sa1, | ||
315 | const struct sockaddr *sa2) | ||
316 | { | ||
317 | const struct sockaddr_in *saddr1 = (const struct sockaddr_in *)sa1; | ||
318 | const struct sockaddr_in *saddr2 = (const struct sockaddr_in *)sa2; | ||
319 | |||
320 | if (saddr1->sin_addr.s_addr != saddr2->sin_addr.s_addr) | ||
321 | return 0; | ||
322 | return saddr1->sin_port == saddr2->sin_port; | ||
323 | } | ||
324 | |||
325 | /* | ||
326 | * Test if two socket addresses represent the same actual socket, | ||
327 | * by comparing (only) relevant fields. | ||
328 | */ | ||
329 | static int nfs_sockaddr_cmp(const struct sockaddr *sa1, | ||
330 | const struct sockaddr *sa2) | ||
331 | { | ||
332 | if (sa1->sa_family != sa2->sa_family) | ||
333 | return 0; | ||
334 | |||
335 | switch (sa1->sa_family) { | ||
336 | case AF_INET: | ||
337 | return nfs_sockaddr_cmp_ip4(sa1, sa2); | ||
338 | case AF_INET6: | ||
339 | return nfs_sockaddr_cmp_ip6(sa1, sa2); | ||
340 | } | ||
341 | return 0; | ||
342 | } | ||
343 | |||
344 | /* | ||
276 | * Find a client by IP address and protocol version | 345 | * Find a client by IP address and protocol version |
277 | * - returns NULL if no such client | 346 | * - returns NULL if no such client |
278 | */ | 347 | */ |
@@ -344,8 +413,10 @@ struct nfs_client *nfs_find_client_next(struct nfs_client *clp) | |||
344 | static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) | 413 | static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *data) |
345 | { | 414 | { |
346 | struct nfs_client *clp; | 415 | struct nfs_client *clp; |
416 | const struct sockaddr *sap = data->addr; | ||
347 | 417 | ||
348 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { | 418 | list_for_each_entry(clp, &nfs_client_list, cl_share_link) { |
419 | const struct sockaddr *clap = (struct sockaddr *)&clp->cl_addr; | ||
349 | /* Don't match clients that failed to initialise properly */ | 420 | /* Don't match clients that failed to initialise properly */ |
350 | if (clp->cl_cons_state < 0) | 421 | if (clp->cl_cons_state < 0) |
351 | continue; | 422 | continue; |
@@ -358,7 +429,7 @@ static struct nfs_client *nfs_match_client(const struct nfs_client_initdata *dat | |||
358 | continue; | 429 | continue; |
359 | 430 | ||
360 | /* Match the full socket address */ | 431 | /* Match the full socket address */ |
361 | if (memcmp(&clp->cl_addr, data->addr, sizeof(clp->cl_addr)) != 0) | 432 | if (!nfs_sockaddr_cmp(sap, clap)) |
362 | continue; | 433 | continue; |
363 | 434 | ||
364 | atomic_inc(&clp->cl_count); | 435 | atomic_inc(&clp->cl_count); |
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e35c8199f82f..672368f865ca 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -1892,8 +1892,14 @@ static int nfs_do_access(struct inode *inode, struct rpc_cred *cred, int mask) | |||
1892 | cache.cred = cred; | 1892 | cache.cred = cred; |
1893 | cache.jiffies = jiffies; | 1893 | cache.jiffies = jiffies; |
1894 | status = NFS_PROTO(inode)->access(inode, &cache); | 1894 | status = NFS_PROTO(inode)->access(inode, &cache); |
1895 | if (status != 0) | 1895 | if (status != 0) { |
1896 | if (status == -ESTALE) { | ||
1897 | nfs_zap_caches(inode); | ||
1898 | if (!S_ISDIR(inode->i_mode)) | ||
1899 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); | ||
1900 | } | ||
1896 | return status; | 1901 | return status; |
1902 | } | ||
1897 | nfs_access_add_cache(inode, &cache); | 1903 | nfs_access_add_cache(inode, &cache); |
1898 | out: | 1904 | out: |
1899 | if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) | 1905 | if ((mask & ~cache.mask & (MAY_READ | MAY_WRITE | MAY_EXEC)) == 0) |
diff --git a/fs/nfs/nfs3acl.c b/fs/nfs/nfs3acl.c index cef62557c87d..6bbf0e6daad2 100644 --- a/fs/nfs/nfs3acl.c +++ b/fs/nfs/nfs3acl.c | |||
@@ -292,7 +292,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
292 | { | 292 | { |
293 | struct nfs_server *server = NFS_SERVER(inode); | 293 | struct nfs_server *server = NFS_SERVER(inode); |
294 | struct nfs_fattr fattr; | 294 | struct nfs_fattr fattr; |
295 | struct page *pages[NFSACL_MAXPAGES] = { }; | 295 | struct page *pages[NFSACL_MAXPAGES]; |
296 | struct nfs3_setaclargs args = { | 296 | struct nfs3_setaclargs args = { |
297 | .inode = inode, | 297 | .inode = inode, |
298 | .mask = NFS_ACL, | 298 | .mask = NFS_ACL, |
@@ -303,7 +303,7 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
303 | .rpc_argp = &args, | 303 | .rpc_argp = &args, |
304 | .rpc_resp = &fattr, | 304 | .rpc_resp = &fattr, |
305 | }; | 305 | }; |
306 | int status, count; | 306 | int status; |
307 | 307 | ||
308 | status = -EOPNOTSUPP; | 308 | status = -EOPNOTSUPP; |
309 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) | 309 | if (!nfs_server_capable(inode, NFS_CAP_ACLS)) |
@@ -319,6 +319,20 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
319 | if (S_ISDIR(inode->i_mode)) { | 319 | if (S_ISDIR(inode->i_mode)) { |
320 | args.mask |= NFS_DFACL; | 320 | args.mask |= NFS_DFACL; |
321 | args.acl_default = dfacl; | 321 | args.acl_default = dfacl; |
322 | args.len = nfsacl_size(acl, dfacl); | ||
323 | } else | ||
324 | args.len = nfsacl_size(acl, NULL); | ||
325 | |||
326 | if (args.len > NFS_ACL_INLINE_BUFSIZE) { | ||
327 | unsigned int npages = 1 + ((args.len - 1) >> PAGE_SHIFT); | ||
328 | |||
329 | status = -ENOMEM; | ||
330 | do { | ||
331 | args.pages[args.npages] = alloc_page(GFP_KERNEL); | ||
332 | if (args.pages[args.npages] == NULL) | ||
333 | goto out_freepages; | ||
334 | args.npages++; | ||
335 | } while (args.npages < npages); | ||
322 | } | 336 | } |
323 | 337 | ||
324 | dprintk("NFS call setacl\n"); | 338 | dprintk("NFS call setacl\n"); |
@@ -329,10 +343,6 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
329 | nfs_zap_acl_cache(inode); | 343 | nfs_zap_acl_cache(inode); |
330 | dprintk("NFS reply setacl: %d\n", status); | 344 | dprintk("NFS reply setacl: %d\n", status); |
331 | 345 | ||
332 | /* pages may have been allocated at the xdr layer. */ | ||
333 | for (count = 0; count < NFSACL_MAXPAGES && args.pages[count]; count++) | ||
334 | __free_page(args.pages[count]); | ||
335 | |||
336 | switch (status) { | 346 | switch (status) { |
337 | case 0: | 347 | case 0: |
338 | status = nfs_refresh_inode(inode, &fattr); | 348 | status = nfs_refresh_inode(inode, &fattr); |
@@ -346,6 +356,11 @@ static int nfs3_proc_setacls(struct inode *inode, struct posix_acl *acl, | |||
346 | case -ENOTSUPP: | 356 | case -ENOTSUPP: |
347 | status = -EOPNOTSUPP; | 357 | status = -EOPNOTSUPP; |
348 | } | 358 | } |
359 | out_freepages: | ||
360 | while (args.npages != 0) { | ||
361 | args.npages--; | ||
362 | __free_page(args.pages[args.npages]); | ||
363 | } | ||
349 | out: | 364 | out: |
350 | return status; | 365 | return status; |
351 | } | 366 | } |
diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 11cdddec1432..6cdeacffde46 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c | |||
@@ -82,8 +82,10 @@ | |||
82 | #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) | 82 | #define NFS3_commitres_sz (1+NFS3_wcc_data_sz+2) |
83 | 83 | ||
84 | #define ACL3_getaclargs_sz (NFS3_fh_sz+1) | 84 | #define ACL3_getaclargs_sz (NFS3_fh_sz+1) |
85 | #define ACL3_setaclargs_sz (NFS3_fh_sz+1+2*(2+5*3)) | 85 | #define ACL3_setaclargs_sz (NFS3_fh_sz+1+ \ |
86 | #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+2*(2+5*3)) | 86 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) |
87 | #define ACL3_getaclres_sz (1+NFS3_post_op_attr_sz+1+ \ | ||
88 | XDR_QUADLEN(NFS_ACL_INLINE_BUFSIZE)) | ||
87 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) | 89 | #define ACL3_setaclres_sz (1+NFS3_post_op_attr_sz) |
88 | 90 | ||
89 | /* | 91 | /* |
@@ -703,28 +705,18 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, | |||
703 | struct nfs3_setaclargs *args) | 705 | struct nfs3_setaclargs *args) |
704 | { | 706 | { |
705 | struct xdr_buf *buf = &req->rq_snd_buf; | 707 | struct xdr_buf *buf = &req->rq_snd_buf; |
706 | unsigned int base, len_in_head, len = nfsacl_size( | 708 | unsigned int base; |
707 | (args->mask & NFS_ACL) ? args->acl_access : NULL, | 709 | int err; |
708 | (args->mask & NFS_DFACL) ? args->acl_default : NULL); | ||
709 | int count, err; | ||
710 | 710 | ||
711 | p = xdr_encode_fhandle(p, NFS_FH(args->inode)); | 711 | p = xdr_encode_fhandle(p, NFS_FH(args->inode)); |
712 | *p++ = htonl(args->mask); | 712 | *p++ = htonl(args->mask); |
713 | base = (char *)p - (char *)buf->head->iov_base; | 713 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); |
714 | /* put as much of the acls into head as possible. */ | 714 | base = req->rq_slen; |
715 | len_in_head = min_t(unsigned int, buf->head->iov_len - base, len); | 715 | |
716 | len -= len_in_head; | 716 | if (args->npages != 0) |
717 | req->rq_slen = xdr_adjust_iovec(req->rq_svec, p + (len_in_head >> 2)); | 717 | xdr_encode_pages(buf, args->pages, 0, args->len); |
718 | 718 | else | |
719 | for (count = 0; (count << PAGE_SHIFT) < len; count++) { | 719 | req->rq_slen += args->len; |
720 | args->pages[count] = alloc_page(GFP_KERNEL); | ||
721 | if (!args->pages[count]) { | ||
722 | while (count) | ||
723 | __free_page(args->pages[--count]); | ||
724 | return -ENOMEM; | ||
725 | } | ||
726 | } | ||
727 | xdr_encode_pages(buf, args->pages, 0, len); | ||
728 | 720 | ||
729 | err = nfsacl_encode(buf, base, args->inode, | 721 | err = nfsacl_encode(buf, base, args->inode, |
730 | (args->mask & NFS_ACL) ? | 722 | (args->mask & NFS_ACL) ? |
diff --git a/fs/nfs/nfs4namespace.c b/fs/nfs/nfs4namespace.c index 30befc39b3c6..2a2a0a7143ad 100644 --- a/fs/nfs/nfs4namespace.c +++ b/fs/nfs/nfs4namespace.c | |||
@@ -21,7 +21,9 @@ | |||
21 | #define NFSDBG_FACILITY NFSDBG_VFS | 21 | #define NFSDBG_FACILITY NFSDBG_VFS |
22 | 22 | ||
23 | /* | 23 | /* |
24 | * Check if fs_root is valid | 24 | * Convert the NFSv4 pathname components into a standard posix path. |
25 | * | ||
26 | * Note that the resulting string will be placed at the end of the buffer | ||
25 | */ | 27 | */ |
26 | static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, | 28 | static inline char *nfs4_pathname_string(const struct nfs4_pathname *pathname, |
27 | char *buffer, ssize_t buflen) | 29 | char *buffer, ssize_t buflen) |
@@ -99,21 +101,20 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
99 | { | 101 | { |
100 | struct vfsmount *mnt = ERR_PTR(-ENOENT); | 102 | struct vfsmount *mnt = ERR_PTR(-ENOENT); |
101 | char *mnt_path; | 103 | char *mnt_path; |
102 | int page2len; | 104 | unsigned int maxbuflen; |
103 | unsigned int s; | 105 | unsigned int s; |
104 | 106 | ||
105 | mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); | 107 | mnt_path = nfs4_pathname_string(&location->rootpath, page2, PAGE_SIZE); |
106 | if (IS_ERR(mnt_path)) | 108 | if (IS_ERR(mnt_path)) |
107 | return mnt; | 109 | return mnt; |
108 | mountdata->mnt_path = mnt_path; | 110 | mountdata->mnt_path = mnt_path; |
109 | page2 += strlen(mnt_path) + 1; | 111 | maxbuflen = mnt_path - 1 - page2; |
110 | page2len = PAGE_SIZE - strlen(mnt_path) - 1; | ||
111 | 112 | ||
112 | for (s = 0; s < location->nservers; s++) { | 113 | for (s = 0; s < location->nservers; s++) { |
113 | const struct nfs4_string *buf = &location->servers[s]; | 114 | const struct nfs4_string *buf = &location->servers[s]; |
114 | struct sockaddr_storage addr; | 115 | struct sockaddr_storage addr; |
115 | 116 | ||
116 | if (buf->len <= 0 || buf->len >= PAGE_SIZE) | 117 | if (buf->len <= 0 || buf->len >= maxbuflen) |
117 | continue; | 118 | continue; |
118 | 119 | ||
119 | mountdata->addr = (struct sockaddr *)&addr; | 120 | mountdata->addr = (struct sockaddr *)&addr; |
@@ -126,8 +127,8 @@ static struct vfsmount *try_location(struct nfs_clone_mount *mountdata, | |||
126 | continue; | 127 | continue; |
127 | nfs_set_port(mountdata->addr, NFS_PORT); | 128 | nfs_set_port(mountdata->addr, NFS_PORT); |
128 | 129 | ||
129 | strncpy(page2, buf->data, page2len); | 130 | memcpy(page2, buf->data, buf->len); |
130 | page2[page2len] = '\0'; | 131 | page2[buf->len] = '\0'; |
131 | mountdata->hostname = page2; | 132 | mountdata->hostname = page2; |
132 | 133 | ||
133 | snprintf(page, PAGE_SIZE, "%s:%s", | 134 | snprintf(page, PAGE_SIZE, "%s:%s", |