Commit 32995340 authored by Steve French's avatar Steve French

Merge bk://linux.bkbits.net/linux-2.5

into hostme.bitkeeper.com:/repos/c/cifs/linux-2.5cifs
parents 3a2b9514 5221ad8c
Version 0.84
------------
Finish support for Linux 2.5 open/create changes, which removes the
redundant NTCreate/QPathInfo/close that was sent during file create.
Enable oplock by default. Enable packet signing by default (needed to
access many recent Windows servers)
Version 0.83
------------
Fix oops when mounting to long server names caused by inverted parms to kmalloc.
......
......@@ -150,7 +150,10 @@ Configuration pseudo-files:
point and if the uids user/password mapping
information is available. (default is 0)
PacketSigningEnabled If set to one, cifs packet signing is enabled
(default 0)
and will be used if the server requires
it. If set to two, cifs packet signing is
required even if the server considers packet
signing optional. (default 1)
cifsFYI If set to one, additional debug information is
logged to the system error log. (default 0)
ExtendedSecurity If set to one, SPNEGO session establishment
......@@ -166,6 +169,7 @@ Configuration pseudo-files:
for one second improving performance of lookups
(default 1)
OplockEnabled If set to one, safe distributed caching enabled.
(default 1)
These experimental features and tracing can be enabled by changing flags in /proc/fs/cifs
(after the cifs module has been installed or built into the kernel, e.g. insmod cifs).
......
......@@ -47,12 +47,12 @@ extern struct file_system_type cifs_fs_type;
int cifsFYI = 0;
int cifsERROR = 1;
int traceSMB = 0;
unsigned int oplockEnabled = 0;
unsigned int oplockEnabled = 1;
unsigned int lookupCacheEnabled = 1;
unsigned int multiuser_mount = 0;
unsigned int extended_security = 0;
unsigned int ntlmv2_support = 0;
unsigned int sign_CIFS_PDUs = 0;
unsigned int sign_CIFS_PDUs = 1;
unsigned int CIFSMaximumBufferSize = CIFS_MAX_MSGSIZE;
struct task_struct * oplockThread = NULL;
......@@ -439,7 +439,6 @@ static int cifs_oplock_thread(void * dummyarg)
struct list_head * tmp;
struct list_head * tmp1;
struct oplock_q_entry * oplock_item;
struct file * pfile;
struct cifsTconInfo *pTcon;
int rc;
......@@ -457,23 +456,19 @@ static int cifs_oplock_thread(void * dummyarg)
qhead);
if(oplock_item) {
pTcon = oplock_item->tcon;
pfile = oplock_item->file_to_flush;
cFYI(1,("process item on queue"));/* BB remove */
DeleteOplockQEntry(oplock_item);
write_unlock(&GlobalMid_Lock);
rc = filemap_fdatawrite(pfile->f_dentry->d_inode->i_mapping);
rc = filemap_fdatawrite(oplock_item->pinode->i_mapping);
if(rc)
CIFS_I(pfile->f_dentry->d_inode)->write_behind_rc
CIFS_I(oplock_item->pinode)->write_behind_rc
= rc;
cFYI(1,("Oplock flush file %p rc %d",pfile,rc));
if(pfile->private_data) {
rc = CIFSSMBLock(0, pTcon,
((struct cifsFileInfo *) pfile->private_data)->netfid,
0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */);
cFYI(1,("Oplock release rc = %d ",rc));
}
cFYI(1,("Oplock flush inode %p rc %d",oplock_item->pinode,rc));
rc = CIFSSMBLock(0, pTcon,
oplock_item->netfid,
0 /* len */ , 0 /* offset */, 0,
0, LOCKING_ANDX_OPLOCK_RELEASE,
0 /* wait flag */);
cFYI(1,("Oplock release rc = %d ",rc));
write_lock(&GlobalMid_Lock);
} else
break;
......
......@@ -208,6 +208,7 @@ struct cifsFileInfo {
/* BB add lock scope info here if needed */ ;
/* lock scope id (0 if none) */
struct file * pfile; /* needed for writepage */
struct inode * pInode; /* needed for oplock break */
int endOfSearch:1; /* we have reached end of search */
int closePend:1; /* file is marked to close */
int emptyDir:1;
......@@ -263,8 +264,9 @@ struct mid_q_entry {
struct oplock_q_entry {
struct list_head qhead;
struct file * file_to_flush;
struct inode * pinode;
struct cifsTconInfo * tcon;
__u16 netfid;
};
#define MID_FREE 0
......
......@@ -57,7 +57,7 @@ extern void header_assemble(struct smb_hdr *, char /* command */ ,
const struct cifsTconInfo *, int
/* length of fixed section (word count) in two byte units */
);
struct oplock_q_entry * AllocOplockQEntry(struct file *,struct cifsTconInfo *);
struct oplock_q_entry * AllocOplockQEntry(struct inode *, u16, struct cifsTconInfo *);
void DeleteOplockQEntry(struct oplock_q_entry *);
extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
extern u64 cifs_UnixTimeToNT(struct timespec);
......@@ -68,7 +68,8 @@ extern void RevUcode_to_Ucode_with_Len(char *revUnicode, char *UnicodeName,
extern void Ucode_to_RevUcode_with_Len(char *Unicode, char *revUnicodeName,
int Len);
extern int cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path,
const unsigned char *search_path,
FILE_ALL_INFO * pfile_info,
struct super_block *sb);
extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path,
......@@ -195,7 +196,7 @@ extern int CIFSSMBQueryReparseLinkInfo(const int xid,
extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int disposition,
const int access_flags, const int omode,
__u16 * netfid, int *pOplock,
__u16 * netfid, int *pOplock, FILE_ALL_INFO *,
const struct nls_table *nls_codepage);
extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id);
......
......@@ -179,7 +179,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
cERROR(1,
("Server requires /proc/fs/cifs/PacketSigningEnabled"));
server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
} else if(sign_CIFS_PDUs == 1) {
if((server->secMode & SECMODE_SIGN_REQUIRED) == 0)
server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED);
}
}
if (pSMB)
buf_release(pSMB);
......@@ -419,7 +423,8 @@ int
CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int openDisposition,
const int access_flags, const int create_options, __u16 * netfid,
int *pOplock, const struct nls_table *nls_codepage)
int *pOplock, FILE_ALL_INFO * pfile_info,
const struct nls_table *nls_codepage)
{
int rc = -EACCES;
OPEN_REQ *pSMB = NULL;
......@@ -484,8 +489,14 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
*pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */
*netfid = pSMBr->Fid; /* cifs fid stays in le */
/* Do we care about the CreateAction in any cases? */
/* BB add code to update inode file sizes from create response */
if(pfile_info) {
memcpy((char *)pfile_info,(char *)&pSMBr->CreationTime,
36 /* CreationTime to Attributes */);
/* the file_info buf is endian converted by caller */
pfile_info->AllocationSize = pSMBr->AllocationSize;
pfile_info->EndOfFile = pSMBr->EndOfFile;
pfile_info->NumberOfLinks = cpu_to_le32(1);
}
}
if (pSMB)
buf_release(pSMB);
......@@ -1231,11 +1242,12 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
/* BB also check enough total bytes returned */
if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512))
rc = -EIO; /* bad smb */
else {
else if (pFindData){
memcpy((char *) pFindData,
(char *) &pSMBr->hdr.Protocol +
pSMBr->DataOffset, sizeof (FILE_ALL_INFO));
}
} else
rc = -ENOMEM;
}
if (pSMB)
buf_release(pSMB);
......
......@@ -131,7 +131,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon;
char *full_path = NULL;
FILE_ALL_INFO * buf = NULL;
struct inode *newinode = NULL;
struct cifsFileInfo * pCifsFile = NULL;
struct cifsInodeInfo * pCifsInode;
xid = GetXid();
......@@ -140,10 +143,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
full_path = build_path_from_dentry(direntry);
if(nd) {
cFYI(1,("In create nd flags = 0x%x for %s",nd->flags,full_path));
cFYI(1,("Intent flags: 0x%x", nd->intent.open.flags));
if ((nd->intent.open.flags & O_ACCMODE) == O_RDONLY)
desiredAccess = GENERIC_READ;
else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY)
......@@ -152,12 +154,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
desiredAccess = GENERIC_ALL;
}
/* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */
if (!oplockEnabled)
oplock = REQ_OPLOCK;
/* BB add processing for setting the equivalent of mode - e.g. via CreateX with ACLs */
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OVERWRITE_IF,
desiredAccess, CREATE_NOT_DIR,
&fileHandle, &oplock, cifs_sb->local_nls);
&fileHandle, &oplock, buf, cifs_sb->local_nls);
if (rc) {
cFYI(1, ("cifs_create returned 0x%x ", rc));
} else {
......@@ -166,28 +170,55 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
inode->i_sb);
else
rc = cifs_get_inode_info(&newinode, full_path,
inode->i_sb);
buf, inode->i_sb);
if (rc != 0) {
cFYI(1,("Create worked but get_inode_info failed with rc = %d",
rc));
/* close handle */
} else {
direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode);
}
/* BB check oplock state before deciding to call following */
/* if(*oplock)
save off handle in inode and dontdoclose */
CIFSSMBClose(xid, pTcon, fileHandle);
/* BB In the future chain close with the NTCreateX to narrow window */
if(newinode)
newinode->i_mode = mode;
}
if(newinode) {
newinode->i_mode = mode;
pCifsFile = (struct cifsFileInfo *)
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
if (pCifsFile) {
memset((char *)pCifsFile, 0,
sizeof (struct cifsFileInfo));
pCifsFile->netfid = fileHandle;
pCifsFile->pid = current->pid;
pCifsFile->pInode = newinode;
/* pCifsFile->pfile = file; */ /* put in at open time */
write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList);
pCifsInode = CIFS_I(newinode);
if(pCifsInode->openFileList.next)
list_add(&pCifsFile->flist,&pCifsInode->openFileList);
write_unlock(&GlobalSMBSeslock);
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
CIFSSMBUnixSetPerms(xid, pTcon, full_path, inode->i_mode,
(__u64)-1,
(__u64)-1,
0 /* dev */,
cifs_sb->local_nls);
else { /* BB implement via Windows security descriptors */
/* eg CIFSSMBWinSetPerms(xid,pTcon,full_path,mode,-1,-1,local_nls);*/
/* in the meantime could set r/o dos attribute when perms are eg:
mode & 0222 == 0 */
}
}
}
}
if (buf)
kfree(buf);
if (full_path)
kfree(full_path);
kfree(full_path);
FreeXid(xid);
return rc;
......@@ -261,17 +292,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
cFYI(1,
(" Full path: %s inode = 0x%p", full_path, direntry->d_inode));
if(nd) { /* BB remove begin */
cFYI(1,("In lookup nd flags = 0x%x",nd->flags));
cFYI(1,("Intent flags: 0x%x", nd->intent.open.flags));
}
/* BB remove end BB */
if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newInode, full_path,
parent_dir_inode->i_sb);
else
rc = cifs_get_inode_info(&newInode, full_path,
rc = cifs_get_inode_info(&newInode, full_path, NULL,
parent_dir_inode->i_sb);
if ((rc == 0) && (newInode != NULL)) {
......@@ -328,12 +353,6 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd)
/* lock_kernel(); *//* surely we do not want to lock the kernel for a whole network round trip which could take seconds */
if(nd) { /* BB remove begin */
cFYI(1,("In d_revalidate nd flags = 0x%x",nd->flags));
cFYI(1,("Intent flags: 0x%x", nd->intent.open.flags));
}
/* BB remove end BB */
if (direntry->d_inode) {
if (cifs_revalidate(direntry)) {
/* unlock_kernel(); */
......
......@@ -45,6 +45,7 @@ cifs_open(struct inode *inode, struct file *file)
struct cifsTconInfo *pTcon;
struct cifsFileInfo *pCifsFile;
struct cifsInodeInfo *pCifsInode;
struct list_head * tmp;
char *full_path = NULL;
int desiredAccess = 0x20197;
int disposition = FILE_OPEN;
......@@ -55,6 +56,29 @@ cifs_open(struct inode *inode, struct file *file)
cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon;
if (file->f_flags & O_CREAT) {
/* search inode for this file and fill in file->private_data = */
pCifsInode = CIFS_I(file->f_dentry->d_inode);
read_lock(&GlobalSMBSeslock);
list_for_each(tmp, &pCifsInode->openFileList) {
pCifsFile = list_entry(tmp,struct cifsFileInfo, flist);
if((pCifsFile->pfile == NULL)&& (pCifsFile->pid = current->pid)){
/* set mode ?? */
pCifsFile->pfile = file; /* needed for writepage */
file->private_data = pCifsFile;
break;
}
}
read_unlock(&GlobalSMBSeslock);
if(file->private_data != NULL) {
rc = 0;
FreeXid(xid);
return rc;
} else {
cERROR(1,("could not find file instance for new file %p ",file));
}
}
full_path = build_path_from_dentry(file->f_dentry);
cFYI(1, (" inode = 0x%p file flags are %x for %s", inode, file->f_flags,full_path));
......@@ -86,20 +110,21 @@ cifs_open(struct inode *inode, struct file *file)
if (file->f_flags & O_CREAT)
disposition = FILE_OVERWRITE;
/* BB first check if file has batch oplock (or oplock ?) */
/* BB finish adding in oplock support BB */
if (oplockEnabled)
oplock = REQ_OPLOCK;
else
oplock = FALSE;
/* BB pass O_SYNC flag through on file attributes .. BB */
/* BB add code to refresh inode by passing in file_info buf on open
and calling get_inode_info with returned buf (at least
helps non-Unix server case */
rc = CIFSSMBOpen(xid, pTcon, full_path, disposition, desiredAccess,
CREATE_NOT_DIR, &netfid, &oplock, cifs_sb->local_nls);
CREATE_NOT_DIR, &netfid, &oplock, NULL, cifs_sb->local_nls);
if (rc) {
cFYI(1, ("cifs_open returned 0x%x ", rc));
cFYI(1, ("oplock: %d ", oplock));
cFYI(1, ("oplock: %d ", oplock));
} else {
file->private_data =
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
......@@ -110,6 +135,7 @@ cifs_open(struct inode *inode, struct file *file)
pCifsFile->netfid = netfid;
pCifsFile->pid = current->pid;
pCifsFile->pfile = file; /* needed for writepage */
pCifsFile->pInode = inode;
write_lock(&file->f_owner.lock);
write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList);
......@@ -1248,7 +1274,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
pfindDataUnix->FileName,
cifsFile->resume_name_length);
}
for (i = 2; i < findParms.SearchCount + 2; i++) {
for (i = 2; i < (unsigned int)findParms.SearchCount + 2; i++) {
if (UnixSearch == FALSE) {
pfindData->FileNameLength =
le32_to_cpu(pfindData->FileNameLength);
......
......@@ -155,24 +155,30 @@ cifs_get_inode_info_unix(struct inode **pinode,
}
int
cifs_get_inode_info(struct inode **pinode,
const unsigned char *search_path, struct super_block *sb)
cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
FILE_ALL_INFO * pfindData, struct super_block *sb)
{
int xid;
int rc = 0;
FILE_ALL_INFO findData;
struct cifsTconInfo *pTcon;
struct inode *inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *tmp_path;
char *buf = NULL;
xid = GetXid();
pTcon = cifs_sb->tcon;
cFYI(1, (" Getting info on %s ", search_path));
/* we could have done a find first instead but this returns more info */
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, &findData,
/* if file info not passed in then get it from server */
if(pfindData == NULL) {
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
pfindData = (FILE_ALL_INFO *)buf;
/* could do find first instead but this returns more info */
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
cifs_sb->local_nls);
}
/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
if (rc) {
if (rc == -EREMOTE) {
......@@ -183,8 +189,10 @@ cifs_get_inode_info(struct inode **pinode,
strnlen(search_path, MAX_PATHCONF) + 1,
GFP_KERNEL);
if (tmp_path == NULL) {
FreeXid(xid);
return -ENOMEM;
if(buf)
kfree(buf);
FreeXid(xid);
return -ENOMEM;
}
strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
......@@ -195,8 +203,10 @@ cifs_get_inode_info(struct inode **pinode,
kfree(tmp_path);
/* BB fix up inode etc. */
} else if (rc) {
FreeXid(xid);
return rc;
if(buf)
kfree(buf);
FreeXid(xid);
return rc;
}
} else {
struct cifsInodeInfo *cifsInfo;
......@@ -208,8 +218,8 @@ cifs_get_inode_info(struct inode **pinode,
inode = *pinode;
cifsInfo = CIFS_I(inode);
findData.Attributes = le32_to_cpu(findData.Attributes);
cifsInfo->cifsAttrs = findData.Attributes;
pfindData->Attributes = le32_to_cpu(pfindData->Attributes);
cifsInfo->cifsAttrs = pfindData->Attributes;
cFYI(1, (" Old time %ld ", cifsInfo->time));
cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time));
......@@ -219,21 +229,21 @@ cifs_get_inode_info(struct inode **pinode,
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;
/* Linux can not store file creation time unfortunately so we ignore it */
inode->i_atime =
cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime));
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
inode->i_mtime =
cifs_NTtimeToUnix(le64_to_cpu(findData.LastWriteTime));
cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(findData.ChangeTime));
cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
cFYI(0,
(" Attributes came in as 0x%x ", findData.Attributes));
(" Attributes came in as 0x%x ", pfindData->Attributes));
/* set default mode. will override for dirs below */
inode->i_mode = cifs_sb->mnt_file_mode;
if (findData.Attributes & ATTR_REPARSE) {
if (pfindData->Attributes & ATTR_REPARSE) {
/* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */
inode->i_mode |= S_IFLNK;
} else if (findData.Attributes & ATTR_DIRECTORY) {
} else if (pfindData->Attributes & ATTR_DIRECTORY) {
/* override default perms since we do not do byte range locking on dirs */
inode->i_mode = cifs_sb->mnt_dir_mode;
inode->i_mode |= S_IFDIR;
......@@ -244,14 +254,14 @@ cifs_get_inode_info(struct inode **pinode,
inode->i_mode &= ~(S_IWUGO);
/* BB add code here - validate if device or weird share or device type? */
}
inode->i_size = le64_to_cpu(findData.EndOfFile);
findData.AllocationSize = le64_to_cpu(findData.AllocationSize);
inode->i_size = le64_to_cpu(pfindData->EndOfFile);
pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
inode->i_blocks =
do_div(findData.AllocationSize, inode->i_blksize);
do_div(pfindData->AllocationSize, inode->i_blksize);
cFYI(1,
(" Size %ld and blocks %ld ",
(unsigned long) inode->i_size, inode->i_blocks));
inode->i_nlink = le32_to_cpu(findData.NumberOfLinks);
inode->i_nlink = le32_to_cpu(pfindData->NumberOfLinks);
/* BB fill in uid and gid here? with help from winbind?
or retrieve from NTFS stream extended attribute */
......@@ -275,6 +285,8 @@ cifs_get_inode_info(struct inode **pinode,
kdev_t_to_nr(inode->i_rdev));
}
}
if(buf)
kfree(buf);
FreeXid(xid);
return rc;
}
......@@ -290,7 +302,7 @@ cifs_read_inode(struct inode *inode)
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
cifs_get_inode_info_unix(&inode, "", inode->i_sb);
else
cifs_get_inode_info(&inode, "", inode->i_sb);
cifs_get_inode_info(&inode, "", NULL, inode->i_sb);
}
int
......@@ -323,7 +335,7 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, cifs_sb->local_nls);
&netfid, &oplock, NULL, cifs_sb->local_nls);
if(rc==0) {
CIFSSMBClose(xid, pTcon, netfid);
/* BB In the future chain close with the NTCreateX to narrow window */
......@@ -387,7 +399,7 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb);
else
rc = cifs_get_inode_info(&newinode, full_path,
rc = cifs_get_inode_info(&newinode, full_path,NULL,
inode->i_sb);
direntry->d_op = &cifs_dentry_ops;
......@@ -531,7 +543,7 @@ cifs_revalidate(struct dentry *direntry)
cifs_get_inode_info_unix(&direntry->d_inode, full_path,
direntry->d_sb);
else
cifs_get_inode_info(&direntry->d_inode, full_path,
cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
direntry->d_sb);
/* BB if not oplocked, invalidate inode pages if mtime has changed */
......
......@@ -160,7 +160,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb);
else
rc = cifs_get_inode_info(&newinode, full_path,
rc = cifs_get_inode_info(&newinode, full_path, NULL,
inode->i_sb);
if (rc != 0) {
......@@ -221,7 +221,7 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
cifs_sb->local_nls);
else {
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ,
OPEN_REPARSE_POINT,&fid, &oplock, cifs_sb->local_nls);
OPEN_REPARSE_POINT,&fid, &oplock, NULL, cifs_sb->local_nls);
if(!rc) {
rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
tmpbuffer,
......
......@@ -390,12 +390,12 @@ is_valid_oplock_break(struct smb_hdr *buf)
read_unlock(&GlobalSMBSeslock);
cFYI(1,("Matching file id, processing oplock break"));
pCifsInode =
CIFS_I(netfile->pfile->f_dentry->d_inode);
CIFS_I(netfile->pInode);
pCifsInode->clientCanCacheAll = FALSE;
if(pSMB->OplockLevel == 0)
pCifsInode->clientCanCacheRead = FALSE;
pCifsInode->oplockPending = TRUE;
AllocOplockQEntry(netfile->pfile, tcon);
AllocOplockQEntry(netfile->pInode, netfile->netfid, tcon);
cFYI(1,("about to wake up oplock thd"));
wake_up_process(oplockThread);
return TRUE;
......
......@@ -101,10 +101,10 @@ DeleteMidQEntry(struct mid_q_entry *midEntry)
}
struct oplock_q_entry *
AllocOplockQEntry(struct file * file, struct cifsTconInfo * tcon)
AllocOplockQEntry(struct inode * pinode, __u16 fid, struct cifsTconInfo * tcon)
{
struct oplock_q_entry *temp;
if ((file == NULL) || (tcon == NULL)) {
if ((pinode== NULL) || (tcon == NULL)) {
cERROR(1, ("Null parms passed to AllocOplockQEntry"));
return NULL;
}
......@@ -113,8 +113,9 @@ AllocOplockQEntry(struct file * file, struct cifsTconInfo * tcon)
if (temp == NULL)
return temp;
else {
temp->file_to_flush = file;
temp->pinode = pinode;
temp->tcon = tcon;
temp->netfid = fid;
write_lock(&GlobalMid_Lock);
list_add_tail(&temp->qhead, &GlobalOplock_Q);
write_unlock(&GlobalMid_Lock);
......
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