mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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: 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
							
								
									69c3c023af
								
							
						
					
					
						commit
						3ee1a1fc39
					
				
					 14 changed files with 361 additions and 180 deletions
				
			
		| 
						 | 
					@ -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 = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 = {
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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;
 | 
				
			||||||
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);
 | 
				
			||||||
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 {
 | 
				
			||||||
	/* 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 {
 | 
				
			||||||
#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 {
 | 
				
			||||||
	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,
 | 
				
			||||||
				   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);
 | 
				
			||||||
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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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
 | 
				
			||||||
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)
 | 
				
			||||||
		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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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
 | 
				
			||||||
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)
 | 
				
			||||||
			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)
 | 
				
			||||||
		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)
 | 
				
			||||||
	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)
 | 
				
			||||||
		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)
 | 
				
			||||||
	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 = {
 | 
				
			||||||
	.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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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)
 | 
				
			||||||
	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,
 | 
				
			||||||
	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,
 | 
				
			||||||
	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,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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,
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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)
 | 
				
			||||||
	 * 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)
 | 
				
			||||||
	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)
 | 
				
			||||||
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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)))
 | 
						if (!CIFS_CACHE_WRITE(CIFS_I(inode))) {
 | 
				
			||||||
		goto out;
 | 
							rc = filemap_fdatawrite(inode->i_mapping);
 | 
				
			||||||
 | 
							if (rc)
 | 
				
			||||||
 | 
								cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n",
 | 
				
			||||||
 | 
									 rc, inode);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	rc = filemap_fdatawrite(inode->i_mapping);
 | 
					 | 
				
			||||||
	if (rc)
 | 
					 | 
				
			||||||
		cifs_dbg(FYI, "cifs_file_write_iter: %d rc on %p inode\n",
 | 
					 | 
				
			||||||
			 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)
 | 
				
			||||||
	 * 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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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,
 | 
				
			||||||
		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,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)
 | 
				
			||||||
         */
 | 
					         */
 | 
				
			||||||
        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,21 +5429,19 @@ 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,
 | 
						.dirty_folio	= netfs_dirty_folio,
 | 
				
			||||||
	.write_end = cifs_write_end,
 | 
						.release_folio	= netfs_release_folio,
 | 
				
			||||||
	.dirty_folio = netfs_dirty_folio,
 | 
						.direct_IO	= noop_direct_IO,
 | 
				
			||||||
	.release_folio = cifs_release_folio,
 | 
						.invalidate_folio = netfs_invalidate_folio,
 | 
				
			||||||
	.direct_IO = cifs_direct_io,
 | 
						.migrate_folio	= filemap_migrate_folio,
 | 
				
			||||||
	.invalidate_folio = cifs_invalidate_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
 | 
				
			||||||
	 * helper if needed
 | 
						 * helper if needed
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	.swap_activate = cifs_swap_activate,
 | 
						.swap_activate	= cifs_swap_activate,
 | 
				
			||||||
	.swap_deactivate = cifs_swap_deactivate,
 | 
						.swap_deactivate = cifs_swap_deactivate,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,
 | 
						.dirty_folio	= netfs_dirty_folio,
 | 
				
			||||||
	.write_end = cifs_write_end,
 | 
						.release_folio	= netfs_release_folio,
 | 
				
			||||||
	.dirty_folio = netfs_dirty_folio,
 | 
						.invalidate_folio = netfs_invalidate_folio,
 | 
				
			||||||
	.release_folio = cifs_release_folio,
 | 
						.migrate_folio	= filemap_migrate_folio,
 | 
				
			||||||
	.invalidate_folio = cifs_invalidate_folio,
 | 
					 | 
				
			||||||
	.migrate_folio = filemap_migrate_folio,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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,
 | 
				
			||||||
	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
 | 
				
			||||||
			   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,
 | 
				
			||||||
	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
 | 
				
			||||||
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)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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 @@
 | 
				
			||||||
#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,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	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,10 +4421,12 @@ 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,
 | 
				
			||||||
			io_parms->persistent_fid,
 | 
								      rdata ? rdata->subreq.debug_index : 0,
 | 
				
			||||||
			io_parms->tcon->tid, io_parms->tcon->ses->Suid,
 | 
								      rdata ? rdata->xid : 0,
 | 
				
			||||||
			io_parms->offset, io_parms->length);
 | 
								      io_parms->persistent_fid,
 | 
				
			||||||
 | 
								      io_parms->tcon->tid, io_parms->tcon->ses->Suid,
 | 
				
			||||||
 | 
								      io_parms->offset, io_parms->length);
 | 
				
			||||||
#ifdef CONFIG_CIFS_SMB_DIRECT
 | 
					#ifdef CONFIG_CIFS_SMB_DIRECT
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * If we want to do a RDMA write, fill in and append
 | 
						 * If we want to do a RDMA write, fill in and append
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
		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)
 | 
				
			||||||
#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)
 | 
				
			||||||
	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)
 | 
				
			||||||
	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)
 | 
				
			||||||
		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,22 +4706,23 @@ 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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cifs_small_buf_release(req);
 | 
						cifs_small_buf_release(req);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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)
 | 
				
			||||||
	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)
 | 
				
			||||||
			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)
 | 
				
			||||||
		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)
 | 
				
			||||||
				     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)
 | 
				
			||||||
		.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)
 | 
				
			||||||
	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)
 | 
				
			||||||
				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)
 | 
				
			||||||
		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,
 | 
				
			||||||
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;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 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,
 | 
				
			||||||
		__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,    \
 | 
				
			||||||
		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,
 | 
				
			||||||
		__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,   \
 | 
				
			||||||
		__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)
 | 
				
			||||||
		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;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue