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) ...@@ -213,8 +213,13 @@ static void netfs_rreq_assess_dio(struct netfs_io_request *rreq)
unsigned int i; unsigned int i;
size_t transferred = 0; 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); 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) { list_for_each_entry(subreq, &rreq->subrequests, rreq_link) {
if (subreq->error || subreq->transferred == 0) if (subreq->error || subreq->transferred == 0)
......
...@@ -1522,8 +1522,8 @@ const struct file_operations cifs_file_strict_ops = { ...@@ -1522,8 +1522,8 @@ const struct file_operations cifs_file_strict_ops = {
}; };
const struct file_operations cifs_file_direct_ops = { const struct file_operations cifs_file_direct_ops = {
.read_iter = cifs_direct_readv, .read_iter = netfs_unbuffered_read_iter,
.write_iter = cifs_direct_writev, .write_iter = netfs_file_write_iter,
.open = cifs_open, .open = cifs_open,
.release = cifs_close, .release = cifs_close,
.lock = cifs_lock, .lock = cifs_lock,
...@@ -1578,8 +1578,8 @@ const struct file_operations cifs_file_strict_nobrl_ops = { ...@@ -1578,8 +1578,8 @@ const struct file_operations cifs_file_strict_nobrl_ops = {
}; };
const struct file_operations cifs_file_direct_nobrl_ops = { const struct file_operations cifs_file_direct_nobrl_ops = {
.read_iter = cifs_direct_readv, .read_iter = netfs_unbuffered_read_iter,
.write_iter = cifs_direct_writev, .write_iter = netfs_file_write_iter,
.open = cifs_open, .open = cifs_open,
.release = cifs_close, .release = cifs_close,
.fsync = cifs_fsync, .fsync = cifs_fsync,
......
...@@ -94,11 +94,7 @@ extern const struct file_operations cifs_file_strict_nobrl_ops; ...@@ -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_open(struct inode *inode, struct file *file);
extern int cifs_close(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 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_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); 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_file_write_iter(struct kiocb *iocb, struct iov_iter *from);
ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter); 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); ...@@ -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 const struct file_operations cifs_dir_ops;
extern int cifs_dir_open(struct inode *inode, struct file *file); extern int cifs_dir_open(struct inode *inode, struct file *file);
extern int cifs_readdir(struct file *file, struct dir_context *ctx); 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 */ /* Functions related to dir entries */
extern const struct dentry_operations cifs_dentry_ops; extern const struct dentry_operations cifs_dentry_ops;
......
...@@ -451,7 +451,7 @@ struct smb_version_operations { ...@@ -451,7 +451,7 @@ struct smb_version_operations {
/* async read from the server */ /* async read from the server */
int (*async_readv)(struct cifs_io_subrequest *); int (*async_readv)(struct cifs_io_subrequest *);
/* async write to the server */ /* async write to the server */
int (*async_writev)(struct cifs_io_subrequest *); void (*async_writev)(struct cifs_io_subrequest *);
/* sync read from the server */ /* sync read from the server */
int (*sync_read)(const unsigned int, struct cifs_fid *, int (*sync_read)(const unsigned int, struct cifs_fid *,
struct cifs_io_parms *, unsigned int *, char **, struct cifs_io_parms *, unsigned int *, char **,
...@@ -1516,7 +1516,7 @@ struct cifs_io_subrequest { ...@@ -1516,7 +1516,7 @@ struct cifs_io_subrequest {
#endif #endif
struct cifs_credits credits; struct cifs_credits credits;
// TODO: Remove following elements #if 0 // TODO: Remove following elements
struct list_head list; struct list_head list;
struct completion done; struct completion done;
struct work_struct work; struct work_struct work;
...@@ -1526,6 +1526,7 @@ struct cifs_io_subrequest { ...@@ -1526,6 +1526,7 @@ struct cifs_io_subrequest {
enum writeback_sync_modes sync_mode; enum writeback_sync_modes sync_mode;
bool uncached; bool uncached;
struct bio_vec *bv; struct bio_vec *bv;
#endif
}; };
/* /*
......
...@@ -148,6 +148,8 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof, ...@@ -148,6 +148,8 @@ extern bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 eof,
bool from_readdir); bool from_readdir);
extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset, extern void cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
unsigned int bytes_written); 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 struct cifsFileInfo *find_writable_file(struct cifsInodeInfo *, int);
extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode, extern int cifs_get_writable_file(struct cifsInodeInfo *cifs_inode,
int flags, int flags,
...@@ -599,6 +601,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses); ...@@ -599,6 +601,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses);
extern struct cifs_ses * extern struct cifs_ses *
cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx); 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); void cifs_readdata_release(struct cifs_io_subrequest *rdata);
static inline void cifs_get_readdata(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) ...@@ -609,11 +612,13 @@ static inline void cifs_put_readdata(struct cifs_io_subrequest *rdata)
if (refcount_dec_and_test(&rdata->subreq.ref)) if (refcount_dec_and_test(&rdata->subreq.ref))
cifs_readdata_release(rdata); cifs_readdata_release(rdata);
} }
#endif
int cifs_async_readv(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_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); void cifs_writev_complete(struct work_struct *work);
#if 0 // TODO Remove
struct cifs_io_subrequest *cifs_writedata_alloc(work_func_t complete); struct cifs_io_subrequest *cifs_writedata_alloc(work_func_t complete);
void cifs_writedata_release(struct cifs_io_subrequest *rdata); void cifs_writedata_release(struct cifs_io_subrequest *rdata);
static inline void cifs_get_writedata(struct cifs_io_subrequest *wdata) 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) ...@@ -625,6 +630,7 @@ static inline void cifs_put_writedata(struct cifs_io_subrequest *wdata)
if (refcount_dec_and_test(&wdata->subreq.ref)) if (refcount_dec_and_test(&wdata->subreq.ref))
cifs_writedata_release(wdata); cifs_writedata_release(wdata);
} }
#endif
int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon, int cifs_query_mf_symlink(unsigned int xid, struct cifs_tcon *tcon,
struct cifs_sb_info *cifs_sb, struct cifs_sb_info *cifs_sb,
const unsigned char *path, char *pbuf, const unsigned char *path, char *pbuf,
......
...@@ -1265,7 +1265,7 @@ static void ...@@ -1265,7 +1265,7 @@ static void
cifs_readv_callback(struct mid_q_entry *mid) cifs_readv_callback(struct mid_q_entry *mid)
{ {
struct cifs_io_subrequest *rdata = mid->callback_data; 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 TCP_Server_Info *server = tcon->ses->server;
struct smb_rqst rqst = { .rq_iov = rdata->iov, struct smb_rqst rqst = { .rq_iov = rdata->iov,
.rq_nvec = 2, .rq_nvec = 2,
...@@ -1306,7 +1306,13 @@ cifs_readv_callback(struct mid_q_entry *mid) ...@@ -1306,7 +1306,13 @@ cifs_readv_callback(struct mid_q_entry *mid)
rdata->result = -EIO; 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); release_mid(mid);
add_credits(server, &credits, 0); add_credits(server, &credits, 0);
} }
...@@ -1318,7 +1324,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata) ...@@ -1318,7 +1324,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
int rc; int rc;
READ_REQ *smb = NULL; READ_REQ *smb = NULL;
int wct; 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, struct smb_rqst rqst = { .rq_iov = rdata->iov,
.rq_nvec = 2 }; .rq_nvec = 2 };
...@@ -1343,7 +1349,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata) ...@@ -1343,7 +1349,7 @@ cifs_async_readv(struct cifs_io_subrequest *rdata)
smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16)); smb->hdr.PidHigh = cpu_to_le16((__u16)(rdata->pid >> 16));
smb->AndXCommand = 0xFF; /* none */ 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); smb->OffsetLow = cpu_to_le32(rdata->subreq.start & 0xFFFFFFFF);
if (wct == 12) if (wct == 12)
smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32); smb->OffsetHigh = cpu_to_le32(rdata->subreq.start >> 32);
...@@ -1613,15 +1619,16 @@ static void ...@@ -1613,15 +1619,16 @@ static void
cifs_writev_callback(struct mid_q_entry *mid) cifs_writev_callback(struct mid_q_entry *mid)
{ {
struct cifs_io_subrequest *wdata = mid->callback_data; struct cifs_io_subrequest *wdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
unsigned int written;
WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf; WRITE_RSP *smb = (WRITE_RSP *)mid->resp_buf;
struct cifs_credits credits = { .value = 1, .instance = 0 }; struct cifs_credits credits = { .value = 1, .instance = 0 };
ssize_t result;
size_t written;
switch (mid->mid_state) { switch (mid->mid_state) {
case MID_RESPONSE_RECEIVED: case MID_RESPONSE_RECEIVED:
wdata->result = cifs_check_receive(mid, tcon->ses->server, 0); result = cifs_check_receive(mid, tcon->ses->server, 0);
if (wdata->result != 0) if (result != 0)
break; break;
written = le16_to_cpu(smb->CountHigh); written = le16_to_cpu(smb->CountHigh);
...@@ -1637,32 +1644,33 @@ cifs_writev_callback(struct mid_q_entry *mid) ...@@ -1637,32 +1644,33 @@ cifs_writev_callback(struct mid_q_entry *mid)
written &= 0xFFFF; written &= 0xFFFF;
if (written < wdata->subreq.len) if (written < wdata->subreq.len)
wdata->result = -ENOSPC; result = -ENOSPC;
else else
wdata->subreq.len = written; result = written;
break; break;
case MID_REQUEST_SUBMITTED: case MID_REQUEST_SUBMITTED:
case MID_RETRY_NEEDED: case MID_RETRY_NEEDED:
wdata->result = -EAGAIN; result = -EAGAIN;
break; break;
default: default:
wdata->result = -EIO; result = -EIO;
break; break;
} }
queue_work(cifsiod_wq, &wdata->work); wdata->credits.value = 0;
cifs_write_subrequest_terminated(wdata, result, true);
release_mid(mid); release_mid(mid);
add_credits(tcon->ses->server, &credits, 0); add_credits(tcon->ses->server, &credits, 0);
} }
/* cifs_async_writev - send an async write, and set up mid to handle result */ /* cifs_async_writev - send an async write, and set up mid to handle result */
int void
cifs_async_writev(struct cifs_io_subrequest *wdata) cifs_async_writev(struct cifs_io_subrequest *wdata)
{ {
int rc = -EACCES; int rc = -EACCES;
WRITE_REQ *smb = NULL; WRITE_REQ *smb = NULL;
int wct; 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 kvec iov[2];
struct smb_rqst rqst = { }; struct smb_rqst rqst = { };
...@@ -1672,7 +1680,8 @@ cifs_async_writev(struct cifs_io_subrequest *wdata) ...@@ -1672,7 +1680,8 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
wct = 12; wct = 12;
if (wdata->subreq.start >> 32 > 0) { if (wdata->subreq.start >> 32 > 0) {
/* can not handle big offset for old srv */ /* 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) ...@@ -1684,7 +1693,7 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16)); smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->pid >> 16));
smb->AndXCommand = 0xFF; /* none */ 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); smb->OffsetLow = cpu_to_le32(wdata->subreq.start & 0xFFFFFFFF);
if (wct == 14) if (wct == 14)
smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32); smb->OffsetHigh = cpu_to_le32(wdata->subreq.start >> 32);
...@@ -1724,18 +1733,19 @@ cifs_async_writev(struct cifs_io_subrequest *wdata) ...@@ -1724,18 +1733,19 @@ cifs_async_writev(struct cifs_io_subrequest *wdata)
iov[1].iov_len += 4; /* pad bigger by four bytes */ iov[1].iov_len += 4; /* pad bigger by four bytes */
} }
cifs_get_writedata(wdata);
rc = cifs_call_async(tcon->ses->server, &rqst, NULL, rc = cifs_call_async(tcon->ses->server, &rqst, NULL,
cifs_writev_callback, NULL, wdata, 0, NULL); cifs_writev_callback, NULL, wdata, 0, NULL);
/* Can't touch wdata if rc == 0 */
if (rc == 0) if (rc == 0)
cifs_stats_inc(&tcon->stats.cifs_stats.num_writes); cifs_stats_inc(&tcon->stats.cifs_stats.num_writes);
else
cifs_put_writedata(wdata);
async_writev_out: async_writev_out:
cifs_small_buf_release(smb); 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 int
......
...@@ -119,7 +119,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq) ...@@ -119,7 +119,7 @@ static void cifs_issue_write(struct netfs_io_subrequest *subreq)
else else
trace_netfs_sreq(subreq, netfs_sreq_trace_fail); trace_netfs_sreq(subreq, netfs_sreq_trace_fail);
add_credits_and_wake_if(wdata->server, &wdata->credits, 0); add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
netfs_write_subrequest_terminated(wdata, rc, false); cifs_write_subrequest_terminated(wdata, rc, false);
goto out; goto out;
} }
...@@ -352,6 +352,7 @@ const struct netfs_request_ops cifs_req_ops = { ...@@ -352,6 +352,7 @@ const struct netfs_request_ops cifs_req_ops = {
.issue_write = cifs_issue_write, .issue_write = cifs_issue_write,
}; };
#if 0 // TODO remove 397
/* /*
* Remove the dirty flags from a span of pages. * Remove the dirty flags from a span of pages.
*/ */
...@@ -476,6 +477,7 @@ void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int le ...@@ -476,6 +477,7 @@ void cifs_pages_write_redirty(struct inode *inode, loff_t start, unsigned int le
rcu_read_unlock(); rcu_read_unlock();
} }
#endif // end netfslib remove 397
/* /*
* Mark as invalid, all open files on tree connections since they * Mark as invalid, all open files on tree connections since they
...@@ -2522,20 +2524,23 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock) ...@@ -2522,20 +2524,23 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *flock)
return rc; return rc;
} }
/* void cifs_write_subrequest_terminated(struct cifs_io_subrequest *wdata, ssize_t result,
* update the file size (if needed) after a write. Should be called with bool was_async)
* the inode->i_lock held
*/
void
cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
unsigned int bytes_written)
{ {
loff_t end_of_write = offset + bytes_written; struct netfs_io_request *wreq = wdata->rreq;
loff_t new_server_eof;
if (end_of_write > cifsi->netfs.remote_i_size) if (result > 0) {
netfs_resize_file(&cifsi->netfs, end_of_write, true); new_server_eof = wdata->subreq.start + wdata->subreq.transferred + result;
if (new_server_eof > netfs_inode(wreq->inode)->remote_i_size)
netfs_resize_file(netfs_inode(wreq->inode), new_server_eof, true);
}
netfs_write_subrequest_terminated(&wdata->subreq, result, was_async);
} }
#if 0 // TODO remove 2483
static ssize_t static ssize_t
cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data,
size_t write_size, loff_t *offset) size_t write_size, loff_t *offset)
...@@ -2619,6 +2624,7 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data, ...@@ -2619,6 +2624,7 @@ cifs_write(struct cifsFileInfo *open_file, __u32 pid, const char *write_data,
free_xid(xid); free_xid(xid);
return total_written; return total_written;
} }
#endif // end netfslib remove 2483
struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode, struct cifsFileInfo *find_readable_file(struct cifsInodeInfo *cifs_inode,
bool fsuid_only) bool fsuid_only)
...@@ -2824,6 +2830,7 @@ cifs_get_readable_path(struct cifs_tcon *tcon, const char *name, ...@@ -2824,6 +2830,7 @@ cifs_get_readable_path(struct cifs_tcon *tcon, const char *name,
return -ENOENT; return -ENOENT;
} }
#if 0 // TODO remove 2773
void void
cifs_writedata_release(struct cifs_io_subrequest *wdata) cifs_writedata_release(struct cifs_io_subrequest *wdata)
{ {
...@@ -3454,7 +3461,11 @@ static int cifs_write_end(struct file *file, struct address_space *mapping, ...@@ -3454,7 +3461,11 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
return rc; return rc;
} }
#endif // End netfs removal 2773
/*
* Flush data on a strict file.
*/
int cifs_strict_fsync(struct file *file, loff_t start, loff_t end, int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
int datasync) int datasync)
{ {
...@@ -3509,6 +3520,9 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end, ...@@ -3509,6 +3520,9 @@ int cifs_strict_fsync(struct file *file, loff_t start, loff_t end,
return rc; return rc;
} }
/*
* Flush data on a non-strict data.
*/
int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync) int cifs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
{ {
unsigned int xid; unsigned int xid;
...@@ -3575,6 +3589,7 @@ int cifs_flush(struct file *file, fl_owner_t id) ...@@ -3575,6 +3589,7 @@ int cifs_flush(struct file *file, fl_owner_t id)
return rc; return rc;
} }
#if 0 // TODO remove 3594
static void collect_uncached_write_data(struct cifs_aio_ctx *ctx); static void collect_uncached_write_data(struct cifs_aio_ctx *ctx);
static void static void
...@@ -4037,6 +4052,7 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from) ...@@ -4037,6 +4052,7 @@ ssize_t cifs_user_writev(struct kiocb *iocb, struct iov_iter *from)
{ {
return __cifs_writev(iocb, from, false); return __cifs_writev(iocb, from, false);
} }
#endif // TODO remove 3594
static ssize_t static ssize_t
cifs_writev(struct kiocb *iocb, struct iov_iter *from) cifs_writev(struct kiocb *iocb, struct iov_iter *from)
...@@ -4048,7 +4064,10 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) ...@@ -4048,7 +4064,10 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server; struct TCP_Server_Info *server = tlink_tcon(cfile->tlink)->ses->server;
ssize_t rc; ssize_t rc;
inode_lock(inode); rc = netfs_start_io_write(inode);
if (rc < 0)
return rc;
/* /*
* We need to hold the sem to be sure nobody modifies lock list * We need to hold the sem to be sure nobody modifies lock list
* with a brlock that prevents writing. * with a brlock that prevents writing.
...@@ -4062,13 +4081,12 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from) ...@@ -4062,13 +4081,12 @@ cifs_writev(struct kiocb *iocb, struct iov_iter *from)
if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from), if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(from),
server->vals->exclusive_lock_type, 0, server->vals->exclusive_lock_type, 0,
NULL, CIFS_WRITE_OP)) NULL, CIFS_WRITE_OP))
rc = __generic_file_write_iter(iocb, from); rc = netfs_buffered_write_iter_locked(iocb, from, NULL);
else else
rc = -EACCES; rc = -EACCES;
out: out:
up_read(&cinode->lock_sem); up_read(&cinode->lock_sem);
inode_unlock(inode); netfs_end_io_write(inode);
if (rc > 0) if (rc > 0)
rc = generic_write_sync(iocb, rc); rc = generic_write_sync(iocb, rc);
return rc; return rc;
...@@ -4091,9 +4109,9 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) ...@@ -4091,9 +4109,9 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
if (CIFS_CACHE_WRITE(cinode)) { if (CIFS_CACHE_WRITE(cinode)) {
if (cap_unix(tcon->ses) && if (cap_unix(tcon->ses) &&
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
&& ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) { ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
written = generic_file_write_iter(iocb, from); written = netfs_file_write_iter(iocb, from);
goto out; goto out;
} }
written = cifs_writev(iocb, from); written = cifs_writev(iocb, from);
...@@ -4105,7 +4123,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) ...@@ -4105,7 +4123,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
* affected pages because it may cause a error with mandatory locks on * affected pages because it may cause a error with mandatory locks on
* these pages but not on the region from pos to ppos+len-1. * these pages but not on the region from pos to ppos+len-1.
*/ */
written = cifs_user_writev(iocb, from); written = netfs_file_write_iter(iocb, from);
if (CIFS_CACHE_READ(cinode)) { if (CIFS_CACHE_READ(cinode)) {
/* /*
* We have read level caching and we have just sent a write * We have read level caching and we have just sent a write
...@@ -4124,6 +4142,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from) ...@@ -4124,6 +4142,7 @@ cifs_strict_writev(struct kiocb *iocb, struct iov_iter *from)
return written; return written;
} }
#if 0 // TODO remove 4143
static struct cifs_io_subrequest *cifs_readdata_alloc(work_func_t complete) static struct cifs_io_subrequest *cifs_readdata_alloc(work_func_t complete)
{ {
struct cifs_io_subrequest *rdata; struct cifs_io_subrequest *rdata;
...@@ -4563,7 +4582,9 @@ ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to) ...@@ -4563,7 +4582,9 @@ ssize_t cifs_direct_readv(struct kiocb *iocb, struct iov_iter *to)
ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to) ssize_t cifs_user_readv(struct kiocb *iocb, struct iov_iter *to)
{ {
return __cifs_readv(iocb, to, false); return __cifs_readv(iocb, to, false);
} }
#endif // end netfslib removal 4143
ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter) ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
{ {
...@@ -4571,13 +4592,13 @@ ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter) ...@@ -4571,13 +4592,13 @@ ssize_t cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
struct inode *inode = file_inode(iocb->ki_filp); struct inode *inode = file_inode(iocb->ki_filp);
if (iocb->ki_flags & IOCB_DIRECT) if (iocb->ki_flags & IOCB_DIRECT)
return cifs_user_readv(iocb, iter); return netfs_unbuffered_read_iter(iocb, iter);
rc = cifs_revalidate_mapping(inode); rc = cifs_revalidate_mapping(inode);
if (rc) if (rc)
return rc; return rc;
return generic_file_read_iter(iocb, iter); return netfs_file_read_iter(iocb, iter);
} }
ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
...@@ -4588,7 +4609,7 @@ ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -4588,7 +4609,7 @@ ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
int rc; int rc;
if (iocb->ki_filp->f_flags & O_DIRECT) { if (iocb->ki_filp->f_flags & O_DIRECT) {
written = cifs_user_writev(iocb, from); written = netfs_unbuffered_write_iter(iocb, from);
if (written > 0 && CIFS_CACHE_READ(cinode)) { if (written > 0 && CIFS_CACHE_READ(cinode)) {
cifs_zap_mapping(inode); cifs_zap_mapping(inode);
cifs_dbg(FYI, cifs_dbg(FYI,
...@@ -4603,17 +4624,15 @@ ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from) ...@@ -4603,17 +4624,15 @@ ssize_t cifs_file_write_iter(struct kiocb *iocb, struct iov_iter *from)
if (written) if (written)
return written; return written;
written = generic_file_write_iter(iocb, from); written = netfs_file_write_iter(iocb, from);
if (CIFS_CACHE_WRITE(CIFS_I(inode)))
goto out;
if (!CIFS_CACHE_WRITE(CIFS_I(inode))) {
rc = filemap_fdatawrite(inode->i_mapping); rc = filemap_fdatawrite(inode->i_mapping);
if (rc) if (rc)
cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n", cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n",
rc, inode); rc, inode);
}
out:
cifs_put_writer(cinode); cifs_put_writer(cinode);
return written; return written;
} }
...@@ -4638,12 +4657,15 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to) ...@@ -4638,12 +4657,15 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
* pos+len-1. * pos+len-1.
*/ */
if (!CIFS_CACHE_READ(cinode)) if (!CIFS_CACHE_READ(cinode))
return cifs_user_readv(iocb, to); return netfs_unbuffered_read_iter(iocb, to);
if (cap_unix(tcon->ses) && if (cap_unix(tcon->ses) &&
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) && (CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
return generic_file_read_iter(iocb, to); if (iocb->ki_flags & IOCB_DIRECT)
return netfs_unbuffered_read_iter(iocb, to);
return netfs_buffered_read_iter(iocb, to);
}
/* /*
* We need to hold the sem to be sure nobody modifies lock list * We need to hold the sem to be sure nobody modifies lock list
...@@ -4652,12 +4674,17 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to) ...@@ -4652,12 +4674,17 @@ cifs_strict_readv(struct kiocb *iocb, struct iov_iter *to)
down_read(&cinode->lock_sem); down_read(&cinode->lock_sem);
if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(to), if (!cifs_find_lock_conflict(cfile, iocb->ki_pos, iov_iter_count(to),
tcon->ses->server->vals->shared_lock_type, tcon->ses->server->vals->shared_lock_type,
0, NULL, CIFS_READ_OP)) 0, NULL, CIFS_READ_OP)) {
rc = generic_file_read_iter(iocb, to); if (iocb->ki_flags & IOCB_DIRECT)
rc = netfs_unbuffered_read_iter(iocb, to);
else
rc = netfs_buffered_read_iter(iocb, to);
}
up_read(&cinode->lock_sem); up_read(&cinode->lock_sem);
return rc; return rc;
} }
#if 0 // TODO remove 4633
static ssize_t static ssize_t
cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
{ {
...@@ -4749,29 +4776,11 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset) ...@@ -4749,29 +4776,11 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
free_xid(xid); free_xid(xid);
return total_read; return total_read;
} }
#endif // end netfslib remove 4633
/*
* If the page is mmap'ed into a process' page tables, then we need to make
* sure that it doesn't change while being written back.
*/
static vm_fault_t cifs_page_mkwrite(struct vm_fault *vmf) static vm_fault_t cifs_page_mkwrite(struct vm_fault *vmf)
{ {
struct folio *folio = page_folio(vmf->page); return netfs_page_mkwrite(vmf, NULL);
/* Wait for the folio to be written to the cache before we allow it to
* be modified. We then assume the entire folio will need writing back.
*/
#ifdef CONFIG_CIFS_FSCACHE
if (folio_test_private_2(folio) && /* [DEPRECATED] */
folio_wait_private_2_killable(folio) < 0)
return VM_FAULT_RETRY;
#endif
folio_wait_writeback(folio);
if (folio_lock_killable(folio) < 0)
return VM_FAULT_RETRY;
return VM_FAULT_LOCKED;
} }
static const struct vm_operations_struct cifs_file_vm_ops = { static const struct vm_operations_struct cifs_file_vm_ops = {
...@@ -4817,6 +4826,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -4817,6 +4826,7 @@ int cifs_file_mmap(struct file *file, struct vm_area_struct *vma)
return rc; return rc;
} }
#if 0 // TODO remove 4794
/* /*
* Unlock a bunch of folios in the pagecache. * Unlock a bunch of folios in the pagecache.
*/ */
...@@ -5101,6 +5111,7 @@ static int cifs_read_folio(struct file *file, struct folio *folio) ...@@ -5101,6 +5111,7 @@ static int cifs_read_folio(struct file *file, struct folio *folio)
free_xid(xid); free_xid(xid);
return rc; return rc;
} }
#endif // end netfslib remove 4794
static int is_inode_writable(struct cifsInodeInfo *cifs_inode) static int is_inode_writable(struct cifsInodeInfo *cifs_inode)
{ {
...@@ -5149,6 +5160,7 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file, ...@@ -5149,6 +5160,7 @@ bool is_size_safe_to_change(struct cifsInodeInfo *cifsInode, __u64 end_of_file,
return true; return true;
} }
#if 0 // TODO remove 5152
static int cifs_write_begin(struct file *file, struct address_space *mapping, static int cifs_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, loff_t pos, unsigned len,
struct page **pagep, void **fsdata) struct page **pagep, void **fsdata)
...@@ -5244,6 +5256,7 @@ static void cifs_invalidate_folio(struct folio *folio, size_t offset, ...@@ -5244,6 +5256,7 @@ static void cifs_invalidate_folio(struct folio *folio, size_t offset,
{ {
folio_wait_private_2(folio); /* [DEPRECATED] */ folio_wait_private_2(folio); /* [DEPRECATED] */
} }
#endif // end netfslib remove 5152
void cifs_oplock_break(struct work_struct *work) void cifs_oplock_break(struct work_struct *work)
{ {
...@@ -5334,6 +5347,7 @@ void cifs_oplock_break(struct work_struct *work) ...@@ -5334,6 +5347,7 @@ void cifs_oplock_break(struct work_struct *work)
cifs_done_oplock_break(cinode); cifs_done_oplock_break(cinode);
} }
#if 0 // TODO remove 5333
/* /*
* The presence of cifs_direct_io() in the address space ops vector * The presence of cifs_direct_io() in the address space ops vector
* allowes open() O_DIRECT flags which would have failed otherwise. * allowes open() O_DIRECT flags which would have failed otherwise.
...@@ -5352,6 +5366,7 @@ cifs_direct_io(struct kiocb *iocb, struct iov_iter *iter) ...@@ -5352,6 +5366,7 @@ cifs_direct_io(struct kiocb *iocb, struct iov_iter *iter)
*/ */
return -EINVAL; return -EINVAL;
} }
#endif // netfs end remove 5333
static int cifs_swap_activate(struct swap_info_struct *sis, static int cifs_swap_activate(struct swap_info_struct *sis,
struct file *swap_file, sector_t *span) struct file *swap_file, sector_t *span)
...@@ -5414,15 +5429,13 @@ static void cifs_swap_deactivate(struct file *file) ...@@ -5414,15 +5429,13 @@ static void cifs_swap_deactivate(struct file *file)
} }
const struct address_space_operations cifs_addr_ops = { const struct address_space_operations cifs_addr_ops = {
.read_folio = cifs_read_folio, .read_folio = netfs_read_folio,
.readahead = cifs_readahead, .readahead = netfs_readahead,
.writepages = cifs_writepages, .writepages = netfs_writepages,
.write_begin = cifs_write_begin,
.write_end = cifs_write_end,
.dirty_folio = netfs_dirty_folio, .dirty_folio = netfs_dirty_folio,
.release_folio = cifs_release_folio, .release_folio = netfs_release_folio,
.direct_IO = cifs_direct_io, .direct_IO = noop_direct_IO,
.invalidate_folio = cifs_invalidate_folio, .invalidate_folio = netfs_invalidate_folio,
.migrate_folio = filemap_migrate_folio, .migrate_folio = filemap_migrate_folio,
/* /*
* TODO: investigate and if useful we could add an is_dirty_writeback * TODO: investigate and if useful we could add an is_dirty_writeback
...@@ -5438,12 +5451,10 @@ const struct address_space_operations cifs_addr_ops = { ...@@ -5438,12 +5451,10 @@ const struct address_space_operations cifs_addr_ops = {
* to leave cifs_readahead out of the address space operations. * to leave cifs_readahead out of the address space operations.
*/ */
const struct address_space_operations cifs_addr_ops_smallbuf = { const struct address_space_operations cifs_addr_ops_smallbuf = {
.read_folio = cifs_read_folio, .read_folio = netfs_read_folio,
.writepages = cifs_writepages, .writepages = netfs_writepages,
.write_begin = cifs_write_begin,
.write_end = cifs_write_end,
.dirty_folio = netfs_dirty_folio, .dirty_folio = netfs_dirty_folio,
.release_folio = cifs_release_folio, .release_folio = netfs_release_folio,
.invalidate_folio = cifs_invalidate_folio, .invalidate_folio = netfs_invalidate_folio,
.migrate_folio = filemap_migrate_folio, .migrate_folio = filemap_migrate_folio,
}; };
...@@ -171,6 +171,7 @@ void cifs_fscache_release_inode_cookie(struct inode *inode) ...@@ -171,6 +171,7 @@ void cifs_fscache_release_inode_cookie(struct inode *inode)
} }
} }
#if 0 // TODO remove
/* /*
* Fallback page reading interface. * Fallback page reading interface.
*/ */
...@@ -279,3 +280,4 @@ int __cifs_fscache_query_occupancy(struct inode *inode, ...@@ -279,3 +280,4 @@ int __cifs_fscache_query_occupancy(struct inode *inode,
fscache_end_operation(&cres); fscache_end_operation(&cres);
return ret; return ret;
} }
#endif
...@@ -74,6 +74,7 @@ static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags ...@@ -74,6 +74,7 @@ static inline void cifs_invalidate_cache(struct inode *inode, unsigned int flags
i_size_read(inode), flags); i_size_read(inode), flags);
} }
#if 0 // TODO remove
extern int __cifs_fscache_query_occupancy(struct inode *inode, extern int __cifs_fscache_query_occupancy(struct inode *inode,
pgoff_t first, unsigned int nr_pages, pgoff_t first, unsigned int nr_pages,
pgoff_t *_data_first, pgoff_t *_data_first,
...@@ -108,6 +109,7 @@ static inline void cifs_readahead_to_fscache(struct inode *inode, ...@@ -108,6 +109,7 @@ static inline void cifs_readahead_to_fscache(struct inode *inode,
if (cifs_inode_cookie(inode)) if (cifs_inode_cookie(inode))
__cifs_readahead_to_fscache(inode, pos, len); __cifs_readahead_to_fscache(inode, pos, len);
} }
#endif
static inline bool cifs_fscache_enabled(struct inode *inode) 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 ...@@ -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 void cifs_invalidate_cache(struct inode *inode, unsigned int flags) {}
static inline bool cifs_fscache_enabled(struct inode *inode) { return false; } 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, static inline int cifs_fscache_query_occupancy(struct inode *inode,
pgoff_t first, unsigned int nr_pages, pgoff_t first, unsigned int nr_pages,
pgoff_t *_data_first, pgoff_t *_data_first,
...@@ -149,6 +152,7 @@ cifs_readpage_from_fscache(struct inode *inode, struct page *page) ...@@ -149,6 +152,7 @@ cifs_readpage_from_fscache(struct inode *inode, struct page *page)
static inline static inline
void cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len) {} void cifs_readahead_to_fscache(struct inode *inode, loff_t pos, size_t len) {}
#endif
#endif /* CONFIG_CIFS_FSCACHE */ #endif /* CONFIG_CIFS_FSCACHE */
......
...@@ -28,14 +28,29 @@ ...@@ -28,14 +28,29 @@
#include "cached_dir.h" #include "cached_dir.h"
#include "reparse.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) static void cifs_set_ops(struct inode *inode)
{ {
struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
struct netfs_inode *ictx = netfs_inode(inode);
switch (inode->i_mode & S_IFMT) { switch (inode->i_mode & S_IFMT) {
case S_IFREG: case S_IFREG:
inode->i_op = &cifs_file_inode_ops; inode->i_op = &cifs_file_inode_ops;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO) { 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) if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_BRL)
inode->i_fop = &cifs_file_direct_nobrl_ops; inode->i_fop = &cifs_file_direct_nobrl_ops;
else else
...@@ -221,8 +236,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr, ...@@ -221,8 +236,10 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,
if (fattr->cf_flags & CIFS_FATTR_JUNCTION) if (fattr->cf_flags & CIFS_FATTR_JUNCTION)
inode->i_flags |= S_AUTOMOUNT; 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); cifs_set_ops(inode);
}
return 0; return 0;
} }
......
...@@ -4421,7 +4421,9 @@ smb2_new_read_req(void **buf, unsigned int *total_len, ...@@ -4421,7 +4421,9 @@ smb2_new_read_req(void **buf, unsigned int *total_len,
req->Length = cpu_to_le32(io_parms->length); req->Length = cpu_to_le32(io_parms->length);
req->Offset = cpu_to_le64(io_parms->offset); req->Offset = cpu_to_le64(io_parms->offset);
trace_smb3_read_enter(0 /* xid */, trace_smb3_read_enter(rdata ? rdata->rreq->debug_id : 0,
rdata ? rdata->subreq.debug_index : 0,
rdata ? rdata->xid : 0,
io_parms->persistent_fid, io_parms->persistent_fid,
io_parms->tcon->tid, io_parms->tcon->ses->Suid, io_parms->tcon->tid, io_parms->tcon->ses->Suid,
io_parms->offset, io_parms->length); io_parms->offset, io_parms->length);
...@@ -4486,7 +4488,7 @@ static void ...@@ -4486,7 +4488,7 @@ static void
smb2_readv_callback(struct mid_q_entry *mid) smb2_readv_callback(struct mid_q_entry *mid)
{ {
struct cifs_io_subrequest *rdata = mid->callback_data; 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 = rdata->server; struct TCP_Server_Info *server = rdata->server;
struct smb2_hdr *shdr = struct smb2_hdr *shdr =
(struct smb2_hdr *)rdata->iov[0].iov_base; (struct smb2_hdr *)rdata->iov[0].iov_base;
...@@ -4514,7 +4516,6 @@ smb2_readv_callback(struct mid_q_entry *mid) ...@@ -4514,7 +4516,6 @@ smb2_readv_callback(struct mid_q_entry *mid)
if (server->sign && !mid->decrypted) { if (server->sign && !mid->decrypted) {
int rc; int rc;
iov_iter_revert(&rqst.rq_iter, rdata->got_bytes);
iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes); iov_iter_truncate(&rqst.rq_iter, rdata->got_bytes);
rc = smb2_verify_signature(&rqst, server); rc = smb2_verify_signature(&rqst, server);
if (rc) if (rc)
...@@ -4555,17 +4556,33 @@ smb2_readv_callback(struct mid_q_entry *mid) ...@@ -4555,17 +4556,33 @@ smb2_readv_callback(struct mid_q_entry *mid)
#endif #endif
if (rdata->result && rdata->result != -ENODATA) { if (rdata->result && rdata->result != -ENODATA) {
cifs_stats_fail_inc(tcon, SMB2_READ_HE); cifs_stats_fail_inc(tcon, SMB2_READ_HE);
trace_smb3_read_err(0 /* xid */, trace_smb3_read_err(rdata->rreq->debug_id,
rdata->cfile->fid.persistent_fid, rdata->subreq.debug_index,
rdata->xid,
rdata->req->cfile->fid.persistent_fid,
tcon->tid, tcon->ses->Suid, rdata->subreq.start, tcon->tid, tcon->ses->Suid, rdata->subreq.start,
rdata->subreq.len, rdata->result); rdata->subreq.len, rdata->result);
} else } else
trace_smb3_read_done(0 /* xid */, trace_smb3_read_done(rdata->rreq->debug_id,
rdata->cfile->fid.persistent_fid, rdata->subreq.debug_index,
rdata->xid,
rdata->req->cfile->fid.persistent_fid,
tcon->tid, tcon->ses->Suid, tcon->tid, tcon->ses->Suid,
rdata->subreq.start, rdata->got_bytes); rdata->subreq.start, rdata->got_bytes);
queue_work(cifsiod_wq, &rdata->work); if (rdata->result == -ENODATA) {
/* We may have got an EOF error because fallocate
* failed to enlarge the file.
*/
if (rdata->subreq.start < rdata->subreq.rreq->i_size)
rdata->result = 0;
}
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, true);
release_mid(mid); release_mid(mid);
add_credits(server, &credits, 0); add_credits(server, &credits, 0);
} }
...@@ -4581,7 +4598,7 @@ smb2_async_readv(struct cifs_io_subrequest *rdata) ...@@ -4581,7 +4598,7 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)
struct smb_rqst rqst = { .rq_iov = rdata->iov, struct smb_rqst rqst = { .rq_iov = rdata->iov,
.rq_nvec = 1 }; .rq_nvec = 1 };
struct TCP_Server_Info *server; struct TCP_Server_Info *server;
struct cifs_tcon *tcon = tlink_tcon(rdata->cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(rdata->req->cfile->tlink);
unsigned int total_len; unsigned int total_len;
int credit_request; int credit_request;
...@@ -4591,12 +4608,12 @@ smb2_async_readv(struct cifs_io_subrequest *rdata) ...@@ -4591,12 +4608,12 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)
if (!rdata->server) if (!rdata->server)
rdata->server = cifs_pick_channel(tcon->ses); rdata->server = cifs_pick_channel(tcon->ses);
io_parms.tcon = tlink_tcon(rdata->cfile->tlink); io_parms.tcon = tlink_tcon(rdata->req->cfile->tlink);
io_parms.server = server = rdata->server; io_parms.server = server = rdata->server;
io_parms.offset = rdata->subreq.start; io_parms.offset = rdata->subreq.start;
io_parms.length = rdata->subreq.len; io_parms.length = rdata->subreq.len;
io_parms.persistent_fid = rdata->cfile->fid.persistent_fid; io_parms.persistent_fid = rdata->req->cfile->fid.persistent_fid;
io_parms.volatile_fid = rdata->cfile->fid.volatile_fid; io_parms.volatile_fid = rdata->req->cfile->fid.volatile_fid;
io_parms.pid = rdata->pid; io_parms.pid = rdata->pid;
rc = smb2_new_read_req( rc = smb2_new_read_req(
...@@ -4630,15 +4647,15 @@ smb2_async_readv(struct cifs_io_subrequest *rdata) ...@@ -4630,15 +4647,15 @@ smb2_async_readv(struct cifs_io_subrequest *rdata)
flags |= CIFS_HAS_CREDITS; flags |= CIFS_HAS_CREDITS;
} }
cifs_get_readdata(rdata);
rc = cifs_call_async(server, &rqst, rc = cifs_call_async(server, &rqst,
cifs_readv_receive, smb2_readv_callback, cifs_readv_receive, smb2_readv_callback,
smb3_handle_read_data, rdata, flags, smb3_handle_read_data, rdata, flags,
&rdata->credits); &rdata->credits);
if (rc) { if (rc) {
cifs_put_readdata(rdata);
cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE); cifs_stats_fail_inc(io_parms.tcon, SMB2_READ_HE);
trace_smb3_read_err(0 /* xid */, io_parms.persistent_fid, trace_smb3_read_err(rdata->rreq->debug_id,
rdata->subreq.debug_index,
rdata->xid, io_parms.persistent_fid,
io_parms.tcon->tid, io_parms.tcon->tid,
io_parms.tcon->ses->Suid, io_parms.tcon->ses->Suid,
io_parms.offset, io_parms.length, rc); io_parms.offset, io_parms.length, rc);
...@@ -4689,19 +4706,20 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, ...@@ -4689,19 +4706,20 @@ SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
if (rc != -ENODATA) { if (rc != -ENODATA) {
cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE); cifs_stats_fail_inc(io_parms->tcon, SMB2_READ_HE);
cifs_dbg(VFS, "Send error in read = %d\n", rc); cifs_dbg(VFS, "Send error in read = %d\n", rc);
trace_smb3_read_err(xid, trace_smb3_read_err(0, 0, xid,
req->PersistentFileId, req->PersistentFileId,
io_parms->tcon->tid, ses->Suid, io_parms->tcon->tid, ses->Suid,
io_parms->offset, io_parms->length, io_parms->offset, io_parms->length,
rc); rc);
} else } else
trace_smb3_read_done(xid, req->PersistentFileId, io_parms->tcon->tid, trace_smb3_read_done(0, 0, xid,
req->PersistentFileId, io_parms->tcon->tid,
ses->Suid, io_parms->offset, 0); ses->Suid, io_parms->offset, 0);
free_rsp_buf(resp_buftype, rsp_iov.iov_base); free_rsp_buf(resp_buftype, rsp_iov.iov_base);
cifs_small_buf_release(req); cifs_small_buf_release(req);
return rc == -ENODATA ? 0 : rc; return rc == -ENODATA ? 0 : rc;
} else } else
trace_smb3_read_done(xid, trace_smb3_read_done(0, 0, xid,
req->PersistentFileId, req->PersistentFileId,
io_parms->tcon->tid, ses->Suid, io_parms->tcon->tid, ses->Suid,
io_parms->offset, io_parms->length); io_parms->offset, io_parms->length);
...@@ -4738,11 +4756,12 @@ static void ...@@ -4738,11 +4756,12 @@ static void
smb2_writev_callback(struct mid_q_entry *mid) smb2_writev_callback(struct mid_q_entry *mid)
{ {
struct cifs_io_subrequest *wdata = mid->callback_data; struct cifs_io_subrequest *wdata = mid->callback_data;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
struct TCP_Server_Info *server = wdata->server; struct TCP_Server_Info *server = wdata->server;
unsigned int written;
struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf; struct smb2_write_rsp *rsp = (struct smb2_write_rsp *)mid->resp_buf;
struct cifs_credits credits = { .value = 0, .instance = 0 }; struct cifs_credits credits = { .value = 0, .instance = 0 };
ssize_t result = 0;
size_t written;
WARN_ONCE(wdata->server != mid->server, WARN_ONCE(wdata->server != mid->server,
"wdata server %p != mid server %p", "wdata server %p != mid server %p",
...@@ -4752,8 +4771,8 @@ smb2_writev_callback(struct mid_q_entry *mid) ...@@ -4752,8 +4771,8 @@ smb2_writev_callback(struct mid_q_entry *mid)
case MID_RESPONSE_RECEIVED: case MID_RESPONSE_RECEIVED:
credits.value = le16_to_cpu(rsp->hdr.CreditRequest); credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
credits.instance = server->reconnect_instance; credits.instance = server->reconnect_instance;
wdata->result = smb2_check_receive(mid, server, 0); result = smb2_check_receive(mid, server, 0);
if (wdata->result != 0) if (result != 0)
break; break;
written = le32_to_cpu(rsp->DataLength); written = le32_to_cpu(rsp->DataLength);
...@@ -4770,17 +4789,18 @@ smb2_writev_callback(struct mid_q_entry *mid) ...@@ -4770,17 +4789,18 @@ smb2_writev_callback(struct mid_q_entry *mid)
wdata->result = -ENOSPC; wdata->result = -ENOSPC;
else else
wdata->subreq.len = written; wdata->subreq.len = written;
iov_iter_advance(&wdata->subreq.io_iter, written);
break; break;
case MID_REQUEST_SUBMITTED: case MID_REQUEST_SUBMITTED:
case MID_RETRY_NEEDED: case MID_RETRY_NEEDED:
wdata->result = -EAGAIN; result = -EAGAIN;
break; break;
case MID_RESPONSE_MALFORMED: case MID_RESPONSE_MALFORMED:
credits.value = le16_to_cpu(rsp->hdr.CreditRequest); credits.value = le16_to_cpu(rsp->hdr.CreditRequest);
credits.instance = server->reconnect_instance; credits.instance = server->reconnect_instance;
fallthrough; fallthrough;
default: default:
wdata->result = -EIO; result = -EIO;
break; break;
} }
#ifdef CONFIG_CIFS_SMB_DIRECT #ifdef CONFIG_CIFS_SMB_DIRECT
...@@ -4796,10 +4816,10 @@ smb2_writev_callback(struct mid_q_entry *mid) ...@@ -4796,10 +4816,10 @@ smb2_writev_callback(struct mid_q_entry *mid)
wdata->mr = NULL; wdata->mr = NULL;
} }
#endif #endif
if (wdata->result) { if (result) {
cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
trace_smb3_write_err(0 /* no xid */, trace_smb3_write_err(wdata->xid,
wdata->cfile->fid.persistent_fid, wdata->req->cfile->fid.persistent_fid,
tcon->tid, tcon->ses->Suid, wdata->subreq.start, tcon->tid, tcon->ses->Suid, wdata->subreq.start,
wdata->subreq.len, wdata->result); wdata->subreq.len, wdata->result);
if (wdata->result == -ENOSPC) if (wdata->result == -ENOSPC)
...@@ -4807,27 +4827,28 @@ smb2_writev_callback(struct mid_q_entry *mid) ...@@ -4807,27 +4827,28 @@ smb2_writev_callback(struct mid_q_entry *mid)
tcon->tree_name); tcon->tree_name);
} else } else
trace_smb3_write_done(0 /* no xid */, trace_smb3_write_done(0 /* no xid */,
wdata->cfile->fid.persistent_fid, wdata->req->cfile->fid.persistent_fid,
tcon->tid, tcon->ses->Suid, tcon->tid, tcon->ses->Suid,
wdata->subreq.start, wdata->subreq.len); wdata->subreq.start, wdata->subreq.len);
queue_work(cifsiod_wq, &wdata->work); wdata->credits.value = 0;
cifs_write_subrequest_terminated(wdata, result ?: written, true);
release_mid(mid); release_mid(mid);
add_credits(server, &credits, 0); add_credits(server, &credits, 0);
} }
/* smb2_async_writev - send an async write, and set up mid to handle result */ /* smb2_async_writev - send an async write, and set up mid to handle result */
int void
smb2_async_writev(struct cifs_io_subrequest *wdata) smb2_async_writev(struct cifs_io_subrequest *wdata)
{ {
int rc = -EACCES, flags = 0; int rc = -EACCES, flags = 0;
struct smb2_write_req *req = NULL; struct smb2_write_req *req = NULL;
struct smb2_hdr *shdr; struct smb2_hdr *shdr;
struct cifs_tcon *tcon = tlink_tcon(wdata->cfile->tlink); struct cifs_tcon *tcon = tlink_tcon(wdata->req->cfile->tlink);
struct TCP_Server_Info *server = wdata->server; struct TCP_Server_Info *server = wdata->server;
struct kvec iov[1]; struct kvec iov[1];
struct smb_rqst rqst = { }; struct smb_rqst rqst = { };
unsigned int total_len; unsigned int total_len, xid = wdata->xid;
struct cifs_io_parms _io_parms; struct cifs_io_parms _io_parms;
struct cifs_io_parms *io_parms = NULL; struct cifs_io_parms *io_parms = NULL;
int credit_request; int credit_request;
...@@ -4844,8 +4865,8 @@ smb2_async_writev(struct cifs_io_subrequest *wdata) ...@@ -4844,8 +4865,8 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
.server = server, .server = server,
.offset = wdata->subreq.start, .offset = wdata->subreq.start,
.length = wdata->subreq.len, .length = wdata->subreq.len,
.persistent_fid = wdata->cfile->fid.persistent_fid, .persistent_fid = wdata->req->cfile->fid.persistent_fid,
.volatile_fid = wdata->cfile->fid.volatile_fid, .volatile_fid = wdata->req->cfile->fid.volatile_fid,
.pid = wdata->pid, .pid = wdata->pid,
}; };
io_parms = &_io_parms; io_parms = &_io_parms;
...@@ -4853,7 +4874,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata) ...@@ -4853,7 +4874,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
rc = smb2_plain_req_init(SMB2_WRITE, tcon, server, rc = smb2_plain_req_init(SMB2_WRITE, tcon, server,
(void **) &req, &total_len); (void **) &req, &total_len);
if (rc) if (rc)
return rc; goto out;
if (smb3_encryption_required(tcon)) if (smb3_encryption_required(tcon))
flags |= CIFS_TRANSFORM_REQ; flags |= CIFS_TRANSFORM_REQ;
...@@ -4871,7 +4892,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata) ...@@ -4871,7 +4892,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
offsetof(struct smb2_write_req, Buffer)); offsetof(struct smb2_write_req, Buffer));
req->RemainingBytes = 0; req->RemainingBytes = 0;
trace_smb3_write_enter(0 /* xid */, trace_smb3_write_enter(wdata->xid,
io_parms->persistent_fid, io_parms->persistent_fid,
io_parms->tcon->tid, io_parms->tcon->tid,
io_parms->tcon->ses->Suid, io_parms->tcon->ses->Suid,
...@@ -4952,25 +4973,27 @@ smb2_async_writev(struct cifs_io_subrequest *wdata) ...@@ -4952,25 +4973,27 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)
flags |= CIFS_HAS_CREDITS; flags |= CIFS_HAS_CREDITS;
} }
cifs_get_writedata(wdata);
rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL, rc = cifs_call_async(server, &rqst, NULL, smb2_writev_callback, NULL,
wdata, flags, &wdata->credits); wdata, flags, &wdata->credits);
/* Can't touch wdata if rc == 0 */
if (rc) { if (rc) {
trace_smb3_write_err(0 /* no xid */, trace_smb3_write_err(xid,
io_parms->persistent_fid, io_parms->persistent_fid,
io_parms->tcon->tid, io_parms->tcon->tid,
io_parms->tcon->ses->Suid, io_parms->tcon->ses->Suid,
io_parms->offset, io_parms->offset,
io_parms->length, io_parms->length,
rc); rc);
cifs_put_writedata(wdata);
cifs_stats_fail_inc(tcon, SMB2_WRITE_HE); cifs_stats_fail_inc(tcon, SMB2_WRITE_HE);
} }
async_writev_out: async_writev_out:
cifs_small_buf_release(req); cifs_small_buf_release(req);
return rc; out:
if (rc) {
add_credits_and_wake_if(wdata->server, &wdata->credits, 0);
cifs_write_subrequest_terminated(wdata, rc, true);
}
} }
/* /*
......
...@@ -213,7 +213,7 @@ extern int SMB2_get_srv_num(const unsigned int xid, struct cifs_tcon *tcon, ...@@ -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_async_readv(struct cifs_io_subrequest *rdata);
extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms, extern int SMB2_read(const unsigned int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, char **buf, int *buf_type); 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, extern int SMB2_write(const unsigned int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, struct kvec *iov, int n_vec); unsigned int *nbytes, struct kvec *iov, int n_vec);
extern int SMB2_echo(struct TCP_Server_Info *server); extern int SMB2_echo(struct TCP_Server_Info *server);
......
...@@ -85,6 +85,62 @@ smb3_tcon_ref_traces; ...@@ -85,6 +85,62 @@ smb3_tcon_ref_traces;
/* For logging errors in read or write */ /* For logging errors in read or write */
DECLARE_EVENT_CLASS(smb3_rw_err_class, 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, TP_PROTO(unsigned int xid,
__u64 fid, __u64 fid,
__u32 tid, __u32 tid,
...@@ -116,8 +172,8 @@ DECLARE_EVENT_CLASS(smb3_rw_err_class, ...@@ -116,8 +172,8 @@ DECLARE_EVENT_CLASS(smb3_rw_err_class,
__entry->offset, __entry->len, __entry->rc) __entry->offset, __entry->len, __entry->rc)
) )
#define DEFINE_SMB3_RW_ERR_EVENT(name) \ #define DEFINE_SMB3_OTHER_ERR_EVENT(name) \
DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \ DEFINE_EVENT(smb3_other_err_class, smb3_##name, \
TP_PROTO(unsigned int xid, \ TP_PROTO(unsigned int xid, \
__u64 fid, \ __u64 fid, \
__u32 tid, \ __u32 tid, \
...@@ -127,15 +183,67 @@ DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \ ...@@ -127,15 +183,67 @@ DEFINE_EVENT(smb3_rw_err_class, smb3_##name, \
int rc), \ int rc), \
TP_ARGS(xid, fid, tid, sesid, offset, len, rc)) TP_ARGS(xid, fid, tid, sesid, offset, len, rc))
DEFINE_SMB3_RW_ERR_EVENT(write_err); DEFINE_SMB3_OTHER_ERR_EVENT(write_err);
DEFINE_SMB3_RW_ERR_EVENT(read_err); DEFINE_SMB3_OTHER_ERR_EVENT(query_dir_err);
DEFINE_SMB3_RW_ERR_EVENT(query_dir_err); DEFINE_SMB3_OTHER_ERR_EVENT(zero_err);
DEFINE_SMB3_RW_ERR_EVENT(zero_err); DEFINE_SMB3_OTHER_ERR_EVENT(falloc_err);
DEFINE_SMB3_RW_ERR_EVENT(falloc_err);
/* For logging successful read or write */ /* For logging successful read or write */
DECLARE_EVENT_CLASS(smb3_rw_done_class, 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, TP_PROTO(unsigned int xid,
__u64 fid, __u64 fid,
__u32 tid, __u32 tid,
...@@ -164,8 +272,8 @@ DECLARE_EVENT_CLASS(smb3_rw_done_class, ...@@ -164,8 +272,8 @@ DECLARE_EVENT_CLASS(smb3_rw_done_class,
__entry->offset, __entry->len) __entry->offset, __entry->len)
) )
#define DEFINE_SMB3_RW_DONE_EVENT(name) \ #define DEFINE_SMB3_OTHER_DONE_EVENT(name) \
DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \ DEFINE_EVENT(smb3_other_done_class, smb3_##name, \
TP_PROTO(unsigned int xid, \ TP_PROTO(unsigned int xid, \
__u64 fid, \ __u64 fid, \
__u32 tid, \ __u32 tid, \
...@@ -174,16 +282,14 @@ DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \ ...@@ -174,16 +282,14 @@ DEFINE_EVENT(smb3_rw_done_class, smb3_##name, \
__u32 len), \ __u32 len), \
TP_ARGS(xid, fid, tid, sesid, offset, len)) TP_ARGS(xid, fid, tid, sesid, offset, len))
DEFINE_SMB3_RW_DONE_EVENT(write_enter); DEFINE_SMB3_OTHER_DONE_EVENT(write_enter);
DEFINE_SMB3_RW_DONE_EVENT(read_enter); DEFINE_SMB3_OTHER_DONE_EVENT(query_dir_enter);
DEFINE_SMB3_RW_DONE_EVENT(query_dir_enter); DEFINE_SMB3_OTHER_DONE_EVENT(zero_enter);
DEFINE_SMB3_RW_DONE_EVENT(zero_enter); DEFINE_SMB3_OTHER_DONE_EVENT(falloc_enter);
DEFINE_SMB3_RW_DONE_EVENT(falloc_enter); DEFINE_SMB3_OTHER_DONE_EVENT(write_done);
DEFINE_SMB3_RW_DONE_EVENT(write_done); DEFINE_SMB3_OTHER_DONE_EVENT(query_dir_done);
DEFINE_SMB3_RW_DONE_EVENT(read_done); DEFINE_SMB3_OTHER_DONE_EVENT(zero_done);
DEFINE_SMB3_RW_DONE_EVENT(query_dir_done); DEFINE_SMB3_OTHER_DONE_EVENT(falloc_done);
DEFINE_SMB3_RW_DONE_EVENT(zero_done);
DEFINE_SMB3_RW_DONE_EVENT(falloc_done);
/* For logging successful set EOF (truncate) */ /* For logging successful set EOF (truncate) */
DECLARE_EVENT_CLASS(smb3_eof_class, DECLARE_EVENT_CLASS(smb3_eof_class,
......
...@@ -1813,8 +1813,11 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid) ...@@ -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. */ length = data_len; /* An RDMA read is already done. */
else else
#endif #endif
{
length = cifs_read_iter_from_socket(server, &rdata->subreq.io_iter, length = cifs_read_iter_from_socket(server, &rdata->subreq.io_iter,
data_len); data_len);
iov_iter_revert(&rdata->subreq.io_iter, data_len);
}
if (length > 0) if (length > 0)
rdata->got_bytes += length; rdata->got_bytes += length;
server->total_read += 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