Skip to content

Commit 753b67e

Browse files
committed
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
1 parent 0f7c0f3 commit 753b67e

8 files changed

Lines changed: 58 additions & 52 deletions

File tree

fs/smb/client/cifsglob.h

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ struct dfs_info3_param;
268268
struct cifs_fattr;
269269
struct smb3_fs_context;
270270
struct cifs_fid;
271-
struct cifs_readdata;
271+
struct cifs_io_subrequest;
272272
struct cifs_writedata;
273273
struct cifs_io_parms;
274274
struct cifs_search_info;
@@ -450,7 +450,7 @@ struct smb_version_operations {
450450
/* send a flush request to the server */
451451
int (*flush)(const unsigned int, struct cifs_tcon *, struct cifs_fid *);
452452
/* async read from the server */
453-
int (*async_readv)(struct cifs_readdata *);
453+
int (*async_readv)(struct cifs_io_subrequest *);
454454
/* async write to the server */
455455
int (*async_writev)(struct cifs_writedata *,
456456
void (*release)(struct kref *));
@@ -1493,26 +1493,28 @@ struct cifs_aio_ctx {
14931493
};
14941494

14951495
/* asynchronous read support */
1496-
struct cifs_readdata {
1497-
struct kref refcount;
1498-
struct list_head list;
1499-
struct completion done;
1496+
struct cifs_io_subrequest {
1497+
struct netfs_io_subrequest subreq;
15001498
struct cifsFileInfo *cfile;
15011499
struct address_space *mapping;
15021500
struct cifs_aio_ctx *ctx;
1503-
__u64 offset;
15041501
ssize_t got_bytes;
1505-
unsigned int bytes;
15061502
pid_t pid;
15071503
int result;
1508-
struct work_struct work;
1509-
struct iov_iter iter;
15101504
struct kvec iov[2];
15111505
struct TCP_Server_Info *server;
15121506
#ifdef CONFIG_CIFS_SMB_DIRECT
15131507
struct smbd_mr *mr;
15141508
#endif
15151509
struct cifs_credits credits;
1510+
1511+
// TODO: Remove following elements
1512+
struct list_head list;
1513+
struct completion done;
1514+
struct work_struct work;
1515+
struct iov_iter iter;
1516+
__u64 offset;
1517+
unsigned int bytes;
15161518
};
15171519

15181520
/* asynchronous write support */

fs/smb/client/cifsproto.h

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -599,8 +599,17 @@ void __cifs_put_smb_ses(struct cifs_ses *ses);
599599
extern struct cifs_ses *
600600
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx);
601601

602-
void cifs_readdata_release(struct kref *refcount);
603-
int cifs_async_readv(struct cifs_readdata *rdata);
602+
void cifs_readdata_release(struct cifs_io_subrequest *rdata);
603+
static inline void cifs_get_readdata(struct cifs_io_subrequest *rdata)
604+
{
605+
refcount_inc(&rdata->subreq.ref);
606+
}
607+
static inline void cifs_put_readdata(struct cifs_io_subrequest *rdata)
608+
{
609+
if (refcount_dec_and_test(&rdata->subreq.ref))
610+
cifs_readdata_release(rdata);
611+
}
612+
int cifs_async_readv(struct cifs_io_subrequest *rdata);
604613
int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
605614

606615
int cifs_async_writev(struct cifs_writedata *wdata,

fs/smb/client/cifssmb.c

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <linux/swap.h>
2525
#include <linux/task_io_accounting_ops.h>
2626
#include <linux/uaccess.h>
27+
#include <linux/netfs.h>
28+
#include <trace/events/netfs.h>
2729
#include "cifspdu.h"
2830
#include "cifsfs.h"
2931
#include "cifsglob.h"
@@ -1262,12 +1264,11 @@ CIFS_open(const unsigned int xid, struct cifs_open_parms *oparms, int *oplock,
12621264
static void
12631265
cifs_readv_callback(struct mid_q_entry *mid)
12641266
{
1265-
struct cifs_readdata *rdata = mid->callback_data;
1267+
struct cifs_io_subrequest *rdata = mid->callback_data;
12661268
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
12671269
struct TCP_Server_Info *server = tcon->ses->server;
12681270
struct smb_rqst rqst = { .rq_iov = rdata->iov,
12691271
.rq_nvec = 2,
1270-
.rq_iter_size = iov_iter_count(&rdata->iter),
12711272
.rq_iter = rdata->iter };
12721273
struct cifs_credits credits = { .value = 1, .instance = 0 };
12731274

@@ -1312,7 +1313,7 @@ cifs_readv_callback(struct mid_q_entry *mid)
13121313

13131314
/* cifs_async_readv - send an async write, and set up mid to handle result */
13141315
int
1315-
cifs_async_readv(struct cifs_readdata *rdata)
1316+
cifs_async_readv(struct cifs_io_subrequest *rdata)
13161317
{
13171318
int rc;
13181319
READ_REQ *smb = NULL;
@@ -1364,15 +1365,11 @@ cifs_async_readv(struct cifs_readdata *rdata)
13641365
rdata->iov[1].iov_base = (char *)smb + 4;
13651366
rdata->iov[1].iov_len = get_rfc1002_length(smb);
13661367

1367-
kref_get(&rdata->refcount);
13681368
rc = cifs_call_async(tcon->ses->server, &rqst, cifs_readv_receive,
13691369
cifs_readv_callback, NULL, rdata, 0, NULL);
13701370

13711371
if (rc == 0)
13721372
cifs_stats_inc(&tcon->stats.cifs_stats.num_reads);
1373-
else
1374-
kref_put(&rdata->refcount, cifs_readdata_release);
1375-
13761373
cifs_small_buf_release(smb);
13771374
return rc;
13781375
}

fs/smb/client/file.c

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3822,13 +3822,13 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
38223822
return written;
38233823
}
38243824

3825-
static struct cifs_readdata *cifs_readdata_alloc(work_func_t complete)
3825+
static struct cifs_io_subrequest *cifs_readdata_alloc(work_func_t complete)
38263826
{
3827-
struct cifs_readdata *rdata;
3827+
struct cifs_io_subrequest *rdata;
38283828

38293829
rdata = kzalloc(sizeof(*rdata), GFP_KERNEL);
38303830
if (rdata) {
3831-
kref_init(&rdata->refcount);
3831+
refcount_set(&rdata->subreq.ref, 1);
38323832
INIT_LIST_HEAD(&rdata->list);
38333833
init_completion(&rdata->done);
38343834
INIT_WORK(&rdata->work, complete);
@@ -3838,11 +3838,8 @@ static struct cifs_readdata *cifs_readdata_alloc(work_func_t complete)
38383838
}
38393839

38403840
void
3841-
cifs_readdata_release(struct kref *refcount)
3841+
cifs_readdata_release(struct cifs_io_subrequest *rdata)
38423842
{
3843-
struct cifs_readdata *rdata = container_of(refcount,
3844-
struct cifs_readdata, refcount);
3845-
38463843
if (rdata->ctx)
38473844
kref_put(&rdata->ctx->refcount, cifs_aio_ctx_release);
38483845
#ifdef CONFIG_CIFS_SMB_DIRECT
@@ -3862,16 +3859,16 @@ static void collect_uncached_read_data(struct cifs_aio_ctx *ctx);
38623859
static void
38633860
cifs_uncached_readv_complete(struct work_struct *work)
38643861
{
3865-
struct cifs_readdata *rdata = container_of(work,
3866-
struct cifs_readdata, work);
3862+
struct cifs_io_subrequest *rdata =
3863+
container_of(work, struct cifs_io_subrequest, work);
38673864

38683865
complete(&rdata->done);
38693866
collect_uncached_read_data(rdata->ctx);
38703867
/* the below call can possibly free the last ref to aio ctx */
3871-
kref_put(&rdata->refcount, cifs_readdata_release);
3868+
cifs_put_readdata(rdata);
38723869
}
38733870

3874-
static int cifs_resend_rdata(struct cifs_readdata *rdata,
3871+
static int cifs_resend_rdata(struct cifs_io_subrequest *rdata,
38753872
struct list_head *rdata_list,
38763873
struct cifs_aio_ctx *ctx)
38773874
{
@@ -3939,7 +3936,7 @@ static int cifs_resend_rdata(struct cifs_readdata *rdata,
39393936
} while (rc == -EAGAIN);
39403937

39413938
fail:
3942-
kref_put(&rdata->refcount, cifs_readdata_release);
3939+
cifs_put_readdata(rdata);
39433940
return rc;
39443941
}
39453942

@@ -3948,7 +3945,7 @@ cifs_send_async_read(loff_t fpos, size_t len, struct cifsFileInfo *open_file,
39483945
struct cifs_sb_info *cifs_sb, struct list_head *rdata_list,
39493946
struct cifs_aio_ctx *ctx)
39503947
{
3951-
struct cifs_readdata *rdata;
3948+
struct cifs_io_subrequest *rdata;
39523949
unsigned int rsize, nsegs, max_segs = INT_MAX;
39533950
struct cifs_credits credits_on_stack;
39543951
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,
40304027

40314028
if (rc) {
40324029
add_credits_and_wake_if(server, &rdata->credits, 0);
4033-
kref_put(&rdata->refcount, cifs_readdata_release);
4030+
cifs_put_readdata(rdata);
40344031
if (rc == -EAGAIN)
40354032
continue;
40364033
break;
@@ -4048,7 +4045,7 @@ cifs_send_async_read(loff_t fpos, size_t len, struct cifsFileInfo *open_file,
40484045
static void
40494046
collect_uncached_read_data(struct cifs_aio_ctx *ctx)
40504047
{
4051-
struct cifs_readdata *rdata, *tmp;
4048+
struct cifs_io_subrequest *rdata, *tmp;
40524049
struct cifs_sb_info *cifs_sb;
40534050
int rc;
40544051

@@ -4094,8 +4091,7 @@ collect_uncached_read_data(struct cifs_aio_ctx *ctx)
40944091
rdata->cfile, cifs_sb,
40954092
&tmp_list, ctx);
40964093

4097-
kref_put(&rdata->refcount,
4098-
cifs_readdata_release);
4094+
cifs_put_readdata(rdata);
40994095
}
41004096

41014097
list_splice(&tmp_list, &ctx->list);
@@ -4111,7 +4107,7 @@ collect_uncached_read_data(struct cifs_aio_ctx *ctx)
41114107
ctx->total_len += rdata->got_bytes;
41124108
}
41134109
list_del_init(&rdata->list);
4114-
kref_put(&rdata->refcount, cifs_readdata_release);
4110+
cifs_put_readdata(rdata);
41154111
}
41164112

41174113
/* mask nodata case */
@@ -4483,8 +4479,8 @@ static void cifs_unlock_folios(struct address_space *mapping, pgoff_t first, pgo
44834479

44844480
static void cifs_readahead_complete(struct work_struct *work)
44854481
{
4486-
struct cifs_readdata *rdata = container_of(work,
4487-
struct cifs_readdata, work);
4482+
struct cifs_io_subrequest *rdata = container_of(work,
4483+
struct cifs_io_subrequest, work);
44884484
struct folio *folio;
44894485
pgoff_t last;
44904486
bool good = rdata->result == 0 || (rdata->result == -EAGAIN && rdata->got_bytes);
@@ -4510,7 +4506,7 @@ static void cifs_readahead_complete(struct work_struct *work)
45104506
}
45114507
rcu_read_unlock();
45124508

4513-
kref_put(&rdata->refcount, cifs_readdata_release);
4509+
cifs_put_readdata(rdata);
45144510
}
45154511

45164512
static void cifs_readahead(struct readahead_control *ractl)
@@ -4550,7 +4546,7 @@ static void cifs_readahead(struct readahead_control *ractl)
45504546
*/
45514547
while ((nr_pages = ra_pages)) {
45524548
unsigned int i, rsize;
4553-
struct cifs_readdata *rdata;
4549+
struct cifs_io_subrequest *rdata;
45544550
struct cifs_credits credits_on_stack;
45554551
struct cifs_credits *credits = &credits_on_stack;
45564552
struct folio *folio;
@@ -4669,11 +4665,11 @@ static void cifs_readahead(struct readahead_control *ractl)
46694665
rdata->offset / PAGE_SIZE,
46704666
(rdata->offset + rdata->bytes - 1) / PAGE_SIZE);
46714667
/* Fallback to the readpage in error/reconnect cases */
4672-
kref_put(&rdata->refcount, cifs_readdata_release);
4668+
cifs_put_readdata(rdata);
46734669
break;
46744670
}
46754671

4676-
kref_put(&rdata->refcount, cifs_readdata_release);
4672+
cifs_put_readdata(rdata);
46774673
}
46784674

46794675
free_xid(xid);

fs/smb/client/smb2ops.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4490,7 +4490,7 @@ handle_read_data(struct TCP_Server_Info *server, struct mid_q_entry *mid,
44904490
unsigned int cur_off;
44914491
unsigned int cur_page_idx;
44924492
unsigned int pad_len;
4493-
struct cifs_readdata *rdata = mid->callback_data;
4493+
struct cifs_io_subrequest *rdata = mid->callback_data;
44944494
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
44954495
int length;
44964496
bool use_rdma_mr = false;

fs/smb/client/smb2pdu.c

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@
2323
#include <linux/uuid.h>
2424
#include <linux/pagemap.h>
2525
#include <linux/xattr.h>
26+
#include <linux/netfs.h>
27+
#include <trace/events/netfs.h>
2628
#include "cifsglob.h"
2729
#include "cifsacl.h"
2830
#include "cifsproto.h"
@@ -4391,7 +4393,7 @@ static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)
43914393
*/
43924394
static int
43934395
smb2_new_read_req(void **buf, unsigned int *total_len,
4394-
struct cifs_io_parms *io_parms, struct cifs_readdata *rdata,
4396+
struct cifs_io_parms *io_parms, struct cifs_io_subrequest *rdata,
43954397
unsigned int remaining_bytes, int request_type)
43964398
{
43974399
int rc = -EACCES;
@@ -4483,7 +4485,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
44834485
static void
44844486
smb2_readv_callback(struct mid_q_entry *mid)
44854487
{
4486-
struct cifs_readdata *rdata = mid->callback_data;
4488+
struct cifs_io_subrequest *rdata = mid->callback_data;
44874489
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
44884490
struct TCP_Server_Info *server = rdata->server;
44894491
struct smb2_hdr *shdr =
@@ -4570,7 +4572,7 @@ smb2_readv_callback(struct mid_q_entry *mid)
45704572

45714573
/* smb2_async_readv - send an async read, and set up mid to handle result */
45724574
int
4573-
smb2_async_readv(struct cifs_readdata *rdata)
4575+
smb2_async_readv(struct cifs_io_subrequest *rdata)
45744576
{
45754577
int rc, flags = 0;
45764578
char *buf;
@@ -4628,13 +4630,13 @@ smb2_async_readv(struct cifs_readdata *rdata)
46284630
flags |= CIFS_HAS_CREDITS;
46294631
}
46304632

4631-
kref_get(&rdata->refcount);
4633+
cifs_get_readdata(rdata);
46324634
rc = cifs_call_async(server, &rqst,
46334635
cifs_readv_receive, smb2_readv_callback,
46344636
smb3_handle_read_data, rdata, flags,
46354637
&rdata->credits);
46364638
if (rc) {
4637-
kref_put(&rdata->refcount, cifs_readdata_release);
4639+
cifs_put_readdata(rdata);
46384640
cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
46394641
trace_smb3_read_err(0 /* xid */, io_parms.persistent_fid,
46404642
io_parms.tcon->tid,

fs/smb/client/smb2proto.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ extern int SMB2_query_acl(const unsigned int xid, struct cifs_tcon *tcon,
210210
extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
211211
u64 persistent_fid, u64 volatile_fid,
212212
__le64 *uniqueid);
213-
extern int smb2_async_readv(struct cifs_readdata *rdata);
213+
extern int smb2_async_readv(struct cifs_io_subrequest *rdata);
214214
extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
215215
unsigned int *nbytes, char **buf, int *buf_type);
216216
extern int smb2_async_writev(struct cifs_writedata *wdata,

fs/smb/client/transport.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,7 +1692,7 @@ __cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid,
16921692
static int
16931693
cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
16941694
{
1695-
struct cifs_readdata *rdata = mid->callback_data;
1695+
struct cifs_io_subrequest *rdata = mid->callback_data;
16961696

16971697
return __cifs_readv_discard(server, mid, rdata->result);
16981698
}
@@ -1702,7 +1702,7 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
17021702
{
17031703
int length, len;
17041704
unsigned int data_offset, data_len;
1705-
struct cifs_readdata *rdata = mid->callback_data;
1705+
struct cifs_io_subrequest *rdata = mid->callback_data;
17061706
char *buf = server->smallbuf;
17071707
unsigned int buflen = server->pdu_size + HEADER_PREAMBLE_SIZE(server);
17081708
bool use_rdma_mr = false;

0 commit comments

Comments
 (0)