mirror of
https://github.com/adulau/aha.git
synced 2024-12-29 04:06:22 +00:00
[CIFS] Level 1 QPathInfo needed for proper OS2 support
Signed-off-by: Steve French <sfrench@us.ibm.com>
This commit is contained in:
parent
ddae957da4
commit
acf1a1b104
3 changed files with 23 additions and 4 deletions
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue