Commit ed22e1db authored by David Howells's avatar David Howells
Browse files

netfs, afs: Implement helpers for new write code



Implement the helpers for the new write code in afs.  There's now an
optional ->prepare_write() that allows the filesystem to set the parameters
for the next write, such as maximum size and maximum segment count, and an
->issue_write() that is called to initiate an (asynchronous) write
operation.

Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
parent 4824e591
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -400,6 +400,9 @@ const struct netfs_request_ops afs_req_ops = {
	.update_i_size		= afs_update_i_size,
	.invalidate_cache	= afs_netfs_invalidate_cache,
	.create_write_requests	= afs_create_write_requests,
	.begin_writeback	= afs_begin_writeback,
	.prepare_write		= afs_prepare_write,
	.issue_write		= afs_issue_write,
};

static void afs_add_open_mmap(struct afs_vnode *vnode)
+3 −0
Original line number Diff line number Diff line
@@ -1598,6 +1598,9 @@ extern int afs_check_volume_status(struct afs_volume *, struct afs_operation *);
/*
 * write.c
 */
void afs_prepare_write(struct netfs_io_subrequest *subreq);
void afs_issue_write(struct netfs_io_subrequest *subreq);
void afs_begin_writeback(struct netfs_io_request *wreq);
extern int afs_writepages(struct address_space *, struct writeback_control *);
extern int afs_fsync(struct file *, loff_t, loff_t, int);
extern vm_fault_t afs_page_mkwrite(struct vm_fault *vmf);
+54 −0
Original line number Diff line number Diff line
@@ -194,6 +194,60 @@ void afs_create_write_requests(struct netfs_io_request *wreq, loff_t start, size
		netfs_queue_write_request(subreq);
}

/*
 * Writeback calls this when it finds a folio that needs uploading.  This isn't
 * called if writeback only has copy-to-cache to deal with.
 */
void afs_begin_writeback(struct netfs_io_request *wreq)
{
	wreq->io_streams[0].avail = true;
}

/*
 * Prepare a subrequest to write to the server.  This sets the max_len
 * parameter.
 */
void afs_prepare_write(struct netfs_io_subrequest *subreq)
{
	//if (test_bit(NETFS_SREQ_RETRYING, &subreq->flags))
	//	subreq->max_len = 512 * 1024;
	//else
	subreq->max_len = 256 * 1024 * 1024;
}

/*
 * Issue a subrequest to write to the server.
 */
static void afs_issue_write_worker(struct work_struct *work)
{
	struct netfs_io_subrequest *subreq = container_of(work, struct netfs_io_subrequest, work);
	struct afs_vnode *vnode = AFS_FS_I(subreq->rreq->inode);
	ssize_t ret;

	_enter("%x[%x],%zx",
	       subreq->rreq->debug_id, subreq->debug_index, subreq->io_iter.count);

#if 0 // Error injection
	if (subreq->debug_index == 3)
		return netfs_write_subrequest_terminated(subreq, -ENOANO, false);

	if (!test_bit(NETFS_SREQ_RETRYING, &subreq->flags)) {
		set_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags);
		return netfs_write_subrequest_terminated(subreq, -EAGAIN, false);
	}
#endif

	ret = afs_store_data(vnode, &subreq->io_iter, subreq->start);
	netfs_write_subrequest_terminated(subreq, ret < 0 ? ret : subreq->len, false);
}

void afs_issue_write(struct netfs_io_subrequest *subreq)
{
	subreq->work.func = afs_issue_write_worker;
	if (!queue_work(system_unbound_wq, &subreq->work))
		WARN_ON_ONCE(1);
}

/*
 * write some of the pending data back to the server
 */