Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fa2989f4 authored by Pavel Shilovsky's avatar Pavel Shilovsky Committed by Steve French
Browse files

CIFS: Use pid saved from cifsFileInfo in writepages and set_file_size



We need it to make them work with mandatory locking style because
we can fail in a situation like when kernel need to flush dirty pages
and there is a lock held by a process who opened file.

Signed-off-by: default avatarPavel Shilovsky <piastry@etersoft.ru>
Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent c28c89fc
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -455,6 +455,14 @@ struct cifsFileInfo {
	struct work_struct oplock_break; /* work for oplock breaks */
};

struct cifs_io_parms {
	__u16 netfid;
	__u32 pid;
	__u64 offset;
	unsigned int length;
	struct cifsTconInfo *tcon;
};

/*
 * Take a reference on the file private data. Must be called with
 * cifs_file_list_lock held.
+5 −8
Original line number Diff line number Diff line
@@ -348,15 +348,12 @@ extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
			const int netfid, unsigned int count,
			const __u64 lseek, unsigned int *nbytes, char **buf,
			int *return_buf_type);
extern int CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
			const int netfid, const unsigned int count,
			const __u64 lseek, unsigned int *nbytes,
			const char *buf, const char __user *ubuf,
extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
			unsigned int *nbytes, const char *buf,
			const char __user *ubuf, const int long_op);
extern int CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
			unsigned int *nbytes, struct kvec *iov, const int nvec,
			const int long_op);
extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
			const int netfid, const unsigned int count,
			const __u64 offset, unsigned int *nbytes,
			struct kvec *iov, const int nvec, const int long_op);
extern int CIFSGetSrvInodeNumber(const int xid, struct cifsTconInfo *tcon,
			const unsigned char *searchName, __u64 *inode_number,
			const struct nls_table *nls_codepage,
+26 −7
Original line number Diff line number Diff line
@@ -1487,9 +1487,8 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,


int
CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
	     const int netfid, const unsigned int count,
	     const __u64 offset, unsigned int *nbytes, const char *buf,
CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
	     unsigned int *nbytes, const char *buf,
	     const char __user *ubuf, const int long_op)
{
	int rc = -EACCES;
@@ -1498,6 +1497,11 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
	int bytes_returned, wct;
	__u32 bytes_sent;
	__u16 byte_count;
	__u32 pid = io_parms->pid;
	__u16 netfid = io_parms->netfid;
	__u64 offset = io_parms->offset;
	struct cifsTconInfo *tcon = io_parms->tcon;
	unsigned int count = io_parms->length;

	*nbytes = 0;

@@ -1519,6 +1523,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
		      (void **) &pSMBr);
	if (rc)
		return rc;

	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));

	/* tcon and ses pointer are checked in smb_init */
	if (tcon->ses->server == NULL)
		return -ECONNABORTED;
@@ -1778,6 +1786,9 @@ cifs_async_writev(struct cifs_writedata *wdata)
		goto async_writev_out;
	}

	smb->hdr.Pid = cpu_to_le16((__u16)wdata->cfile->pid);
	smb->hdr.PidHigh = cpu_to_le16((__u16)(wdata->cfile->pid >> 16));

	smb->AndXCommand = 0xFF;	/* none */
	smb->Fid = wdata->cfile->netfid;
	smb->OffsetLow = cpu_to_le32(wdata->offset & 0xFFFFFFFF);
@@ -1841,16 +1852,20 @@ cifs_async_writev(struct cifs_writedata *wdata)
}

int
CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
	     const int netfid, const unsigned int count,
	     const __u64 offset, unsigned int *nbytes, struct kvec *iov,
	     int n_vec, const int long_op)
