diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-11-30 21:56:32 -0500 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2010-12-01 08:16:16 -0500 |
commit | 0aded708d125a3ff7e5abaea9c2d9c6d7ebbfdcd (patch) | |
tree | 124bb3e0e1cd8104f9310f7df224ca00301c10c7 /fs/nfs/dir.c | |
parent | 22a5b566c8c442b0b35b3b106795e2f2b3578096 (diff) |
NFS: Ensure we use the correct cookie in nfs_readdir_xdr_filler
We need to use the cookie from the previous array entry, not the
actual cookie that we are searching for (except for the case of
uncached_readdir).
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r-- | fs/nfs/dir.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f0a384e2ae63..e03537ff9350 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -178,6 +178,7 @@ typedef struct { | |||
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 | ||
@@ -344,6 +345,8 @@ int nfs_readdir_search_array(nfs_readdir_descriptor_t *desc) | |||
344 | else | 345 | else |
345 | status = nfs_readdir_search_for_cookie(array, desc); | 346 | status = nfs_readdir_search_for_cookie(array, desc); |
346 | 347 | ||
348 | if (status == -EAGAIN) | ||
349 | desc->last_cookie = array->last_cookie; | ||
347 | nfs_readdir_release_array(desc->page); | 350 | nfs_readdir_release_array(desc->page); |
348 | out: | 351 | out: |
349 | return status; | 352 | return status; |
@@ -563,7 +566,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, | |||
563 | unsigned int array_size = ARRAY_SIZE(pages); | 566 | unsigned int array_size = ARRAY_SIZE(pages); |
564 | 567 | ||
565 | entry.prev_cookie = 0; | 568 | entry.prev_cookie = 0; |
566 | entry.cookie = *desc->dir_cookie; | 569 | entry.cookie = desc->last_cookie; |
567 | entry.eof = 0; | 570 | entry.eof = 0; |
568 | entry.fh = nfs_alloc_fhandle(); | 571 | entry.fh = nfs_alloc_fhandle(); |
569 | entry.fattr = nfs_alloc_fattr(); | 572 | entry.fattr = nfs_alloc_fattr(); |
@@ -672,8 +675,10 @@ int readdir_search_pagecache(nfs_readdir_descriptor_t *desc) | |||
672 | { | 675 | { |
673 | int res; | 676 | int res; |
674 | 677 | ||
675 | if (desc->page_index == 0) | 678 | if (desc->page_index == 0) { |
676 | desc->current_index = 0; | 679 | desc->current_index = 0; |
680 | desc->last_cookie = 0; | ||
681 | } | ||
677 | while (1) { | 682 | while (1) { |
678 | res = find_cache_page(desc); | 683 | res = find_cache_page(desc); |
679 | if (res != -EAGAIN) | 684 | if (res != -EAGAIN) |
@@ -764,6 +769,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, | |||
764 | } | 769 | } |
765 | 770 | ||
766 | desc->page_index = 0; | 771 | desc->page_index = 0; |
772 | desc->last_cookie = *desc->dir_cookie; | ||
767 | desc->page = page; | 773 | desc->page = page; |
768 | 774 | ||
769 | status = nfs_readdir_xdr_to_array(desc, page, inode); | 775 | status = nfs_readdir_xdr_to_array(desc, page, inode); |