Commit 9fff59ed authored by Trond Myklebust's avatar Trond Myklebust

NFS: Handle NFS4ERR_NOT_SAME and NFSERR_BADCOOKIE from readdir calls

If the server returns NFS4ERR_NOT_SAME or tells us that the cookie is
bad in response to a READDIR call, then we should empty the page cache
so that we can fill it from scratch again.
Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
Reviewed-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Tested-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Tested-by: default avatarDave Wysochanski <dwysocha@redhat.com>
parent 82e22a5e
...@@ -861,15 +861,21 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc) ...@@ -861,15 +861,21 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)
return -ENOMEM; return -ENOMEM;
if (nfs_readdir_page_needs_filling(desc->page)) { if (nfs_readdir_page_needs_filling(desc->page)) {
res = nfs_readdir_xdr_to_array(desc, desc->page, inode); res = nfs_readdir_xdr_to_array(desc, desc->page, inode);
if (res < 0) if (res < 0) {
goto error; nfs_readdir_page_unlock_and_put_cached(desc);
if (res == -EBADCOOKIE || res == -ENOTSYNC) {
invalidate_inode_pages2(desc->file->f_mapping);
desc->page_index = 0;
return -EAGAIN;
}
return res;
}
} }
res = nfs_readdir_search_array(desc); res = nfs_readdir_search_array(desc);
if (res == 0) { if (res == 0) {
nfsi->page_index = desc->page_index; nfsi->page_index = desc->page_index;
return 0; return 0;
} }
error:
nfs_readdir_page_unlock_and_put_cached(desc); nfs_readdir_page_unlock_and_put_cached(desc);
return res; return res;
} }
...@@ -879,12 +885,12 @@ static int readdir_search_pagecache(struct nfs_readdir_descriptor *desc) ...@@ -879,12 +885,12 @@ static int readdir_search_pagecache(struct nfs_readdir_descriptor *desc)
{ {
int res; int res;
if (desc->page_index == 0) {
desc->current_index = 0;
desc->prev_index = 0;
desc->last_cookie = 0;
}
do { do {
if (desc->page_index == 0) {
desc->current_index = 0;
desc->prev_index = 0;
desc->last_cookie = 0;
}
res = find_and_lock_cache_page(desc); res = find_and_lock_cache_page(desc);
} while (res == -EAGAIN); } while (res == -EAGAIN);
return res; return res;
...@@ -1030,6 +1036,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1030,6 +1036,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
res = uncached_readdir(desc); res = uncached_readdir(desc);
if (res == 0) if (res == 0)
continue; continue;
if (res == -EBADCOOKIE || res == -ENOTSYNC)
res = 0;
} }
break; break;
} }
......
...@@ -184,6 +184,8 @@ static int nfs4_map_errors(int err) ...@@ -184,6 +184,8 @@ static int nfs4_map_errors(int err)
return -EPROTONOSUPPORT; return -EPROTONOSUPPORT;
case -NFS4ERR_FILE_OPEN: case -NFS4ERR_FILE_OPEN:
return -EBUSY; return -EBUSY;
case -NFS4ERR_NOT_SAME:
return -ENOTSYNC;
default: default:
dprintk("%s could not handle NFSv4 error %d\n", dprintk("%s could not handle NFSv4 error %d\n",
__func__, -err); __func__, -err);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment