mirror of
git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-11-01 09:13:37 +00:00
cifs: Replace cifs_readdata with a wrapper around netfs_io_subrequest
Netfslib has a facility whereby the allocation for netfs_io_subrequest can be increased to so that filesystem-specific data can be tagged on the end. Prepare to use this by making a struct, cifs_io_subrequest, that wraps netfs_io_subrequest, and absorb struct cifs_readdata into it. 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: Jeff Layton <jlayton@kernel.org> cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org
This commit is contained in:
parent
0f7c0f3f51
commit
753b67eb63
8 changed files with 58 additions and 52 deletions
|
|
@ -268,7 +268,7 @@ struct dfs_info3_param;
|
|||
struct cifs_fattr;
|
||||
struct smb3_fs_context;
|
||||
struct cifs_fid;
|
||||
struct cifs_readdata;
|
||||
struct cifs_io_subrequest;
|
||||
struct cifs_writedata;
|
||||
struct cifs_io_parms;
|
||||
struct cifs_search_info;
|
||||
|
|
@ -450,7 +450,7 @@ struct smb_version_operations {
|
|||
/* send a flush request to the server */
|
||||
int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *);
|
||||
/* async read from the server */
|
||||
int (*async_readv)(struct cifs_readdata *);
|
||||
int (*async_readv)(struct cifs_io_subrequest *);
|
||||
/* async write to the server */
|
||||
int (*async_writev)(struct cifs_writedata *,
|
||||
void (*release)(struct kref *));
|
||||
|
|
@ -1493,26 +1493,28 @@ struct cifs_aio_ctx {
|
|||
};
|
||||
|
||||
/* asynchronous read support */
|
||||
struct cifs_readdata {
|
||||
struct kref refcount;
|
||||
struct list_head list;
|
||||
struct completion done;
|
||||
struct cifs_io_subrequest {
|
||||
struct netfs_io_subrequest subreq;
|
||||
struct cifsFileInfo *cfile;
|
||||
struct address_space *mapping;
|
||||
struct cifs_aio_ctx *ctx;
|
||||
__u64 offset;
|
||||
ssize_t got_bytes;
|
||||
unsigned int bytes;
|
||||
pid_t pid;
|
||||
int result;
|
||||
struct work_struct work;
|
||||
struct iov_iter iter;
|
||||
struct kvec iov[2];
|
||||
struct TCP_Server_Info *server;
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
struct smbd_mr *mr;
|
||||
#endif
|
||||
struct cifs_credits credits;
|
||||
|
||||
// TODO: Remove following elements
|
||||
struct list_head list;
|
||||
struct completion done;
|
||||
struct work_struct work;
|
||||
struct iov_iter iter;
|
||||
__u64 offset;
|
||||
unsigned int bytes;
|
||||
};
|
||||
|
||||
/* asynchronous write support */
|
||||
|
|
|
|||
|
|
@ -599,8 +599,17 @@ void __cifs_put_smb_ses(struct cifs_ses *ses);
|
|||
extern struct cifs_ses *
|
||||
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx);
|
||||
|
||||
void cifs_readdata_release(struct kref *refcount);
|
||||
int cifs_async_readv(struct cifs_readdata *rdata);
|
||||
void cifs_readdata_release(struct cifs_io_subrequest *rdata);
|
||||
static inline void cifs_get_readdata(struct cifs_io_subrequest *rdata)
|
||||
{
|
||||
refcount_inc(&rdata->subreq.ref);
|
||||
}
|
||||
static inline void cifs_put_readdata(struct cifs_io_subrequest *rdata)
|
||||
{
|
||||
if (refcount_dec_and_test(&rdata->subreq.ref))
|
||||
cifs_readdata_release(rdata);
|
||||
}
|
||||
int cifs_async_readv(struct cifs_io_subrequest *rdata);
|
||||
int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
|
||||
|
||||
int cifs_async_writev(struct cifs_writedata *wdata,
|
||||
|
|
|
|||
|
|
@ -24,6 +24,8 @@
|
|||
#include <linux/swap.h>
|
||||
#include <linux/task_io_accounting_ops.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/netfs.h>
|
||||
#include <trace/events/netfs.h>
|
||||
#include "cifspdu.h"
|
||||
#include "cifsfs.h"
|
||||
#include "cifsglob.h"
|
||||
|
|
@ -1262,12 +1264,11 @@ openRetry:
|
|||
static void
|
||||
cifs_readv_callback(struct mid_q_entry *mid)
|
||||
{
|
||||
struct cifs_readdata *rdata = mid->callback_data;
|
||||
struct cifs_io_subrequest *rdata = mid->callback_data;
|
||||
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
|
||||
struct TCP_Server_Info *server = tcon->ses->server;
|
||||
struct smb_rqst rqst = { .rq_iov = rdata->iov,
|
||||
.rq_nvec = 2,
|
||||
.rq_iter_size = iov_iter_count(&rdata->iter),
|
||||
.rq_iter = rdata->iter };
|
||||
struct cifs_credits credits = { .value = 1, .instance = 0 };
|
||||
|
||||
|
|
@ -1312,7 +1313,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
|
|||
|
||||
/* cifs_async_readv - send an async write, and set up mid to handle result */
|
||||
int
|
||||
cifs_async_readv(struct cifs_readdata *rdata)
|
||||
cifs_async_readv(struct cifs_io_subrequest *rdata)
|
||||
{
|
||||
int rc;
|
||||
READ_REQ *smb = NULL;
|
||||
|
|
@ -1364,15 +1365,11 @@ cifs_async_readv(struct cifs_readdata *rdata)
|
|||
rdata->iov[1].iov_base = (char *)smb + 4;
|
||||
rdata->iov[1].iov_len = get_rfc1002_length(smb);
|
||||
|
||||
kref_get(&rdata->refcount);
|
||||
rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
|
||||
cifs_readv_callback, NULL, rdata, 0, NULL);
|
||||
|
||||
if (rc == 0)
|
||||
cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
|
||||
else
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
|
||||
cifs_small_buf_release(smb);
|
||||
return rc;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3822,13 +3822,13 @@ out:
|
|||
return written;
|
||||
}
|
||||
|
||||
static struct cifs_readdata *cifs_readdata_alloc(work_func_t complete)
|
||||
static struct cifs_io_subrequest *cifs_readdata_alloc(work_func_t complete)
|
||||
{
|
||||
struct cifs_readdata *rdata;
|
||||
struct cifs_io_subrequest *rdata;
|
||||
|
||||
rdata = kzalloc(sizeof(*rdata), GFP_KERNEL);
|
||||
if (rdata) {
|
||||
kref_init(&rdata->refcount);
|
||||
refcount_set(&rdata->subreq.ref, 1);
|
||||
INIT_LIST_HEAD(&rdata->list);
|
||||
init_completion(&rdata->done);
|
||||
INIT_WORK(&rdata->work, complete);
|
||||
|
|
@ -3838,11 +3838,8 @@ static struct cifs_readdata *cifs_readdata_alloc(work_func_t complete)
|
|||
}
|
||||
|
||||
void
|
||||
cifs_readdata_release(struct kref *refcount)
|
||||
cifs_readdata_release(struct cifs_io_subrequest *rdata)
|
||||
{
|
||||
struct cifs_readdata *rdata = container_of(refcount,
|
||||
struct cifs_readdata, refcount);
|
||||
|
||||
if (rdata->ctx)
|
||||
kref_put(&rdata->ctx->refcount, cifs_aio_ctx_release);
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
|
|
@ -3862,16 +3859,16 @@ static void collect_uncached_read_data(struct cifs_aio_ctx *ctx);
|
|||
static void
|
||||
cifs_uncached_readv_complete(struct work_struct *work)
|
||||
{
|
||||
struct cifs_readdata *rdata = container_of(work,
|
||||
struct cifs_readdata, work);
|
||||
struct cifs_io_subrequest *rdata =
|
||||
container_of(work, struct cifs_io_subrequest, work);
|
||||
|
||||
complete(&rdata->done);
|
||||
collect_uncached_read_data(rdata->ctx);
|
||||
/* the below call can possibly free the last ref to aio ctx */
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
}
|
||||
|
||||
static int cifs_resend_rdata(struct cifs_readdata *rdata,
|
||||
static int cifs_resend_rdata(struct cifs_io_subrequest *rdata,
|
||||
struct list_head *rdata_list,
|
||||
struct cifs_aio_ctx *ctx)
|
||||
{
|
||||
|
|
@ -3939,7 +3936,7 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
|
|||
} while (rc == -EAGAIN);
|
||||
|
||||
fail:
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -3948,7 +3945,7 @@ cifs_send_async_read(loff_t fpos, size_t len, struct cifsFileInfo *open_file,
|
|||
struct cifs_sb_info *cifs_sb, struct list_head *rdata_list,
|
||||
struct cifs_aio_ctx *ctx)
|
||||
{
|
||||
struct cifs_readdata *rdata;
|
||||
struct cifs_io_subrequest *rdata;
|
||||
unsigned int rsize, nsegs, max_segs = INT_MAX;
|
||||
struct cifs_credits credits_on_stack;
|
||||
struct cifs_credits *credits = &credits_on_stack;
|
||||
|
|
@ -4030,7 +4027,7 @@ cifs_send_async_read(loff_t fpos, size_t len, struct cifsFileInfo *open_file,
|
|||
|
||||
if (rc) {
|
||||
add_credits_and_wake_if(server, &rdata->credits, 0);
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
if (rc == -EAGAIN)
|
||||
continue;
|
||||
break;
|
||||
|
|
@ -4048,7 +4045,7 @@ cifs_send_async_read(loff_t fpos, size_t len, struct cifsFileInfo *open_file,
|
|||
static void
|
||||
collect_uncached_read_data(struct cifs_aio_ctx *ctx)
|
||||
{
|
||||
struct cifs_readdata *rdata, *tmp;
|
||||
struct cifs_io_subrequest *rdata, *tmp;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
int rc;
|
||||
|
||||
|
|
@ -4094,8 +4091,7 @@ again:
|
|||
rdata->cfile, cifs_sb,
|
||||
&tmp_list, ctx);
|
||||
|
||||
kref_put(&rdata->refcount,
|
||||
cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
}
|
||||
|
||||
list_splice(&tmp_list, &ctx->list);
|
||||
|
|
@ -4111,7 +4107,7 @@ again:
|
|||
ctx->total_len += rdata->got_bytes;
|
||||
}
|
||||
list_del_init(&rdata->list);
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
}
|
||||
|
||||
/* mask nodata case */
|
||||
|
|
@ -4483,8 +4479,8 @@ static void cifs_unlock_folios(struct address_space *mapping, pgoff_t first, pgo
|
|||
|
||||
static void cifs_readahead_complete(struct work_struct *work)
|
||||
{
|
||||
struct cifs_readdata *rdata = container_of(work,
|
||||
struct cifs_readdata, work);
|
||||
struct cifs_io_subrequest *rdata = container_of(work,
|
||||
struct cifs_io_subrequest, work);
|
||||
struct folio *folio;
|
||||
pgoff_t last;
|
||||
bool good = rdata->result == 0 || (rdata->result == -EAGAIN && rdata->got_bytes);
|
||||
|
|
@ -4510,7 +4506,7 @@ static void cifs_readahead_complete(struct work_struct *work)
|
|||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
}
|
||||
|
||||
static void cifs_readahead(struct readahead_control *ractl)
|
||||
|
|
@ -4550,7 +4546,7 @@ static void cifs_readahead(struct readahead_control *ractl)
|
|||
*/
|
||||
while ((nr_pages = ra_pages)) {
|
||||
unsigned int i, rsize;
|
||||
struct cifs_readdata *rdata;
|
||||
struct cifs_io_subrequest *rdata;
|
||||
struct cifs_credits credits_on_stack;
|
||||
struct cifs_credits *credits = &credits_on_stack;
|
||||
struct folio *folio;
|
||||
|
|
@ -4669,11 +4665,11 @@ static void cifs_readahead(struct readahead_control *ractl)
|
|||
rdata->offset / PAGE_SIZE,
|
||||
(rdata->offset + rdata->bytes - 1) / PAGE_SIZE);
|
||||
/* Fallback to the readpage in error/reconnect cases */
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
break;
|
||||
}
|
||||
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
}
|
||||
|
||||
free_xid(xid);
|
||||
|
|
|
|||
|
|
@ -4490,7 +4490,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
|
|||
unsigned int cur_off;
|
||||
unsigned int cur_page_idx;
|
||||
unsigned int pad_len;
|
||||
struct cifs_readdata *rdata = mid->callback_data;
|
||||
struct cifs_io_subrequest *rdata = mid->callback_data;
|
||||
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
|
||||
int length;
|
||||
bool use_rdma_mr = false;
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@
|
|||
#include <linux/uuid.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/xattr.h>
|
||||
#include <linux/netfs.h>
|
||||
#include <trace/events/netfs.h>
|
||||
#include "cifsglob.h"
|
||||
#include "cifsacl.h"
|
||||
#include "cifsproto.h"
|
||||
|
|
@ -4391,7 +4393,7 @@ static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)
|
|||
*/
|
||||
static int
|
||||
smb2_new_read_req(void **buf, unsigned int *total_len,
|
||||
struct cifs_io_parms *io_parms, struct cifs_readdata *rdata,
|
||||
struct cifs_io_parms *io_parms, struct cifs_io_subrequest *rdata,
|
||||
unsigned int remaining_bytes, int request_type)
|
||||
{
|
||||
int rc = -EACCES;
|
||||
|
|
@ -4483,7 +4485,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
|
|||
static void
|
||||
smb2_readv_callback(struct mid_q_entry *mid)
|
||||
{
|
||||
struct cifs_readdata *rdata = mid->callback_data;
|
||||
struct cifs_io_subrequest *rdata = mid->callback_data;
|
||||
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
|
||||
struct TCP_Server_Info *server = rdata->server;
|
||||
struct smb2_hdr *shdr =
|
||||
|
|
@ -4570,7 +4572,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
|
|||
|
||||
/* smb2_async_readv - send an async read, and set up mid to handle result */
|
||||
int
|
||||
smb2_async_readv(struct cifs_readdata *rdata)
|
||||
smb2_async_readv(struct cifs_io_subrequest *rdata)
|
||||
{
|
||||
int rc, flags = 0;
|
||||
char *buf;
|
||||
|
|
@ -4628,13 +4630,13 @@ smb2_async_readv(struct cifs_readdata *rdata)
|
|||
flags |= CIFS_HAS_CREDITS;
|
||||
}
|
||||
|
||||
kref_get(&rdata->refcount);
|
||||
cifs_get_readdata(rdata);
|
||||
rc = cifs_call_async(server, &rqst,
|
||||
cifs_readv_receive, smb2_readv_callback,
|
||||
smb3_handle_read_data, rdata, flags,
|
||||
&rdata->credits);
|
||||
if (rc) {
|
||||
kref_put(&rdata->refcount, cifs_readdata_release);
|
||||
cifs_put_readdata(rdata);
|
||||
cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
|
||||
trace_smb3_read_err(0 /* xid */, io_parms.persistent_fid,
|
||||
io_parms.tcon->tid,
|
||||
|
|
|
|||
|
|
@ -210,7 +210,7 @@ extern int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
|
||||
u64 persistent_fid, u64 volatile_fid,
|
||||
__le64 *uniqueid);
|
||||
extern int smb2_async_readv(struct cifs_readdata *rdata);
|
||||
extern int smb2_async_readv(struct cifs_io_subrequest *rdata);
|
||||
extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, char **buf, int *buf_type);
|
||||
extern int smb2_async_writev(struct cifs_writedata *wdata,
|
||||
|
|
|
|||
|
|
@ -1692,7 +1692,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
|
|||
static int
|
||||
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
||||
{
|
||||
struct cifs_readdata *rdata = mid->callback_data;
|
||||
struct cifs_io_subrequest *rdata = mid->callback_data;
|
||||
|
||||
return __cifs_readv_discard(server, mid, rdata->result);
|
||||
}
|
||||
|
|
@ -1702,7 +1702,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
|
|||
{
|
||||
int length, len;
|
||||
unsigned int data_offset, data_len;
|
||||
struct cifs_readdata *rdata = mid->callback_data;
|
||||
struct cifs_io_subrequest *rdata = mid->callback_data;
|
||||
char *buf = server->smallbuf;
|
||||
unsigned int buflen = server->pdu_size + HEADER_PREAMBLE_SIZE(server);
|
||||
bool use_rdma_mr = false;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue