[CIFS] Level 1 QPathInfo needed for proper OS2 support

Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
Steve French 2006-10-12 03:28:28 +00:00
parent ddae957da4
commit acf1a1b104
3 changed files with 23 additions and 4 deletions

View file

@ -119,6 +119,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_ALL_INFO * findData, FILE_ALL_INFO * findData,
int legacy /* whether to use old info level */,
const struct nls_table *nls_codepage, int remap); const struct nls_table *nls_codepage, int remap);
extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,

View file

@ -2969,6 +2969,7 @@ int
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
const unsigned char *searchName, const unsigned char *searchName,
FILE_ALL_INFO * pFindData, FILE_ALL_INFO * pFindData,
int legacy /* old style infolevel */,
const struct nls_table *nls_codepage, int remap) const struct nls_table *nls_codepage, int remap)
{ {
/* level 263 SMB_QUERY_FILE_ALL_INFO */ /* level 263 SMB_QUERY_FILE_ALL_INFO */
@ -3017,7 +3018,10 @@ QPathInfoRetry:
byte_count = params + 1 /* pad */ ; byte_count = params + 1 /* pad */ ;
pSMB->TotalParameterCount = cpu_to_le16(params); pSMB->TotalParameterCount = cpu_to_le16(params);
pSMB->ParameterCount = pSMB->TotalParameterCount; pSMB->ParameterCount = pSMB->TotalParameterCount;
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO); if(legacy)
pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
else
pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
pSMB->Reserved4 = 0; pSMB->Reserved4 = 0;
pSMB->hdr.smb_buf_length += byte_count; pSMB->hdr.smb_buf_length += byte_count;
pSMB->ByteCount = cpu_to_le16(byte_count); pSMB->ByteCount = cpu_to_le16(byte_count);
@ -3029,13 +3033,24 @@ QPathInfoRetry:
} else { /* decode response */ } else { /* decode response */
rc = validate_t2((struct smb_t2_rsp *)pSMBr); rc = validate_t2((struct smb_t2_rsp *)pSMBr);
if (rc || (pSMBr->ByteCount < 40)) if (rc) /* BB add auto retry on EOPNOTSUPP? */
rc = -EIO;
else if (!legacy && (pSMBr->ByteCount < 40))
rc = -EIO; /* bad smb */ rc = -EIO; /* bad smb */
else if(legacy && (pSMBr->ByteCount < 24))
rc = -EIO; /* 24 or 26 expected but we do not read last field */
else if (pFindData){ else if (pFindData){
int size;
__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset); __u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
if(legacy) /* we do not read the last field, EAsize, fortunately
since it varies by subdialect and on Set vs. Get, is
two bytes or 4 bytes depending but we don't care here */
size = sizeof(FILE_INFO_STANDARD);
else
size = sizeof(FILE_ALL_INFO);
memcpy((char *) pFindData, memcpy((char *) pFindData,
(char *) &pSMBr->hdr.Protocol + (char *) &pSMBr->hdr.Protocol +
data_offset, sizeof (FILE_ALL_INFO)); data_offset, size);
} else } else
rc = -ENOMEM; rc = -ENOMEM;
} }

View file

@ -338,6 +338,7 @@ int cifs_get_inode_info(struct inode **pinode,
pfindData = (FILE_ALL_INFO *)buf; pfindData = (FILE_ALL_INFO *)buf;
/* could do find first instead but this returns more info */ /* could do find first instead but this returns more info */
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
0 /* not legacy */,
cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
CIFS_MOUNT_MAP_SPECIAL_CHR); CIFS_MOUNT_MAP_SPECIAL_CHR);
/* BB optimize code so we do not make the above call /* BB optimize code so we do not make the above call
@ -385,8 +386,10 @@ int cifs_get_inode_info(struct inode **pinode,
/* get new inode */ /* get new inode */
if (*pinode == NULL) { if (*pinode == NULL) {
*pinode = new_inode(sb); *pinode = new_inode(sb);
if (*pinode == NULL) if (*pinode == NULL) {
kfree(buf);
return -ENOMEM; return -ENOMEM;
}
/* Is an i_ino of zero legal? Can we use that to check /* Is an i_ino of zero legal? Can we use that to check
if the server supports returning inode numbers? Are if the server supports returning inode numbers? Are
there other sanity checks we can use to ensure that there other sanity checks we can use to ensure that