Unverified Commit 3956e728 authored by Christian Brauner's avatar Christian Brauner
Browse files

Merge branch 'netfs-writeback' of...

Merge branch 'netfs-writeback' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs into vfs.netfs

Merge patch series "netfs: Read/write improvements" from David Howells
<dhowells@redhat.com>.

* 'netfs-writeback' of ssh://gitolite.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs

: (25 commits)
  cifs: Don't support ITER_XARRAY
  cifs: Switch crypto buffer to use a folio_queue rather than an xarray
  cifs: Use iterate_and_advance*() routines directly for hashing
  netfs: Cancel dirty folios that have no storage destination
  cachefiles, netfs: Fix write to partial block at EOF
  netfs: Remove fs/netfs/io.c
  netfs: Speed up buffered reading
  afs: Make read subreqs async
  netfs: Simplify the writeback code
  netfs: Provide an iterator-reset function
  netfs: Use new folio_queue data type and iterator instead of xarray iter
  cifs: Provide the capability to extract from ITER_FOLIOQ to RDMA SGEs
  iov_iter: Provide copy_folio_from_iter()
  mm: Define struct folio_queue and ITER_FOLIOQ to handle a sequence of folios
  netfs: Use bh-disabling spinlocks for rreq->lock
  netfs: Set the request work function upon allocation
  netfs: Remove NETFS_COPY_TO_CACHE
  netfs: Reserve netfs_sreq_source 0 as unset/unknown
  netfs: Move max_len/max_nr_segs from netfs_io_subrequest to netfs_io_stream
  netfs, cifs: Move CIFS_INO_MODIFIED_ATTR to netfs_inode
  ...

Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
parents 4356ab33 4aa571d6
Loading
Loading
Loading
Loading
+8 −3
Original line number Diff line number Diff line
@@ -68,17 +68,22 @@ static void v9fs_issue_read(struct netfs_io_subrequest *subreq)
{
	struct netfs_io_request *rreq = subreq->rreq;
	struct p9_fid *fid = rreq->netfs_priv;
	unsigned long long pos = subreq->start + subreq->transferred;
	int total, err;

	total = p9_client_read(fid, subreq->start + subreq->transferred,
			       &subreq->io_iter, &err);
	total = p9_client_read(fid, pos, &subreq->io_iter, &err);

	/* if we just extended the file size, any portion not in
	 * cache won't be on server and is zeroes */
	if (subreq->rreq->origin != NETFS_DIO_READ)
		__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
	if (pos + total >= i_size_read(rreq->inode))
		__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);

	netfs_subreq_terminated(subreq, err ?: total, false);
	if (!err)
		subreq->transferred += total;

	netfs_read_subreq_terminated(subreq, err, false);
}

