Re: [PATCH 8/8] rpdfs: add read_folio, dirty_folio, write_begin, write_end

Zach Brown <[email protected]> Mon, 27 Apr 2026 16:58:59 -0700
Newsgroups dev.linux.lists.rpdfs-devel
Message-ID <[email protected]>
On Fri, Apr 24, 2026 at 04:05:20PM +0200, Valerie Aurora wrote:
> This commit completes basic file data read/write support. Currently it
> will deadlock with multiple clients, so much more work is needed.

> +/*
> + * TODO: cannot block on block acquisition while holding the folio lock.

There's not much to it.

	ret = acquire(, RBAF_NONBLOCK_MODE);
	if (ret == -EAGAIN) {
		folio_unlock(folio);
		ret = acquire(, 0);
		if (ret == 0)
			release(&hnd);
		ret = AOP_TRUNCATED_PAGE;
		goto out;
	}

The caller will retry and this time it'll be able to acquire the block
without waiting.

> +/*
> + * Do whatever preparation is necessary before the VFS copies the data
> + * from the user buffer into the folio pages. Must return a folio.
> + *
> + * Called before a write starts with the page lock held. Due to this, we
> + * can't do anything that blocks on acquisition of a block. Right now it
> + * just gets the folio. In the future it might check quotas, file system
> + * error state, etc.
> + */

It's not called with the page lock held.  That's what the
__filemap_get_folio() is doing.  FGP_WRITEBGIN includes FGP_LOCK.  We
have the freedom to place the page lock in whatever order we need.

(holy moly is it hard to type FGP_ without typing GFP_)

Most of what's in write_end should be brought up in to write_begin.
Interestingly, I don't think we need to communicate the txn to
write_end.  write_begin just needs to make sure that all our dirty
blocks for the change (inode, mapping, data blocks) are all in one
atomic write.  write_end just needs to do the vfs work.  Ala
generic_write_end().

> +	/* copy the data into the actual block */
> +	memcpy(blk_hnd->data + offset, folio_address(folio) + offset, len);

Let's do this by wiring up writepages and having our network IO
reference the page.

> +	rpdfs_prd("i_size %lld ret %d", i_size_read(inode), ret);
> +	return ret;

I'm hoping we can get away with not causing errors in write_end.  It'd
avoid having to unwind the mapping and folio insertions that we did in
write_begin.  (Poke around ext2_write_failed()).

- z