Commit f280895e authored by Steve French's avatar Steve French Committed by Steve French

cifs enablement for lookup intents (new 2.5 create/lookup flags) final part

parent f02e6170
...@@ -208,6 +208,7 @@ struct cifsFileInfo { ...@@ -208,6 +208,7 @@ struct cifsFileInfo {
/* BB add lock scope info here if needed */ ; /* BB add lock scope info here if needed */ ;
/* lock scope id (0 if none) */ /* lock scope id (0 if none) */
struct file * pfile; /* needed for writepage */ struct file * pfile; /* needed for writepage */
struct inode * pInode; /* needed for oplock break */
int endOfSearch:1; /* we have reached end of search */ int endOfSearch:1; /* we have reached end of search */
int closePend:1; /* file is marked to close */ int closePend:1; /* file is marked to close */
int emptyDir:1; int emptyDir:1;
...@@ -263,8 +264,9 @@ struct mid_q_entry { ...@@ -263,8 +264,9 @@ struct mid_q_entry {
struct oplock_q_entry { struct oplock_q_entry {
struct list_head qhead; struct list_head qhead;
struct file * file_to_flush; struct inode * pinode;
struct cifsTconInfo * tcon; struct cifsTconInfo * tcon;
__u16 netfid;
}; };
#define MID_FREE 0 #define MID_FREE 0
......
...@@ -57,7 +57,7 @@ extern void header_assemble(struct smb_hdr *, char /* command */ , ...@@ -57,7 +57,7 @@ extern void header_assemble(struct smb_hdr *, char /* command */ ,
const struct cifsTconInfo *, int const struct cifsTconInfo *, int
/* length of fixed section (word count) in two byte units */ /* 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 *); void DeleteOplockQEntry(struct oplock_q_entry *);
extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ ); extern struct timespec cifs_NTtimeToUnix(u64 /* utc nanoseconds since 1601 */ );
extern u64 cifs_UnixTimeToNT(struct timespec); extern u64 cifs_UnixTimeToNT(struct timespec);
...@@ -68,7 +68,8 @@ extern void RevUcode_to_Ucode_with_Len(char *revUnicode, char *UnicodeName, ...@@ -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, extern void Ucode_to_RevUcode_with_Len(char *Unicode, char *revUnicodeName,
int Len); int Len);
extern int cifs_get_inode_info(struct inode **pinode, 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); struct super_block *sb);
extern int cifs_get_inode_info_unix(struct inode **pinode, extern int cifs_get_inode_info_unix(struct inode **pinode,
const unsigned char *search_path, const unsigned char *search_path,
...@@ -195,7 +196,7 @@ extern int CIFSSMBQueryReparseLinkInfo(const int xid, ...@@ -195,7 +196,7 @@ extern int CIFSSMBQueryReparseLinkInfo(const int xid,
extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int disposition, const char *fileName, const int disposition,
const int access_flags, const int omode, const int access_flags, const int omode,
__u16 * netfid, int *pOplock, __u16 * netfid, int *pOplock, FILE_ALL_INFO *,
const struct nls_table *nls_codepage); const struct nls_table *nls_codepage);
extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBClose(const int xid, struct cifsTconInfo *tcon,
const int smb_file_id); const int smb_file_id);
......
...@@ -179,7 +179,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses) ...@@ -179,7 +179,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
cERROR(1, cERROR(1,
("Server requires /proc/fs/cifs/PacketSigningEnabled")); ("Server requires /proc/fs/cifs/PacketSigningEnabled"));
server->secMode &= ~(SECMODE_SIGN_ENABLED | SECMODE_SIGN_REQUIRED); 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) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -419,7 +423,8 @@ int ...@@ -419,7 +423,8 @@ int
CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
const char *fileName, const int openDisposition, const char *fileName, const int openDisposition,
const int access_flags, const int create_options, __u16 * netfid, 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; int rc = -EACCES;
OPEN_REQ *pSMB = NULL; OPEN_REQ *pSMB = NULL;
...@@ -484,8 +489,14 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon, ...@@ -484,8 +489,14 @@ CIFSSMBOpen(const int xid, struct cifsTconInfo *tcon,
*pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */ *pOplock = pSMBr->OplockLevel; /* one byte no need to le_to_cpu */
*netfid = pSMBr->Fid; /* cifs fid stays in le */ *netfid = pSMBr->Fid; /* cifs fid stays in le */
/* Do we care about the CreateAction in any cases? */ /* Do we care about the CreateAction in any cases? */
if(pfile_info) {
/* BB add code to update inode file sizes from create response */ 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) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
...@@ -1231,11 +1242,12 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, ...@@ -1231,11 +1242,12 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
/* BB also check enough total bytes returned */ /* BB also check enough total bytes returned */
if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512)) if ((pSMBr->ByteCount < 40) || (pSMBr->DataOffset > 512))
rc = -EIO; /* bad smb */ rc = -EIO; /* bad smb */
else { else if (pFindData){
memcpy((char *) pFindData, memcpy((char *) pFindData,
(char *) &pSMBr->hdr.Protocol + (char *) &pSMBr->hdr.Protocol +
pSMBr->DataOffset, sizeof (FILE_ALL_INFO)); pSMBr->DataOffset, sizeof (FILE_ALL_INFO));
} } else
rc = -ENOMEM;
} }
if (pSMB) if (pSMB)
buf_release(pSMB); buf_release(pSMB);
......
...@@ -131,7 +131,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -131,7 +131,10 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
struct cifs_sb_info *cifs_sb; struct cifs_sb_info *cifs_sb;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
char *full_path = NULL; char *full_path = NULL;
FILE_ALL_INFO * buf = NULL;
struct inode *newinode = NULL; struct inode *newinode = NULL;
struct cifsFileInfo * pCifsFile = NULL;
struct cifsInodeInfo * pCifsInode;
xid = GetXid(); xid = GetXid();
...@@ -140,10 +143,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -140,10 +143,9 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
full_path = build_path_from_dentry(direntry); full_path = build_path_from_dentry(direntry);
if(nd) { if(nd) {
cFYI(1,("In create nd flags = 0x%x for %s",nd->flags,full_path)); 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) if ((nd->intent.open.flags & O_ACCMODE) == O_RDONLY)
desiredAccess = GENERIC_READ; desiredAccess = GENERIC_READ;
else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY) else if ((nd->intent.open.flags & O_ACCMODE) == O_WRONLY)
...@@ -152,14 +154,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -152,14 +154,14 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
desiredAccess = GENERIC_ALL; desiredAccess = GENERIC_ALL;
} }
/* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */ /* BB add processing to set equivalent of mode - e.g. via CreateX with ACLs */
if (!oplockEnabled) if (!oplockEnabled)
oplock = REQ_OPLOCK; oplock = REQ_OPLOCK;
buf = kmalloc(sizeof(FILE_ALL_INFO),GFP_KERNEL);
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OVERWRITE_IF, rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OVERWRITE_IF,
desiredAccess, CREATE_NOT_DIR, desiredAccess, CREATE_NOT_DIR,
&fileHandle, &oplock, cifs_sb->local_nls); &fileHandle, &oplock, buf, cifs_sb->local_nls);
if (rc) { if (rc) {
cFYI(1, ("cifs_create returned 0x%x ", rc)); cFYI(1, ("cifs_create returned 0x%x ", rc));
} else { } else {
...@@ -168,28 +170,55 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode, ...@@ -168,28 +170,55 @@ cifs_create(struct inode *inode, struct dentry *direntry, int mode,
inode->i_sb); inode->i_sb);
else else
rc = cifs_get_inode_info(&newinode, full_path, rc = cifs_get_inode_info(&newinode, full_path,
inode->i_sb); buf, inode->i_sb);
if (rc != 0) { if (rc != 0) {
cFYI(1,("Create worked but get_inode_info failed with rc = %d", cFYI(1,("Create worked but get_inode_info failed with rc = %d",
rc)); rc));
/* close handle */
} else { } else {
direntry->d_op = &cifs_dentry_ops; direntry->d_op = &cifs_dentry_ops;
d_instantiate(direntry, newinode); 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) if(newinode) {
newinode->i_mode = mode; 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) if (full_path)
kfree(full_path); kfree(full_path);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
...@@ -263,17 +292,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name ...@@ -263,17 +292,11 @@ cifs_lookup(struct inode *parent_dir_inode, struct dentry *direntry, struct name
cFYI(1, cFYI(1,
(" Full path: %s inode = 0x%p", full_path, direntry->d_inode)); (" 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) if (pTcon->ses->capabilities & CAP_UNIX)
rc = cifs_get_inode_info_unix(&newInode, full_path, rc = cifs_get_inode_info_unix(&newInode, full_path,
parent_dir_inode->i_sb); parent_dir_inode->i_sb);
else else
rc = cifs_get_inode_info(&newInode, full_path, rc = cifs_get_inode_info(&newInode, full_path, NULL,
parent_dir_inode->i_sb); parent_dir_inode->i_sb);
if ((rc == 0) && (newInode != NULL)) { if ((rc == 0) && (newInode != NULL)) {
...@@ -330,12 +353,6 @@ cifs_d_revalidate(struct dentry *direntry, struct nameidata *nd) ...@@ -330,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 */ /* 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 (direntry->d_inode) {
if (cifs_revalidate(direntry)) { if (cifs_revalidate(direntry)) {
/* unlock_kernel(); */ /* unlock_kernel(); */
......
...@@ -45,6 +45,7 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -45,6 +45,7 @@ cifs_open(struct inode *inode, struct file *file)
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
struct cifsFileInfo *pCifsFile; struct cifsFileInfo *pCifsFile;
struct cifsInodeInfo *pCifsInode; struct cifsInodeInfo *pCifsInode;
struct list_head * tmp;
char *full_path = NULL; char *full_path = NULL;
int desiredAccess = 0x20197; int desiredAccess = 0x20197;
int disposition = FILE_OPEN; int disposition = FILE_OPEN;
...@@ -55,6 +56,29 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -55,6 +56,29 @@ cifs_open(struct inode *inode, struct file *file)
cifs_sb = CIFS_SB(inode->i_sb); cifs_sb = CIFS_SB(inode->i_sb);
pTcon = cifs_sb->tcon; 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); 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)); cFYI(1, (" inode = 0x%p file flags are %x for %s", inode, file->f_flags,full_path));
...@@ -92,11 +116,15 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -92,11 +116,15 @@ cifs_open(struct inode *inode, struct file *file)
oplock = FALSE; oplock = FALSE;
/* BB pass O_SYNC flag through on file attributes .. BB */ /* 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, 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) { if (rc) {
cFYI(1, ("cifs_open returned 0x%x ", rc)); cFYI(1, ("cifs_open returned 0x%x ", rc));
cFYI(1, ("oplock: %d ", oplock)); cFYI(1, ("oplock: %d ", oplock));
} else { } else {
file->private_data = file->private_data =
kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL); kmalloc(sizeof (struct cifsFileInfo), GFP_KERNEL);
...@@ -107,6 +135,7 @@ cifs_open(struct inode *inode, struct file *file) ...@@ -107,6 +135,7 @@ cifs_open(struct inode *inode, struct file *file)
pCifsFile->netfid = netfid; pCifsFile->netfid = netfid;
pCifsFile->pid = current->pid; pCifsFile->pid = current->pid;
pCifsFile->pfile = file; /* needed for writepage */ pCifsFile->pfile = file; /* needed for writepage */
pCifsFile->pInode = inode;
write_lock(&file->f_owner.lock); write_lock(&file->f_owner.lock);
write_lock(&GlobalSMBSeslock); write_lock(&GlobalSMBSeslock);
list_add(&pCifsFile->tlist,&pTcon->openFileList); list_add(&pCifsFile->tlist,&pTcon->openFileList);
...@@ -1245,7 +1274,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir) ...@@ -1245,7 +1274,7 @@ cifs_readdir(struct file *file, void *direntry, filldir_t filldir)
pfindDataUnix->FileName, pfindDataUnix->FileName,
cifsFile->resume_name_length); 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) { if (UnixSearch == FALSE) {
pfindData->FileNameLength = pfindData->FileNameLength =
le32_to_cpu(pfindData->FileNameLength); le32_to_cpu(pfindData->FileNameLength);
......
...@@ -155,24 +155,30 @@ cifs_get_inode_info_unix(struct inode **pinode, ...@@ -155,24 +155,30 @@ cifs_get_inode_info_unix(struct inode **pinode,
} }
int int
cifs_get_inode_info(struct inode **pinode, cifs_get_inode_info(struct inode **pinode, const unsigned char *search_path,
const unsigned char *search_path, struct super_block *sb) FILE_ALL_INFO * pfindData, struct super_block *sb)
{ {
int xid; int xid;
int rc = 0; int rc = 0;
FILE_ALL_INFO findData;
struct cifsTconInfo *pTcon; struct cifsTconInfo *pTcon;
struct inode *inode; struct inode *inode;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb); struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
char *tmp_path; char *tmp_path;
char *buf = NULL;
xid = GetXid(); xid = GetXid();
pTcon = cifs_sb->tcon; pTcon = cifs_sb->tcon;
cFYI(1, (" Getting info on %s ", search_path)); 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); cifs_sb->local_nls);
}
/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
if (rc) { if (rc) {
if (rc == -EREMOTE) { if (rc == -EREMOTE) {
...@@ -183,8 +189,10 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -183,8 +189,10 @@ cifs_get_inode_info(struct inode **pinode,
strnlen(search_path, MAX_PATHCONF) + 1, strnlen(search_path, MAX_PATHCONF) + 1,
GFP_KERNEL); GFP_KERNEL);
if (tmp_path == NULL) { if (tmp_path == NULL) {
FreeXid(xid); if(buf)
return -ENOMEM; kfree(buf);
FreeXid(xid);
return -ENOMEM;
} }
strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE); strncpy(tmp_path, pTcon->treeName, MAX_TREE_SIZE);
...@@ -195,8 +203,10 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -195,8 +203,10 @@ cifs_get_inode_info(struct inode **pinode,
kfree(tmp_path); kfree(tmp_path);
/* BB fix up inode etc. */ /* BB fix up inode etc. */
} else if (rc) { } else if (rc) {
FreeXid(xid); if(buf)
return rc; kfree(buf);
FreeXid(xid);
return rc;
} }
} else { } else {
struct cifsInodeInfo *cifsInfo; struct cifsInodeInfo *cifsInfo;
...@@ -208,8 +218,8 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -208,8 +218,8 @@ cifs_get_inode_info(struct inode **pinode,
inode = *pinode; inode = *pinode;
cifsInfo = CIFS_I(inode); cifsInfo = CIFS_I(inode);
findData.Attributes = le32_to_cpu(findData.Attributes); pfindData->Attributes = le32_to_cpu(pfindData->Attributes);
cifsInfo->cifsAttrs = findData.Attributes; cifsInfo->cifsAttrs = pfindData->Attributes;
cFYI(1, (" Old time %ld ", cifsInfo->time)); cFYI(1, (" Old time %ld ", cifsInfo->time));
cifsInfo->time = jiffies; cifsInfo->time = jiffies;
cFYI(1, (" New time %ld ", cifsInfo->time)); cFYI(1, (" New time %ld ", cifsInfo->time));
...@@ -219,21 +229,21 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -219,21 +229,21 @@ cifs_get_inode_info(struct inode **pinode,
(pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00; (pTcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE) & 0xFFFFFE00;
/* Linux can not store file creation time unfortunately so we ignore it */ /* Linux can not store file creation time unfortunately so we ignore it */
inode->i_atime = inode->i_atime =
cifs_NTtimeToUnix(le64_to_cpu(findData.LastAccessTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastAccessTime));
inode->i_mtime = inode->i_mtime =
cifs_NTtimeToUnix(le64_to_cpu(findData.LastWriteTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->LastWriteTime));
inode->i_ctime = inode->i_ctime =
cifs_NTtimeToUnix(le64_to_cpu(findData.ChangeTime)); cifs_NTtimeToUnix(le64_to_cpu(pfindData->ChangeTime));
cFYI(0, 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 */ /* set default mode. will override for dirs below */
inode->i_mode = cifs_sb->mnt_file_mode; 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? */ /* Can IFLNK be set as it basically is on windows with IFREG or IFDIR? */
inode->i_mode |= S_IFLNK; 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 */ /* override default perms since we do not do byte range locking on dirs */
inode->i_mode = cifs_sb->mnt_dir_mode; inode->i_mode = cifs_sb->mnt_dir_mode;
inode->i_mode |= S_IFDIR; inode->i_mode |= S_IFDIR;
...@@ -244,14 +254,14 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -244,14 +254,14 @@ cifs_get_inode_info(struct inode **pinode,
inode->i_mode &= ~(S_IWUGO); inode->i_mode &= ~(S_IWUGO);
/* BB add code here - validate if device or weird share or device type? */ /* BB add code here - validate if device or weird share or device type? */
} }
inode->i_size = le64_to_cpu(findData.EndOfFile); inode->i_size = le64_to_cpu(pfindData->EndOfFile);
findData.AllocationSize = le64_to_cpu(findData.AllocationSize); pfindData->AllocationSize = le64_to_cpu(pfindData->AllocationSize);
inode->i_blocks = inode->i_blocks =
do_div(findData.AllocationSize, inode->i_blksize); do_div(pfindData->AllocationSize, inode->i_blksize);
cFYI(1, cFYI(1,
(" Size %ld and blocks %ld ", (" Size %ld and blocks %ld ",
(unsigned long) inode->i_size, inode->i_blocks)); (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? /* BB fill in uid and gid here? with help from winbind?
or retrieve from NTFS stream extended attribute */ or retrieve from NTFS stream extended attribute */
...@@ -275,6 +285,8 @@ cifs_get_inode_info(struct inode **pinode, ...@@ -275,6 +285,8 @@ cifs_get_inode_info(struct inode **pinode,
kdev_t_to_nr(inode->i_rdev)); kdev_t_to_nr(inode->i_rdev));
} }
} }
if(buf)
kfree(buf);
FreeXid(xid); FreeXid(xid);
return rc; return rc;
} }
...@@ -290,7 +302,7 @@ cifs_read_inode(struct inode *inode) ...@@ -290,7 +302,7 @@ cifs_read_inode(struct inode *inode)
if (cifs_sb->tcon->ses->capabilities & CAP_UNIX) if (cifs_sb->tcon->ses->capabilities & CAP_UNIX)
cifs_get_inode_info_unix(&inode, "", inode->i_sb); cifs_get_inode_info_unix(&inode, "", inode->i_sb);
else else
cifs_get_inode_info(&inode, "", inode->i_sb); cifs_get_inode_info(&inode, "", NULL, inode->i_sb);
} }
int int
...@@ -323,7 +335,7 @@ cifs_unlink(struct inode *inode, struct dentry *direntry) ...@@ -323,7 +335,7 @@ cifs_unlink(struct inode *inode, struct dentry *direntry)
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE, rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, DELETE,
CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE, CREATE_NOT_DIR | CREATE_DELETE_ON_CLOSE,
&netfid, &oplock, cifs_sb->local_nls); &netfid, &oplock, NULL, cifs_sb->local_nls);
if(rc==0) { if(rc==0) {
CIFSSMBClose(xid, pTcon, netfid); CIFSSMBClose(xid, pTcon, netfid);
/* BB In the future chain close with the NTCreateX to narrow window */ /* 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) ...@@ -387,7 +399,7 @@ cifs_mkdir(struct inode *inode, struct dentry *direntry, int mode)
rc = cifs_get_inode_info_unix(&newinode, full_path, rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb); inode->i_sb);
else else
rc = cifs_get_inode_info(&newinode, full_path, rc = cifs_get_inode_info(&newinode, full_path,NULL,
inode->i_sb); inode->i_sb);
direntry->d_op = &cifs_dentry_ops; direntry->d_op = &cifs_dentry_ops;
...@@ -531,7 +543,7 @@ cifs_revalidate(struct dentry *direntry) ...@@ -531,7 +543,7 @@ cifs_revalidate(struct dentry *direntry)
cifs_get_inode_info_unix(&direntry->d_inode, full_path, cifs_get_inode_info_unix(&direntry->d_inode, full_path,
direntry->d_sb); direntry->d_sb);
else else
cifs_get_inode_info(&direntry->d_inode, full_path, cifs_get_inode_info(&direntry->d_inode, full_path, NULL,
direntry->d_sb); direntry->d_sb);
/* BB if not oplocked, invalidate inode pages if mtime has changed */ /* 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) ...@@ -160,7 +160,7 @@ cifs_symlink(struct inode *inode, struct dentry *direntry, const char *symname)
rc = cifs_get_inode_info_unix(&newinode, full_path, rc = cifs_get_inode_info_unix(&newinode, full_path,
inode->i_sb); inode->i_sb);
else else
rc = cifs_get_inode_info(&newinode, full_path, rc = cifs_get_inode_info(&newinode, full_path, NULL,
inode->i_sb); inode->i_sb);
if (rc != 0) { if (rc != 0) {
...@@ -221,7 +221,7 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen) ...@@ -221,7 +221,7 @@ cifs_readlink(struct dentry *direntry, char *pBuffer, int buflen)
cifs_sb->local_nls); cifs_sb->local_nls);
else { else {
rc = CIFSSMBOpen(xid, pTcon, full_path, FILE_OPEN, GENERIC_READ, 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) { if(!rc) {
rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path, rc = CIFSSMBQueryReparseLinkInfo(xid, pTcon, full_path,
tmpbuffer, tmpbuffer,
......
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