Skip to content

Commit 762567b

Browse files
author
Trond Myklebust
committed
NFS: Optimisations for monotonically increasing readdir cookies
If the server is handing out monotonically increasing readdir cookie values, then we can optimise away searches through pages that contain cookies that lie outside our search range. Signed-off-by: Trond Myklebust <[email protected]> Reviewed-by: Benjamin Coddington <[email protected]> Tested-by: Benjamin Coddington <[email protected]> Tested-by: Dave Wysochanski <[email protected]>
1 parent b593c09 commit 762567b

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

fs/nfs/dir.c

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,8 @@ struct nfs_cache_array {
140140
u64 last_cookie;
141141
unsigned int size;
142142
unsigned char page_full : 1,
143-
page_is_eof : 1;
143+
page_is_eof : 1,
144+
cookies_are_ordered : 1;
144145
struct nfs_cache_array_entry array[];
145146
};
146147

@@ -178,6 +179,7 @@ static void nfs_readdir_page_init_array(struct page *page, u64 last_cookie)
178179
array = kmap_atomic(page);
179180
nfs_readdir_array_init(array);
180181
array->last_cookie = last_cookie;
182+
array->cookies_are_ordered = 1;
181183
kunmap_atomic(array);
182184
}
183185

@@ -269,6 +271,8 @@ int nfs_readdir_add_to_array(struct nfs_entry *entry, struct page *page)
269271
cache_entry->name_len = entry->len;
270272
cache_entry->name = name;
271273
array->last_cookie = entry->cookie;
274+
if (array->last_cookie <= cache_entry->cookie)
275+
array->cookies_are_ordered = 0;
272276
array->size++;
273277
if (entry->eof != 0)
274278
nfs_readdir_array_set_eof(array);
@@ -395,13 +399,29 @@ nfs_readdir_inode_mapping_valid(struct nfs_inode *nfsi)
395399
return !test_bit(NFS_INO_INVALIDATING, &nfsi->flags);
396400
}
397401

402+
static bool nfs_readdir_array_cookie_in_range(struct nfs_cache_array *array,
403+
u64 cookie)
404+
{
405+
if (!array->cookies_are_ordered)
406+
return true;
407+
/* Optimisation for monotonically increasing cookies */
408+
if (cookie >= array->last_cookie)
409+
return false;
410+
if (array->size && cookie < array->array[0].cookie)
411+
return false;
412+
return true;
413+
}
414+
398415
static int nfs_readdir_search_for_cookie(struct nfs_cache_array *array,
399416
struct nfs_readdir_descriptor *desc)
400417
{
401418
int i;
402419
loff_t new_pos;
403420
int status = -EAGAIN;
404421

422+
if (!nfs_readdir_array_cookie_in_range(array, desc->dir_cookie))
423+
goto check_eof;
424+
405425
for (i = 0; i < array->size; i++) {
406426
if (array->array[i].cookie == desc->dir_cookie) {
407427
struct nfs_inode *nfsi = NFS_I(file_inode(desc->file));
@@ -435,6 +455,7 @@ static int nfs_readdir_search_for_cookie(struct nfs_cache_array *array,
435455
return 0;
436456
}
437457
}
458+
check_eof:
438459
if (array->page_is_eof) {
439460
status = -EBADCOOKIE;
440461
if (desc->dir_cookie == array->last_cookie)

0 commit comments

Comments
 (0)