mirror of
https://github.com/torvalds/linux
synced 2024-10-15 07:47:34 +00:00
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
This commit is contained in:
parent
753b67eb63
commit
a975a2f22c
|
@ -269,7 +269,6 @@ struct cifs_fattr;
|
|||
struct smb3_fs_context;
|
||||
struct cifs_fid;
|
||||
struct cifs_io_subrequest;
|
||||
struct cifs_writedata;
|
||||
struct cifs_io_parms;
|
||||
struct cifs_search_info;
|
||||
struct cifsInodeInfo;
|
||||
|
@ -452,8 +451,7 @@ struct smb_version_operations {
|
|||
/* async read from the server */
|
||||
int (*async_readv)(struct cifs_io_subrequest *);
|
||||
/* async write to the server */
|
||||
int (*async_writev)(struct cifs_writedata *,
|
||||
void (*release)(struct kref *));
|
||||
int (*async_writev)(struct cifs_io_subrequest *);
|
||||
/* sync read from the server */
|
||||
int (*sync_read)(const unsigned int, struct cifs_fid *,
|
||||
struct cifs_io_parms *, unsigned int *, char **,
|
||||
|
@ -1508,6 +1506,11 @@ struct cifs_io_subrequest {
|
|||
#endif
|
||||
struct cifs_credits credits;
|
||||
|
||||
enum writeback_sync_modes sync_mode;
|
||||
bool uncached;
|
||||
bool replay;
|
||||
struct bio_vec *bv;
|
||||
|
||||
// TODO: Remove following elements
|
||||
struct list_head list;
|
||||
struct completion done;
|
||||
|
@ -1517,29 +1520,6 @@ struct cifs_io_subrequest {
|
|||
unsigned int bytes;
|
||||
};
|
||||
|
||||
/* asynchronous write support */
|
||||
struct cifs_writedata {
|
||||
struct kref refcount;
|
||||
struct list_head list;
|
||||
struct completion done;
|
||||
enum writeback_sync_modes sync_mode;
|
||||
struct work_struct work;
|
||||
struct cifsFileInfo *cfile;
|
||||
struct cifs_aio_ctx *ctx;
|
||||
struct iov_iter iter;
|
||||
struct bio_vec *bv;
|
||||
__u64 offset;
|
||||
pid_t pid;
|
||||
unsigned int bytes;
|
||||
int result;
|
||||
struct TCP_Server_Info *server;
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
struct smbd_mr *mr;
|
||||
#endif
|
||||
struct cifs_credits credits;
|
||||
bool replay;
|
||||
};
|
||||
|
||||
/*
|
||||
* Take a reference on the file private data. Must be called with
|
||||
* cfile->file_info_lock held.
|
||||
|
|
|
@ -612,11 +612,19 @@ static inline void cifs_put_readdata(struct cifs_io_subrequest *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,
|
||||
void (*release)(struct kref *kref));
|
||||
int cifs_async_writev(struct cifs_io_subrequest *wdata);
|
||||
void cifs_writev_complete(struct work_struct *work);
|
||||
struct cifs_writedata *cifs_writedata_alloc(work_func_t complete);
|
||||
void cifs_writedata_release(struct kref *refcount);
|
||||
struct cifs_io_subrequest *cifs_writedata_alloc(work_func_t complete);
|
||||
void cifs_writedata_release(struct cifs_io_subrequest *rdata);
|
||||
static inline void cifs_get_writedata(struct cifs_io_subrequest *wdata)
|
||||
{
|
||||
refcount_inc(&wdata->subreq.ref);
|
||||
}
|
||||
static inline void cifs_put_writedata(struct cifs_io_subrequest *wdata)
|
||||
{
|
||||
if (refcount_dec_and_test(&wdata->subreq.ref))
|
||||
cifs_writedata_release(wdata);
|
||||
}
|
||||
int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
|
||||
struct cifs_sb_info *cifs_sb,
|
||||
const unsigned char *path, char *pbuf,
|
||||
|
|
|
@ -1612,7 +1612,7 @@ CIFSSMBWrite(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|||
static void
|
||||
cifs_writev_callback(struct mid_q_entry *mid)
|
||||
{
|
||||
struct cifs_writedata *wdata = mid->callback_data;
|
||||
struct cifs_io_subrequest *wdata = mid->callback_data;
|
||||
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
|
||||
unsigned int written;
|
||||
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
|
||||
|
@ -1657,8 +1657,7 @@ cifs_writev_callback(struct mid_q_entry *mid)
|
|||
|
||||
/* cifs_async_writev - send an async write, and set up mid to handle result */
|
||||
int
|
||||
cifs_async_writev(struct cifs_writedata *wdata,
|
||||
void (*release)(struct kref *kref))
|
||||
cifs_async_writev(struct cifs_io_subrequest *wdata)
|
||||
{
|
||||
int rc = -EACCES;
|
||||
WRITE_REQ *smb = NULL;
|
||||
|
@ -1725,14 +1724,14 @@ cifs_async_writev(struct cifs_writedata *wdata,
|
|||
iov[1].iov_len += 4; /* pad bigger by four bytes */
|
||||
}
|
||||
|
||||
kref_get(&wdata->refcount);
|
||||
cifs_get_writedata(wdata);
|
||||
rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
|
||||
cifs_writev_callback, NULL, wdata, 0, NULL);
|
||||
|
||||
if (rc == 0)
|
||||
cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
|
||||
else
|
||||
kref_put(&wdata->refcount, release);
|
||||
cifs_put_writedata(wdata);
|
||||
|
||||
async_writev_out:
|
||||
cifs_small_buf_release(smb);
|
||||
|
|
|
@ -2510,10 +2510,10 @@ cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
|
|||
}
|
||||
|
||||
void
|
||||
cifs_writedata_release(struct kref *refcount)
|
||||
cifs_writedata_release(struct cifs_io_subrequest *wdata)
|
||||
{
|
||||
struct cifs_writedata *wdata = container_of(refcount,
|
||||
struct cifs_writedata, refcount);
|
||||
if (wdata->uncached)
|
||||
kref_put(&wdata->ctx->refcount, cifs_aio_ctx_release);
|
||||
#ifdef CONFIG_CIFS_SMB_DIRECT
|
||||
if (wdata->mr) {
|
||||
smbd_deregister_mr(wdata->mr);
|
||||
|
@ -2532,7 +2532,7 @@ cifs_writedata_release(struct kref *refcount)
|
|||
* possible that the page was redirtied so re-clean the page.
|
||||
*/
|
||||
static void
|
||||
cifs_writev_requeue(struct cifs_writedata *wdata)
|
||||
cifs_writev_requeue(struct cifs_io_subrequest *wdata)
|
||||
{
|
||||
int rc = 0;
|
||||
struct inode *inode = d_inode(wdata->cfile->dentry);
|
||||
|
@ -2542,7 +2542,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
|
|||
|
||||
server = tlink_tcon(wdata->cfile->tlink)->ses->server;
|
||||
do {
|
||||
struct cifs_writedata *wdata2;
|
||||
struct cifs_io_subrequest *wdata2;
|
||||
unsigned int wsize, cur_len;
|
||||
|
||||
wsize = server->ops->wp_retry_size(inode);
|
||||
|
@ -2565,7 +2565,7 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
|
|||
wdata2->sync_mode = wdata->sync_mode;
|
||||
wdata2->offset = fpos;
|
||||
wdata2->bytes = cur_len;
|
||||
wdata2->iter = wdata->iter;
|
||||
wdata2->iter = wdata->iter;
|
||||
|
||||
iov_iter_advance(&wdata2->iter, fpos - wdata->offset);
|
||||
iov_iter_truncate(&wdata2->iter, wdata2->bytes);
|
||||
|
@ -2587,11 +2587,10 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
|
|||
rc = -EBADF;
|
||||
} else {
|
||||
wdata2->pid = wdata2->cfile->pid;
|
||||
rc = server->ops->async_writev(wdata2,
|
||||
cifs_writedata_release);
|
||||
rc = server->ops->async_writev(wdata2);
|
||||
}
|
||||
|
||||
kref_put(&wdata2->refcount, cifs_writedata_release);
|
||||
cifs_put_writedata(wdata2);
|
||||
if (rc) {
|
||||
if (is_retryable_error(rc))
|
||||
continue;
|
||||
|
@ -2610,14 +2609,14 @@ cifs_writev_requeue(struct cifs_writedata *wdata)
|
|||
|
||||
if (rc != 0 && !is_retryable_error(rc))
|
||||
mapping_set_error(inode->i_mapping, rc);
|
||||
kref_put(&wdata->refcount, cifs_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
}
|
||||
|
||||
void
|
||||
cifs_writev_complete(struct work_struct *work)
|
||||
{
|
||||
struct cifs_writedata *wdata = container_of(work,
|
||||
struct cifs_writedata, work);
|
||||
struct cifs_io_subrequest *wdata = container_of(work,
|
||||
struct cifs_io_subrequest, work);
|
||||
struct inode *inode = d_inode(wdata->cfile->dentry);
|
||||
|
||||
if (wdata->result == 0) {
|
||||
|
@ -2638,16 +2637,16 @@ cifs_writev_complete(struct work_struct *work)
|
|||
|
||||
if (wdata->result != -EAGAIN)
|
||||
mapping_set_error(inode->i_mapping, wdata->result);
|
||||
kref_put(&wdata->refcount, cifs_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
}
|
||||
|
||||
struct cifs_writedata *cifs_writedata_alloc(work_func_t complete)
|
||||
struct cifs_io_subrequest *cifs_writedata_alloc(work_func_t complete)
|
||||
{
|
||||
struct cifs_writedata *wdata;
|
||||
struct cifs_io_subrequest *wdata;
|
||||
|
||||
wdata = kzalloc(sizeof(*wdata), GFP_NOFS);
|
||||
if (wdata != NULL) {
|
||||
kref_init(&wdata->refcount);
|
||||
refcount_set(&wdata->subreq.ref, 1);
|
||||
INIT_LIST_HEAD(&wdata->list);
|
||||
init_completion(&wdata->done);
|
||||
INIT_WORK(&wdata->work, complete);
|
||||
|
@ -2778,7 +2777,7 @@ static ssize_t cifs_write_back_from_locked_folio(struct address_space *mapping,
|
|||
{
|
||||
struct inode *inode = mapping->host;
|
||||
struct TCP_Server_Info *server;
|
||||
struct cifs_writedata *wdata;
|
||||
struct cifs_io_subrequest *wdata;
|
||||
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
|
||||
struct cifs_credits credits_on_stack;
|
||||
struct cifs_credits *credits = &credits_on_stack;
|
||||
|
@ -2871,10 +2870,9 @@ static ssize_t cifs_write_back_from_locked_folio(struct address_space *mapping,
|
|||
if (wdata->cfile->invalidHandle)
|
||||
rc = -EAGAIN;
|
||||
else
|
||||
rc = wdata->server->ops->async_writev(wdata,
|
||||
cifs_writedata_release);
|
||||
rc = wdata->server->ops->async_writev(wdata);
|
||||
if (rc >= 0) {
|
||||
kref_put(&wdata->refcount, cifs_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
goto err_close;
|
||||
}
|
||||
} else {
|
||||
|
@ -2884,7 +2882,7 @@ static ssize_t cifs_write_back_from_locked_folio(struct address_space *mapping,
|
|||
}
|
||||
|
||||
err_wdata:
|
||||
kref_put(&wdata->refcount, cifs_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
err_uncredit:
|
||||
add_credits_and_wake_if(server, credits, 0);
|
||||
err_close:
|
||||
|
@ -3261,23 +3259,13 @@ int cifs_flush(struct file *file, fl_owner_t id)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static void
|
||||
cifs_uncached_writedata_release(struct kref *refcount)
|
||||
{
|
||||
struct cifs_writedata *wdata = container_of(refcount,
|
||||
struct cifs_writedata, refcount);
|
||||
|
||||
kref_put(&wdata->ctx->refcount, cifs_aio_ctx_release);
|
||||
cifs_writedata_release(refcount);
|
||||
}
|
||||
|
||||
static void collect_uncached_write_data(struct cifs_aio_ctx *ctx);
|
||||
|
||||
static void
|
||||
cifs_uncached_writev_complete(struct work_struct *work)
|
||||
{
|
||||
struct cifs_writedata *wdata = container_of(work,
|
||||
struct cifs_writedata, work);
|
||||
struct cifs_io_subrequest *wdata = container_of(work,
|
||||
struct cifs_io_subrequest, work);
|
||||
struct inode *inode = d_inode(wdata->cfile->dentry);
|
||||
struct cifsInodeInfo *cifsi = CIFS_I(inode);
|
||||
|
||||
|
@ -3290,11 +3278,11 @@ cifs_uncached_writev_complete(struct work_struct *work)
|
|||
complete(&wdata->done);
|
||||
collect_uncached_write_data(wdata->ctx);
|
||||
/* the below call can possibly free the last ref to aio ctx */
|
||||
kref_put(&wdata->refcount, cifs_uncached_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
}
|
||||
|
||||
static int
|
||||
cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
|
||||
cifs_resend_wdata(struct cifs_io_subrequest *wdata, struct list_head *wdata_list,
|
||||
struct cifs_aio_ctx *ctx)
|
||||
{
|
||||
unsigned int wsize;
|
||||
|
@ -3344,8 +3332,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
|
|||
wdata->mr = NULL;
|
||||
}
|
||||
#endif
|
||||
rc = server->ops->async_writev(wdata,
|
||||
cifs_uncached_writedata_release);
|
||||
rc = server->ops->async_writev(wdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3360,7 +3347,7 @@ cifs_resend_wdata(struct cifs_writedata *wdata, struct list_head *wdata_list,
|
|||
} while (rc == -EAGAIN);
|
||||
|
||||
fail:
|
||||
kref_put(&wdata->refcount, cifs_uncached_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -3412,7 +3399,7 @@ cifs_write_from_iter(loff_t fpos, size_t len, struct iov_iter *from,
|
|||
{
|
||||
int rc = 0;
|
||||
size_t cur_len, max_len;
|
||||
struct cifs_writedata *wdata;
|
||||
struct cifs_io_subrequest *wdata;
|
||||
pid_t pid;
|
||||
struct TCP_Server_Info *server;
|
||||
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,
|
|||
break;
|
||||
}
|
||||
|
||||
wdata->uncached = true;
|
||||
wdata->sync_mode = WB_SYNC_ALL;
|
||||
wdata->offset = (__u64)fpos;
|
||||
wdata->cfile = cifsFileInfo_get(open_file);
|
||||
|
@ -3495,14 +3483,12 @@ cifs_write_from_iter(loff_t fpos, size_t len, struct iov_iter *from,
|
|||
if (wdata->cfile->invalidHandle)
|
||||
rc = -EAGAIN;
|
||||
else
|
||||
rc = server->ops->async_writev(wdata,
|
||||
cifs_uncached_writedata_release);
|
||||
rc = server->ops->async_writev(wdata);
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
add_credits_and_wake_if(server, &wdata->credits, 0);
|
||||
kref_put(&wdata->refcount,
|
||||
cifs_uncached_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
if (rc == -EAGAIN)
|
||||
continue;
|
||||
break;
|
||||
|
@ -3520,7 +3506,7 @@ cifs_write_from_iter(loff_t fpos, size_t len, struct iov_iter *from,
|
|||
|
||||
static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)
|
||||
{
|
||||
struct cifs_writedata *wdata, *tmp;
|
||||
struct cifs_io_subrequest *wdata, *tmp;
|
||||
struct cifs_tcon *tcon;
|
||||
struct cifs_sb_info *cifs_sb;
|
||||
struct dentry *dentry = ctx->cfile->dentry;
|
||||
|
@ -3575,8 +3561,7 @@ static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)
|
|||
ctx->cfile, cifs_sb, &tmp_list,
|
||||
ctx);
|
||||
|
||||
kref_put(&wdata->refcount,
|
||||
cifs_uncached_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
}
|
||||
|
||||
list_splice(&tmp_list, &ctx->list);
|
||||
|
@ -3584,7 +3569,7 @@ static void collect_uncached_write_data(struct cifs_aio_ctx *ctx)
|
|||
}
|
||||
}
|
||||
list_del_init(&wdata->list);
|
||||
kref_put(&wdata->refcount, cifs_uncached_writedata_release);
|
||||
cifs_put_writedata(wdata);
|
||||
}
|
||||
|
||||
cifs_stats_bytes_written(tcon, ctx->total_len);
|
||||
|
|
|
@ -4737,7 +4737,7 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
|
|||
static void
|
||||
smb2_writev_callback(struct mid_q_entry *mid)
|
||||
{
|
||||
struct cifs_writedata *wdata = mid->callback_data;
|
||||
struct cifs_io_subrequest *wdata = mid->callback_data;
|
||||
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
|
||||
struct TCP_Server_Info *server = wdata->server;
|
||||
unsigned int written;
|
||||
|
@ -4818,8 +4818,7 @@ smb2_writev_callback(struct mid_q_entry *mid)
|
|||
|
||||
/* smb2_async_writev - send an async write, and set up mid to handle result */
|
||||
int
|
||||
smb2_async_writev(struct cifs_writedata *wdata,
|
||||
void (*release)(struct kref *kref))
|
||||
smb2_async_writev(struct cifs_io_subrequest *wdata)
|
||||
{
|
||||
int rc = -EACCES, flags = 0;
|
||||
struct smb2_write_req *req = NULL;
|
||||
|
@ -4953,7 +4952,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
|
|||
flags |= CIFS_HAS_CREDITS;
|
||||
}
|
||||
|
||||
kref_get(&wdata->refcount);
|
||||
cifs_get_writedata(wdata);
|
||||
rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL,
|
||||
wdata, flags, &wdata->credits);
|
||||
|
||||
|
@ -4965,7 +4964,7 @@ smb2_async_writev(struct cifs_writedata *wdata,
|
|||
io_parms->offset,
|
||||
io_parms->length,
|
||||
rc);
|
||||
kref_put(&wdata->refcount, release);
|
||||
cifs_put_writedata(wdata);
|
||||
cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
|
||||
}
|
||||
|
||||
|
|
|
@ -213,8 +213,7 @@ extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon,
|
|||
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,
|
||||
void (*release)(struct kref *kref));
|
||||
extern int smb2_async_writev(struct cifs_io_subrequest *wdata);
|
||||
extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
|
||||
unsigned int *nbytes, struct kvec *iov, int n_vec);
|
||||
extern int SMB2_echo(struct TCP_Server_Info *server);
|
||||
|
|
Loading…
Reference in a new issue