[Linux-cachefs] [RFC PATCH] cifs: Transition from ->readpages() to ->readahead()
David Howells
dhowells at redhat.com
Mon Jan 24 16:25:11 UTC 2022
Matthew Wilcox <willy at infradead.org> wrote:
> Well, that's the problem isn't it? You're expecting to mutate the state
> and then refer to its previous state instead of its current state,
No. I *don't* want to see the previous state. That's where the problem is:
The previous state isn't cleared up until the point I ask for a new batch -
but I need to query the ractl to find the remaining window before I can ask
for a new batch.
The first pass through the loop is, in effect, substantially different to the
second and subsequent passes.
> whereas the other users refer to the current state instead of the
> previous state.
Fuse has exactly the same issues:
nr_pages = readahead_count(rac) - nr_pages;
if (nr_pages > max_pages)
nr_pages = max_pages;
if (nr_pages == 0)
break;
ia = fuse_io_alloc(NULL, nr_pages);
...
nr_pages = __readahead_batch(rac, ap->pages, nr_pages);
It needs to find out how many pages it needs so that it can allocate its page
array before it can get a new batch, but the ractl is holding the previous
state.
> Can't you pull readahead_index() out of the ractl ahead of the mutation?
I'm not sure what you mean by that. What I'm now doing is:
while ((nr_pages = readahead_count(ractl) - ractl->_batch_count)) {
...
pgoff_t index = readahead_index(ractl) + ractl->_batch_count;
...
rc = cifs_fscache_query_occupancy(
ractl->mapping->host, index, nr_pages,
...
rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
&rsize, credits);
...
nr_pages = min_t(size_t, rsize / PAGE_SIZE, readahead_count(ractl));
nr_pages = min_t(size_t, nr_pages, next_cached - index);
...
rdata = cifs_readdata_alloc(nr_pages, cifs_readv_complete);
...
got = __readahead_batch(ractl, rdata->pages, nr_pages);
...
}
I need the count to know how many, if any, pages are remaining; I need the
count and index of the window to find out if fscache has any data; I need the
count to allocate a page array. Only after all that can I crank the next
batch for the server (assuming I didn't delegate to the cache along the way,
but that calls readahead_page()).
(Yes, I would like to remove this code entirely and just call into netfslib.
I have patches to do that, but it involves quite an overhaul of the cifs
driver, but the above might get cifs caching again more quickly pending that.
Maybe I should just take the easy way here and cache the last state so that I
can compensate in the way fuse does).
David
More information about the Linux-cachefs
mailing list