CIFSSMBWrite2(const int xid, struct cifs_io_parms *io_parms,
	      unsigned int *nbytes, struct kvec *iov, int n_vec,
	      const int long_op)
{
	int rc = -EACCES;
	WRITE_REQ *pSMB = NULL;
	int wct;
	int smb_hdr_len;
	int resp_buf_type = 0;
	__u32 pid = io_parms->pid;
	__u16 netfid = io_parms->netfid;
	__u64 offset = io_parms->offset;
	struct cifsTconInfo *tcon = io_parms->tcon;
	unsigned int count = io_parms->length;

	*nbytes = 0;

@@ -1868,6 +1883,10 @@ CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
	rc = small_smb_init(SMB_COM_WRITE_ANDX, wct, tcon, (void **) &pSMB);
	if (rc)
		return rc;

	pSMB->hdr.Pid = cpu_to_le16((__u16)pid);
	pSMB->hdr.PidHigh = cpu_to_le16((__u16)(pid >> 16));

	/* tcon and ses pointer are checked in smb_init */
	if (tcon->ses->server == NULL)
		return -ECONNABORTED;
+10 −8
Original line number Diff line number Diff line
@@ -357,6 +357,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
	struct cifs_sb_info *cifs_sb;
	struct tcon_link *tlink;
	struct cifsTconInfo *pTcon;
	struct cifs_io_parms io_parms;
	char *full_path = NULL;
	struct inode *newinode = NULL;
	int oplock = 0;
@@ -439,16 +440,19 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
	 * timestamps in, but we can reuse it safely */

	pdev = (struct win_dev *)buf;
	io_parms.netfid = fileHandle;
	io_parms.pid = current->tgid;
	io_parms.tcon = pTcon;
	io_parms.offset = 0;
	io_parms.length = sizeof(struct win_dev);
	if (S_ISCHR(mode)) {
		memcpy(pdev->type, "IntxCHR", 8);
		pdev->major =
		      cpu_to_le64(MAJOR(device_number));
		pdev->minor =
		      cpu_to_le64(MINOR(device_number));
		rc = CIFSSMBWrite(xid, pTcon,
			fileHandle,
			sizeof(struct win_dev),
			0, &bytes_written, (char *)pdev,
		rc = CIFSSMBWrite(xid, &io_parms,
			&bytes_written, (char *)pdev,
			NULL, 0);
	} else if (S_ISBLK(mode)) {
		memcpy(pdev->type, "IntxBLK", 8);
@@ -456,10 +460,8 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode,
		      cpu_to_le64(MAJOR(device_number));
		pdev->minor =
		      cpu_to_le64(MINOR(device_number));
		rc = CIFSSMBWrite(xid, pTcon,
			fileHandle,
			sizeof(struct win_dev),
			0, &bytes_written, (char *)pdev,
		rc = CIFSSMBWrite(xid, &io_parms,
			&bytes_written, (char *)pdev,
			NULL, 0);
	} /* else if (S_ISFIFO) */
	CIFSSMBClose(xid, pTcon, fileHandle);
+21 −10
Original line number Diff line number Diff line
@@ -857,7 +857,7 @@ cifs_update_eof(struct cifsInodeInfo *cifsi, loff_t offset,
		cifsi->server_eof = end_of_write;
}

static ssize_t cifs_write(struct cifsFileInfo *open_file,
static ssize_t cifs_write(struct cifsFileInfo *open_file, __u32 pid,
			  const char *write_data, size_t write_size,
			  loff_t *poffset)
{
@@ -869,6 +869,7 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
	int xid;
	struct dentry *dentry = open_file->dentry;
	struct cifsInodeInfo *cifsi = CIFS_I(dentry->d_inode);
	struct cifs_io_parms io_parms;

	cifs_sb = CIFS_SB(dentry->d_sb);

@@ -901,8 +902,13 @@ static ssize_t cifs_write(struct cifsFileInfo *open_file,
			/* iov[0] is reserved for smb header */
			iov[1].iov_base = (char *)write_data + total_written;
			iov[1].iov_len = len;
			rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid, len,
					   *poffset, &bytes_written, iov, 1, 0);
			io_parms.netfid = open_file->netfid;
			io_parms.pid = pid;
			io_parms.tcon = pTcon;
			io_parms.offset = *poffset;
			io_parms.length = len;
			rc = CIFSSMBWrite2(xid, &io_parms, &bytes_written, iov,
					   1, 0);
		}
		if (rc || (bytes_written == 0)) {
			if (total_written)
@@ -1071,8 +1077,8 @@ static int cifs_partialpagewrite(struct page *page, unsigned from, unsigned to)

	open_file = find_writable_file(CIFS_I(mapping->host), false);
	if (open_file) {
		bytes_written = cifs_write(open_file, write_data,
					   to - from, &offset);
		bytes_written = cifs_write(open_file, open_file->pid,
					   write_data, to - from, &offset);
		cifsFileInfo_put(open_file);
		/* Does mm or vfs already set times? */
		inode->i_atime = inode->i_mtime = current_fs_time(inode->i_sb);
@@ -1363,8 +1369,8 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
		/* BB check if anything else missing out of ppw
		   such as updating last write time */
		page_data = kmap(page);
		rc = cifs_write(file->private_data, page_data + offset,
				copied, &pos);
		rc = cifs_write(file->private_data, current->tgid,
				page_data + offset, copied, &pos);
		/* if (rc < 0) should we set writebehind rc? */
		kunmap(page);

@@ -1515,6 +1521,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
	struct cifsFileInfo *open_file;
	struct cifsTconInfo *pTcon;
	struct cifs_sb_info *cifs_sb;
	struct cifs_io_parms io_parms;
	int xid, rc;

	len = iov_length(iov, nr_segs);
@@ -1573,9 +1580,13 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
				if (rc != 0)
					break;
			}
			rc = CIFSSMBWrite2(xid, pTcon, open_file->netfid,
					   cur_len, *poffset, &written,
					   to_send, npages, 0);
			io_parms.netfid = open_file->netfid;
			io_parms.pid = current->tgid;
			io_parms.tcon = pTcon;
			io_parms.offset = *poffset;
			io_parms.length = cur_len;
			rc = CIFSSMBWrite2(xid, &io_parms, &written, to_send,
					   npages, 0);
		} while (rc == -EAGAIN);

		for (i = 0; i < npages; i++)
Loading