NFS: Don't advance the page pointer unless the page is full
authorTrond Myklebust <trond.myklebust@hammerspace.com>
Sat, 26 Feb 2022 14:38:19 +0000 (09:38 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Wed, 2 Mar 2022 13:43:38 +0000 (08:43 -0500)
When we hit the end of the data in the readdir page, we don't want to
start filling a new page, unless this one is full.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/dir.c

index 93f7069..60f7fee 100644 (file)
@@ -417,6 +417,18 @@ bool nfs_readdir_use_cookie(const struct file *filp)
        return true;
 }
 
+static void nfs_readdir_seek_next_array(struct nfs_cache_array *array,
+                                       struct nfs_readdir_descriptor *desc)
+{
+       if (array->page_full) {
+               desc->last_cookie = array->last_cookie;
+               desc->current_index += array->size;
+               desc->cache_entry_index = 0;
+               desc->page_index++;
+       } else
+               desc->last_cookie = array->array[0].cookie;
+}
+
 static int nfs_readdir_search_for_pos(struct nfs_cache_array *array,
                                      struct nfs_readdir_descriptor *desc)
 {
@@ -428,6 +440,7 @@ static int nfs_readdir_search_for_pos(struct nfs_cache_array *array,
        if (diff >= array->size) {
                if (array->page_is_eof)
                        goto out_eof;
+               nfs_readdir_seek_next_array(array, desc);
                return -EAGAIN;
        }
 
@@ -500,7 +513,8 @@ check_eof:
                status = -EBADCOOKIE;
                if (desc->dir_cookie == array->last_cookie)
                        desc->eof = true;
-       }
+       } else
+               nfs_readdir_seek_next_array(array, desc);
 out:
        return status;
 }
@@ -517,11 +531,6 @@ static int nfs_readdir_search_array(struct nfs_readdir_descriptor *desc)
        else
                status = nfs_readdir_search_for_cookie(array, desc);
 
-       if (status == -EAGAIN) {
-               desc->last_cookie = array->last_cookie;
-               desc->current_index += array->size;
-               desc->page_index++;
-       }
        kunmap_atomic(array);
        return status;
 }
@@ -998,7 +1007,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
 {
        struct file     *file = desc->file;
        struct nfs_cache_array *array;
-       unsigned int i = 0;
+       unsigned int i;
 
        array = kmap(desc->page);
        for (i = desc->cache_entry_index; i < array->size; i++) {
@@ -1011,10 +1020,13 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
                        break;
                }
                memcpy(desc->verf, verf, sizeof(desc->verf));
-               if (i < (array->size-1))
-                       desc->dir_cookie = array->array[i+1].cookie;
-               else
+               if (i == array->size - 1) {
                        desc->dir_cookie = array->last_cookie;
+                       nfs_readdir_seek_next_array(array, desc);
+               } else {
+                       desc->dir_cookie = array->array[i + 1].cookie;
+                       desc->last_cookie = array->array[0].cookie;
+               }
                if (nfs_readdir_use_cookie(file))
                        desc->ctx->pos = desc->dir_cookie;
                else