Commit cd87796d authored by Pavel Shilovsky's avatar Pavel Shilovsky

Fixes in 2.6.35

- oplock handling - update from longterm tree
parent 3de18c09
...@@ -104,7 +104,8 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, ...@@ -104,7 +104,8 @@ extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode, extern struct cifsFileInfo *cifs_new_fileinfo(struct inode *newinode,
__u16 fileHandle, struct file *file, __u16 fileHandle, struct file *file,
struct vfsmount *mnt, unsigned int oflags); struct vfsmount *mnt, unsigned int oflags,
__u32 oplock);
extern int cifs_posix_open(char *full_path, struct inode **pinode, extern int cifs_posix_open(char *full_path, struct inode **pinode,
struct super_block *sb, struct super_block *sb,
int mode, int oflags, int mode, int oflags,
...@@ -341,7 +342,8 @@ extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen, ...@@ -341,7 +342,8 @@ extern int cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 netfid, const __u64 len, const __u64 offset, const __u16 netfid, const __u64 len, const __u64 offset,
const __u32 numUnlock, const __u32 numLock, const __u32 numUnlock, const __u32 numLock,
const __u8 lockType, const bool waitFlag); const __u8 lockType, const bool waitFlag,
const __u8 oplock_level);
extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const int get_flag, const __u16 smb_file_id, const int get_flag,
const __u64 len, struct file_lock *, const __u64 len, struct file_lock *,
......
...@@ -1665,7 +1665,7 @@ int ...@@ -1665,7 +1665,7 @@ int
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const __u64 len, const __u64 offset, const __u16 smb_file_id, const __u64 len, const __u64 offset,
const __u32 numUnlock, const __u32 numLock, const __u8 lockType, const __u32 numUnlock, const __u32 numLock, const __u8 lockType,
const bool waitFlag) const bool waitFlag, const __u8 oplock_level)
{ {
int rc = 0; int rc = 0;
LOCK_REQ *pSMB = NULL; LOCK_REQ *pSMB = NULL;
...@@ -1693,6 +1693,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -1693,6 +1693,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
pSMB->NumberOfLocks = cpu_to_le16(numLock); pSMB->NumberOfLocks = cpu_to_le16(numLock);
pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock);
pSMB->LockType = lockType; pSMB->LockType = lockType;
pSMB->OplockLevel = oplock_level;
pSMB->AndXCommand = 0xFF; /* none */ pSMB->AndXCommand = 0xFF; /* none */
pSMB->Fid = smb_file_id; /* netfid stays le */ pSMB->Fid = smb_file_id; /* netfid stays le */
......
...@@ -1682,9 +1682,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) ...@@ -1682,9 +1682,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
if (ses) { if (ses) {
cFYI(1, "Existing smb sess found (status=%d)", ses->status); cFYI(1, "Existing smb sess found (status=%d)", ses->status);
/* existing SMB ses has a server reference already */
cifs_put_tcp_session(server);
mutex_lock(&ses->session_mutex); mutex_lock(&ses->session_mutex);
rc = cifs_negotiate_protocol(xid, ses); rc = cifs_negotiate_protocol(xid, ses);
if (rc) { if (rc) {
...@@ -1707,6 +1704,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info) ...@@ -1707,6 +1704,9 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
} }
} }
mutex_unlock(&ses->session_mutex); mutex_unlock(&ses->session_mutex);
/* existing SMB ses has a server reference already */
cifs_put_tcp_session(server);
FreeXid(xid); FreeXid(xid);
return ses; return ses;
} }
......
...@@ -138,9 +138,9 @@ cifs_bp_rename_retry: ...@@ -138,9 +138,9 @@ cifs_bp_rename_retry:
*/ */
struct cifsFileInfo * struct cifsFileInfo *
cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
struct file *file, struct vfsmount *mnt, unsigned int oflags) struct file *file, struct vfsmount *mnt, unsigned int oflags,
__u32 oplock)
{ {
int oplock = 0;
struct cifsFileInfo *pCifsFile; struct cifsFileInfo *pCifsFile;
struct cifsInodeInfo *pCifsInode; struct cifsInodeInfo *pCifsInode;
struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb); struct cifs_sb_info *cifs_sb = CIFS_SB(mnt->mnt_sb);
...@@ -149,9 +149,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle, ...@@ -149,9 +149,6 @@ cifs_new_fileinfo(struct inode *newinode, __u16 fileHandle,
if (pCifsFile == NULL) if (pCifsFile == NULL)
return pCifsFile; return pCifsFile;
if (oplockEnabled)
oplock = REQ_OPLOCK;
pCifsFile->netfid = fileHandle; pCifsFile->netfid = fileHandle;
pCifsFile->pid = current->tgid; pCifsFile->pid = current->tgid;
pCifsFile->pInode = igrab(newinode); pCifsFile->pInode = igrab(newinode);
...@@ -477,7 +474,7 @@ cifs_create_set_dentry: ...@@ -477,7 +474,7 @@ cifs_create_set_dentry:
} }
pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp, pfile_info = cifs_new_fileinfo(newinode, fileHandle, filp,
nd->path.mnt, oflags); nd->path.mnt, oflags, oplock);
if (pfile_info == NULL) { if (pfile_info == NULL) {
fput(filp); fput(filp);
CIFSSMBClose(xid, tcon, fileHandle); CIFSSMBClose(xid, tcon, fileHandle);
...@@ -741,7 +738,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, ...@@ -741,7 +738,8 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
cfile = cifs_new_fileinfo(newInode, fileHandle, filp, cfile = cifs_new_fileinfo(newInode, fileHandle, filp,
nd->path.mnt, nd->path.mnt,
nd->intent.open.flags); nd->intent.open.flags,
oplock);
if (cfile == NULL) { if (cfile == NULL) {
fput(filp); fput(filp);
CIFSSMBClose(xid, pTcon, fileHandle); CIFSSMBClose(xid, pTcon, fileHandle);
......
...@@ -284,7 +284,7 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -284,7 +284,7 @@ int cifs_open(struct inode *inode, struct file *file)
pCifsFile = cifs_new_fileinfo(inode, netfid, file, pCifsFile = cifs_new_fileinfo(inode, netfid, file,
file->f_path.mnt, file->f_path.mnt,
oflags); oflags, oplock);
if (pCifsFile == NULL) { if (pCifsFile == NULL) {
CIFSSMBClose(xid, tcon, netfid); CIFSSMBClose(xid, tcon, netfid);
rc = -ENOMEM; rc = -ENOMEM;
...@@ -375,7 +375,7 @@ int cifs_open(struct inode *inode, struct file *file) ...@@ -375,7 +375,7 @@ int cifs_open(struct inode *inode, struct file *file)
goto out; goto out;
pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt, pCifsFile = cifs_new_fileinfo(inode, netfid, file, file->f_path.mnt,
file->f_flags); file->f_flags, oplock);
if (pCifsFile == NULL) { if (pCifsFile == NULL) {
rc = -ENOMEM; rc = -ENOMEM;
goto out; goto out;
...@@ -808,12 +808,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -808,12 +808,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
/* BB we could chain these into one lock request BB */ /* BB we could chain these into one lock request BB */
rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start,
0, 1, lockType, 0 /* wait flag */ ); 0, 1, lockType, 0 /* wait flag */, 0);
if (rc == 0) { if (rc == 0) {
rc = CIFSSMBLock(xid, tcon, netfid, length, rc = CIFSSMBLock(xid, tcon, netfid, length,
pfLock->fl_start, 1 /* numUnlock */ , pfLock->fl_start, 1 /* numUnlock */ ,
0 /* numLock */ , lockType, 0 /* numLock */ , lockType,
0 /* wait flag */ ); 0 /* wait flag */, 0);
pfLock->fl_type = F_UNLCK; pfLock->fl_type = F_UNLCK;
if (rc != 0) if (rc != 0)
cERROR(1, "Error unlocking previously locked " cERROR(1, "Error unlocking previously locked "
...@@ -830,13 +830,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -830,13 +830,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
rc = CIFSSMBLock(xid, tcon, netfid, length, rc = CIFSSMBLock(xid, tcon, netfid, length,
pfLock->fl_start, 0, 1, pfLock->fl_start, 0, 1,
lockType | LOCKING_ANDX_SHARED_LOCK, lockType | LOCKING_ANDX_SHARED_LOCK,
0 /* wait flag */); 0 /* wait flag */, 0);
if (rc == 0) { if (rc == 0) {
rc = CIFSSMBLock(xid, tcon, netfid, rc = CIFSSMBLock(xid, tcon, netfid,
length, pfLock->fl_start, 1, 0, length, pfLock->fl_start, 1, 0,
lockType | lockType |
LOCKING_ANDX_SHARED_LOCK, LOCKING_ANDX_SHARED_LOCK,
0 /* wait flag */); 0 /* wait flag */, 0);
pfLock->fl_type = F_RDLCK; pfLock->fl_type = F_RDLCK;
if (rc != 0) if (rc != 0)
cERROR(1, "Error unlocking " cERROR(1, "Error unlocking "
...@@ -881,7 +881,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -881,7 +881,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
if (numLock) { if (numLock) {
rc = CIFSSMBLock(xid, tcon, netfid, length, rc = CIFSSMBLock(xid, tcon, netfid, length,
pfLock->fl_start, 0, numLock, lockType, pfLock->fl_start, 0, numLock, lockType,
wait_flag); wait_flag, 0);
if (rc == 0) { if (rc == 0) {
/* For Windows locks we must store them. */ /* For Windows locks we must store them. */
...@@ -903,7 +903,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -903,7 +903,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
stored_rc = CIFSSMBLock(xid, tcon, stored_rc = CIFSSMBLock(xid, tcon,
netfid, li->length, netfid, li->length,
li->offset, 1, 0, li->offset, 1, 0,
li->type, false); li->type, false, 0);
if (stored_rc) if (stored_rc)
rc = stored_rc; rc = stored_rc;
else { else {
...@@ -2348,7 +2348,8 @@ cifs_oplock_break(struct slow_work *work) ...@@ -2348,7 +2348,8 @@ cifs_oplock_break(struct slow_work *work)
*/ */
if (!cfile->closePend && !cfile->oplock_break_cancelled) { if (!cfile->closePend && !cfile->oplock_break_cancelled) {
rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0, rc = CIFSSMBLock(0, cifs_sb->tcon, cfile->netfid, 0, 0, 0, 0,
LOCKING_ANDX_OPLOCK_RELEASE, false); LOCKING_ANDX_OPLOCK_RELEASE, false,
cinode->clientCanCacheRead ? 1 : 0);
cFYI(1, "Oplock release rc = %d", rc); cFYI(1, "Oplock release rc = %d", rc);
} }
} }
......
...@@ -804,8 +804,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) ...@@ -804,8 +804,10 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
rc = cifs_get_inode_info(&inode, full_path, NULL, sb, rc = cifs_get_inode_info(&inode, full_path, NULL, sb,
xid, NULL); xid, NULL);
if (!inode) if (!inode) {
return ERR_PTR(-ENOMEM); inode = ERR_PTR(rc);
goto out;
}
if (rc && cifs_sb->tcon->ipc) { if (rc && cifs_sb->tcon->ipc) {
cFYI(1, "ipc connection - fake read inode"); cFYI(1, "ipc connection - fake read inode");
...@@ -816,13 +818,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino) ...@@ -816,13 +818,11 @@ struct inode *cifs_root_iget(struct super_block *sb, unsigned long ino)
inode->i_uid = cifs_sb->mnt_uid; inode->i_uid = cifs_sb->mnt_uid;
inode->i_gid = cifs_sb->mnt_gid; inode->i_gid = cifs_sb->mnt_gid;
} else if (rc) { } else if (rc) {
kfree(full_path);
_FreeXid(xid);
iget_failed(inode); iget_failed(inode);
return ERR_PTR(rc); inode = ERR_PTR(rc);
} }
out:
kfree(full_path); kfree(full_path);
/* can not call macro FreeXid here since in a void func /* can not call macro FreeXid here since in a void func
* TODO: This is no longer true * TODO: This is no longer true
......
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