From: David Howells <dhowells@redhat.com>
To: linux-cachefs@redhat.com
Cc: Steve French <sfrench@samba.org>,
Shyam Prasad N <nspmangalore@gmail.com>,
Rohith Surabattula <rohiths.msft@gmail.com>,
linux-cifs@vger.kernel.org, dhowells@redhat.com,
Steve French <sfrench@samba.org>,
Shyam Prasad N <nspmangalore@gmail.com>,
Rohith Surabattula <rohiths.msft@gmail.com>,
Jeff Layton <jlayton@redhat.com>,
linux-cifs@vger.kernel.org, linux-fsdevel@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-mm@kvack.org
Subject: [PATCH 11/14] cifs: Clamp length according to credits and rsize
Date: Thu, 07 Apr 2022 00:04:43 +0100 [thread overview]
Message-ID: <164928628373.457102.3447384159737994076.stgit@warthog.procyon.org.uk> (raw)
In-Reply-To: <164928615045.457102.10607899252434268982.stgit@warthog.procyon.org.uk>
A read request can get expanded beyond the capacity of the available
credits and rsize, so use the ->clamp_length() method to cut the request up
into pieces rather than trying to do it in ->issue_read(), at which point
the subrequest size is already determined.
Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <sfrench@samba.org>
cc: Shyam Prasad N <nspmangalore@gmail.com>
cc: Rohith Surabattula <rohiths.msft@gmail.com>
cc: linux-cifs@vger.kernel.org
---
fs/cifs/cifsglob.h | 2 +
fs/cifs/file.c | 71 ++++++++++++++++++++++++++++++++++++----------------
fs/cifs/smb2pdu.c | 5 ++--
3 files changed, 54 insertions(+), 24 deletions(-)
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index e1e77225d634..2b1930a918b0 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1328,8 +1328,10 @@ struct cifs_io_subrequest {
__u64 offset;
ssize_t got_bytes;
unsigned int bytes;
+ unsigned int xid;
pid_t pid;
int result;
+ bool have_credits;
struct kvec iov[2];
struct TCP_Server_Info *server;
#ifdef CONFIG_CIFS_SMB_DIRECT
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 45510bd1f702..12663d9d1e51 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -3437,6 +3437,47 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
return rc;
}
+/*
+ * Split the read up according to how many credits we can get for each piece.
+ * It's okay to sleep here if we need to wait for more credit to become
+ * available.
+ *
+ * We also choose the server and allocate an operation ID to be cleaned up
+ * later.
+ */
+static bool cifs_clamp_length(struct netfs_io_subrequest *subreq)
+{
+ struct netfs_io_request *rreq = subreq->rreq;
+ struct TCP_Server_Info *server;
+ struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq);
+ struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq);
+ struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb);
+ unsigned int rsize = 0;
+ int rc;
+
+ rdata->xid = get_xid();
+
+ server = cifs_pick_channel(tlink_tcon(req->cfile->tlink)->ses);
+ rdata->server = server;
+
+ if (cifs_sb->ctx->rsize == 0)
+ cifs_sb->ctx->rsize =
+ server->ops->negotiate_rsize(tlink_tcon(req->cfile->tlink),
+ cifs_sb->ctx);
+
+
+ rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize, &rsize,
+ &rdata->credits);
+ if (rc) {
+ subreq->error = rc;
+ return false;
+ }
+
+ rdata->have_credits = true;
+ subreq->len = min_t(size_t, subreq->len, rsize);
+ return true;
+}
+
/*
* Issue a read operation on behalf of the netfs helper functions. We're asked
* to make a read of a certain size at a point in the file. We are permitted
@@ -3446,24 +3487,17 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
static void cifs_req_issue_read(struct netfs_io_subrequest *subreq)
{
struct netfs_io_request *rreq = subreq->rreq;
- struct TCP_Server_Info *server;
struct cifs_io_subrequest *rdata = container_of(subreq, struct cifs_io_subrequest, subreq);
struct cifs_io_request *req = container_of(subreq->rreq, struct cifs_io_request, rreq);
struct cifs_sb_info *cifs_sb = CIFS_SB(rreq->inode->i_sb);
- unsigned int xid;
pid_t pid;
int rc = 0;
- unsigned int rsize;
-
- xid = get_xid();
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = req->cfile->pid;
else
pid = current->tgid; // Ummm... This may be a workqueue
- server = cifs_pick_channel(tlink_tcon(req->cfile->tlink)->ses);
-
cifs_dbg(FYI, "%s: op=%08x[%x] mapping=%p len=%zu/%zu\n",
__func__, rreq->debug_id, subreq->debug_index, rreq->mapping,
subreq->transferred, subreq->len);
@@ -3476,32 +3510,20 @@ static void cifs_req_issue_read(struct netfs_io_subrequest *subreq)
goto out;
}
- if (cifs_sb->ctx->rsize == 0)
- cifs_sb->ctx->rsize =
- server->ops->negotiate_rsize(tlink_tcon(req->cfile->tlink),
- cifs_sb->ctx);
-
- rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize, &rsize,
- &rdata->credits);
- if (rc)
- goto out;
-
__set_bit(NETFS_SREQ_CLEAR_TAIL, &subreq->flags);
- rdata->server = server;
rdata->offset = subreq->start + subreq->transferred;
rdata->bytes = subreq->len - subreq->transferred;
rdata->pid = pid;
- rc = adjust_credits(server, &rdata->credits, rdata->bytes);
+ rc = adjust_credits(rdata->server, &rdata->credits, rdata->bytes);
if (!rc) {
if (rdata->req->cfile->invalidHandle)
rc = -EAGAIN;
else
- rc = server->ops->async_readv(rdata);
+ rc = rdata->server->ops->async_readv(rdata);
}
out:
- free_xid(xid);
if (rc)
netfs_subreq_terminated(subreq, rc, false);
}
@@ -3580,6 +3602,7 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
{
struct cifs_io_subrequest *rdata =
container_of(subreq, struct cifs_io_subrequest, subreq);
+ int rc;
if (rdata->subreq.source == NETFS_DOWNLOAD_FROM_SERVER) {
#ifdef CONFIG_CIFS_SMB_DIRECT
@@ -3589,7 +3612,10 @@ static void cifs_free_subrequest(struct netfs_io_subrequest *subreq)
}
#endif
- add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
+ if (rdata->have_credits)
+ add_credits_and_wake_if(rdata->server, &rdata->credits, 0);
+ rc = subreq->error;
+ free_xid(rdata->xid);
}
}
@@ -3601,6 +3627,7 @@ const struct netfs_request_ops cifs_req_ops = {
.free_subrequest = cifs_free_subrequest,
.begin_cache_operation = cifs_begin_cache_operation,
.expand_readahead = cifs_expand_readahead,
+ .clamp_length = cifs_clamp_length,
.issue_read = cifs_req_issue_read,
.done = cifs_rreq_done,
};
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 6a8aaa003e54..952f242bee55 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -4174,7 +4174,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
#endif
if (rdata->result && rdata->result != -ENODATA) {
cifs_stats_fail_inc(tcon, SMB2_READ_HE);
- trace_smb3_read_err(0 /* xid */,
+ trace_smb3_read_err(rdata->xid,
rdata->req->cfile->fid.persistent_fid,
tcon->tid, tcon->ses->Suid, rdata->offset,
rdata->bytes, rdata->result);
@@ -4193,6 +4193,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
}
if (rdata->result == 0 || rdata->result == -EAGAIN)
iov_iter_advance(&rdata->subreq.iter, rdata->got_bytes);
+ rdata->have_credits = false;
netfs_subreq_terminated(&rdata->subreq,
(rdata->result == 0 || rdata->result == -EAGAIN) ?
rdata->got_bytes : rdata->result, true);
@@ -4259,7 +4260,7 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)
&rdata->credits);
if (rc) {
cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
- trace_smb3_read_err(0 /* xid */, io_parms.persistent_fid,
+ trace_smb3_read_err(rdata->xid, io_parms.persistent_fid,
io_parms.tcon->tid,
io_parms.tcon->ses->Suid,
io_parms.offset, io_parms.length, rc);
next prev parent reply other threads:[~2022-04-06 23:09 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-04-06 23:02 [PATCH 00/14] cifs: Iterators, netfslib and folios David Howells
2022-04-06 23:02 ` [PATCH 01/14] cifs: Add some helper functions David Howells
2022-04-06 23:02 ` [PATCH 02/14] cifs: Add a function to read into an iter from a socket David Howells
2022-04-06 23:03 ` [PATCH 03/14] cifs: Check the IOCB_DIRECT flag, not O_DIRECT David Howells
2022-04-06 23:03 ` [PATCH 04/14] cifs: Change the I/O paths to use an iterator rather than a page list David Howells
2022-04-06 23:03 ` [PATCH 05/14] cifs: Remove unused code David Howells
2022-04-06 23:03 ` [PATCH 06/14] cifs: Use netfslib to handle reads David Howells
2022-04-06 23:04 ` [PATCH 07/14] cifs: Share server EOF pos with netfslib David Howells
2022-04-06 23:04 ` [PATCH 08/14] netfs: Allow the netfs to make the io (sub)request alloc larger David Howells
2022-04-06 23:04 ` [PATCH 09/14] cifs: Put credits into cifs_io_subrequest, not on the stack David Howells
2022-04-06 23:04 ` [PATCH 10/14] cifs: Hold the open file on netfs_io_request, not netfs_io_subrequest David Howells
2022-04-06 23:04 ` David Howells [this message]
2022-04-06 23:04 ` [PATCH 12/14] cifs: Expose netfs subrequest debug ID and index in read tracepoints David Howells
2022-04-06 23:04 ` [PATCH 13/14] cifs: Split the smb3_add_credits tracepoint David Howells
2022-04-06 23:05 ` [PATCH 14/14] mm, netfs, fscache: Stop read optimisation when folio removed from pagecache David Howells
2022-04-07 3:13 ` Matthew Wilcox
2022-04-07 6:41 ` David Howells
2022-04-07 21:22 ` Matthew Wilcox
2022-04-25 12:07 ` David Howells
2022-04-25 12:30 ` Matthew Wilcox
2022-09-02 0:30 ` David Wysochanski
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=164928628373.457102.3447384159737994076.stgit@warthog.procyon.org.uk \
--to=dhowells@redhat.com \
--cc=jlayton@redhat.com \
--cc=linux-cachefs@redhat.com \
--cc=linux-cifs@vger.kernel.org \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mm@kvack.org \
--cc=nspmangalore@gmail.com \
--cc=rohiths.msft@gmail.com \
--cc=sfrench@samba.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox