aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c220
1 files changed, 123 insertions, 97 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 07ac3847e562..996dd8989a91 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -34,6 +34,7 @@
34#include <linux/mount.h> 34#include <linux/mount.h>
35#include <linux/sched.h> 35#include <linux/sched.h>
36#include <linux/vmalloc.h> 36#include <linux/vmalloc.h>
37#include <linux/kmemleak.h>
37 38
38#include "delegation.h" 39#include "delegation.h"
39#include "iostat.h" 40#include "iostat.h"
@@ -56,7 +57,7 @@ static int nfs_rename(struct inode *, struct dentry *,
56 struct inode *, struct dentry *); 57 struct inode *, struct dentry *);
57static int nfs_fsync_dir(struct file *, int); 58static int nfs_fsync_dir(struct file *, int);
58static loff_t nfs_llseek_dir(struct file *, loff_t, int); 59static loff_t nfs_llseek_dir(struct file *, loff_t, int);
59static int nfs_readdir_clear_array(struct page*, gfp_t); 60static void nfs_readdir_clear_array(struct page*);
60 61
61const struct file_operations nfs_dir_operations = { 62const struct file_operations nfs_dir_operations = {
62 .llseek = nfs_llseek_dir, 63 .llseek = nfs_llseek_dir,
@@ -82,8 +83,8 @@ const struct inode_operations nfs_dir_inode_operations = {
82 .setattr = nfs_setattr, 83 .setattr = nfs_setattr,
83}; 84};
84 85
85const struct address_space_operations nfs_dir_addr_space_ops = { 86const struct address_space_operations nfs_dir_aops = {
86 .releasepage = nfs_readdir_clear_array, 87 .freepage = nfs_readdir_clear_array,
87}; 88};
88 89
89#ifdef CONFIG_NFS_V3 90#ifdef CONFIG_NFS_V3
@@ -161,6 +162,7 @@ struct nfs_cache_array_entry {
161 u64 cookie; 162 u64 cookie;
162 u64 ino; 163 u64 ino;
163 struct qstr string; 164 struct qstr string;
165 unsigned char d_type;
164}; 166};
165 167
166struct nfs_cache_array { 168struct nfs_cache_array {
@@ -170,14 +172,13 @@ struct nfs_cache_array {
170 struct nfs_cache_array_entry array[0]; 172 struct nfs_cache_array_entry array[0];
171}; 173};
172 174
173#define MAX_READDIR_ARRAY ((PAGE_SIZE - sizeof(struct nfs_cache_array)) / sizeof(struct nfs_cache_array_entry))
174
175typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); 175typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int);
176typedef struct { 176typedef struct {
177 struct file *file; 177 struct file *file;
178 struct page *page; 178 struct page *page;
179 unsigned long page_index; 179 unsigned long page_index;
180 u64 *dir_cookie; 180 u64 *dir_cookie;
181 u64 last_cookie;
181 loff_t current_index; 182 loff_t current_index;
182 decode_dirent_t decode; 183 decode_dirent_t decode;
183 184
@@ -194,9 +195,13 @@ typedef struct {
194static 195static
195struct nfs_cache_array *nfs_readdir_get_array(struct page *page) 196struct nfs_cache_array *nfs_readdir_get_array(struct page *page)
196{ 197{
198 void *ptr;
197 if (page == NULL) 199 if (page == NULL)
198 return ERR_PTR(-EIO); 200 return ERR_PTR(-EIO);
199 return (struct nfs_cache_array *)kmap(page); 201 ptr = kmap(page);
202 if (ptr == NULL)
203 return ERR_PTR(-ENOMEM);
204 return ptr;
200} 205}
201 206
202static 207static
@@ -209,14 +214,15 @@ void nfs_readdir_release_array(struct page *page)
209 * we are freeing strings created by nfs_add_to_readdir_array() 214 * we are freeing strings created by nfs_add_to_readdir_array()
210 */ 215 */
211static 216static
212int nfs_readdir_clear_array(struct page *page, gfp_t mask) 217void nfs_readdir_clear_array(struct page *page)
213{ 218{
214 struct nfs_cache_array *array = nfs_readdir_get_array(page); 219 struct nfs_cache_array *array;
215 int i; 220 int i;
221
222 array = kmap_atomic(page, KM_USER0);
216 for (i = 0; i < array->size; i++) 223 for (i = 0; i < array->size; i++)
217 kfree(array->array[i].string.name); 224 kfree(array->array[i].string.name);
218 nfs_readdir_release_array(page); 225 kunmap_atomic(array, KM_USER0);
219 return 0;
220} 226}
221 227
222/* 228/*
@@ -231,6 +237,11 @@ int nfs_readdir_make_qstr(struct qstr *string, const char *name, unsigned int le
231 string->name = kmemdup(name, len, GFP_KERNEL); 237 string->name = kmemdup(name, len, GFP_KERNEL);
232 if (string->name == NULL) 238 if (string->name == NULL)
233 return -ENOMEM; 239 return -ENOMEM;
240 /*
241 * Avoid a kmemleak false positive. The pointer to the name is stored
242 * in a page cache page which kmemleak does not scan.
243 */
244 kmemleak_not_leak(string->name);
234 string->hash = full_name_hash(name, len); 245 string->hash = full_name_hash(name, len);
235 return 0; 246 return 0;
236} 247}
@@ -244,20 +255,24 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
244 255
245 if (IS_ERR(array)) 256 if (IS_ERR(array))
246 return PTR_ERR(array); 257 return PTR_ERR(array);
247 ret = -EIO;
248 if (array->size >= MAX_READDIR_ARRAY)
249 goto out;
250 258
251 cache_entry = &array->array[array->size]; 259 cache_entry = &array->array[array->size];
260
261 /* Check that this entry lies within the page bounds */
262 ret = -ENOSPC;
263 if ((char *)&cache_entry[1] - (char *)page_address(page) > PAGE_SIZE)
264 goto out;
265
252 cache_entry->cookie = entry->prev_cookie; 266 cache_entry->cookie = entry->prev_cookie;
253 cache_entry->ino = entry->ino; 267 cache_entry->ino = entry->ino;
268 cache_entry->d_type = entry->d_type;
254 ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len); 269 ret = nfs_readdir_make_qstr(&cache_entry->string, entry->name, entry->len);
255 if (ret) 270 if (ret)
256 goto out; 271 goto out;
257 array->last_cookie = entry->cookie; 272 array->last_cookie = entry->cookie;
258 if (entry->eof == 1)
259 array->eof_index = array->size;
260 array->size++; 273 array->size++;
274 if (entry->eof != 0)
275 array->eof_index = array->size;
261out: 276out:
262 nfs_readdir_release_array(page); 277 nfs_readdir_release_array(page);
263 return ret; 278 return ret;
@@ -272,7 +287,7 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri
272 if (diff < 0) 287 if (diff < 0)
273 goto out_eof; 288 goto out_eof;
274 if (diff >= array->size) { 289 if (diff >= array->size) {
275 if (array->eof_index > 0) 290 if (array->eof_index >= 0)
276 goto out_eof; 291 goto out_eof;
277 desc->current_index += array->size; 292 desc->current_index += array->size;
278 return -EAGAIN; 293 return -EAGAIN;
@@ -281,8 +296,6 @@ int nfs_readdir_search_for_pos(struct nfs_cache_array *array, nfs_readdir_descri
281 index = (unsigned int)diff; 296 index = (unsigned int)diff;
282 *desc->dir_cookie = array->array[index].cookie; 297 *desc->dir_cookie = array->array[index].cookie;
283 desc->cache_entry_index = index; 298 desc->cache_entry_index = index;
284 if (index == array->eof_index)
285 desc->eof = 1;
286 return 0; 299 return 0;
287out_eof: 300out_eof:
288 desc->eof = 1; 301 desc->eof = 1;
@@ -296,17 +309,16 @@ int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_des
296 int status = -EAGAIN; 309 int status = -EAGAIN;
297 310
298 for (i = 0; i < array->size; i++) { 311 for (i = 0; i < array->size; i++) {
299 if (i == array->eof_index) {
300 desc->eof = 1;
301 status = -EBADCOOKIE;
302 }
303 if (array->array[i].cookie == *desc->dir_cookie) { 312 if (array->array[i].cookie == *desc->dir_cookie) {
304 desc->cache_entry_index = i; 313 desc->cache_entry_index = i;
305 status = 0; 314 return 0;
306 break;
307 } 315 }
308 } 316 }
309 317 if (array->eof_index >= 0) {
318 status = -EBADCOOKIE;
319 if (*desc->dir_cookie == array->last_cookie)
320 desc->eof = 1;
321 }
310 return status; 322 return status;
311} 323}
312 324
@@ -314,10 +326,7 @@ static
314int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) 326int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
315{ 327{
316 struct nfs_cache_array *array; 328 struct nfs_cache_array *array;
317 int status = -EBADCOOKIE; 329 int status;
318
319 if (desc->dir_cookie == NULL)
320 goto out;
321 330
322 array = nfs_readdir_get_array(desc->page); 331 array = nfs_readdir_get_array(desc->page);
323 if (IS_ERR(array)) { 332 if (IS_ERR(array)) {
@@ -330,6 +339,10 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc)
330 else 339 else
331 status = nfs_readdir_search_for_cookie(array, desc); 340 status = nfs_readdir_search_for_cookie(array, desc);
332 341
342 if (status == -EAGAIN) {
343 desc->last_cookie = array->last_cookie;
344 desc->page_index++;
345 }
333 nfs_readdir_release_array(desc->page); 346 nfs_readdir_release_array(desc->page);
334out: 347out:
335 return status; 348 return status;
@@ -381,13 +394,9 @@ int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct x
381static 394static
382int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry) 395int nfs_same_file(struct dentry *dentry, struct nfs_entry *entry)
383{ 396{
384 struct nfs_inode *node;
385 if (dentry->d_inode == NULL) 397 if (dentry->d_inode == NULL)
386 goto different; 398 goto different;
387 node = NFS_I(dentry->d_inode); 399 if (nfs_compare_fh(entry->fh, NFS_FH(dentry->d_inode)) != 0)
388 if (node->fh.size != entry->fh->size)
389 goto different;
390 if (strncmp(node->fh.data, entry->fh->data, node->fh.size) != 0)
391 goto different; 400 goto different;
392 return 1; 401 return 1;
393different: 402different:
@@ -449,14 +458,15 @@ out:
449 458
450/* Perform conversion from xdr to cache array */ 459/* Perform conversion from xdr to cache array */
451static 460static
452void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, 461int nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry,
453 void *xdr_page, struct page *page, unsigned int buflen) 462 void *xdr_page, struct page *page, unsigned int buflen)
454{ 463{
455 struct xdr_stream stream; 464 struct xdr_stream stream;
456 struct xdr_buf buf; 465 struct xdr_buf buf;
457 __be32 *ptr = xdr_page; 466 __be32 *ptr = xdr_page;
458 int status;
459 struct nfs_cache_array *array; 467 struct nfs_cache_array *array;
468 unsigned int count = 0;
469 int status;
460 470
461 buf.head->iov_base = xdr_page; 471 buf.head->iov_base = xdr_page;
462 buf.head->iov_len = buflen; 472 buf.head->iov_len = buflen;
@@ -471,21 +481,32 @@ void nfs_readdir_page_filler(nfs_readdir_descriptor_t *desc, struct nfs_entry *e
471 481
472 do { 482 do {
473 status = xdr_decode(desc, entry, &stream); 483 status = xdr_decode(desc, entry, &stream);
474 if (status != 0) 484 if (status != 0) {
485 if (status == -EAGAIN)
486 status = 0;
475 break; 487 break;
488 }
476 489
477 if (nfs_readdir_add_to_array(entry, page) == -1) 490 count++;
478 break; 491
479 if (desc->plus == 1) 492 if (desc->plus != 0)
480 nfs_prime_dcache(desc->file->f_path.dentry, entry); 493 nfs_prime_dcache(desc->file->f_path.dentry, entry);
494
495 status = nfs_readdir_add_to_array(entry, page);
496 if (status != 0)
497 break;
481 } while (!entry->eof); 498 } while (!entry->eof);
482 499
483 if (status == -EBADCOOKIE && entry->eof) { 500 if (count == 0 || (status == -EBADCOOKIE && entry->eof != 0)) {
484 array = nfs_readdir_get_array(page); 501 array = nfs_readdir_get_array(page);
485 array->eof_index = array->size - 1; 502 if (!IS_ERR(array)) {
486 status = 0; 503 array->eof_index = array->size;
487 nfs_readdir_release_array(page); 504 status = 0;
505 nfs_readdir_release_array(page);
506 } else
507 status = PTR_ERR(array);
488 } 508 }
509 return status;
489} 510}
490 511
491static 512static
@@ -537,11 +558,11 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
537 struct nfs_entry entry; 558 struct nfs_entry entry;
538 struct file *file = desc->file; 559 struct file *file = desc->file;
539 struct nfs_cache_array *array; 560 struct nfs_cache_array *array;
540 int status = 0; 561 int status = -ENOMEM;
541 unsigned int array_size = ARRAY_SIZE(pages); 562 unsigned int array_size = ARRAY_SIZE(pages);
542 563
543 entry.prev_cookie = 0; 564 entry.prev_cookie = 0;
544 entry.cookie = *desc->dir_cookie; 565 entry.cookie = desc->last_cookie;
545 entry.eof = 0; 566 entry.eof = 0;
546 entry.fh = nfs_alloc_fhandle(); 567 entry.fh = nfs_alloc_fhandle();
547 entry.fattr = nfs_alloc_fattr(); 568 entry.fattr = nfs_alloc_fattr();
@@ -549,6 +570,10 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
549 goto out; 570 goto out;
550 571
551 array = nfs_readdir_get_array(page); 572 array = nfs_readdir_get_array(page);
573 if (IS_ERR(array)) {
574 status = PTR_ERR(array);
575 goto out;
576 }
552 memset(array, 0, sizeof(struct nfs_cache_array)); 577 memset(array, 0, sizeof(struct nfs_cache_array));
553 array->eof_index = -1; 578 array->eof_index = -1;
554 579
@@ -556,12 +581,19 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page,
556 if (!pages_ptr) 581 if (!pages_ptr)
557 goto out_release_array; 582 goto out_release_array;
558 do { 583 do {
584 unsigned int pglen;
559 status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode); 585 status = nfs_readdir_xdr_filler(pages, desc, &entry, file, inode);
560 586
561 if (status < 0) 587 if (status < 0)
562 break; 588 break;
563 nfs_readdir_page_filler(desc, &entry, pages_ptr, page, array_size * PAGE_SIZE); 589 pglen = status;
564 } while (array->eof_index < 0 && array->size < MAX_READDIR_ARRAY); 590 status = nfs_readdir_page_filler(desc, &entry, pages_ptr, page, pglen);
591 if (status < 0) {
592 if (status == -ENOSPC)
593 status = 0;
594 break;
595 }
596 } while (array->eof_index < 0);
565 597
566 nfs_readdir_free_large_page(pages_ptr, pages, array_size); 598 nfs_readdir_free_large_page(pages_ptr, pages, array_size);
567out_release_array: 599out_release_array:
@@ -582,8 +614,10 @@ static
582int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) 614int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
583{ 615{
584 struct inode *inode = desc->file->f_path.dentry->d_inode; 616 struct inode *inode = desc->file->f_path.dentry->d_inode;
617 int ret;
585 618
586 if (nfs_readdir_xdr_to_array(desc, page, inode) < 0) 619 ret = nfs_readdir_xdr_to_array(desc, page, inode);
620 if (ret < 0)
587 goto error; 621 goto error;
588 SetPageUptodate(page); 622 SetPageUptodate(page);
589 623
@@ -595,12 +629,14 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page)
595 return 0; 629 return 0;
596 error: 630 error:
597 unlock_page(page); 631 unlock_page(page);
598 return -EIO; 632 return ret;
599} 633}
600 634
601static 635static
602void cache_page_release(nfs_readdir_descriptor_t *desc) 636void cache_page_release(nfs_readdir_descriptor_t *desc)
603{ 637{
638 if (!desc->page->mapping)
639 nfs_readdir_clear_array(desc->page);
604 page_cache_release(desc->page); 640 page_cache_release(desc->page);
605 desc->page = NULL; 641 desc->page = NULL;
606} 642}
@@ -608,12 +644,8 @@ void cache_page_release(nfs_readdir_descriptor_t *desc)
608static 644static
609struct page *get_cache_page(nfs_readdir_descriptor_t *desc) 645struct page *get_cache_page(nfs_readdir_descriptor_t *desc)
610{ 646{
611 struct page *page; 647 return read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping,
612 page = read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping,
613 desc->page_index, (filler_t *)nfs_readdir_filler, desc); 648 desc->page_index, (filler_t *)nfs_readdir_filler, desc);
614 if (IS_ERR(page))
615 desc->eof = 1;
616 return page;
617} 649}
618 650
619/* 651/*
@@ -629,9 +661,8 @@ int find_cache_page(nfs_readdir_descriptor_t *desc)
629 return PTR_ERR(desc->page); 661 return PTR_ERR(desc->page);
630 662
631 res = nfs_readdir_search_array(desc); 663 res = nfs_readdir_search_array(desc);
632 if (res == 0) 664 if (res != 0)
633 return 0; 665 cache_page_release(desc);
634 cache_page_release(desc);
635 return res; 666 return res;
636} 667}
637 668
@@ -639,22 +670,18 @@ int find_cache_page(nfs_readdir_descriptor_t *desc)
639static inline 670static inline
640int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) 671int readdir_search_pagecache(nfs_readdir_descriptor_t *desc)
641{ 672{
642 int res = -EAGAIN; 673 int res;
643 674
644 while (1) { 675 if (desc->page_index == 0) {
645 res = find_cache_page(desc); 676 desc->current_index = 0;
646 if (res != -EAGAIN) 677 desc->last_cookie = 0;
647 break;
648 desc->page_index++;
649 } 678 }
679 do {
680 res = find_cache_page(desc);
681 } while (res == -EAGAIN);
650 return res; 682 return res;
651} 683}
652 684
653static inline unsigned int dt_type(struct inode *inode)
654{
655 return (inode->i_mode >> 12) & 15;
656}
657
658/* 685/*
659 * Once we've found the start of the dirent within a page: fill 'er up... 686 * Once we've found the start of the dirent within a page: fill 'er up...
660 */ 687 */
@@ -666,35 +693,35 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent,
666 int i = 0; 693 int i = 0;
667 int res = 0; 694 int res = 0;
668 struct nfs_cache_array *array = NULL; 695 struct nfs_cache_array *array = NULL;
669 unsigned int d_type = DT_UNKNOWN;
670 struct dentry *dentry = NULL;
671 696
672 array = nfs_readdir_get_array(desc->page); 697 array = nfs_readdir_get_array(desc->page);
698 if (IS_ERR(array)) {
699 res = PTR_ERR(array);
700 goto out;
701 }
673 702
674 for (i = desc->cache_entry_index; i < array->size; i++) { 703 for (i = desc->cache_entry_index; i < array->size; i++) {
675 d_type = DT_UNKNOWN; 704 struct nfs_cache_array_entry *ent;
676 705
677 res = filldir(dirent, array->array[i].string.name, 706 ent = &array->array[i];
678 array->array[i].string.len, file->f_pos, 707 if (filldir(dirent, ent->string.name, ent->string.len,
679 nfs_compat_user_ino64(array->array[i].ino), d_type); 708 file->f_pos, nfs_compat_user_ino64(ent->ino),
680 if (res < 0) 709 ent->d_type) < 0) {
710 desc->eof = 1;
681 break; 711 break;
712 }
682 file->f_pos++; 713 file->f_pos++;
683 desc->cache_entry_index = i;
684 if (i < (array->size-1)) 714 if (i < (array->size-1))
685 *desc->dir_cookie = array->array[i+1].cookie; 715 *desc->dir_cookie = array->array[i+1].cookie;
686 else 716 else
687 *desc->dir_cookie = array->last_cookie; 717 *desc->dir_cookie = array->last_cookie;
688 if (i == array->eof_index) {
689 desc->eof = 1;
690 break;
691 }
692 } 718 }
719 if (array->eof_index >= 0)
720 desc->eof = 1;
693 721
694 nfs_readdir_release_array(desc->page); 722 nfs_readdir_release_array(desc->page);
723out:
695 cache_page_release(desc); 724 cache_page_release(desc);
696 if (dentry != NULL)
697 dput(dentry);
698 dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n", 725 dfprintk(DIRCACHE, "NFS: nfs_do_filldir() filling ended @ cookie %Lu; returning = %d\n",
699 (unsigned long long)*desc->dir_cookie, res); 726 (unsigned long long)*desc->dir_cookie, res);
700 return res; 727 return res;
@@ -729,13 +756,14 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
729 goto out; 756 goto out;
730 } 757 }
731 758
732 if (nfs_readdir_xdr_to_array(desc, page, inode) == -1) {
733 status = -EIO;
734 goto out_release;
735 }
736
737 desc->page_index = 0; 759 desc->page_index = 0;
760 desc->last_cookie = *desc->dir_cookie;
738 desc->page = page; 761 desc->page = page;
762
763 status = nfs_readdir_xdr_to_array(desc, page, inode);
764 if (status < 0)
765 goto out_release;
766
739 status = nfs_do_filldir(desc, dirent, filldir); 767 status = nfs_do_filldir(desc, dirent, filldir);
740 768
741 out: 769 out:
@@ -757,7 +785,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
757 struct inode *inode = dentry->d_inode; 785 struct inode *inode = dentry->d_inode;
758 nfs_readdir_descriptor_t my_desc, 786 nfs_readdir_descriptor_t my_desc,
759 *desc = &my_desc; 787 *desc = &my_desc;
760 int res = -ENOMEM; 788 int res;
761 789
762 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", 790 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
763 dentry->d_parent->d_name.name, dentry->d_name.name, 791 dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -782,18 +810,18 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
782 if (res < 0) 810 if (res < 0)
783 goto out; 811 goto out;
784 812
785 while (desc->eof != 1) { 813 do {
786 res = readdir_search_pagecache(desc); 814 res = readdir_search_pagecache(desc);
787 815
788 if (res == -EBADCOOKIE) { 816 if (res == -EBADCOOKIE) {
817 res = 0;
789 /* This means either end of directory */ 818 /* This means either end of directory */
790 if (*desc->dir_cookie && desc->eof == 0) { 819 if (*desc->dir_cookie && desc->eof == 0) {
791 /* Or that the server has 'lost' a cookie */ 820 /* Or that the server has 'lost' a cookie */
792 res = uncached_readdir(desc, dirent, filldir); 821 res = uncached_readdir(desc, dirent, filldir);
793 if (res >= 0) 822 if (res == 0)
794 continue; 823 continue;
795 } 824 }
796 res = 0;
797 break; 825 break;
798 } 826 }
799 if (res == -ETOOSMALL && desc->plus) { 827 if (res == -ETOOSMALL && desc->plus) {
@@ -808,11 +836,9 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
808 break; 836 break;
809 837
810 res = nfs_do_filldir(desc, dirent, filldir); 838 res = nfs_do_filldir(desc, dirent, filldir);
811 if (res < 0) { 839 if (res < 0)
812 res = 0;
813 break; 840 break;
814 } 841 } while (!desc->eof);
815 }
816out: 842out:
817 nfs_unblock_sillyrename(dentry); 843 nfs_unblock_sillyrename(dentry);
818 if (res > 0) 844 if (res > 0)
@@ -1345,12 +1371,12 @@ static struct dentry *nfs_atomic_lookup(struct inode *dir, struct dentry *dentry
1345 res = NULL; 1371 res = NULL;
1346 goto out; 1372 goto out;
1347 /* This turned out not to be a regular file */ 1373 /* This turned out not to be a regular file */
1348 case -EISDIR:
1349 case -ENOTDIR: 1374 case -ENOTDIR:
1350 goto no_open; 1375 goto no_open;
1351 case -ELOOP: 1376 case -ELOOP:
1352 if (!(nd->intent.open.flags & O_NOFOLLOW)) 1377 if (!(nd->intent.open.flags & O_NOFOLLOW))
1353 goto no_open; 1378 goto no_open;
1379 /* case -EISDIR: */
1354 /* case -EINVAL: */ 1380 /* case -EINVAL: */
1355 default: 1381 default:
1356 res = ERR_CAST(inode); 1382 res = ERR_CAST(inode);