diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES index 031e2073d78d0e899662a4690142bc09d4789255..26174632cb938512cbbb0c4550fe58e8f86a71c2 100644 --- a/fs/cifs/CHANGES +++ b/fs/cifs/CHANGES @@ -1,3 +1,10 @@ +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. diff --git a/fs/cifs/README b/fs/cifs/README index dc85adecd5b260f9ee6e87dec5a388816eba1690..76217e7b8a500303d6ae1ba010b7b5d18b190fd4 100644 --- a/fs/cifs/README +++ b/fs/cifs/README @@ -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). diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index 0b8e3ba926478a4608d6a81d074d4045dbd20352..e86ff7493a91c6a55cfa6801b7cc7d837c966dec 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -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; diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 6d65f4c71e1fc182ffcf33093a62dd21052647db..64289691f60c170a0fedd9d0d5501294334d1498 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -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 diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index 4179a651a3b2fc36fd0bcf83d24280cefbd6069f..3c8e4cf8f4edd227eca0d7aa7beab6181de24da5 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -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); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 18a51253c97a517535597777b21c35e2df3980b1..d28d6d82f72730a3c7734dbafe708057f4df30ad 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -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); diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 0cad099716967aac85111ae1e5865743c276b820..694a9f27347f6d225e69ef4d97dea0c0876e4bab 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -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(); */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index af9091dd0ebb3c0fa6175996fd374ca8220cc4b9..630b1027ec1732d63867e25a4f6a1eb7597495d8 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -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); diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 8da95697dcd7413cb5fb76b43d0609163ae1912f..b1f0a4ebc071d14d9d6a0e65349e8f93609c8008 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -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 */ diff --git a/fs/cifs/link.c b/fs/cifs/link.c index 1301198c46ed8944bcf59b74c3728566320c1ce9..9717910ee51453e772d58f6287e07efea0a825d2 100644 --- a/fs/cifs/link.c +++ b/fs/cifs/link.c @@ -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, diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 7f3a5b9057329aab2e84e7a26487766d257c58f4..388cfa22b1228099b0a818152efba708a117e179 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -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; diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 7a667c06e3b18490331d157bdf968b60816a8f7a..94990dfcddcbdf99287bc876a22876af045fe8ce 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -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);