From 40136f392fe0e277db3846a513b71609b183f263 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 12 Oct 2006 03:28:28 +0000 Subject: [PATCH] --- yaml --- r: 39535 b: refs/heads/master c: acf1a1b1043327b2179ea529730358e58c7c277e h: refs/heads/master i: 39533: 1fc1cae101445d9506b1322b0aa3df37c36840f4 39531: c3e76580acf17a4592597b02c2d63010f20e7674 39527: 1886cd2a86ea5de2b7217af245d1952de02f0d8a 39519: 5173f1ae1a5a9838f7024e6cabe32056151f1eb4 v: v3 --- [refs] | 2 +- trunk/fs/cifs/cifsproto.h | 1 + trunk/fs/cifs/cifssmb.c | 21 ++++++++++++++++++--- trunk/fs/cifs/inode.c | 5 ++++- 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/[refs] b/[refs] index dfd235752759..3ec7eb3a751f 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: ddae957da48cc381c1472a8909905e1818e4afdd +refs/heads/master: acf1a1b1043327b2179ea529730358e58c7c277e diff --git a/trunk/fs/cifs/cifsproto.h b/trunk/fs/cifs/cifsproto.h index 7dd2f48a4073..4a4fd2dbca63 100644 --- a/trunk/fs/cifs/cifsproto.h +++ b/trunk/fs/cifs/cifsproto.h @@ -119,6 +119,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon, extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, FILE_ALL_INFO * findData, + int legacy /* whether to use old info level */, const struct nls_table *nls_codepage, int remap); extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, diff --git a/trunk/fs/cifs/cifssmb.c b/trunk/fs/cifs/cifssmb.c index 79a01d35a783..6f50f2bc8870 100644 --- a/trunk/fs/cifs/cifssmb.c +++ b/trunk/fs/cifs/cifssmb.c @@ -2969,6 +2969,7 @@ int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, const unsigned char *searchName, FILE_ALL_INFO * pFindData, + int legacy /* old style infolevel */, const struct nls_table *nls_codepage, int remap) { /* level 263 SMB_QUERY_FILE_ALL_INFO */ @@ -3017,7 +3018,10 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, byte_count = params + 1 /* pad */ ; pSMB->TotalParameterCount = cpu_to_le16(params); 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->hdr.smb_buf_length += byte_count; pSMB->ByteCount = cpu_to_le16(byte_count); @@ -3029,13 +3033,24 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, } else { /* decode response */ 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 */ + else if(legacy && (pSMBr->ByteCount < 24)) + rc = -EIO; /* 24 or 26 expected but we do not read last field */ else if (pFindData){ + int size; __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, (char *) &pSMBr->hdr.Protocol + - data_offset, sizeof (FILE_ALL_INFO)); + data_offset, size); } else rc = -ENOMEM; } diff --git a/trunk/fs/cifs/inode.c b/trunk/fs/cifs/inode.c index 06dbce3a1815..fe6d21f99964 100644 --- a/trunk/fs/cifs/inode.c +++ b/trunk/fs/cifs/inode.c @@ -338,6 +338,7 @@ int cifs_get_inode_info(struct inode **pinode, pfindData = (FILE_ALL_INFO *)buf; /* could do find first instead but this returns more info */ rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, + 0 /* not legacy */, cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); /* 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 */ if (*pinode == NULL) { *pinode = new_inode(sb); - if (*pinode == NULL) + if (*pinode == NULL) { + kfree(buf); return -ENOMEM; + } /* Is an i_ino of zero legal? Can we use that to check if the server supports returning inode numbers? Are there other sanity checks we can use to ensure that