Re: [PATCH v12 00/10] enable bs > ps in XFS

David Howells
2024-08-19T12:25:19Z

Hannes Reinecke <hare@suse.de> wrote:

> IE you essentially nail AFS to use PAGE_SIZE.
> Not sure how you would tell AFS to use a different block size;
> maybe a mount option?

As far as I know:

sb->s_blocksize = PAGE_SIZE;
sb->s_blocksize_bits = PAGE_SHIFT;

isn't used by the VM.

> Hmm. I'd rather fix the obvious places in afs first; just do a quick
> grep for 'PAGE_', that'll give you a good impression of places to look at.

Sure:

fs/afs/dir.c: nr_pages = (i_size + PAGE_SIZE - 1) / PAGE_SIZE;
fs/afs/dir.c: req->len = nr_pages * PAGE_SIZE; /* We can ask for more than there is */
fs/afs/dir.c: task_io_account_read(PAGE_SIZE * req->nr_pages);
fs/afs/dir.c: folio = __filemap_get_folio(dir->i_mapping, ctx->pos / PAGE_SIZE,
fs/afs/xdr_fs.h:#define AFS_DIR_BLOCKS_PER_PAGE (PAGE_SIZE / AFS_DIR_BLOCK_SIZE)

Those only affect directories.

fs/afs/mntpt.c: if (size < 2 || size > PAGE_SIZE - 1)

That only affects mountpoint symlinks.

fs/afs/super.c: sb->s_blocksize = PAGE_SIZE;

This is the only thing (and sb->s_blocksize_bits) that might affect files. I
checked, and doubling this and adding 1 to bits does not alter the outcome.

Now, the VM wrangling is offloaded to netfslib, and most of that is to do with
converting between indices and file positions. Going through the usages of
PAGE_SIZE there:

fs/netfs/buffered_read.c: size += PAGE_SIZE << order;

That was recording the size of a folio readahead allocated.

fs/netfs/buffered_read.c: size_t nr_bvec = flen / PAGE_SIZE + 2;
fs/netfs/buffered_read.c: part = min_t(size_t, to - off, PAGE_SIZE);

Those two are used to fill in the gaps around a partial page - but that didn't
appear in the logs.

fs/netfs/buffered_write.c: pgoff_t index = pos / PAGE_SIZE;
fs/netfs/buffered_write.c: fgp_flags |= fgf_set_order(pos % PAGE_SIZE + part);

Those two are used when asking __filemap_get_folio() to allocate a folio to
write into. I got a folio of the right size and index, so that's not the
problem.

fs/netfs/fscache_io.c: pgoff_t first = start / PAGE_SIZE;
fs/netfs/fscache_io.c: pgoff_t last = (start + len - 1) / PAGE_SIZE;

Caching is not enabled at the moment, so these don't happen.

fs/netfs/iterator.c: cur_npages = DIV_ROUND_UP(ret, PAGE_SIZE);
fs/netfs/iterator.c: len = ret > PAGE_SIZE ? PAGE_SIZE : ret;

I'm not doing DIO, so these aren't used.

fs/netfs/iterator.c: pgoff_t index = pos / PAGE_SIZE;

I'm not using an ITER_XARRAY iterator, so this doesn't happen.

fs/netfs/misc.c: rreq->io_iter.count += PAGE_SIZE << order;

This is just multiplying up the folio size to add to the byte count.

fs/netfs/read_collect.c: fsize = PAGE_SIZE << subreq->curr_folio_order;
fs/netfs/read_collect.c: WARN_ON_ONCE(folioq_folio(folioq, slot)->index != fpos / PAGE_SIZE)) {

These two are converting between a file pos and an index - but only during
read, and I can see from wireshark that we're writing the wrong data to the
server before we get this far.

And that's all the PAGE_SIZE usages in afs and netfslib.

David