Skip to content

Commit

Permalink
netfs, afs: Implement helpers for new write code
Browse files Browse the repository at this point in the history
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: David Howells <dhowells@redhat.com>
Reviewed-by: Jeff 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
  • Loading branch information
David Howells committed May 1, 2024
1 parent 4824e59 commit ed22e1d
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
3 changes: 3 additions & 0 deletions fs/afs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions fs/afs/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
54 changes: 54 additions & 0 deletions fs/afs/write.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down

0 comments on commit ed22e1d

Please sign in to comment.