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: Ignore kmemleak false positive in nfs_readdir_make_qstr
SUNRPC: Simplify rpc_alloc_iostats by removing pointless local variable
nfs: trivial: remove unused nfs_wait_event macro
NFS: readdir shouldn't read beyond the reply returned by the server
NFS: Fix a couple of regressions in readdir.
Revert "NFSv4: Fall back to ordinary lookup if nfs4_atomic_open() returns EISDIR"
Regression: fix mounting NFS when NFSv3 support is not compiled
NLM: Fix a regression in lockd

+86 -58
+4 -7
fs/lockd/host.c
··· 124 124 continue; 125 125 if (host->h_server != ni->server) 126 126 continue; 127 - if (ni->server && 127 + if (ni->server && ni->src_len != 0 && 128 128 !rpc_cmp_addr(nlm_srcaddr(host), ni->src_sap)) 129 129 continue; 130 130 ··· 167 167 host->h_addrlen = ni->salen; 168 168 rpc_set_port(nlm_addr(host), 0); 169 169 memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len); 170 + host->h_srcaddrlen = ni->src_len; 170 171 host->h_version = ni->version; 171 172 host->h_proto = ni->protocol; 172 173 host->h_rpcclnt = NULL; ··· 239 238 const char *hostname, 240 239 int noresvport) 241 240 { 242 - const struct sockaddr source = { 243 - .sa_family = AF_UNSPEC, 244 - }; 245 241 struct nlm_lookup_host_info ni = { 246 242 .server = 0, 247 243 .sap = sap, ··· 247 249 .version = version, 248 250 .hostname = hostname, 249 251 .hostname_len = strlen(hostname), 250 - .src_sap = &source, 251 - .src_len = sizeof(source), 252 252 .noresvport = noresvport, 253 253 }; 254 254 ··· 353 357 .protocol = host->h_proto, 354 358 .address = nlm_addr(host), 355 359 .addrsize = host->h_addrlen, 356 - .saddress = nlm_srcaddr(host), 357 360 .timeout = &timeparms, 358 361 .servername = host->h_name, 359 362 .program = &nlm_program, ··· 371 376 args.flags |= RPC_CLNT_CREATE_HARDRTRY; 372 377 if (host->h_noresvport) 373 378 args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; 379 + if (host->h_srcaddrlen) 380 + args.saddress = nlm_srcaddr(host); 374 381 375 382 clnt = rpc_create(&args); 376 383 if (!IS_ERR(clnt))
+65 -35
fs/nfs/dir.c
··· 34 34 #include <linux/mount.h> 35 35 #include <linux/sched.h> 36 36 #include <linux/vmalloc.h> 37 + #include <linux/kmemleak.h> 37 38 38 39 #include "delegation.h" 39 40 #include "iostat.h" ··· 195 194 static 196 195 struct nfs_cache_array *nfs_readdir_get_array(struct page *page) 197 196 { 197 + void *ptr; 198 198 if (page == NULL) 199 199 return ERR_PTR(-EIO); 200 - return (struct nfs_cache_array *)kmap(page); 200 + ptr = kmap(page); 201 + if (ptr == NULL) 202 + return ERR_PTR(-ENOMEM); 203 + return ptr; 201 204 } 202 205 203 206 static ··· 218 213 { 219 214 struct nfs_cache_array *array = nfs_readdir_get_array(page); 220 215 int i; 216 + 217 + if (IS_ERR(array)) 218 + return PTR_ERR(array); 221 219 for (i = 0; i < array->size; i++) 222 220 kfree(array->array[i].string.name); 223 221 nfs_readdir_release_array(page); ··· 239 231 string->name = kmemdup(name, len, GFP_KERNEL); 240 232 if (string->name == NULL) 241 233 return -ENOMEM; 234 + /* 235 + * Avoid a kmemleak false positive. The pointer to the name is stored 236 + * in a page cache page which kmemleak does not scan. 237 + */ 238 + kmemleak_not_leak(string->name); 242 239 string->hash = full_name_hash(name, len); 243 240 return 0; 244 241 } ··· 257 244 258 245 if (IS_ERR(array)) 259 246 return PTR_ERR(array); 260 - ret = -EIO; 247 + ret = -ENOSPC; 261 248 if (array->size >= MAX_READDIR_ARRAY) 262 249 goto out; 263 250 ··· 268 255 if (ret) 269 256 goto out; 270 257 array->last_cookie = entry->cookie; 258 + array->size++; 271 259 if (entry->eof == 1) 272 260 array->eof_index = array->size; 273 - array->size++; 274 261 out: 275 262 nfs_readdir_release_array(page); 276 263 return ret; ··· 285 272 if (diff < 0) 286 273 goto out_eof; 287 274 if (diff >= array->size) { 288 - if (array->eof_index > 0) 275 + if (array->eof_index >= 0) 289 276 goto out_eof; 290 277 desc->current_index += array->size; 291 278 return -EAGAIN; ··· 294 281 index = (unsigned int)diff; 295 282 *desc->dir_cookie = array->array[index].cookie; 296 283 desc->cache_entry_index = index; 297 - if (index == array->eof_index) 298 - desc->eof = 1; 299 284 return 0; 300 285 out_eof: 301 286 desc->eof = 1; ··· 307 296 int status = -EAGAIN; 308 297 309 298 for (i = 0; i < array->size; i++) { 310 - if (i == array->eof_index) { 311 - desc->eof = 1; 312 - status = -EBADCOOKIE; 313 - } 314 299 if (array->array[i].cookie == *desc->dir_cookie) { 315 300 desc->cache_entry_index = i; 316 301 status = 0; 317 - break; 302 + goto out; 318 303 } 319 304 } 320 - 305 + if (i == array->eof_index) { 306 + desc->eof = 1; 307 + status = -EBADCOOKIE; 308 + } 309 + out: 321 310 return status; 322 311 } 323 312 ··· 460 449 461 450 /* Perform conversion from xdr to cache array */ 462 451 static 463 - void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, 452 + int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, 464 453 void *xdr_page, struct page *page, unsigned int buflen) 465 454 { 466 455 struct xdr_stream stream; ··· 482 471 483 472 do { 484 473 status = xdr_decode(desc, entry, &stream); 485 - if (status != 0) 474 + if (status != 0) { 475 + if (status == -EAGAIN) 476 + status = 0; 486 477 break; 478 + } 487 479 488 - if (nfs_readdir_add_to_array(entry, page) == -1) 489 - break; 490 480 if (desc->plus == 1) 491 481 nfs_prime_dcache(desc->file->f_path.dentry, entry); 482 + 483 + status = nfs_readdir_add_to_array(entry, page); 484 + if (status != 0) 485 + break; 492 486 } while (!entry->eof); 493 487 494 488 if (status == -EBADCOOKIE && entry->eof) { 495 489 array = nfs_readdir_get_array(page); 496 - array->eof_index = array->size - 1; 497 - status = 0; 498 - nfs_readdir_release_array(page); 490 + if (!IS_ERR(array)) { 491 + array->eof_index = array->size; 492 + status = 0; 493 + nfs_readdir_release_array(page); 494 + } 499 495 } 496 + return status; 500 497 } 501 498 502 499 static ··· 556 537 struct nfs_entry entry; 557 538 struct file *file = desc->file; 558 539 struct nfs_cache_array *array; 559 - int status = 0; 540 + int status = -ENOMEM; 560 541 unsigned int array_size = ARRAY_SIZE(pages); 561 542 562 543 entry.prev_cookie = 0; ··· 568 549 goto out; 569 550 570 551 array = nfs_readdir_get_array(page); 552 + if (IS_ERR(array)) { 553 + status = PTR_ERR(array); 554 + goto out; 555 + } 571 556 memset(array, 0, sizeof(struct nfs_cache_array)); 572 557 array->eof_index = -1; 573 558 ··· 579 556 if (!pages_ptr) 580 557 goto out_release_array; 581 558 do { 559 + unsigned int pglen; 582 560 status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode); 583 561 584 562 if (status < 0) 585 563 break; 586 - nfs_readdir_page_filler(desc, &entry, pages_ptr, page, array_size * PAGE_SIZE); 587 - } while (array->eof_index < 0 && array->size < MAX_READDIR_ARRAY); 564 + pglen = status; 565 + status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen); 566 + if (status < 0) { 567 + if (status == -ENOSPC) 568 + status = 0; 569 + break; 570 + } 571 + } while (array->eof_index < 0); 588 572 589 573 nfs_readdir_free_large_page(pages_ptr, pages, array_size); 590 574 out_release_array: ··· 612 582 int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) 613 583 { 614 584 struct inode *inode = desc->file->f_path.dentry->d_inode; 585 + int ret; 615 586 616 - if (nfs_readdir_xdr_to_array(desc, page, inode) < 0) 587 + ret = nfs_readdir_xdr_to_array(desc, page, inode); 588 + if (ret < 0) 617 589 goto error; 618 590 SetPageUptodate(page); 619 591 ··· 627 595 return 0; 628 596 error: 629 597 unlock_page(page); 630 - return -EIO; 598 + return ret; 631 599 } 632 600 633 601 static ··· 640 608 static 641 609 struct page *get_cache_page(nfs_readdir_descriptor_t *desc) 642 610 { 643 - struct page *page; 644 - page = read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping, 611 + return read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping, 645 612 desc->page_index, (filler_t *)nfs_readdir_filler, desc); 646 - if (IS_ERR(page)) 647 - desc->eof = 1; 648 - return page; 649 613 } 650 614 651 615 /* ··· 667 639 static inline 668 640 int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) 669 641 { 670 - int res = -EAGAIN; 642 + int res; 671 643 644 + if (desc->page_index == 0) 645 + desc->current_index = 0; 672 646 while (1) { 673 647 res = find_cache_page(desc); 674 648 if (res != -EAGAIN) ··· 700 670 struct dentry *dentry = NULL; 701 671 702 672 array = nfs_readdir_get_array(desc->page); 673 + if (IS_ERR(array)) 674 + return PTR_ERR(array); 703 675 704 676 for (i = desc->cache_entry_index; i < array->size; i++) { 705 677 d_type = DT_UNKNOWN; ··· 717 685 *desc->dir_cookie = array->array[i+1].cookie; 718 686 else 719 687 *desc->dir_cookie = array->last_cookie; 720 - if (i == array->eof_index) { 721 - desc->eof = 1; 722 - break; 723 - } 724 688 } 689 + if (i == array->eof_index) 690 + desc->eof = 1; 725 691 726 692 nfs_readdir_release_array(desc->page); 727 693 cache_page_release(desc); ··· 1375 1345 res = NULL; 1376 1346 goto out; 1377 1347 /* This turned out not to be a regular file */ 1378 - case -EISDIR: 1379 1348 case -ENOTDIR: 1380 1349 goto no_open; 1381 1350 case -ELOOP: 1382 1351 if (!(nd->intent.open.flags & O_NOFOLLOW)) 1383 1352 goto no_open; 1353 + /* case -EISDIR: */ 1384 1354 /* case -EINVAL: */ 1385 1355 default: 1386 1356 res = ERR_CAST(inode);
+2 -2
fs/nfs/nfs2xdr.c
··· 423 423 struct page **page; 424 424 size_t hdrlen; 425 425 unsigned int pglen, recvd; 426 - int status, nr = 0; 426 + int status; 427 427 428 428 if ((status = ntohl(*p++))) 429 429 return nfs_stat_to_errno(status); ··· 443 443 if (pglen > recvd) 444 444 pglen = recvd; 445 445 page = rcvbuf->pages; 446 - return nr; 446 + return pglen; 447 447 } 448 448 449 449 static void print_overflow_msg(const char *func, const struct xdr_stream *xdr)
+2 -2
fs/nfs/nfs3xdr.c
··· 555 555 struct page **page; 556 556 size_t hdrlen; 557 557 u32 recvd, pglen; 558 - int status, nr = 0; 558 + int status; 559 559 560 560 status = ntohl(*p++); 561 561 /* Decode post_op_attrs */ ··· 586 586 pglen = recvd; 587 587 page = rcvbuf->pages; 588 588 589 - return nr; 589 + return pglen; 590 590 } 591 591 592 592 __be32 *
+3 -1
fs/nfs/nfs4proc.c
··· 2852 2852 nfs4_setup_readdir(cookie, NFS_COOKIEVERF(dir), dentry, &args); 2853 2853 res.pgbase = args.pgbase; 2854 2854 status = nfs4_call_sync(NFS_SERVER(dir), &msg, &args, &res, 0); 2855 - if (status == 0) 2855 + if (status >= 0) { 2856 2856 memcpy(NFS_COOKIEVERF(dir), res.verifier.data, NFS4_VERIFIER_SIZE); 2857 + status += args.pgbase; 2858 + } 2857 2859 2858 2860 nfs_invalidate_atime(dir); 2859 2861
+1 -1
fs/nfs/nfs4xdr.c
··· 4518 4518 xdr_read_pages(xdr, pglen); 4519 4519 4520 4520 4521 - return 0; 4521 + return pglen; 4522 4522 } 4523 4523 4524 4524 static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req)
+7 -1
fs/nfs/super.c
··· 67 67 68 68 #define NFSDBG_FACILITY NFSDBG_VFS 69 69 70 + #ifdef CONFIG_NFS_V3 71 + #define NFS_DEFAULT_VERSION 3 72 + #else 73 + #define NFS_DEFAULT_VERSION 2 74 + #endif 75 + 70 76 enum { 71 77 /* Mount options that take no arguments */ 72 78 Opt_soft, Opt_hard, ··· 2283 2277 }; 2284 2278 int error = -ENOMEM; 2285 2279 2286 - data = nfs_alloc_parsed_mount_data(3); 2280 + data = nfs_alloc_parsed_mount_data(NFS_DEFAULT_VERSION); 2287 2281 mntfh = nfs_alloc_fhandle(); 2288 2282 if (data == NULL || mntfh == NULL) 2289 2283 goto out_free_fh;
+1
include/linux/lockd/lockd.h
··· 43 43 struct sockaddr_storage h_addr; /* peer address */ 44 44 size_t h_addrlen; 45 45 struct sockaddr_storage h_srcaddr; /* our address (optional) */ 46 + size_t h_srcaddrlen; 46 47 struct rpc_clnt *h_rpcclnt; /* RPC client to talk to peer */ 47 48 char *h_name; /* remote hostname */ 48 49 u32 h_version; /* interface version */
-6
include/linux/nfs_fs.h
··· 593 593 return ino; 594 594 } 595 595 596 - #define nfs_wait_event(clnt, wq, condition) \ 597 - ({ \ 598 - int __retval = wait_event_killable(wq, condition); \ 599 - __retval; \ 600 - }) 601 - 602 596 #define NFS_JUKEBOX_RETRY_TIME (5 * HZ) 603 597 604 598 #endif /* __KERNEL__ */
+1 -3
net/sunrpc/stats.c
··· 115 115 */ 116 116 struct rpc_iostats *rpc_alloc_iostats(struct rpc_clnt *clnt) 117 117 { 118 - struct rpc_iostats *new; 119 - new = kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); 120 - return new; 118 + return kcalloc(clnt->cl_maxproc, sizeof(struct rpc_iostats), GFP_KERNEL); 121 119 } 122 120 EXPORT_SYMBOL_GPL(rpc_alloc_iostats); 123 121