Commit 8d4a0452 authored by Pavel Shilovsky's avatar Pavel Shilovsky

Pull from cifs-2.6 repo for centos54

Implement WINE logic Fix losing locks during fork()
parent 853e2e0c
......@@ -33,6 +33,7 @@
#define CIFS_MOUNT_DYNPERM 0x1000 /* allow in-memory only mode setting */
#define CIFS_MOUNT_NOPOSIXBRL 0x2000 /* mandatory not posix byte range lock */
#define CIFS_MOUNT_NOSSYNC 0x4000 /* don't do slow SMBflush on every sync*/
#define CIFS_MOUNT_WINE_MODE 0x8000 /* use pid forwarding for wine apps */
struct cifs_sb_info {
struct cifsTconInfo *tcon; /* primary mount */
......
......@@ -423,6 +423,10 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",nocase");
if (tcon->retry)
seq_printf(s, ",hard");
if (tcon->unix_ext)
seq_printf(s, ",unix");
else
seq_printf(s, ",nounix");
}
if (cifs_sb->prepath)
seq_printf(s, ",prepath=%s", cifs_sb->prepath);
......@@ -432,6 +436,10 @@ cifs_show_options(struct seq_file *s, struct vfsmount *m)
seq_printf(s, ",setuids");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)
seq_printf(s, ",serverino");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE)
seq_printf(s, ",wine");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL)
seq_printf(s, ",forcemand");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DIRECT_IO)
seq_printf(s, ",directio");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NO_XATTR)
......@@ -740,7 +748,7 @@ static ssize_t cifs_sync_read(struct file *filp, char __user *buf,
if (!CIFS_I(filp->f_dentry->d_inode)->clientCanCacheRead
&& !posix_locking) {
#endif
retval = cifs_lock(filp, F_GETLK, &pfLock);
retval = cifs_lock(filp, F_GETLK | CIFS_NOPOSIXBRL_READ, &pfLock);
if (retval < 0)
return (ssize_t)retval;
if (pfLock.fl_type == F_UNLCK)
......
......@@ -323,6 +323,8 @@ struct cifsLockInfo {
__u8 type;
};
#define CIFS_NOPOSIXBRL_READ 64
/*
* One of these for each open instance of a file
*/
......
......@@ -328,16 +328,16 @@ extern int CIFSSMBFlush(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id);
extern int CIFSSMBRead(const int xid, struct cifsTconInfo *tcon,
const int netfid, unsigned int count,
const int netfid, const u32 netpid, 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,
const int long_op);
const int netfid, const u32 netpid,
const unsigned int count, const __u64 lseek,
unsigned int *nbytes, const char *buf,
const char __user *ubuf, const int long_op);
extern int CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const int netfid, u32 netpid, 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,
......
......@@ -1390,8 +1390,8 @@ openRetry:
int
CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
const unsigned int count, const __u64 lseek, unsigned int *nbytes,
char **buf, int *pbuf_type)
const u32 netpid, const unsigned int count, const __u64 lseek,
unsigned int *nbytes, char **buf, int *pbuf_type)
{
int rc = -EACCES;
READ_REQ *pSMB = NULL;
......@@ -1417,6 +1417,9 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
if (rc)
return rc;
pSMB->hdr.Pid = cpu_to_le16((__u16)netpid);
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(netpid >> 16));
/* tcon and ses pointer are checked in smb_init */
if (tcon->ses->server == NULL)
return -ECONNABORTED;
......@@ -1495,7 +1498,7 @@ 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 int netfid, const u32 netpid, const unsigned int count,
const __u64 offset, unsigned int *nbytes, const char *buf,
const char __user *ubuf, const int long_op)
{
......@@ -1524,6 +1527,10 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
(void **) &pSMBr);
if (rc)
return rc;
pSMB->hdr.Pid = cpu_to_le16((__u16)netpid);
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(netpid >> 16));
/* tcon and ses pointer are checked in smb_init */
if (tcon->ses->server == NULL)
return -ECONNABORTED;
......@@ -1605,7 +1612,7 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon,
int
CIFSSMBWrite2(const int xid, struct cifsTconInfo *tcon,
const int netfid, const unsigned int count,
const int netfid, const u32 netpid, const unsigned int count,
const __u64 offset, unsigned int *nbytes, struct kvec *iov,
int n_vec, const int long_op)
{
......@@ -1631,6 +1638,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)netpid);
pSMB->hdr.PidHigh = cpu_to_le16((__u16)(netpid >> 16));
/* tcon and ses pointer are checked in smb_init */
if (tcon->ses->server == NULL)
return -ECONNABORTED;
......
......@@ -110,6 +110,7 @@ struct smb_vol {
bool noblocksnd:1;
bool noautotune:1;
bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
bool wine_mode:1;
unsigned int rsize;
unsigned int wsize;
unsigned int sockopt;
......@@ -1341,6 +1342,10 @@ cifs_parse_mount_options(char *options, const char *devname,
vol->server_ino = 1;
} else if (strnicmp(data, "noserverino", 9) == 0) {
vol->server_ino = 0;
} else if (strnicmp(data, "wine", 4) == 0) {
vol->wine_mode = 1;
vol->mand_lock = 1;
vol->direct_io = 1;
} else if (strnicmp(data, "cifsacl", 7) == 0) {
vol->cifs_acl = 1;
} else if (strnicmp(data, "nocifsacl", 9) == 0) {
......@@ -2226,6 +2231,8 @@ static void setup_cifs_sb(struct smb_vol *pvolume_info,
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
if (pvolume_info->mand_lock)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
if (pvolume_info->wine_mode)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_WINE_MODE;
if (pvolume_info->cifs_acl)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
if (pvolume_info->override_uid)
......
......@@ -565,7 +565,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, int devic
pdev->minor =
cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon,
fileHandle,
fileHandle, current->tgid,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0);
......@@ -576,7 +576,7 @@ int cifs_mknod(struct inode *inode, struct dentry *direntry, int mode, int devic
pdev->minor =
cpu_to_le64(MINOR(device_number));
rc = CIFSSMBWrite(xid, pTcon,
fileHandle,
fileHandle, current->tgid,
sizeof(struct win_dev),
0, &bytes_written, (char *)pdev,
NULL, 0);
......
......@@ -892,9 +892,16 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
FreeXid(xid);
return -EBADF;
}
netpid = ((struct cifsFileInfo *)file->private_data)->pid;
netfid = ((struct cifsFileInfo *)file->private_data)->netfid;
if ((cmd & CIFS_NOPOSIXBRL_READ) &&
(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE))
netpid = ((struct cifsFileInfo *)file->private_data)->pid;
else
netpid = current->tgid;
cmd &= ~CIFS_NOPOSIXBRL_READ;
if ((tcon->ses->capabilities & CAP_UNIX) &&
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability)) &&
((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
......@@ -1015,9 +1022,10 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
1, 0, li->type, false);
if (stored_rc)
rc = stored_rc;
list_del(&li->llist);
kfree(li);
else {
list_del(&li->llist);
kfree(li);
}
}
}
mutex_unlock(&fid->lock_mutex);
......@@ -1077,6 +1085,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
int xid, long_op;
struct cifsFileInfo *open_file;
struct cifsInodeInfo *cifsi = CIFS_I(file->f_dentry->d_inode);
__u32 netpid;
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
......@@ -1090,6 +1099,11 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
return -EBADF;
open_file = (struct cifsFileInfo *) file->private_data;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE)
netpid = open_file->pid;
else
netpid = current->tgid;
rc = generic_write_checks(file, poffset, &write_size, 0);
if (rc)
return rc;
......@@ -1127,7 +1141,7 @@ ssize_t cifs_user_write(struct file *file, const char __user *write_data,
}
rc = CIFSSMBWrite(xid, pTcon,
open_file->netfid,
open_file->netfid, netpid,
min_t(const int, cifs_sb->wsize,
write_size - total_written),
*poffset, &bytes_written,
......@@ -1196,6 +1210,7 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
int xid, long_op;
struct cifsFileInfo *open_file;
struct cifsInodeInfo *cifsi = CIFS_I(file->f_dentry->d_inode);
__u32 netpid;
cifs_sb = CIFS_SB(file->f_dentry->d_sb);
......@@ -1208,6 +1223,11 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
return -EBADF;
open_file = (struct cifsFileInfo *)file->private_data;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE)
netpid = open_file->pid;
else
netpid = current->tgid;
xid = GetXid();
long_op = cifs_write_timeout(cifsi, *poffset);
......@@ -1254,12 +1274,13 @@ static ssize_t cifs_write(struct file *file, const char *write_data,
total_written;
iov[1].iov_len = len;
rc = CIFSSMBWrite2(xid, pTcon,
open_file->netfid, len,
*poffset, &bytes_written,
iov, 1, long_op);
open_file->netfid,
netpid, len, *poffset,
&bytes_written, iov,
1, long_op);
} else
rc = CIFSSMBWrite(xid, pTcon,
open_file->netfid,
open_file->netfid, netpid,
min_t(const int, cifs_sb->wsize,
write_size - total_written),
*poffset, &bytes_written,
......@@ -1519,6 +1540,7 @@ static int cifs_writepages(struct address_space *mapping,
int rc = 0;
int scanned = 0;
int xid, long_op;
__u32 netpid;
cifs_sb = CIFS_SB(mapping->host->i_sb);
......@@ -1678,13 +1700,18 @@ retry:
* we used to still be valid
*/
open_file = find_writable_file(CIFS_I(mapping->host));
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE)
netpid = open_file->pid;
else
netpid = current->tgid;
if (!open_file) {
cERROR(1, ("No writable handles for inode"));
rc = -EBADF;
} else {
long_op = cifs_write_timeout(cifsi, offset);
rc = CIFSSMBWrite2(xid, cifs_sb->tcon,
open_file->netfid,
open_file->netfid, netpid,
bytes_to_write, offset,
&bytes_written, iov, n_iov,
long_op);
......@@ -1946,6 +1973,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
char *smb_read_data;
char __user *current_offset;
struct smb_com_read_rsp *pSMBr;
__u32 netpid;
xid = GetXid();
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
......@@ -1961,6 +1989,11 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
}
open_file = (struct cifsFileInfo *)file->private_data;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE)
netpid = open_file->pid;
else
netpid = current->tgid;
if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, ("attempting read on write only file instance"));
......@@ -1980,7 +2013,7 @@ ssize_t cifs_user_read(struct file *file, char __user *read_data,
break;
}
rc = CIFSSMBRead(xid, pTcon,
open_file->netfid,
open_file->netfid, netpid,
current_read_size, *poffset,
&bytes_read, &smb_read_data,
&buf_type);
......@@ -2030,6 +2063,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
char *current_offset;
struct cifsFileInfo *open_file;
int buf_type = CIFS_NO_BUFFER;
__u32 netpid;
xid = GetXid();
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
......@@ -2045,6 +2079,11 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
}
open_file = (struct cifsFileInfo *)file->private_data;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE)
netpid = open_file->pid;
else
netpid = current->tgid;
if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, ("attempting read on write only file instance"));
......@@ -2069,7 +2108,7 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
break;
}
rc = CIFSSMBRead(xid, pTcon,
open_file->netfid,
open_file->netfid, netpid,
current_read_size, *poffset,
&bytes_read, &current_offset,
&buf_type);
......@@ -2175,6 +2214,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
struct pagevec lru_pvec;
struct cifsFileInfo *open_file;
int buf_type = CIFS_NO_BUFFER;
__u32 netpid;
xid = GetXid();
if (file->private_data == NULL) {
......@@ -2189,6 +2229,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
#endif
pTcon = cifs_sb->tcon;
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_WINE_MODE)
netpid = open_file->pid;
else
netpid = current->tgid;
pagevec_init(&lru_pvec, 0);
cFYI(DBG2, ("rpages: num pages %d", num_pages));
for (i = 0; i < num_pages; ) {
......@@ -2235,10 +2280,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
}
rc = CIFSSMBRead(xid, pTcon,
open_file->netfid,
read_size, offset,
&bytes_read, &smb_read_data,
&buf_type);
open_file->netfid, netpid,
read_size, offset, &bytes_read,
&smb_read_data, &buf_type);
/* BB more RC checks ? */
if (rc == -EAGAIN) {
if (smb_read_data) {
......
......@@ -340,8 +340,7 @@ static int decode_sfu_inode(struct inode *inode, __u64 size,
if (rc == 0) {
int buf_type = CIFS_NO_BUFFER;
/* Read header */
rc = CIFSSMBRead(xid, pTcon,
netfid,
rc = CIFSSMBRead(xid, pTcon, netfid, current->tgid,
24 /* length */, 0 /* offset */,
&bytes_read, &pbuf, &buf_type);
if ((rc == 0) && (bytes_read >= 8)) {
......@@ -1739,8 +1738,9 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
cFYI(1, ("SetFSize for attrs rc = %d", rc));
if ((rc == -EINVAL) || (rc == -EOPNOTSUPP)) {
unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon, nfid, 0, attrs->ia_size,
&bytes_written, NULL, NULL, 1);
rc = CIFSSMBWrite(xid, pTcon, nfid, npid,
0, attrs->ia_size, &bytes_written,
NULL, NULL, 1);
cFYI(1, ("Wrt seteof rc %d", rc));
}
} else
......@@ -1768,7 +1768,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc == 0) {
unsigned int bytes_written;
rc = CIFSSMBWrite(xid, pTcon, netfid, 0,
rc = CIFSSMBWrite(xid, pTcon, netfid,
current->tgid, 0,
attrs->ia_size,
&bytes_written, NULL,
NULL, 1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment