Commit 3ee1a1fc authored by David Howells's avatar David Howells

cifs: Cut over to using netfslib

Make the cifs filesystem use netfslib to handle reading and writing on
behalf of cifs.  The changes include:

 (1) Various read_iter/write_iter type functions are turned into wrappers
     around netfslib API functions or are pointed directly at those
     functions:

	cifs_file_direct{,_nobrl}_ops switch to use
	netfs_unbuffered_read_iter and netfs_unbuffered_write_iter.

Large pieces of code that will be removed are #if'd out and will be removed
in subsequent patches.

[?] Why does cifs mark the page dirty in the destination buffer of a DIO
    read?  Should that happen automatically?  Does netfs need to do that?
Signed-off-by: default avatarDavid 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
parent 69c3c023
......@@ -213,8 +213,13 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
unsigned int i;
size_t transferred = 0;
for (i = 0; i < rreq->direct_bv_count; i++)
for (i = 0; i < rreq->direct_bv_count; i++) {
flush_dcache_page(rreq->direct_bv[i].bv_page);
// TODO: cifs marks pages in the destination buffer
// dirty under some circumstances after a read. Do we
// need to do that too?
set_page_dirty(rreq->direct_bv[i].bv_page);
}
list_for_each_entry(subreq, &rreq->subrequests, rreq_link) {
if (subreq->error || subreq->transferred == 0)
......
......@@ -1522,8 +1522,8 @@ const struct file_operations cifs_file_strict_ops = {
};
const struct file_operations cifs_file_direct_ops = {
.read_iter = cifs_direct_readv,
.write_iter = cifs_direct_writev,
.read_iter = netfs_unbuffered_read_iter,
.write_iter = netfs_file_write_iter,
.open = cifs_open,
.release = cifs_close,
.lock = cifs_lock,
......@@ -1578,8 +1578,8 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
};
const struct file_operations cifs_file_direct_nobrl_ops = {
.read_iter = cifs_direct_readv,
.write_iter = cifs_direct_writev,
.read_iter = netfs_unbuffered_read_iter,
.write_iter = netfs_file_write_iter,
.open = cifs_open,
.release = cifs_close,
.fsync = cifs_fsync,
......
......@@ -94,11 +94,7 @@ extern const struct file_operations cifs_file_strict_nobrl_ops;
extern int cifs_open(struct inode *inode, struct file *file);
extern int cifs_close(struct inode *inode, struct file *file);
extern int cifs_closedir(struct inode *inode, struct file *file);
extern ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to);
extern ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to);
extern ssize_t cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to);
extern ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from);
extern ssize_t cifs_direct_writev(struct kiocb *iocb, struct iov_iter *from);
extern ssize_t cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from);
ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter);
......@@ -112,9 +108,6 @@ extern int cifs_file_strict_mmap(struct file *file, struct vm_area_struct *vma);
extern const struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file);
extern int cifs_readdir(struct file *file, struct dir_context *ctx);
extern void cifs_pages_written_back(struct inode *inode, loff_t start, unsigned int len);
extern void cifs_pages_write_failed(struct inode *inode, loff_t start, unsigned int len);
extern void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int len);
/* Functions related to dir entries */
extern const struct dentry_operations cifs_dentry_ops;
......
......@@ -451,7 +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_io_subrequest *);
void (*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 **,
......@@ -1516,7 +1516,7 @@ struct cifs_io_subrequest {
#endif
struct cifs_credits credits;
// TODO: Remove following elements
#if 0 // TODO: Remove following elements
struct list_head list;
struct completion done;
struct work_struct work;
......@@ -1526,6 +1526,7 @@ struct cifs_io_subrequest {
enum writeback_sync_modes sync_mode;
bool uncached;
struct bio_vec *bv;
#endif
};
/*
......
......@@ -148,6 +148,8 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
bool from_readdir);
extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
unsigned int bytes_written);
void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result,
bool was_async);
extern struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
int flags,
......@@ -599,6 +601,7 @@ 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);
#if 0 // TODO Remove
void cifs_readdata_release(struct cifs_io_subrequest *rdata);
static inline void cifs_get_readdata(struct cifs_io_subrequest *rdata)
{
......@@ -609,11 +612,13 @@ static inline void cifs_put_readdata(struct cifs_io_subrequest *rdata)
if (refcount_dec_and_test(&rdata->subreq.ref))
cifs_readdata_release(rdata);
}
#endif
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_io_subrequest *wdata);
void cifs_async_writev(struct cifs_io_subrequest *wdata);
void cifs_writev_complete(struct work_struct *work);
#if 0 // TODO Remove
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)
......@@ -625,6 +630,7 @@ static inline void cifs_put_writedata(struct cifs_io_subrequest *wdata)
if (refcount_dec_and_test(&wdata->subreq.ref))
cifs_writedata_release(wdata);
}
#endif
int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb,
const unsigned char *path, char *pbuf,
......
......@@ -1265,7 +1265,7 @@ static void
cifs_readv_callback(struct mid_q_entry *mid)
{
struct cifs_io_subrequest *rdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
struct TCP_Server_Info *server = tcon->ses->server;
struct smb_rqst rqst = { .rq_iov = rdata->iov,
.rq_nvec = 2,
......@@ -1306,7 +1306,13 @@ cifs_readv_callback(struct mid_q_entry *mid)
rdata->result = -EIO;
}
queue_work(cifsiod_wq, &rdata->work);
if (rdata->result == 0 || rdata->result == -EAGAIN)
iov_iter_advance(&rdata->subreq.io_iter, rdata->got_bytes);
rdata->credits.value = 0;
netfs_subreq_terminated(&rdata->subreq,
(rdata->result == 0 || rdata->result == -EAGAIN) ?
rdata->got_bytes : rdata->result,
false);
release_mid(mid);
add_credits(server, &credits, 0);
}
......@@ -1318,7 +1324,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
int rc;
READ_REQ *smb = NULL;
int wct;
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink);
struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
struct smb_rqst rqst = { .rq_iov = rdata->iov,
.rq_nvec = 2 };
......@@ -1343,7 +1349,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
smb->AndXCommand = 0xFF; /* none */
smb->Fid = rdata->cfile->fid.netfid;
smb->Fid = rdata->req->cfile->fid.netfid;
smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF);
if (wct == 12)
smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32);
......@@ -1613,15 +1619,16 @@ static void
cifs_writev_callback(struct mid_q_entry *mid)
{
struct cifs_io_subrequest *wdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
unsigned int written;
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
struct cifs_credits credits = { .value = 1, .instance = 0 };
ssize_t result;
size_t written;
switch (mid->mid_state) {
case MID_RESPONSE_RECEIVED:
wdata->result = cifs_check_receive(mid, tcon->ses->server, 0);
if (wdata->result != 0)
result = cifs_check_receive(mid, tcon->ses->server, 0);
if (result != 0)
break;
written = le16_to_cpu(smb->CountHigh);
......@@ -1637,32 +1644,33 @@ cifs_writev_callback(struct mid_q_entry *mid)
written &= 0xFFFF;
if (written < wdata->subreq.len)
wdata->result = -ENOSPC;
result = -ENOSPC;
else
wdata->subreq.len = written;
result = written;
break;
case MID_REQUEST_SUBMITTED:
case MID_RETRY_NEEDED:
wdata->result = -EAGAIN;
result = -EAGAIN;
break;
default:
wdata->result = -EIO;
result = -EIO;
break;
}
queue_work(cifsiod_wq, &wdata->work);
wdata->credits.value = 0;
cifs_write_subrequest_terminated(wdata, result, true);
release_mid(mid);
add_credits(tcon->ses->server, &credits, 0);
}
/* cifs_async_writev - send an async write, and set up mid to handle result */
int
void
cifs_async_writev(struct cifs_io_subrequest *wdata)
{
int rc = -EACCES;
WRITE_REQ *smb = NULL;
int wct;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink);
struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
struct kvec iov[2];
struct smb_rqst rqst = { };
......@@ -1672,7 +1680,8 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
wct = 12;
if (wdata->subreq.start >> 32 > 0) {
/* can not handle big offset for old srv */
return -EIO;
rc = -EIO;
goto out;
}
}
......@@ -1684,7 +1693,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
smb->AndXCommand = 0xFF; /* none */
smb->Fid = wdata->cfile->fid.netfid;
smb->Fid = wdata->req->cfile->fid.netfid;
smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
if (wct == 14)
smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
......@@ -1724,18 +1733,19 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
iov[1].iov_len += 4; /* pad bigger by four bytes */
}
cifs_get_writedata(wdata);
rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
cifs_writev_callback, NULL, wdata, 0, NULL);
/* Can't touch wdata if rc == 0 */
if (rc == 0)
cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
else
cifs_put_writedata(wdata);
async_writev_out:
cifs_small_buf_release(smb);
return rc;
out:
if (rc) {
add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
cifs_write_subrequest_terminated(wdata, rc, false);
}
}
int
......
This diff is collapsed.
......@@ -171,6 +171,7 @@ void cifs_fscache_release_inode_cookie(struct inode *inode)
}
}
#if 0 // TODO remove
/*
* Fallback page reading interface.
*/
......@@ -279,3 +280,4 @@ int __cifs_fscache_query_occupancy(struct inode *inode,
fscache_end_operation(&cres);
return ret;
}
#endif
......@@ -74,6 +74,7 @@ static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags
i_size_read(inode), flags);
}
#if 0 // TODO remove
extern int __cifs_fscache_query_occupancy(struct inode *inode,
pgoff_t first, unsigned int nr_pages,
pgoff_t *_data_first,
......@@ -108,6 +109,7 @@ static inline void cifs_readahead_to_fscache(struct inode *inode,
if (cifs_inode_cookie(inode))
__cifs_readahead_to_fscache(inode, pos, len);
}
#endif
static inline bool cifs_fscache_enabled(struct inode *inode)
{
......@@ -131,6 +133,7 @@ static inline struct fscache_cookie *cifs_inode_cookie(struct inode *inode) { re
static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags) {}
static inline bool cifs_fscache_enabled(struct inode *inode) { return false; }
#if 0 // TODO remove
static inline int cifs_fscache_query_occupancy(struct inode *inode,
pgoff_t first, unsigned int nr_pages,
pgoff_t *_data_first,
......@@ -149,6 +152,7 @@ cifs_readpage_from_fscache(struct inode *inode, struct page *page)
static inline
void cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len) {}
#endif
#endif /* CONFIG_CIFS_FSCACHE */
......
......@@ -28,14 +28,29 @@
#include "cached_dir.h"
#include "reparse.h"
/*
* Set parameters for the netfs library
*/
static void cifs_set_netfs_context(struct inode *inode)
{
struct cifsInodeInfo *cifs_i = CIFS_I(inode);
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
netfs_inode_init(&cifs_i->netfs, &cifs_req_ops, true);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_STRICT_IO)
__set_bit(NETFS_ICTX_WRITETHROUGH, &cifs_i->netfs.flags);
}
static void cifs_set_ops(struct inode *inode)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct netfs_inode *ictx = netfs_inode(inode);
switch (inode->i_mode & S_IFMT) {
case S_IFREG:
inode->i_op = &cifs_file_inode_ops;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) {
set_bit(NETFS_ICTX_UNBUFFERED, &ictx->flags);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop = &cifs_file_direct_nobrl_ops;
else
......@@ -221,8 +236,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
if (fattr->cf_flags & CIFS_FATTR_JUNCTION)
inode->i_flags |= S_AUTOMOUNT;
if (inode->i_state & I_NEW)
if (inode->i_state & I_NEW) {
cifs_set_netfs_context(inode);
cifs_set_ops(inode);
}
return 0;
}
......
This diff is collapsed.
......@@ -213,7 +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_io_subrequest *wdata);
extern void 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);
......
......@@ -85,6 +85,62 @@ smb3_tcon_ref_traces;
/* For logging errors in read or write */
DECLARE_EVENT_CLASS(smb3_rw_err_class,
TP_PROTO(unsigned int rreq_debug_id,
unsigned int rreq_debug_index,
unsigned int xid,
__u64 fid,
__u32 tid,
__u64 sesid,
__u64 offset,
__u32 len,
int rc),
TP_ARGS(rreq_debug_id, rreq_debug_index,
xid, fid, tid, sesid, offset, len, rc),
TP_STRUCT__entry(
__field(unsigned int, rreq_debug_id)
__field(unsigned int, rreq_debug_index)
__field(unsigned int, xid)
__field(__u64, fid)
__field(__u32, tid)
__field(__u64, sesid)
__field(__u64, offset)
__field(__u32, len)
__field(int, rc)
),
TP_fast_assign(
__entry->rreq_debug_id = rreq_debug_id;
__entry->rreq_debug_index = rreq_debug_index;
__entry->xid = xid;
__entry->fid = fid;
__entry->tid = tid;
__entry->sesid = sesid;
__entry->offset = offset;
__entry->len = len;
__entry->rc = rc;
),
TP_printk("\tR=%08x[%x] xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x rc=%d",
__entry->rreq_debug_id, __entry->rreq_debug_index,
__entry->xid, __entry->sesid, __entry->tid, __entry->fid,
__entry->offset, __entry->len, __entry->rc)
)
#define DEFINE_SMB3_RW_ERR_EVENT(name) \
DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \
TP_PROTO(unsigned int rreq_debug_id, \
unsigned int rreq_debug_index, \
unsigned int xid, \
__u64 fid, \
__u32 tid, \
__u64 sesid, \
__u64 offset, \
__u32 len, \
int rc), \
TP_ARGS(rreq_debug_id, rreq_debug_index, xid, fid, tid, sesid, offset, len, rc))
DEFINE_SMB3_RW_ERR_EVENT(read_err);
/* For logging errors in other file I/O ops */
DECLARE_EVENT_CLASS(smb3_other_err_class,
TP_PROTO(unsigned int xid,
__u64 fid,
__u32 tid,
......@@ -116,8 +172,8 @@ DECLARE_EVENT_CLASS(smb3_rw_err_class,
__entry->offset, __entry->len, __entry->rc)
)
#define DEFINE_SMB3_RW_ERR_EVENT(name) \
DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \
#define DEFINE_SMB3_OTHER_ERR_EVENT(name) \
DEFINE_EVENT(smb3_other_err_class, smb3_##name, \
TP_PROTO(unsigned int xid, \
__u64 fid, \
__u32 tid, \
......@@ -127,15 +183,67 @@ DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \
int rc), \
TP_ARGS(xid, fid, tid, sesid, offset, len, rc))
DEFINE_SMB3_RW_ERR_EVENT(write_err);
DEFINE_SMB3_RW_ERR_EVENT(read_err);
DEFINE_SMB3_RW_ERR_EVENT(query_dir_err);
DEFINE_SMB3_RW_ERR_EVENT(zero_err);
DEFINE_SMB3_RW_ERR_EVENT(falloc_err);
DEFINE_SMB3_OTHER_ERR_EVENT(write_err);
DEFINE_SMB3_OTHER_ERR_EVENT(query_dir_err);
DEFINE_SMB3_OTHER_ERR_EVENT(zero_err);
DEFINE_SMB3_OTHER_ERR_EVENT(falloc_err);
/* For logging successful read or write */
DECLARE_EVENT_CLASS(smb3_rw_done_class,
TP_PROTO(unsigned int rreq_debug_id,
unsigned int rreq_debug_index,
unsigned int xid,
__u64 fid,
__u32 tid,
__u64 sesid,
__u64 offset,
__u32 len),
TP_ARGS(rreq_debug_id, rreq_debug_index,
xid, fid, tid, sesid, offset, len),
TP_STRUCT__entry(
__field(unsigned int, rreq_debug_id)
__field(unsigned int, rreq_debug_index)
__field(unsigned int, xid)
__field(__u64, fid)
__field(__u32, tid)
__field(__u64, sesid)
__field(__u64, offset)
__field(__u32, len)
),
TP_fast_assign(
__entry->rreq_debug_id = rreq_debug_id;
__entry->rreq_debug_index = rreq_debug_index;
__entry->xid = xid;
__entry->fid = fid;
__entry->tid = tid;
__entry->sesid = sesid;
__entry->offset = offset;
__entry->len = len;
),
TP_printk("R=%08x[%x] xid=%u sid=0x%llx tid=0x%x fid=0x%llx offset=0x%llx len=0x%x",
__entry->rreq_debug_id, __entry->rreq_debug_index,
__entry->xid, __entry->sesid, __entry->tid, __entry->fid,
__entry->offset, __entry->len)
)
#define DEFINE_SMB3_RW_DONE_EVENT(name) \
DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \
TP_PROTO(unsigned int rreq_debug_id, \
unsigned int rreq_debug_index, \
unsigned int xid, \
__u64 fid, \
__u32 tid, \
__u64 sesid, \
__u64 offset, \
__u32 len), \
TP_ARGS(rreq_debug_id, rreq_debug_index, xid, fid, tid, sesid, offset, len))
DEFINE_SMB3_RW_DONE_EVENT(read_enter);
DEFINE_SMB3_RW_DONE_EVENT(read_done);
/* For logging successful other op */
DECLARE_EVENT_CLASS(smb3_other_done_class,
TP_PROTO(unsigned int xid,
__u64 fid,
__u32 tid,
......@@ -164,8 +272,8 @@ DECLARE_EVENT_CLASS(smb3_rw_done_class,
__entry->offset, __entry->len)
)
#define DEFINE_SMB3_RW_DONE_EVENT(name) \
DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \
#define DEFINE_SMB3_OTHER_DONE_EVENT(name) \
DEFINE_EVENT(smb3_other_done_class, smb3_##name, \
TP_PROTO(unsigned int xid, \
__u64 fid, \
__u32 tid, \
......@@ -174,16 +282,14 @@ DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \
__u32 len), \
TP_ARGS(xid, fid, tid, sesid, offset, len))
DEFINE_SMB3_RW_DONE_EVENT(write_enter);
DEFINE_SMB3_RW_DONE_EVENT(read_enter);
DEFINE_SMB3_RW_DONE_EVENT(query_dir_enter);
DEFINE_SMB3_RW_DONE_EVENT(zero_enter);
DEFINE_SMB3_RW_DONE_EVENT(falloc_enter);
DEFINE_SMB3_RW_DONE_EVENT(write_done);
DEFINE_SMB3_RW_DONE_EVENT(read_done);
DEFINE_SMB3_RW_DONE_EVENT(query_dir_done);
DEFINE_SMB3_RW_DONE_EVENT(zero_done);
DEFINE_SMB3_RW_DONE_EVENT(falloc_done);
DEFINE_SMB3_OTHER_DONE_EVENT(write_enter);
DEFINE_SMB3_OTHER_DONE_EVENT(query_dir_enter);
DEFINE_SMB3_OTHER_DONE_EVENT(zero_enter);
DEFINE_SMB3_OTHER_DONE_EVENT(falloc_enter);
DEFINE_SMB3_OTHER_DONE_EVENT(write_done);
DEFINE_SMB3_OTHER_DONE_EVENT(query_dir_done);
DEFINE_SMB3_OTHER_DONE_EVENT(zero_done);
DEFINE_SMB3_OTHER_DONE_EVENT(falloc_done);
/* For logging successful set EOF (truncate) */
DECLARE_EVENT_CLASS(smb3_eof_class,
......
......@@ -1813,8 +1813,11 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
length = data_len; /* An RDMA read is already done. */
else
#endif
{
length = cifs_read_iter_from_socket(server, &rdata->subreq.io_iter,
data_len);
iov_iter_revert(&rdata->subreq.io_iter, data_len);
}
if (length > 0)
rdata->got_bytes += length;
server->total_read += length;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment