Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 252243
b: refs/heads/master
c: d4ffff1
h: refs/heads/master
i:
  252241: a1b1e5e
  252239: d38048d
v: v3
  • Loading branch information
Pavel Shilovsky authored and Steve French committed May 27, 2011
1 parent 3b4e7c9 commit e0113b3
Show file tree
Hide file tree
Showing 11 changed files with 116 additions and 40 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 25c7f41e9234f60af30e086278f1de7974f8816f
refs/heads/master: d4ffff1fa9695c5b5c0bf337e208d8833b88ff2d
3 changes: 3 additions & 0 deletions trunk/fs/cifs/README
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,9 @@ A partial list of the supported mount options follows:
otherwise - read from the server. All written data are stored
in the cache, but if the client doesn't have Exclusive Oplock,
it writes the data to the server.
rwpidforward Forward pid of a process who opened a file to any read or write
operation on that file. This prevent applications like WINE
from failing on read and write if we use mandatory brlock style.
acl Allow setfacl and getfacl to manage posix ACLs if server
supports them. (default)
noacl Do not allow setfacl and getfacl calls on this mount
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/cifs/cifs_fs_sb.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#define CIFS_MOUNT_MF_SYMLINKS 0x10000 /* Minshall+French Symlinks enabled */
#define CIFS_MOUNT_MULTIUSER 0x20000 /* multiuser mount */
#define CIFS_MOUNT_STRICT_IO 0x40000 /* strict cache mode */
#define CIFS_MOUNT_RWPIDFORWARD 0x80000 /* use pid forwarding for rw */

struct cifs_sb_info {
struct rb_root tlink_tree;
Expand Down
8 changes: 8 additions & 0 deletions trunk/fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,12 +415,20 @@ 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->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS)
seq_printf(s, ",posixpaths");
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID)
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_RWPIDFORWARD)
seq_printf(s, ",rwpidforward");
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)
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ struct smb_vol {
bool fsc:1; /* enable fscache */
bool mfsymlinks:1; /* use Minshall+French Symlinks */
bool multiuser:1;
bool rwpidforward:1; /* pid forward for read/write operations */
unsigned int rsize;
unsigned int wsize;
bool sockopt_tcp_nodelay:1;
Expand Down
5 changes: 2 additions & 3 deletions trunk/fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,8 @@ extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
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 __u64 lseek, unsigned int *nbytes, char **buf,
extern int CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, char **buf,
int *return_buf_type);
extern int CIFSSMBWrite(const int xid, struct cifs_io_parms *io_parms,
unsigned int *nbytes, const char *buf,
Expand Down
17 changes: 12 additions & 5 deletions trunk/fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1382,8 +1382,7 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
}

