You need to sign in or sign up before continuing.
Commit 2d8fc107 authored by Pavel Shilovsky's avatar Pavel Shilovsky

Fixes in 2.6.31

- oplock handling - update from stable tree
parent 480e21f5
...@@ -1096,7 +1096,9 @@ static int cifs_oplock_thread(void *dummyarg) ...@@ -1096,7 +1096,9 @@ static int cifs_oplock_thread(void *dummyarg)
rc = CIFSSMBLock(0, pTcon, netfid, netpid, rc = CIFSSMBLock(0, pTcon, netfid, netpid,
0 /* len */ , 0 /* offset */, 0, 0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE, 0, LOCKING_ANDX_OPLOCK_RELEASE,
false /* wait flag */); false /* wait flag */,
CIFS_I(inode)->clientCanCacheRead ? 1 :
0);
cFYI(1, ("Oplock release rc = %d", rc)); cFYI(1, ("Oplock release rc = %d", rc));
} }
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
......
...@@ -322,7 +322,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -322,7 +322,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 netfid, const __u32 netpid, const __u64 len, const __u16 netfid, const __u32 netpid, const __u64 len,
const __u64 offset, const __u32 numUnlock, const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const __u32 numLock, const __u8 lockType,
const bool waitFlag); 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 __u32 netpid, const int get_flag, const __u16 smb_file_id, const __u32 netpid, const int get_flag,
const __u64 len, struct file_lock *, const __u64 len, struct file_lock *,
...@@ -389,4 +389,5 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon, ...@@ -389,4 +389,5 @@ extern int CIFSSMBSetPosixACL(const int xid, struct cifsTconInfo *tcon,
const struct nls_table *nls_codepage, int remap_special_chars); const struct nls_table *nls_codepage, int remap_special_chars);
extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon, extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
const int netfid, __u64 *pExtAttrBits, __u64 *pMask); const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
extern void cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb);
#endif /* _CIFSPROTO_H */ #endif /* _CIFSPROTO_H */
...@@ -1707,7 +1707,8 @@ int ...@@ -1707,7 +1707,8 @@ int
CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, CIFSSMBLock(const int xid, struct cifsTconInfo *tcon,
const __u16 smb_file_id, const __u32 net_pid, const __u64 len, const __u16 smb_file_id, const __u32 net_pid, const __u64 len,
const __u64 offset, const __u32 numUnlock, const __u64 offset, const __u32 numUnlock,
const __u32 numLock, const __u8 lockType, const bool waitFlag) const __u32 numLock, const __u8 lockType,
const bool waitFlag, const __u8 oplock_level)
{ {
int rc = 0; int rc = 0;
LOCK_REQ *pSMB = NULL; LOCK_REQ *pSMB = NULL;
...@@ -1735,6 +1736,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, ...@@ -1735,6 +1736,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 */
......
...@@ -2199,16 +2199,8 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon, ...@@ -2199,16 +2199,8 @@ is_path_accessible(int xid, struct cifsTconInfo *tcon,
struct cifs_sb_info *cifs_sb, const char *full_path) struct cifs_sb_info *cifs_sb, const char *full_path)
{ {
int rc; int rc;
__u64 inode_num;
FILE_ALL_INFO *pfile_info; FILE_ALL_INFO *pfile_info;
rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num,
cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc != -EOPNOTSUPP)
return rc;
pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL); pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
if (pfile_info == NULL) if (pfile_info == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -2274,12 +2266,12 @@ int ...@@ -2274,12 +2266,12 @@ int
cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
char *mount_data_global, const char *devname) char *mount_data_global, const char *devname)
{ {
int rc = 0; int rc;
int xid; int xid;
struct smb_vol *volume_info; struct smb_vol *volume_info;
struct cifsSesInfo *pSesInfo = NULL; struct cifsSesInfo *pSesInfo;
struct cifsTconInfo *tcon = NULL; struct cifsTconInfo *tcon;
struct TCP_Server_Info *srvTcp = NULL; struct TCP_Server_Info *srvTcp;
char *full_path; char *full_path;
char *mount_data = mount_data_global; char *mount_data = mount_data_global;
#ifdef CONFIG_CIFS_DFS_UPCALL #ifdef CONFIG_CIFS_DFS_UPCALL
...@@ -2288,6 +2280,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb, ...@@ -2288,6 +2280,10 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
int referral_walks_count = 0; int referral_walks_count = 0;
try_mount_again: try_mount_again:
#endif #endif
rc = 0;
tcon = NULL;
pSesInfo = NULL;
srvTcp = NULL;
full_path = NULL; full_path = NULL;
xid = GetXid(); xid = GetXid();
...@@ -2584,6 +2580,7 @@ remote_path_check: ...@@ -2584,6 +2580,7 @@ remote_path_check:
cleanup_volume_info(&volume_info); cleanup_volume_info(&volume_info);
referral_walks_count++; referral_walks_count++;
FreeXid(xid);
goto try_mount_again; goto try_mount_again;
} }
#else /* No DFS support, return error on mount */ #else /* No DFS support, return error on mount */
......
...@@ -212,8 +212,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode, ...@@ -212,8 +212,6 @@ int cifs_posix_open(char *full_path, struct inode **pinode,
posix_flags |= SMB_O_EXCL; posix_flags |= SMB_O_EXCL;
if (oflags & O_TRUNC) if (oflags & O_TRUNC)
posix_flags |= SMB_O_TRUNC; posix_flags |= SMB_O_TRUNC;
if (oflags & O_APPEND)
posix_flags |= SMB_O_APPEND;
if (oflags & O_SYNC) if (oflags & O_SYNC)
posix_flags |= SMB_O_SYNC; posix_flags |= SMB_O_SYNC;
if (oflags & O_DIRECTORY) if (oflags & O_DIRECTORY)
...@@ -650,7 +648,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, ...@@ -650,7 +648,7 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry,
* O_EXCL: optimize away the lookup, but don't hash the dentry. Let * O_EXCL: optimize away the lookup, but don't hash the dentry. Let
* the VFS handle the create. * the VFS handle the create.
*/ */
if (nd->flags & LOOKUP_EXCL) { if (nd && (nd->flags & LOOKUP_EXCL)) {
d_instantiate(direntry, NULL); d_instantiate(direntry, NULL);
return 0; return 0;
} }
......
...@@ -897,12 +897,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -897,12 +897,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, netpid, length, pfLock->fl_start, rc = CIFSSMBLock(xid, tcon, netfid, netpid, 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, netpid, length, rc = CIFSSMBLock(xid, tcon, netfid, netpid, 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 "
...@@ -919,13 +919,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -919,13 +919,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
rc = CIFSSMBLock(xid, tcon, netfid, netpid, length, rc = CIFSSMBLock(xid, tcon, netfid, netpid, 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, netpid, rc = CIFSSMBLock(xid, tcon, netfid, netpid,
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 "
...@@ -970,7 +970,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -970,7 +970,7 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
if (numLock) { if (numLock) {
rc = CIFSSMBLock(xid, tcon, netfid, netpid, length, rc = CIFSSMBLock(xid, tcon, netfid, netpid, length,
pfLock->fl_start, pfLock->fl_start,
0, numLock, lockType, wait_flag); 0, numLock, lockType, wait_flag, 0);
if (rc == 0) { if (rc == 0) {
/* For Windows locks we must store them. */ /* For Windows locks we must store them. */
...@@ -992,7 +992,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) ...@@ -992,7 +992,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock)
stored_rc = CIFSSMBLock(xid, tcon, stored_rc = CIFSSMBLock(xid, tcon,
netfid, netpid, netfid, netpid,
li->length, li->offset, li->length, li->offset,
1, 0, li->type, false); 1, 0, li->type, false,
0);
if (stored_rc) if (stored_rc)
rc = stored_rc; rc = stored_rc;
else { else {
......
...@@ -512,13 +512,10 @@ int cifs_get_inode_info(struct inode **pinode, ...@@ -512,13 +512,10 @@ int cifs_get_inode_info(struct inode **pinode,
cifs_sb->local_nls, cifs_sb->local_nls,
cifs_sb->mnt_cifs_flags & cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
if (rc1) { if (rc1 || !fattr.cf_uniqueid) {
cFYI(1, ("GetSrvInodeNum rc %d", rc1)); cFYI(1, ("GetSrvInodeNum rc %d", rc1));
fattr.cf_uniqueid = iunique(sb, ROOT_I); fattr.cf_uniqueid = iunique(sb, ROOT_I);
/* disable serverino if call not supported */ cifs_autodisable_serverino(cifs_sb);
if (rc1 == -EINVAL)
cifs_sb->mnt_cifs_flags &=
~CIFS_MOUNT_SERVER_INUM;
} }
} else { } else {
fattr.cf_uniqueid = iunique(sb, ROOT_I); fattr.cf_uniqueid = iunique(sb, ROOT_I);
......
...@@ -705,3 +705,17 @@ cifsConvertToUCS(__le16 *target, const char *source, int maxlen, ...@@ -705,3 +705,17 @@ cifsConvertToUCS(__le16 *target, const char *source, int maxlen,
ctoUCS_out: ctoUCS_out:
return i; return i;
} }
void
cifs_autodisable_serverino(struct cifs_sb_info *cifs_sb)
{
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM) {
cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
cERROR(1, ("Autodisabling the use of server inode numbers on "
"%s. This server doesn't seem to support them "
"properly. Hardlinks will not be recognized on this "
"mount. Consider mounting with the \"noserverino\" "
"option to silence this message.",
cifs_sb->tcon->treeName));
}
}
...@@ -666,6 +666,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst, ...@@ -666,6 +666,7 @@ static int cifs_get_name_from_search_buf(struct qstr *pqst,
min(len, max_len), nlt, min(len, max_len), nlt,
cifs_sb->mnt_cifs_flags & cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
pqst->len -= nls_nullsize(nlt);
} else { } else {
pqst->name = filename; pqst->name = filename;
pqst->len = len; pqst->len = len;
...@@ -727,11 +728,12 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir, ...@@ -727,11 +728,12 @@ static int cifs_filldir(char *pfindEntry, struct file *file, filldir_t filldir,
cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *) cifs_dir_info_to_fattr(&fattr, (FILE_DIRECTORY_INFO *)
pfindEntry, cifs_sb); pfindEntry, cifs_sb);
/* FIXME: make _to_fattr functions fill this out */ if (inum && (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SERVER_INUM)) {
if (pCifsF->srch_inf.info_level == SMB_FIND_FILE_ID_FULL_DIR_INFO)
fattr.cf_uniqueid = inum; fattr.cf_uniqueid = inum;
else } else {
fattr.cf_uniqueid = iunique(sb, ROOT_I); fattr.cf_uniqueid = iunique(sb, ROOT_I);
cifs_autodisable_serverino(cifs_sb);
}
ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid); ino = cifs_uniqueid_to_ino_t(fattr.cf_uniqueid);
tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr); tmp_dentry = cifs_readdir_lookup(file->f_dentry, &qstring, &fattr);
......
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