Commit 61f02e0a authored by Anna Schumaker's avatar Anna Schumaker

NFS: Convert the readdir array-of-pages into an array-of-folios

This patch only converts the actual array, but doesn't touch the
individual nfs_cache_array pages and related functions (that will be
done in the next patch).

I also adjust the names of the fields in the nfs_readdir_descriptor to
say "folio" instead of "page".
Signed-off-by: default avatarAnna Schumaker <Anna.Schumaker@Netapp.com>
parent 3db63daa
...@@ -154,10 +154,10 @@ struct nfs_cache_array { ...@@ -154,10 +154,10 @@ struct nfs_cache_array {
struct nfs_readdir_descriptor { struct nfs_readdir_descriptor {
struct file *file; struct file *file;
struct page *page; struct folio *folio;
struct dir_context *ctx; struct dir_context *ctx;
pgoff_t page_index; pgoff_t folio_index;
pgoff_t page_index_max; pgoff_t folio_index_max;
u64 dir_cookie; u64 dir_cookie;
u64 last_cookie; u64 last_cookie;
loff_t current_index; loff_t current_index;
...@@ -312,8 +312,8 @@ static int nfs_readdir_array_can_expand(struct nfs_cache_array *array) ...@@ -312,8 +312,8 @@ static int nfs_readdir_array_can_expand(struct nfs_cache_array *array)
} }
static int nfs_readdir_page_array_append(struct page *page, static int nfs_readdir_page_array_append(struct page *page,
const struct nfs_entry *entry, const struct nfs_entry *entry,
u64 *cookie) u64 *cookie)
{ {
struct nfs_cache_array *array; struct nfs_cache_array *array;
struct nfs_cache_array_entry *cache_entry; struct nfs_cache_array_entry *cache_entry;
...@@ -485,7 +485,7 @@ static void nfs_readdir_seek_next_array(struct nfs_cache_array *array, ...@@ -485,7 +485,7 @@ static void nfs_readdir_seek_next_array(struct nfs_cache_array *array,
desc->last_cookie = array->last_cookie; desc->last_cookie = array->last_cookie;
desc->current_index += array->size; desc->current_index += array->size;
desc->cache_entry_index = 0; desc->cache_entry_index = 0;
desc->page_index++; desc->folio_index++;
} else } else
desc->last_cookie = nfs_readdir_array_index_cookie(array); desc->last_cookie = nfs_readdir_array_index_cookie(array);
} }
...@@ -494,7 +494,7 @@ static void nfs_readdir_rewind_search(struct nfs_readdir_descriptor *desc) ...@@ -494,7 +494,7 @@ static void nfs_readdir_rewind_search(struct nfs_readdir_descriptor *desc)
{ {
desc->current_index = 0; desc->current_index = 0;
desc->last_cookie = 0; desc->last_cookie = 0;
desc->page_index = 0; desc->folio_index = 0;
} }
static int nfs_readdir_search_for_pos(struct nfs_cache_array *array, static int nfs_readdir_search_for_pos(struct nfs_cache_array *array,
...@@ -568,7 +568,7 @@ static int nfs_readdir_search_array(struct nfs_readdir_descriptor *desc) ...@@ -568,7 +568,7 @@ static int nfs_readdir_search_array(struct nfs_readdir_descriptor *desc)
struct nfs_cache_array *array; struct nfs_cache_array *array;
int status; int status;
array = kmap_local_page(desc->page); array = kmap_local_folio(desc->folio, 0);
if (desc->dir_cookie == 0) if (desc->dir_cookie == 0)
status = nfs_readdir_search_for_pos(array, desc); status = nfs_readdir_search_for_pos(array, desc);
...@@ -819,16 +819,17 @@ static int nfs_readdir_entry_decode(struct nfs_readdir_descriptor *desc, ...@@ -819,16 +819,17 @@ static int nfs_readdir_entry_decode(struct nfs_readdir_descriptor *desc,
} }
/* Perform conversion from xdr to cache array */ /* Perform conversion from xdr to cache array */
static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc, static int nfs_readdir_folio_filler(struct nfs_readdir_descriptor *desc,
struct nfs_entry *entry, struct nfs_entry *entry,
struct page **xdr_pages, unsigned int buflen, struct page **xdr_pages, unsigned int buflen,
struct page **arrays, size_t narrays, struct folio **arrays, size_t narrays,
u64 change_attr) u64 change_attr)
{ {
struct address_space *mapping = desc->file->f_mapping; struct address_space *mapping = desc->file->f_mapping;
struct folio *folio = *arrays;
struct xdr_stream stream; struct xdr_stream stream;
struct page *scratch, *new;
struct xdr_buf buf; struct xdr_buf buf;
struct page *scratch, *new, *page = *arrays;
u64 cookie; u64 cookie;
int status; int status;
...@@ -844,36 +845,36 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc, ...@@ -844,36 +845,36 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc,
if (status != 0) if (status != 0)
break; break;
status = nfs_readdir_page_array_append(page, entry, &cookie); status = nfs_readdir_page_array_append(folio_page(folio, 0), entry, &cookie);
if (status != -ENOSPC) if (status != -ENOSPC)
continue; continue;
if (page->mapping != mapping) { if (folio->mapping != mapping) {
if (!--narrays) if (!--narrays)
break; break;
new = nfs_readdir_page_array_alloc(cookie, GFP_KERNEL); new = nfs_readdir_page_array_alloc(cookie, GFP_KERNEL);
if (!new) if (!new)
break; break;
arrays++; arrays++;
*arrays = page = new; *arrays = folio = page_folio(new);
} else { } else {
new = nfs_readdir_page_get_next(mapping, cookie, new = nfs_readdir_page_get_next(mapping, cookie,
change_attr); change_attr);
if (!new) if (!new)
break; break;
if (page != *arrays) if (folio != *arrays)
nfs_readdir_page_unlock_and_put(page); nfs_readdir_page_unlock_and_put(folio_page(folio, 0));
page = new; folio = page_folio(new);
} }
desc->page_index_max++; desc->folio_index_max++;
status = nfs_readdir_page_array_append(page, entry, &cookie); status = nfs_readdir_page_array_append(folio_page(folio, 0), entry, &cookie);
} while (!status && !entry->eof); } while (!status && !entry->eof);
switch (status) { switch (status) {
case -EBADCOOKIE: case -EBADCOOKIE:
if (!entry->eof) if (!entry->eof)
break; break;
nfs_readdir_page_set_eof(page); nfs_readdir_page_set_eof(folio_page(folio, 0));
fallthrough; fallthrough;
case -EAGAIN: case -EAGAIN:
status = 0; status = 0;
...@@ -886,8 +887,8 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc, ...@@ -886,8 +887,8 @@ static int nfs_readdir_page_filler(struct nfs_readdir_descriptor *desc,
; ;
} }
if (page != *arrays) if (folio != *arrays)
nfs_readdir_page_unlock_and_put(page); nfs_readdir_page_unlock_and_put(folio_page(folio, 0));
put_page(scratch); put_page(scratch);
return status; return status;
...@@ -927,11 +928,11 @@ static struct page **nfs_readdir_alloc_pages(size_t npages) ...@@ -927,11 +928,11 @@ static struct page **nfs_readdir_alloc_pages(size_t npages)
static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc, static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
__be32 *verf_arg, __be32 *verf_res, __be32 *verf_arg, __be32 *verf_res,
struct page **arrays, size_t narrays) struct folio **arrays, size_t narrays)
{ {
u64 change_attr; u64 change_attr;
struct page **pages; struct page **pages;
struct page *page = *arrays; struct folio *folio = *arrays;
struct nfs_entry *entry; struct nfs_entry *entry;
size_t array_size; size_t array_size;
struct inode *inode = file_inode(desc->file); struct inode *inode = file_inode(desc->file);
...@@ -942,7 +943,7 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc, ...@@ -942,7 +943,7 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
entry = kzalloc(sizeof(*entry), GFP_KERNEL); entry = kzalloc(sizeof(*entry), GFP_KERNEL);
if (!entry) if (!entry)
return -ENOMEM; return -ENOMEM;
entry->cookie = nfs_readdir_page_last_cookie(page); entry->cookie = nfs_readdir_page_last_cookie(folio_page(folio, 0));
entry->fh = nfs_alloc_fhandle(); entry->fh = nfs_alloc_fhandle();
entry->fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode)); entry->fattr = nfs_alloc_fattr_with_label(NFS_SERVER(inode));
entry->server = NFS_SERVER(inode); entry->server = NFS_SERVER(inode);
...@@ -962,10 +963,10 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc, ...@@ -962,10 +963,10 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
pglen = status; pglen = status;
if (pglen != 0) if (pglen != 0)
status = nfs_readdir_page_filler(desc, entry, pages, pglen, status = nfs_readdir_folio_filler(desc, entry, pages, pglen,
arrays, narrays, change_attr); arrays, narrays, change_attr);
else else
nfs_readdir_page_set_eof(page); nfs_readdir_page_set_eof(folio_page(folio, 0));
desc->buffer_fills++; desc->buffer_fills++;
free_pages: free_pages:
...@@ -977,21 +978,21 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc, ...@@ -977,21 +978,21 @@ static int nfs_readdir_xdr_to_array(struct nfs_readdir_descriptor *desc,
return status; return status;
} }
static void nfs_readdir_page_put(struct nfs_readdir_descriptor *desc) static void nfs_readdir_folio_put(struct nfs_readdir_descriptor *desc)
{ {
put_page(desc->page); folio_put(desc->folio);
desc->page = NULL; desc->folio = NULL;
} }
static void static void
nfs_readdir_page_unlock_and_put_cached(struct nfs_readdir_descriptor *desc) nfs_readdir_folio_unlock_and_put_cached(struct nfs_readdir_descriptor *desc)
{ {
unlock_page(desc->page); folio_unlock(desc->folio);
nfs_readdir_page_put(desc); nfs_readdir_folio_put(desc);
} }
static struct page * static struct folio *
nfs_readdir_page_get_cached(struct nfs_readdir_descriptor *desc) nfs_readdir_folio_get_cached(struct nfs_readdir_descriptor *desc)
{ {
struct address_space *mapping = desc->file->f_mapping; struct address_space *mapping = desc->file->f_mapping;
u64 change_attr = inode_peek_iversion_raw(mapping->host); u64 change_attr = inode_peek_iversion_raw(mapping->host);
...@@ -1003,7 +1004,7 @@ nfs_readdir_page_get_cached(struct nfs_readdir_descriptor *desc) ...@@ -1003,7 +1004,7 @@ nfs_readdir_page_get_cached(struct nfs_readdir_descriptor *desc)
return NULL; return NULL;
if (desc->clear_cache && !nfs_readdir_page_needs_filling(page)) if (desc->clear_cache && !nfs_readdir_page_needs_filling(page))
nfs_readdir_page_reinit_array(page, cookie, change_attr); nfs_readdir_page_reinit_array(page, cookie, change_attr);
return page; return page_folio(page);
} }
/* /*
...@@ -1017,21 +1018,21 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc) ...@@ -1017,21 +1018,21 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)
__be32 verf[NFS_DIR_VERIFIER_SIZE]; __be32 verf[NFS_DIR_VERIFIER_SIZE];
int res; int res;
desc->page = nfs_readdir_page_get_cached(desc); desc->folio = nfs_readdir_folio_get_cached(desc);
if (!desc->page) if (!desc->folio)
return -ENOMEM; return -ENOMEM;
if (nfs_readdir_page_needs_filling(desc->page)) { if (nfs_readdir_page_needs_filling(folio_page(desc->folio, 0))) {
/* Grow the dtsize if we had to go back for more pages */ /* Grow the dtsize if we had to go back for more pages */
if (desc->page_index == desc->page_index_max) if (desc->folio_index == desc->folio_index_max)
nfs_grow_dtsize(desc); nfs_grow_dtsize(desc);
desc->page_index_max = desc->page_index; desc->folio_index_max = desc->folio_index;
trace_nfs_readdir_cache_fill(desc->file, nfsi->cookieverf, trace_nfs_readdir_cache_fill(desc->file, nfsi->cookieverf,
desc->last_cookie, desc->last_cookie,
desc->page->index, desc->dtsize); desc->folio->index, desc->dtsize);
res = nfs_readdir_xdr_to_array(desc, nfsi->cookieverf, verf, res = nfs_readdir_xdr_to_array(desc, nfsi->cookieverf, verf,
&desc->page, 1); &desc->folio, 1);
if (res < 0) { if (res < 0) {
nfs_readdir_page_unlock_and_put_cached(desc); nfs_readdir_folio_unlock_and_put_cached(desc);
trace_nfs_readdir_cache_fill_done(inode, res); trace_nfs_readdir_cache_fill_done(inode, res);
if (res == -EBADCOOKIE || res == -ENOTSYNC) { if (res == -EBADCOOKIE || res == -ENOTSYNC) {
invalidate_inode_pages2(desc->file->f_mapping); invalidate_inode_pages2(desc->file->f_mapping);
...@@ -1059,7 +1060,7 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc) ...@@ -1059,7 +1060,7 @@ static int find_and_lock_cache_page(struct nfs_readdir_descriptor *desc)
res = nfs_readdir_search_array(desc); res = nfs_readdir_search_array(desc);
if (res == 0) if (res == 0)
return 0; return 0;
nfs_readdir_page_unlock_and_put_cached(desc); nfs_readdir_folio_unlock_and_put_cached(desc);
return res; return res;
} }
...@@ -1087,7 +1088,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc, ...@@ -1087,7 +1088,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
unsigned int i; unsigned int i;
bool first_emit = !desc->dir_cookie; bool first_emit = !desc->dir_cookie;
array = kmap_local_page(desc->page); array = kmap_local_folio(desc->folio, 0);
for (i = desc->cache_entry_index; i < array->size; i++) { for (i = desc->cache_entry_index; i < array->size; i++) {
struct nfs_cache_array_entry *ent; struct nfs_cache_array_entry *ent;
...@@ -1136,7 +1137,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc, ...@@ -1136,7 +1137,7 @@ static void nfs_do_filldir(struct nfs_readdir_descriptor *desc,
*/ */
static int uncached_readdir(struct nfs_readdir_descriptor *desc) static int uncached_readdir(struct nfs_readdir_descriptor *desc)
{ {
struct page **arrays; struct folio **arrays;
size_t i, sz = 512; size_t i, sz = 512;
__be32 verf[NFS_DIR_VERIFIER_SIZE]; __be32 verf[NFS_DIR_VERIFIER_SIZE];
int status = -ENOMEM; int status = -ENOMEM;
...@@ -1147,14 +1148,14 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc) ...@@ -1147,14 +1148,14 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
arrays = kcalloc(sz, sizeof(*arrays), GFP_KERNEL); arrays = kcalloc(sz, sizeof(*arrays), GFP_KERNEL);
if (!arrays) if (!arrays)
goto out; goto out;
arrays[0] = nfs_readdir_page_array_alloc(desc->dir_cookie, GFP_KERNEL); arrays[0] = page_folio(nfs_readdir_page_array_alloc(desc->dir_cookie, GFP_KERNEL));
if (!arrays[0]) if (!arrays[0])
goto out; goto out;
desc->page_index = 0; desc->folio_index = 0;
desc->cache_entry_index = 0; desc->cache_entry_index = 0;
desc->last_cookie = desc->dir_cookie; desc->last_cookie = desc->dir_cookie;
desc->page_index_max = 0; desc->folio_index_max = 0;
trace_nfs_readdir_uncached(desc->file, desc->verf, desc->last_cookie, trace_nfs_readdir_uncached(desc->file, desc->verf, desc->last_cookie,
-1, desc->dtsize); -1, desc->dtsize);
...@@ -1166,10 +1167,10 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc) ...@@ -1166,10 +1167,10 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
} }
for (i = 0; !desc->eob && i < sz && arrays[i]; i++) { for (i = 0; !desc->eob && i < sz && arrays[i]; i++) {
desc->page = arrays[i]; desc->folio = arrays[i];
nfs_do_filldir(desc, verf); nfs_do_filldir(desc, verf);
} }
desc->page = NULL; desc->folio = NULL;
/* /*
* Grow the dtsize if we have to go back for more pages, * Grow the dtsize if we have to go back for more pages,
...@@ -1179,16 +1180,16 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc) ...@@ -1179,16 +1180,16 @@ static int uncached_readdir(struct nfs_readdir_descriptor *desc)
if (!desc->eob) if (!desc->eob)
nfs_grow_dtsize(desc); nfs_grow_dtsize(desc);
else if (desc->buffer_fills == 1 && else if (desc->buffer_fills == 1 &&
i < (desc->page_index_max >> 1)) i < (desc->folio_index_max >> 1))
nfs_shrink_dtsize(desc); nfs_shrink_dtsize(desc);
} }
out_free: out_free:
for (i = 0; i < sz && arrays[i]; i++) for (i = 0; i < sz && arrays[i]; i++)
nfs_readdir_page_array_free(arrays[i]); nfs_readdir_page_array_free(folio_page(arrays[i], 0));
out: out:
if (!nfs_readdir_use_cookie(desc->file)) if (!nfs_readdir_use_cookie(desc->file))
nfs_readdir_rewind_search(desc); nfs_readdir_rewind_search(desc);
desc->page_index_max = -1; desc->folio_index_max = -1;
kfree(arrays); kfree(arrays);
dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __func__, status); dfprintk(DIRCACHE, "NFS: %s: returns %d\n", __func__, status);
return status; return status;
...@@ -1240,11 +1241,11 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1240,11 +1241,11 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
goto out; goto out;
desc->file = file; desc->file = file;
desc->ctx = ctx; desc->ctx = ctx;
desc->page_index_max = -1; desc->folio_index_max = -1;
spin_lock(&file->f_lock); spin_lock(&file->f_lock);
desc->dir_cookie = dir_ctx->dir_cookie; desc->dir_cookie = dir_ctx->dir_cookie;
desc->page_index = dir_ctx->page_index; desc->folio_index = dir_ctx->page_index;
desc->last_cookie = dir_ctx->last_cookie; desc->last_cookie = dir_ctx->last_cookie;
desc->attr_gencount = dir_ctx->attr_gencount; desc->attr_gencount = dir_ctx->attr_gencount;
desc->eof = dir_ctx->eof; desc->eof = dir_ctx->eof;
...@@ -1291,8 +1292,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1291,8 +1292,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
break; break;
nfs_do_filldir(desc, nfsi->cookieverf); nfs_do_filldir(desc, nfsi->cookieverf);
nfs_readdir_page_unlock_and_put_cached(desc); nfs_readdir_folio_unlock_and_put_cached(desc);
if (desc->page_index == desc->page_index_max) if (desc->folio_index == desc->folio_index_max)
desc->clear_cache = force_clear; desc->clear_cache = force_clear;
} while (!desc->eob && !desc->eof); } while (!desc->eob && !desc->eof);
...@@ -1300,7 +1301,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx) ...@@ -1300,7 +1301,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
dir_ctx->dir_cookie = desc->dir_cookie; dir_ctx->dir_cookie = desc->dir_cookie;
dir_ctx->last_cookie = desc->last_cookie; dir_ctx->last_cookie = desc->last_cookie;
dir_ctx->attr_gencount = desc->attr_gencount; dir_ctx->attr_gencount = desc->attr_gencount;
dir_ctx->page_index = desc->page_index; dir_ctx->page_index = desc->folio_index;
dir_ctx->force_clear = force_clear; dir_ctx->force_clear = force_clear;
dir_ctx->eof = desc->eof; dir_ctx->eof = desc->eof;
dir_ctx->dtsize = desc->dtsize; dir_ctx->dtsize = desc->dtsize;
......
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