/**
+23 −7
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/netfs.h>
#include <trace/events/netfs.h>
#include "internal.h"

static int afs_file_mmap(struct file *file, struct vm_area_struct *vma);
@@ -242,9 +243,10 @@ static void afs_fetch_data_notify(struct afs_operation *op)

	req->error = error;
	if (subreq) {
		if (subreq->rreq->origin != NETFS_DIO_READ)
			__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
		netfs_subreq_terminated(subreq, error ?: req->actual_len, false);
		subreq->rreq->i_size = req->file_size;
		if (req->pos + req->actual_len >= req->file_size)
			__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
		netfs_read_subreq_terminated(subreq, error, false);
		req->subreq = NULL;
	} else if (req->done) {
		req->done(req);
@@ -262,6 +264,12 @@ static void afs_fetch_data_success(struct afs_operation *op)
	afs_fetch_data_notify(op);
}

static void afs_fetch_data_aborted(struct afs_operation *op)
{
	afs_check_for_remote_deletion(op);
	afs_fetch_data_notify(op);
}

static void afs_fetch_data_put(struct afs_operation *op)
{
	op->fetch.req->error = afs_op_error(op);
@@ -272,7 +280,7 @@ static const struct afs_operation_ops afs_fetch_data_operation = {
	.issue_afs_rpc	= afs_fs_fetch_data,
	.issue_yfs_rpc	= yfs_fs_fetch_data,
	.success	= afs_fetch_data_success,
	.aborted	= afs_check_for_remote_deletion,
	.aborted	= afs_fetch_data_aborted,
	.failed		= afs_fetch_data_notify,
	.put		= afs_fetch_data_put,
};
@@ -294,7 +302,7 @@ int afs_fetch_data(struct afs_vnode *vnode, struct afs_read *req)
	op = afs_alloc_operation(req->key, vnode->volume);
	if (IS_ERR(op)) {
		if (req->subreq)
			netfs_subreq_terminated(req->subreq, PTR_ERR(op), false);
			netfs_read_subreq_terminated(req->subreq, PTR_ERR(op), false);
		return PTR_ERR(op);
	}

@@ -305,14 +313,15 @@ int afs_fetch_data(struct afs_vnode *vnode, struct afs_read *req)
	return afs_do_sync_operation(op);
}

static void afs_issue_read(struct netfs_io_subrequest *subreq)
static void afs_read_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);
	struct afs_read *fsreq;

	fsreq = afs_alloc_read(GFP_NOFS);
	if (!fsreq)
		return netfs_subreq_terminated(subreq, -ENOMEM, false);
		return netfs_read_subreq_terminated(subreq, -ENOMEM, false);

	fsreq->subreq	= subreq;
	fsreq->pos	= subreq->start + subreq->transferred;
@@ -321,10 +330,17 @@ static void afs_issue_read(struct netfs_io_subrequest *subreq)
	fsreq->vnode	= vnode;
	fsreq->iter	= &subreq->io_iter;

	trace_netfs_sreq(subreq, netfs_sreq_trace_submit);
	afs_fetch_data(fsreq->vnode, fsreq);
	afs_put_read(fsreq);
}

static void afs_issue_read(struct netfs_io_subrequest *subreq)
{
	INIT_WORK(&subreq->work, afs_read_worker);
	queue_work(system_long_wq, &subreq->work);
}

static int afs_symlink_read_folio(struct file *file, struct folio *folio)
{
	struct afs_vnode *vnode = AFS_FS_I(folio->mapping->host);
+7 −2
Original line number Diff line number Diff line
@@ -304,6 +304,7 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)
	struct afs_vnode_param *vp = &op->file[0];
	struct afs_read *req = op->fetch.req;
	const __be32 *bp;
	size_t count_before;
	int ret;

	_enter("{%u,%zu,%zu/%llu}",
@@ -345,10 +346,14 @@ static int afs_deliver_fs_fetch_data(struct afs_call *call)

		/* extract the returned data */
	case 2:
		_debug("extract data %zu/%llu",
		       iov_iter_count(call->iter), req->actual_len);
		count_before = call->iov_len;
		_debug("extract data %zu/%llu", count_before, req->actual_len);

		ret = afs_extract_data(call, true);
		if (req->subreq) {
			req->subreq->transferred += count_before - call->iov_len;
			netfs_read_subreq_progress(req->subreq, false);
		}
		if (ret < 0)
			return ret;

+3 −1
Original line number Diff line number Diff line
@@ -89,10 +89,12 @@ static const struct afs_operation_ops afs_store_data_operation = {
 */
void afs_prepare_write(struct netfs_io_subrequest *subreq)
{
	struct netfs_io_stream *stream = &subreq->rreq->io_streams[subreq->stream_nr];

	//if (test_bit(NETFS_SREQ_RETRYING, &subreq->flags))
	//	subreq->max_len = 512 * 1024;
	//else
	subreq->max_len = 256 * 1024 * 1024;
	stream->sreq_max_len = 256 * 1024 * 1024;
}

/*
+7 −2
Original line number Diff line number Diff line
@@ -355,6 +355,7 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call)
	struct afs_vnode_param *vp = &op->file[0];
	struct afs_read *req = op->fetch.req;
	const __be32 *bp;
	size_t count_before;
	int ret;

	_enter("{%u,%zu, %zu/%llu}",
@@ -391,10 +392,14 @@ static int yfs_deliver_fs_fetch_data64(struct afs_call *call)

		/* extract the returned data */
	case 2:
		_debug("extract data %zu/%llu",
		       iov_iter_count(call->iter), req->actual_len);
		count_before = call->iov_len;
		_debug("extract data %zu/%llu", count_before, req->actual_len);

		ret = afs_extract_data(call, true);
		if (req->subreq) {
			req->subreq->transferred += count_before - call->iov_len;
			netfs_read_subreq_progress(req->subreq, false);
		}
		if (ret < 0)
			return ret;

Loading