aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSuresh Jayaraman <sjayaraman@suse.de>2010-09-17 09:26:39 -0400
committerSteve French <sfrench@us.ibm.com>2010-09-29 15:04:28 -0400
commitaa91c7e4ab9b0842b7d7a7cbf8cca18b20df89b5 (patch)
tree94827b3006d85b8accf179ea3da30e1569983e68
parenta347ecb209b58a1b37f20d8299ab552f7d3ee8c3 (diff)
cifs: fix broken oplock handling
cifs_new_fileinfo() does not use the 'oplock' value from the callers. Instead, it sets it to REQ_OPLOCK which seems wrong. We should be using the oplock value obtained from the Server to set the inode's clientCanCacheAll or clientCanCacheRead flags. Fix this by passing oplock from the callers to cifs_new_fileinfo(). This change dates back to commit a6ce4932 (2.6.30-rc3). So, all the affected versions will need this fix. Please Cc stable once reviewed and accepted. Cc: Stable <stable@kernel.org> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Suresh Jayaraman <sjayaraman@suse.de> Signed-off-by: Steve French <sfrench@us.ibm.com>
-rw-r--r--fs/cifs/cifsproto.h3
-rw-r--r--fs/cifs/dir.c12
-rw-r--r--fs/cifs/file.c4
3 files changed, 9 insertions, 10 deletions
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 1d60c655e3e0..f110e0e7e947 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -107,7 +107,8 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
107 107
108extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, 108extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
109 __u16 fileHandle, struct file *file, 109 __u16 fileHandle, struct file *file,
110 struct vfsmount *mnt, unsigned int oflags); 110 struct vfsmount *mnt, unsigned int oflags,
111 __u32 oplock);
111extern int cifs_posix_open(char *full_path, struct inode **pinode, 112extern int cifs_posix_open(char *full_path, struct inode **pinode,
112 struct super_block *sb, 113 struct super_block *sb,
113 int mode, int oflags, 114 int mode, int oflags,
diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c
index f9ed0751cc12..0f947bf73f8e 100644
--- a/fs/cifs/dir.c
+++ b/fs/cifs/dir.c
@@ -132,9 +132,9 @@ cifs_bp_rename_retry:
132 132
133struct cifsFileInfo * 133struct cifsFileInfo *
134cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, 134cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
135 struct file *file, struct vfsmount *mnt, unsigned int oflags) 135 struct file *file, struct vfsmount *mnt, unsigned int oflags,
136 __u32 oplock)
136{ 137{
137 int oplock = 0;
138 struct cifsFileInfo *pCifsFile; 138 struct cifsFileInfo *pCifsFile;
139 struct cifsInodeInfo *pCifsInode; 139 struct cifsInodeInfo *pCifsInode;
140 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb); 140 struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
@@ -143,9 +143,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
143 if (pCifsFile == NULL) 143 if (pCifsFile == NULL)
144 return pCifsFile; 144 return pCifsFile;
145 145
146 if (oplockEnabled)
147 oplock = REQ_OPLOCK;
148
149 pCifsFile->netfid = fileHandle; 146 pCifsFile->netfid = fileHandle;
150 pCifsFile->pid = current->tgid; 147 pCifsFile->pid = current->tgid;
151 pCifsFile->pInode = igrab(newinode); 148 pCifsFile->pInode = igrab(newinode);
@@ -468,7 +465,7 @@ cifs_create_set_dentry:
468 } 465 }
469 466
470 pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, 467 pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp,
471 nd->path.mnt, oflags); 468 nd->path.mnt, oflags, oplock);
472 if (pfile_info == NULL) { 469 if (pfile_info == NULL) {
473 fput(filp); 470 fput(filp);
474 CIFSSMBClose(xid, tcon, fileHandle); 471 CIFSSMBClose(xid, tcon, fileHandle);
@@ -729,7 +726,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
729 726
730 cfile = cifs_new_fileinfo(newInode, fileHandle, filp, 727 cfile = cifs_new_fileinfo(newInode, fileHandle, filp,
731 nd->path.mnt, 728 nd->path.mnt,
732 nd->intent.open.flags); 729 nd->intent.open.flags,
730 oplock);
733 if (cfile == NULL) { 731 if (cfile == NULL) {
734 fput(filp); 732 fput(filp);
735 CIFSSMBClose(xid, pTcon, fileHandle); 733 CIFSSMBClose(xid, pTcon, fileHandle);
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index d33da45fe987..60061b9c2f67 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -277,7 +277,7 @@ int cifs_open(struct inode *inode, struct file *file)
277 277
278 pCifsFile = cifs_new_fileinfo(inode, netfid, file, 278 pCifsFile = cifs_new_fileinfo(inode, netfid, file,
279 file->f_path.mnt, 279 file->f_path.mnt,
280 oflags); 280 oflags, oplock);
281 if (pCifsFile == NULL) { 281 if (pCifsFile == NULL) {
282 CIFSSMBClose(xid, tcon, netfid); 282 CIFSSMBClose(xid, tcon, netfid);
283 rc = -ENOMEM; 283 rc = -ENOMEM;
@@ -370,7 +370,7 @@ int cifs_open(struct inode *inode, struct file *file)
370 goto out; 370 goto out;
371 371
372 pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, 372 pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt,
373 file->f_flags); 373 file->f_flags, oplock);
374 if (pCifsFile == NULL) { 374 if (pCifsFile == NULL) {
375 rc = -ENOMEM; 375 rc = -ENOMEM;
376 goto out; 376 goto out;