CIFS: Use pid saved in cifsFileInfo in writepages and set_file_size
Subsystems (2)
A message that is not in the archive (sent off-list or not yet received): [email protected]
PATCH 1/2 CIFS: Use pid saved in 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 process who opened file.
--- fs/cifs/cifsglob.h | 8 ++++++++ fs/cifs/cifsproto.h | 13 +++++-------- fs/cifs/cifssmb.c | 30 +++++++++++++++++++++++------- fs/cifs/dir.c | 18 ++++++++++-------- fs/cifs/file.c | 44 ++++++++++++++++++++++++++++++-------------- fs/cifs/inode.c | 24 ++++++++++++++++++------ fs/cifs/link.c | 12 ++++++++---- 7 files changed, 102 insertions(+), 47 deletions(-)
fs/cifs/cifsglob.h +8 -0
@@ -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.
fs/cifs/cifsproto.h +5 -8
@@ -341,15 +341,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,
fs/cifs/cifssmb.c +23 -7
@@ -1484,9 +1484,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 ;
@@ -1495,6 +1494,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 ;
@@ -1516,6 +1520,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 ;
@@ -1603,16 +1611,20 @@ CIFSSMBWrite(const int xid, struct cifsTconInfo *tcon, }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 ;
@@ -1630,6 +1642,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 ;
fs/cifs/dir.c +10 -8
@@ -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);
fs/cifs/file.c +30 -14
98 lines not on this page · raw message
fs/cifs/inode.c +18 -6
@@ -1871,6 +1871,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,struct cifs_sb_info *cifs_sb =CIFS_SB (inode->i_sb);struct tcon_link *tlink =NULL ;struct cifsTconInfo *pTcon =NULL ; +struct cifs_io_parms io_parms;/* * To avoid spurious oplock breaks from server, in the case of
@@ -1892,8 +1893,14 @@ 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 ); + + io_parms.netfid = nfid; + io_parms.pid = npid; + io_parms.tcon = pTcon; + io_parms.offset =0 ; + io_parms.length = attrs->ia_size; + rc =CIFSSMBWrite (xid, &io_parms, &bytes_written, +NULL ,NULL ,1 );cFYI (1 ,"Wrt seteof rc %d" , rc); } }else
@@ -1928,10 +1935,15 @@ 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 , - attrs->ia_size, - &bytes_written,NULL , -NULL ,1 ); + + io_parms.netfid = netfid; + io_parms.pid = current->tgid; + io_parms.tcon = pTcon; + io_parms.offset =0 ; + io_parms.length = attrs->ia_size; + rc =CIFSSMBWrite (xid, &io_parms, + &bytes_written, +NULL ,NULL ,1 );cFYI (1 ,"wrt seteof rc %d" , rc);CIFSSMBClose (xid, pTcon, netfid); }
fs/cifs/link.c +8 -4
@@ -184,6 +184,7 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,__u16 netfid =0 ;u8 *buf;unsigned int bytes_written =0 ; +struct cifs_io_parms io_parms; buf =kmalloc (CIFS_MF_SYMLINK_FILE_SIZE ,GFP_KERNEL );if (!buf)
@@ -203,10 +204,13 @@ CIFSCreateMFSymLink(const int xid, struct cifsTconInfo *tcon,return rc; } - rc =CIFSSMBWrite (xid, tcon, netfid, -CIFS_MF_SYMLINK_FILE_SIZE /* length */ , -0 /* offset */ , - &bytes_written, buf,NULL ,0 ); + io_parms.netfid = netfid; + io_parms.pid = current->tgid; + io_parms.tcon = tcon; + io_parms.offset =0 ; + io_parms.length =CIFS_MF_SYMLINK_FILE_SIZE ; + + rc =CIFSSMBWrite (xid, &io_parms, &bytes_written, buf,NULL ,0 );CIFSSMBClose (xid, tcon, netfid);kfree (buf);if (rc !=0 )
Signature · 1 line
1.7.1
A message that is not in the archive (sent off-list or not yet received): 1304502271-11557-1-git-send-email-piastry-7qunaywFIewox3rIn2DAYQ@public.gmane.org
2011/5/4 Pavel Shilovsky <[email protected]>:
Quoted 3 lines
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 process who opened file.
I put this and 2/2 Add rwpidforward mount option patch on top of current master branch into pidforward branch on git.etersoft.ru:
http://git.etersoft.ru/people/piastry/packages/?p=cifs-2.6.git;a=shortlog;h=refs/heads/pidforward
Comments?
Signature · 2 lines
Best regards, Pavel Shilovsky.
PATCH 2/2 CIFS: Add rwpidforward mount option (try #2)
In reply to a message not in the archiveAdd rwpidforward mount option that switches on a mode when we forward pid of a process who opened a file to any read and write operation.
This can prevent applications like WINE from failing on read or write operation on a previously locked file region from the same netfd from another process if we use mandatory brlock style.
It is actual for WINE because during a run of WINE program two processes work on the same netfd - share the same file struct between several VFS fds:
1) WINE-server does open and lock;
2) WINE-application does read and write.
--- fs/cifs/README | 3 ++ fs/cifs/cifs_fs_sb.h | 1 + fs/cifs/cifsfs.c | 8 +++++ fs/cifs/cifsproto.h | 5 +-- fs/cifs/cifssmb.c | 17 +++++++--- fs/cifs/connect.c | 5 +++ fs/cifs/file.c | 82 +++++++++++++++++++++++++++++++++++++------------ fs/cifs/inode.c | 11 +++++-- fs/cifs/link.c | 22 ++++++++----- 9 files changed, 115 insertions(+), 39 deletions(-)
fs/cifs/README +3 -0
@@ -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
fs/cifs/cifs_fs_sb.h +1 -0
@@ -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;
fs/cifs/cifsfs.c +8 -0
@@ -455,6 +455,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);if (cifs_sb->mnt_cifs_flags &CIFS_MOUNT_POSIX_PATHS )
@@ -463,6 +467,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_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 )
fs/cifs/cifsproto.h +2 -3
@@ -337,9 +337,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,
fs/cifs/cifssmb.c +12 -5
@@ -1379,8 +1379,7 @@ openRetry: }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 ;
@@ -1390,13 +1389,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 ; }
@@ -1407,15 +1411,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 );
fs/cifs/connect.c +5 -0
@@ -100,6 +100,7 @@ struct smb_vol { bool noautotune:1; bool nostrictsync:1; /* do not force expensive SMBflush on every sync */ bool fsc:1; /* enable fscache */ + bool rwpidforward:1; /* pid forward for rw */ bool mfsymlinks:1; /* use Minshall+French Symlinks */ bool multiuser:1; bool use_smb2:1; /* force smb2 use on mount instead of cifs */
@@ -1374,6 +1375,8 @@ 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,"rwpidforward" ,4 ) ==0 ) { + vol->rwpidforward =1 ; }else if (strnicmp (data,"cifsacl" ,7 ) ==0 ) { vol->cifs_acl =1 ; }else if (strnicmp (data,"nocifsacl" ,9 ) ==0 ) {
@@ -2641,6 +2644,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->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)
fs/cifs/file.c +62 -20
181 lines not on this page · raw message
fs/cifs/inode.c +8 -3
@@ -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;
@@ -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" );
fs/cifs/link.c +14 -8
@@ -235,6 +235,7 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,unsigned int bytes_read =0 ;int buf_type =CIFS_NO_BUFFER ;unsigned int link_len =0 ; +struct cifs_io_parms io_parms;FILE_ALL_INFO file_info; rc = CIFSSMBOpen(xid, tcon, searchName, FILE_OPEN, GENERIC_READ,
@@ -253,11 +254,13 @@ CIFSQueryMFSymLink(const int xid, struct cifsTconInfo *tcon,if (!buf)return -ENOMEM ; pbuf = buf; + io_parms.netfid = netfid; + io_parms.pid = current->tgid; + io_parms.tcon = tcon; + io_parms.offset =0 ; + io_parms.length =CIFS_MF_SYMLINK_FILE_SIZE ; - rc =CIFSSMBRead (xid, tcon, netfid, -CIFS_MF_SYMLINK_FILE_SIZE /* length */ , -0 /* offset */ , - &bytes_read, &pbuf, &buf_type); + rc =CIFSSMBRead (xid, &io_parms, &bytes_read, &pbuf, &buf_type);CIFSSMBClose (xid, tcon, netfid);if (rc !=0 ) {kfree (buf);
@@ -296,6 +299,7 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr,__u16 netfid =0 ;struct tcon_link *tlink;struct cifsTconInfo *pTcon; +struct cifs_io_parms io_parms;u8 *buf;char *pbuf;unsigned int bytes_read =0 ;
@@ -332,11 +336,13 @@ CIFSCheckMFSymlink(struct cifs_fattr *fattr, goto out; } pbuf = buf; + io_parms.netfid = netfid; + io_parms.pid = current->tgid; + io_parms.tcon = pTcon; + io_parms.offset =0 ; + io_parms.length =CIFS_MF_SYMLINK_FILE_SIZE ; - rc =CIFSSMBRead (xid, pTcon, netfid, -CIFS_MF_SYMLINK_FILE_SIZE /* length */ , -0 /* offset */ , - &bytes_read, &pbuf, &buf_type); + rc =CIFSSMBRead (xid, &io_parms, &bytes_read, &pbuf, &buf_type);CIFSSMBClose (xid, pTcon, netfid);if (rc !=0 ) {kfree (buf);
Signature · 1 line
1.7.1