Skip to content

Commit a975a2f

Browse files
committed
cifs: Replace cifs_writedata with a wrapper around netfs_io_subrequest
Replace the cifs_writedata struct with the same wrapper around netfs_io_subrequest that was used to replace cifs_readdata. 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 753b67e commit a975a2f

6 files changed

Lines changed: 59 additions & 89 deletions

File tree

fs/smb/client/cifsglob.h

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@ struct cifs_fattr;
269269
struct smb3_fs_context;
270270
struct cifs_fid;
271271
struct cifs_io_subrequest;
272-
struct cifs_writedata;
273272
struct cifs_io_parms;
274273
struct cifs_search_info;
275274
struct cifsInodeInfo;
@@ -452,8 +451,7 @@ struct smb_version_operations {
452451
/* async read from the server */
453452
int (*async_readv)(struct cifs_io_subrequest *);
454453
/* async write to the server */
455-
int (*async_writev)(struct cifs_writedata *,
456-
void (*release)(struct kref *));
454+
int (*async_writev)(struct cifs_io_subrequest *);
457455
/* sync read from the server */
458456
int (*sync_read)(const unsigned int, struct cifs_fid *,
459457
struct cifs_io_parms *, unsigned int *, char **,
@@ -1508,36 +1506,18 @@ struct cifs_io_subrequest {
15081506
#endif
15091507
struct cifs_credits credits;
15101508

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;
1518-
};
1509+
enum writeback_sync_modes sync_mode;
1510+
bool uncached;
1511+
bool replay;
1512+
struct bio_vec *bv;
15191513

1520-
/* asynchronous write support */
1521-
struct cifs_writedata {
1522-
struct kref refcount;
1514+
// TODO: Remove following elements
15231515
struct list_head list;
15241516
struct completion done;
1525-
enum writeback_sync_modes sync_mode;
15261517
struct work_struct work;
1527-
struct cifsFileInfo *cfile;
1528-
struct cifs_aio_ctx *ctx;
15291518
struct iov_iter iter;
1530-
struct bio_vec *bv;
15311519
__u64 offset;
1532-
pid_t pid;
15331520
unsigned int bytes;
1534-
int result;
1535-
struct TCP_Server_Info *server;
1536-
#ifdef CONFIG_CIFS_SMB_DIRECT
1537-
struct smbd_mr *mr;
1538-
#endif
1539-
struct cifs_credits credits;
1540-
bool replay;
15411521
};
15421522

15431523
/*

fs/smb/client/cifsproto.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -612,11 +612,19 @@ static inline void cifs_put_readdata(struct cifs_io_subrequest *rdata)
612612
int cifs_async_readv(struct cifs_io_subrequest *rdata);
613613
int cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid);
614614

615-
int cifs_async_writev(struct cifs_writedata *wdata,
616-
void (*release)(struct kref *kref));
615+
int cifs_async_writev(struct cifs_io_subrequest *wdata);
617616
void cifs_writev_complete(struct work_struct *work);
618-
struct cifs_writedata *cifs_writedata_alloc(work_func_t complete);
619-
void cifs_writedata_release(struct kref *refcount);
617+
struct cifs_io_subrequest *cifs_writedata_alloc(work_func_t complete);
618+
void cifs_writedata_release(struct cifs_io_subrequest *rdata);
619+
static inline void cifs_get_writedata(struct cifs_io_subrequest *wdata)
620+
{
621+
refcount_inc(&wdata->subreq.ref);
622+
}
623+
static inline void cifs_put_writedata(struct cifs_io_subrequest *wdata)
624+
{
625+
if (refcount_dec_and_test(&wdata->subreq.ref))
626+
cifs_writedata_release(wdata);
627+
}
620628
int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
621629
struct cifs_sb_info *cifs_sb,
622630
const unsigned char *path, char *pbuf,

fs/smb/client/cifssmb.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1612,7 +1612,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
16121612
static void
16131613
cifs_writev_callback(struct mid_q_entry *mid)
16141614
{
1615-
struct cifs_writedata *wdata = mid->callback_data;
1615+
struct cifs_io_subrequest *wdata = mid->callback_data;
16161616
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
16171617
unsigned int written;
16181618
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
@@ -1657,8 +1657,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
16571657

16581658
/* cifs_async_writev - send an async write, and set up mid to handle result */
16591659
int
1660-
cifs_async_writev(struct cifs_writedata *wdata,
1661-
void (*release)(struct kref *kref))
1660+
cifs_async_writev(struct cifs_io_subrequest *wdata)
16621661
{
16631662
int rc = -EACCES;
16641663
WRITE_REQ *smb = NULL;
@@ -1725,14 +1724,14 @@ cifs_async_writev(struct cifs_writedata *wdata,
17251724
iov[1].iov_len += 4; /* pad bigger by four bytes */
17261725
}
17271726

1728-
kref_get(&wdata->refcount);
1727+
cifs_get_writedata(wdata);
17291728
rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
17301729
cifs_writev_callback, NULL, wdata, 0, NULL);
17311730

17321731
if (rc == 0)
17331732
cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
17341733
else
1735-
kref_put(&wdata->refcount, release);
1734+
cifs_put_writedata(wdata);
17361735

17371736
async_writev_out:
17381737
cifs_small_buf_release(smb);

fs/smb/client/file.c

Lines changed: 32 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2510,10 +2510,10 @@ cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
25102510
}
25112511

25122512
void
2513-
cifs_writedata_release(struct kref *refcount)
2513+
cifs_writedata_release(struct cifs_io_subrequest *wdata)
25142514
{
2515-
struct cifs_writedata *wdata = container_of(refcount,
2516-
struct cifs_writedata, refcount);
2515+
if (wdata->uncached)
2516+
kref_put(&wdata->ctx->refcount, cifs_aio_ctx_release);
25172517
#ifdef CONFIG_CIFS_SMB_DIRECT
25182518
if (wdata->mr) {
25192519
smbd_deregister_mr(wdata->mr);
@@ -2532,7 +2532,7 @@ cifs_writedata_release(struct kref *refcount)
25322532
* possible that the page was redirtied so re-clean the page.
25332533
*/
25342534
static void
2535-
cifs_writev_requeue(struct cifs_writedata *wdata)
2535+
cifs_writev_requeue(struct cifs_io_subrequest *wdata)
25362536
{
25372537
int rc = 0;
25382538
struct inode *inode = d_inode(wdata->cfile->dentry);
@@ -2542,7 +2542,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
25422542

25432543
server = tlink_tcon(wdata->cfile->tlink)->ses->server;
25442544
do {
2545-
struct cifs_writedata *wdata2;
2545+
struct cifs_io_subrequest *wdata2;
25462546
unsigned int wsize, cur_len;
25472547

25482548
wsize = server->ops->wp_retry_size(inode);
@@ -2565,7 +2565,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
25652565
wdata2->sync_mode = wdata->sync_mode;
25662566
wdata2->offset = fpos;
25672567
wdata2->bytes = cur_len;
2568-
wdata2->iter = wdata->iter;
2568+
wdata2->iter = wdata->iter;
25692569

25702570
iov_iter_advance(&wdata2->iter, fpos - wdata->offset);
25712571
iov_iter_truncate(&wdata2->iter, wdata2->bytes);
@@ -2587,11 +2587,10 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
25872587
rc = -EBADF;
25882588
} else {
25892589
wdata2->pid = wdata2->cfile->pid;
2590-
rc = server->ops->async_writev(wdata2,
2591-
cifs_writedata_release);
2590+
rc = server->ops->async_writev(wdata2);
25922591
}
25932592

2594-
kref_put(&wdata2->refcount, cifs_writedata_release);
2593+
cifs_put_writedata(wdata2);
25952594
if (rc) {
25962595
if (is_retryable_error(rc))
25972596
continue;
@@ -2610,14 +2609,14 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
26102609

26112610
if (rc != 0 && !is_retryable_error(rc))
26122611
mapping_set_error(inode->i_mapping, rc);
2613-
kref_put(&wdata->refcount, cifs_writedata_release);
2612+
cifs_put_writedata(wdata);
26142613
}
26152614

26162615
void
26172616
cifs_writev_complete(struct work_struct *work)
26182617
{
2619-
struct cifs_writedata *wdata = container_of(work,
2620-
struct cifs_writedata, work);
2618+
struct cifs_io_subrequest *wdata = container_of(work,
2619+
struct cifs_io_subrequest, work);
26212620
struct inode *inode = d_inode(wdata->cfile->dentry);
26222621

26232622
if (wdata->result == 0) {
@@ -2638,16 +2637,16 @@ cifs_writev_complete(struct work_struct *work)
26382637

26392638
if (wdata->result != -EAGAIN)
26402639
mapping_set_error(inode->i_mapping, wdata->result);
2641-
kref_put(&wdata->refcount, cifs_writedata_release);
2640+
cifs_put_writedata(wdata);
26422641
}
26432642

2644-
struct cifs_writedata *cifs_writedata_alloc(work_func_t complete)
2643+
struct cifs_io_subrequest *cifs_writedata_alloc(work_func_t complete)
26452644
{
2646-
struct cifs_writedata *wdata;
2645+
struct cifs_io_subrequest *wdata;
26472646

26482647
wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
26492648
if (wdata != NULL) {
2650-
kref_init(&wdata->refcount);
2649+
refcount_set(&wdata->subreq.ref, 1);
26512650
INIT_LIST_HEAD(&wdata->list);
26522651
init_completion(&wdata->done);
26532652
INIT_WORK(&wdata->work, complete);
@@ -2778,7 +2777,7 @@ static ssize_t cifs_write_back_from_locked_folio(struct address_space *mapping,
27782777
{
27792778
struct inode *inode = mapping->host;
27802779
struct TCP_Server_Info *server;
2781-
struct cifs_writedata *wdata;
2780+
struct cifs_io_subrequest *wdata;
27822781
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
27832782
struct cifs_credits credits_on_stack;
27842783
struct cifs_credits *credits = &credits_on_stack;
@@ -2871,10 +2870,9 @@ static ssize_t cifs_write_back_from_locked_folio(struct address_space *mapping,
28712870
if (wdata->cfile->invalidHandle)
28722871
rc = -EAGAIN;
28732872
else
2874-
rc = wdata->server->ops->async_writev(wdata,
2875-
cifs_writedata_release);
2873+
rc = wdata->server->ops->async_writev(wdata);
28762874
if (rc >= 0) {
2877-
kref_put(&wdata->refcount, cifs_writedata_release);
2875+
cifs_put_writedata(wdata);
28782876
goto err_close;
28792877
}
28802878
} else {
@@ -2884,7 +2882,7 @@ static ssize_t cifs_write_back_from_locked_folio(struct address_space *mapping,
28842882
}
28852883

28862884
err_wdata:
2887-
kref_put(&wdata->refcount, cifs_writedata_release);
2885+
cifs_put_writedata(wdata);
28882886
err_uncredit:
28892887
add_credits_and_wake_if(server, credits, 0);
28902888
err_close:
@@ -3261,23 +3259,13 @@ int cifs_flush(struct file *file, fl_owner_t id)
32613259
return rc;
32623260
}
32633261

3264-
static void
3265-
cifs_uncached_writedata_release(struct kref *refcount)
3266-
{
3267-
struct cifs_writedata *wdata = container_of(refcount,
3268-
struct cifs_writedata, refcount);
3269-
3270-
kref_put(&wdata->ctx->refcount, cifs_aio_ctx_release);
3271-
cifs_writedata_release(refcount);
3272-
}
3273-
32743262
static void collect_uncached_write_data(struct cifs_aio_ctx *ctx);
32753263

32763264
static void
32773265
cifs_uncached_writev_complete(struct work_struct *work)
32783266
{
3279-
struct cifs_writedata *wdata = container_of(work,
3280-
struct cifs_writedata, work);
3267+
struct cifs_io_subrequest *wdata = container_of(work,
3268+
struct cifs_io_subrequest, work);
32813269
struct inode *inode = d_inode(wdata->cfile->dentry);
32823270
struct cifsInodeInfo *cifsi = CIFS_I(inode);
32833271

@@ -3290,11 +3278,11 @@ cifs_uncached_writev_complete(struct work_struct *work)
32903278
complete(&wdata->done);
32913279
collect_uncached_write_data(wdata->ctx);
32923280
/* the below call can possibly free the last ref to aio ctx */
3293-
kref_put(&wdata->refcount, cifs_uncached_writedata_release);
3281+
cifs_put_writedata(wdata);
32943282
}
32953283

32963284
static int
3297-
cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
3285+
cifs_resend_wdata(struct cifs_io_subrequest *wdata, struct list_head *wdata_list,
32983286
struct cifs_aio_ctx *ctx)
32993287
{
33003288
unsigned int wsize;
@@ -3344,8 +3332,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
33443332
wdata->mr = NULL;
33453333
}
33463334
#endif
3347-
rc = server->ops->async_writev(wdata,
3348-
cifs_uncached_writedata_release);
3335+
rc = server->ops->async_writev(wdata);
33493336
}
33503337
}
33513338

@@ -3360,7 +3347,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
33603347
} while (rc == -EAGAIN);
33613348

33623349
fail:
3363-
kref_put(&wdata->refcount, cifs_uncached_writedata_release);
3350+
cifs_put_writedata(wdata);
33643351
return rc;
33653352
}
33663353

@@ -3412,7 +3399,7 @@ cifs_write_from_iter(loff_t fpos, size_t len, struct iov_iter *from,
34123399
{
34133400
int rc = 0;
34143401
size_t cur_len, max_len;
3415-
struct cifs_writedata *wdata;
3402+
struct cifs_io_subrequest *wdata;
34163403
pid_t pid;
34173404
struct TCP_Server_Info *server;
34183405
unsigned int xid, max_segs = INT_MAX;
@@ -3476,6 +3463,7 @@ cifs_write_from_iter(loff_t fpos, size_t len, struct iov_iter *from,
34763463
break;
34773464
}
34783465

3466+
wdata->uncached = true;
34793467
wdata->sync_mode = WB_SYNC_ALL;
34803468
wdata->offset = (__u64)fpos;
34813469
wdata->cfile = cifsFileInfo_get(open_file);
@@ -3495,14 +3483,12 @@ cifs_write_from_iter(loff_t fpos, size_t len, struct iov_iter *from,
34953483
if (wdata->cfile->invalidHandle)
34963484
rc = -EAGAIN;
34973485
else
3498-
rc = server->ops->async_writev(wdata,
3499-
cifs_uncached_writedata_release);
3486+
rc = server->ops->async_writev(wdata);
35003487
}
35013488

35023489
if (rc) {
35033490
add_credits_and_wake_if(server, &wdata->credits, 0);
3504-
kref_put(&wdata->refcount,
3505-
cifs_uncached_writedata_release);
3491+
cifs_put_writedata(wdata);
35063492
if (rc == -EAGAIN)
35073493
continue;
35083494
break;
@@ -3520,7 +3506,7 @@ cifs_write_from_iter(loff_t fpos, size_t len, struct iov_iter *from,
35203506

35213507
static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)
35223508
{
3523-
struct cifs_writedata *wdata, *tmp;
3509+
struct cifs_io_subrequest *wdata, *tmp;
35243510
struct cifs_tcon *tcon;
35253511
struct cifs_sb_info *cifs_sb;
35263512
struct dentry *dentry = ctx->cfile->dentry;
@@ -3575,16 +3561,15 @@ static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)
35753561
ctx->cfile, cifs_sb, &tmp_list,
35763562
ctx);
35773563

3578-
kref_put(&wdata->refcount,
3579-
cifs_uncached_writedata_release);
3564+
cifs_put_writedata(wdata);
35803565
}
35813566

35823567
list_splice(&tmp_list, &ctx->list);
35833568
goto restart_loop;
35843569
}
35853570
}
35863571
list_del_init(&wdata->list);
3587-
kref_put(&wdata->refcount, cifs_uncached_writedata_release);
3572+
cifs_put_writedata(wdata);
35883573
}
35893574

35903575
cifs_stats_bytes_written(tcon, ctx->total_len);

0 commit comments

Comments
 (0)