int
CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
const unsigned int count, const __u64 lseek, unsigned int *nbytes,
CIFSSMBRead(const int xid, struct cifs_io_parms *io_parms, unsigned int *nbytes,
char **buf, int *pbuf_type)
{
int rc = -EACCES;
Expand All @@ -1393,13 +1392,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
int wct;
int resp_buf_type = 0;
struct kvec iov[1];
__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;

cFYI(1, "Reading %d bytes on fid %d", count, netfid);
if (tcon->ses->capabilities & CAP_LARGE_FILES)
wct = 12;
else {
wct = 10; /* old style read */
if ((lseek >> 32) > 0) {
if ((offset >> 32) > 0) {
/* can not handle this big offset for old */
return -EIO;
}
Expand All @@ -1410,15 +1414,18 @@ CIFSSMBRead(const int xid, struct cifsTconInfo *tcon, const int netfid,
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;

pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = netfid;
pSMB->OffsetLow = cpu_to_le32(lseek & 0xFFFFFFFF);
pSMB->OffsetLow = cpu_to_le32(offset & 0xFFFFFFFF);
if (wct == 12)
pSMB->OffsetHigh = cpu_to_le32(lseek >> 32);
pSMB->OffsetHigh = cpu_to_le32(offset >> 32);

pSMB->Remaining = 0;
pSMB->MaxCount = cpu_to_le16(count & 0xFFFF);
Expand Down
4 changes: 4 additions & 0 deletions trunk/fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1359,6 +1359,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
vol->server_ino = 1;
} else if (strnicmp(data, "noserverino", 9) == 0) {
vol->server_ino = 0;
} else if (strnicmp(data, "rwpidforward", 4) == 0) {
vol->rwpidforward = 1;
} else if (strnicmp(data, "cifsacl", 7) == 0) {
vol->cifs_acl = 1;
} else if (strnicmp(data, "nocifsacl", 9) == 0) {
Expand Down Expand Up @@ -2708,6 +2710,8 @@ void cifs_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->rwpidforward)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
if (pvolume_info->cifs_acl)
cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
if (pvolume_info->override_uid)
Expand Down
82 changes: 62 additions & 20 deletions trunk/fs/cifs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -725,8 +725,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
else
posix_lock_type = CIFS_WRLCK;
rc = CIFSSMBPosixLock(xid, tcon, netfid, 1 /* get */,
length, pfLock,
posix_lock_type, wait_flag);
length, pfLock, posix_lock_type,
wait_flag);
FreeXid(xid);
return rc;
}
Expand Down Expand Up @@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
posix_lock_type = CIFS_UNLCK;

rc = CIFSSMBPosixLock(xid, tcon, netfid, 0 /* set */,
length, pfLock,
posix_lock_type, wait_flag);
length, pfLock, posix_lock_type,
wait_flag);
} else {
struct cifsFileInfo *fid = file->private_data;

Expand Down Expand Up @@ -1346,6 +1346,14 @@ static int cifs_write_end(struct file *file, struct address_space *mapping,
{
int rc;
struct inode *inode = mapping->host;
struct cifsFileInfo *cfile = file->private_data;
struct cifs_sb_info *cifs_sb = CIFS_SB(cfile->dentry->d_sb);
__u32 pid;

if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = cfile->pid;
else
pid = current->tgid;

cFYI(1, "write_end for page %p from pos %lld with %d bytes",
page, pos, copied);
Expand All @@ -1369,8 +1377,7 @@ 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, current->tgid,
page_data + offset, copied, &pos);
rc = cifs_write(cfile, pid, page_data + offset, copied, &pos);
/* if (rc < 0) should we set writebehind rc? */
kunmap(page);

Expand Down Expand Up @@ -1523,6 +1530,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
struct cifs_sb_info *cifs_sb;
struct cifs_io_parms io_parms;
int xid, rc;
__u32 pid;

len = iov_length(iov, nr_segs);
if (!len)
Expand Down Expand Up @@ -1554,6 +1562,12 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,

xid = GetXid();
open_file = file->private_data;

if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;

pTcon = tlink_tcon(open_file->tlink);
inode = file->f_path.dentry->d_inode;

Expand Down Expand Up @@ -1581,7 +1595,7 @@ cifs_iovec_write(struct file *file, const struct iovec *iov,
break;
}
io_parms.netfid = open_file->netfid;
io_parms.pid = current->tgid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = cur_len;
Expand Down Expand Up @@ -1682,7 +1696,9 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
struct cifsTconInfo *pTcon;
struct cifsFileInfo *open_file;
struct smb_com_read_rsp *pSMBr;
struct cifs_io_parms io_parms;
char *read_data;
__u32 pid;

if (!nr_segs)
return 0;
Expand All @@ -1697,6 +1713,11 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
open_file = file->private_data;
pTcon = tlink_tcon(open_file->tlink);

if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;

if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, "attempting read on write only file instance");

Expand All @@ -1712,8 +1733,12 @@ cifs_iovec_read(struct file *file, const struct iovec *iov,
if (rc != 0)
break;
}
rc = CIFSSMBRead(xid, pTcon, open_file->netfid,
cur_len, *poffset, &bytes_read,
io_parms.netfid = open_file->netfid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = len;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&read_data, &buf_type);
pSMBr = (struct smb_com_read_rsp *)read_data;
if (read_data) {
Expand Down Expand Up @@ -1794,7 +1819,9 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
int xid;
char *current_offset;
struct cifsFileInfo *open_file;
struct cifs_io_parms io_parms;
int buf_type = CIFS_NO_BUFFER;
__u32 pid;

xid = GetXid();
cifs_sb = CIFS_SB(file->f_path.dentry->d_sb);
Expand All @@ -1807,6 +1834,11 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
open_file = file->private_data;
pTcon = tlink_tcon(open_file->tlink);

if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;

if ((file->f_flags & O_ACCMODE) == O_WRONLY)
cFYI(1, "attempting read on write only file instance");

Expand All @@ -1829,11 +1861,13 @@ static ssize_t cifs_read(struct file *file, char *read_data, size_t read_size,
if (rc != 0)
break;
}
rc = CIFSSMBRead(xid, pTcon,
open_file->netfid,
current_read_size, *poffset,
&bytes_read, &current_offset,
&buf_type);
io_parms.netfid = open_file->netfid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = *poffset;
io_parms.length = current_read_size;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&current_offset, &buf_type);
}
if (rc || (bytes_read == 0)) {
if (total_read) {
Expand Down Expand Up @@ -1970,7 +2004,9 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
char *smb_read_data = NULL;
struct smb_com_read_rsp *pSMBr;
struct cifsFileInfo *open_file;
struct cifs_io_parms io_parms;
int buf_type = CIFS_NO_BUFFER;
__u32 pid;

xid = GetXid();
if (file->private_data == NULL) {
Expand All @@ -1992,6 +2028,11 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
goto read_complete;

cFYI(DBG2, "rpages: num pages %d", num_pages);
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RWPIDFORWARD)
pid = open_file->pid;
else
pid = current->tgid;

for (i = 0; i < num_pages; ) {
unsigned contig_pages;
struct page *tmp_page;
Expand Down Expand Up @@ -2033,12 +2074,13 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
if (rc != 0)
break;
}

rc = CIFSSMBRead(xid, pTcon,
open_file->netfid,
read_size, offset,
&bytes_read, &smb_read_data,
&buf_type);
io_parms.netfid = open_file->netfid;
io_parms.pid = pid;
io_parms.tcon = pTcon;
io_parms.offset = offset;
io_parms.length = read_size;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read,
&smb_read_data, &buf_type);
/* BB more RC checks ? */
if (rc == -EAGAIN) {
if (smb_read_data) {
Expand Down
11 changes: 8 additions & 3 deletions trunk/fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
__u16 netfid;
struct tcon_link *tlink;
struct cifsTconInfo *tcon;
struct cifs_io_parms io_parms;
char buf[24];
unsigned int bytes_read;
char *pbuf;
Expand Down Expand Up @@ -405,9 +406,13 @@ cifs_sfu_type(struct cifs_fattr *fattr, const unsigned char *path,
if (rc == 0) {
int buf_type = CIFS_NO_BUFFER;
/* Read header */
rc = CIFSSMBRead(xid, tcon, netfid,
24 /* length */, 0 /* offset */,
&bytes_read, &pbuf, &buf_type);
io_parms.netfid = netfid;
io_parms.pid = current->tgid;
io_parms.tcon = tcon;
io_parms.offset = 0;
io_parms.length = 24;
rc = CIFSSMBRead(xid, &io_parms, &bytes_read, &pbuf,
&buf_type);
if ((rc == 0) && (bytes_read >= 8)) {
if (memcmp("IntxBLK", pbuf, 8) == 0) {
cFYI(1, "Block device");
Expand Down
Loading

0 comments on commit e0113b3

Please sign in to comment.