aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2005-08-23 23:26:03 -0400
committerSteve French <sfrench@us.ibm.com>2005-08-23 23:26:03 -0400
commit6b8edfe0f918e7585acb3bd63f62ff56e32dd3d2 (patch)
treeea9c6c9c85b0653aeac1abad87ad160114de28af
parenta10faeb2a3e266385cc334fe9af76e08e5e4330f (diff)
[CIFS] Support for mounting to older servers part 2. Add support for
legacy getattr (lookup). Signed-off-by: Steve French (sfrench@us.ibm.com)
-rw-r--r--fs/cifs/CHANGES2
-rw-r--r--fs/cifs/cifspdu.h17
-rw-r--r--fs/cifs/cifsproto.h4
-rw-r--r--fs/cifs/cifssmb.c59
-rw-r--r--fs/cifs/connect.c5
-rw-r--r--fs/cifs/inode.c12
6 files changed, 96 insertions, 3 deletions
diff --git a/fs/cifs/CHANGES b/fs/cifs/CHANGES
index 2137002aecc4..299ed312cea5 100644
--- a/fs/cifs/CHANGES
+++ b/fs/cifs/CHANGES
@@ -1,6 +1,8 @@
1Version 1.36 1Version 1.36
2------------ 2------------
3Add support for moounting to older pre-CIFS servers such as Windows9x and ME. 3Add support for moounting to older pre-CIFS servers such as Windows9x and ME.
4For these older servers, add option for passing netbios name of server in
5on mount (servernetbiosname).
4Add mount option for disabling the default behavior of sending byte range lock 6Add mount option for disabling the default behavior of sending byte range lock
5requests to the server (necessary for certain applications which break with 7requests to the server (necessary for certain applications which break with
6mandatory lock behavior such as Evolution), and also mount option for 8mandatory lock behavior such as Evolution), and also mount option for
diff --git a/fs/cifs/cifspdu.h b/fs/cifs/cifspdu.h
index 49cc66825309..42c16cf32284 100644
--- a/fs/cifs/cifspdu.h
+++ b/fs/cifs/cifspdu.h
@@ -36,6 +36,7 @@
36#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */ 36#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */
37#define SMB_COM_DELETE 0x06 /* trivial response */ 37#define SMB_COM_DELETE 0x06 /* trivial response */
38#define SMB_COM_RENAME 0x07 /* trivial response */ 38#define SMB_COM_RENAME 0x07 /* trivial response */
39#define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */
39#define SMB_COM_SETATTR 0x09 /* trivial response */ 40#define SMB_COM_SETATTR 0x09 /* trivial response */
40#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */ 41#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */
41#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/ 42#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/
@@ -885,6 +886,22 @@ typedef struct smb_com_create_directory_rsp {
885 __u16 ByteCount; /* bct = 0 */ 886 __u16 ByteCount; /* bct = 0 */
886} CREATE_DIRECTORY_RSP; 887} CREATE_DIRECTORY_RSP;
887 888
889typedef struct smb_com_query_information_req {
890 struct smb_hdr hdr; /* wct = 0 */
891 __le16 ByteCount; /* 1 + namelen + 1 */
892 __u8 BufferFormat; /* 4 = ASCII */
893 unsigned char FileName[1];
894} QUERY_INFORMATION_REQ;
895
896typedef struct smb_com_query_information_rsp {
897 struct smb_hdr hdr; /* wct = 10 */
898 __le16 attr;
899 __le32 last_write_time;
900 __le32 size;
901 __u16 reserved[5];
902 __le16 ByteCount; /* bcc = 0 */
903} QUERY_INFORMATION_RSP;
904
888typedef struct smb_com_setattr_req { 905typedef struct smb_com_setattr_req {
889 struct smb_hdr hdr; /* wct = 8 */ 906 struct smb_hdr hdr; /* wct = 8 */
890 __le16 attr; 907 __le16 attr;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index b9b13e3fe79d..0cc0612eacb4 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -105,6 +105,10 @@ extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
105 const unsigned char *searchName, 105 const unsigned char *searchName,
106 FILE_ALL_INFO * findData, 106 FILE_ALL_INFO * findData,
107 const struct nls_table *nls_codepage, int remap); 107 const struct nls_table *nls_codepage, int remap);
108extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
109 const unsigned char *searchName,
110 FILE_ALL_INFO * findData,
111 const struct nls_table *nls_codepage, int remap);
108 112
109extern int CIFSSMBUnixQPathInfo(const int xid, 113extern int CIFSSMBUnixQPathInfo(const int xid,
110 struct cifsTconInfo *tcon, 114 struct cifsTconInfo *tcon,
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index 1292db50fe65..811ab3dffafa 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -2200,6 +2200,65 @@ GetExtAttrOut:
2200 2200
2201#endif /* CONFIG_POSIX */ 2201#endif /* CONFIG_POSIX */
2202 2202
2203/* Legacy Query Path Information call for lookup to old servers such
2204 as Win9x/WinME */
2205int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
2206 const unsigned char *searchName,
2207 FILE_ALL_INFO * pFinfo,
2208 const struct nls_table *nls_codepage, int remap)
2209{
2210 QUERY_INFORMATION_REQ * pSMB;
2211 QUERY_INFORMATION_RSP * pSMBr;
2212 int rc = 0;
2213 int bytes_returned;
2214 int name_len;
2215
2216 cFYI(1, ("In SMBQPath path %s", searchName));
2217QInfRetry:
2218 rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
2219 (void **) &pSMBr);
2220 if (rc)
2221 return rc;
2222
2223 if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
2224 name_len =
2225 cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
2226 PATH_MAX, nls_codepage, remap);
2227 name_len++; /* trailing null */
2228 name_len *= 2;
2229 } else {
2230 name_len = strnlen(searchName, PATH_MAX);
2231 name_len++; /* trailing null */
2232 strncpy(pSMB->FileName, searchName, name_len);
2233 }
2234 pSMB->BufferFormat = 0x04;
2235 name_len++; /* account for buffer type byte */
2236 pSMB->hdr.smb_buf_length += (__u16) name_len;
2237 pSMB->ByteCount = cpu_to_le16(name_len);
2238
2239 rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
2240 (struct smb_hdr *) pSMBr, &bytes_returned, 0);
2241 if (rc) {
2242 cFYI(1, ("Send error in QueryInfo = %d", rc));
2243 } else if (pFinfo) { /* decode response */
2244 memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
2245 pFinfo->AllocationSize = (__le64) pSMBr->size;
2246 pFinfo->EndOfFile = (__le64) pSMBr->size;
2247 pFinfo->Attributes = (__le32) pSMBr->attr;
2248 } else
2249 rc = -EIO; /* bad buffer passed in */
2250
2251 cifs_buf_release(pSMB);
2252
2253 if (rc == -EAGAIN)
2254 goto QInfRetry;
2255
2256 return rc;
2257}
2258
2259
2260
2261
2203int 2262int
2204CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon, 2263CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
2205 const unsigned char *searchName, 2264 const unsigned char *searchName,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 9d61844e89b6..c75bae1242dc 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1730,8 +1730,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1730 else 1730 else
1731 cifs_sb->wsize = CIFSMaxBufSize; /* default */ 1731 cifs_sb->wsize = CIFSMaxBufSize; /* default */
1732 if(cifs_sb->rsize < PAGE_CACHE_SIZE) { 1732 if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
1733 cifs_sb->rsize = PAGE_CACHE_SIZE; 1733 cifs_sb->rsize = PAGE_CACHE_SIZE;
1734 cERROR(1,("Attempt to set readsize for mount to less than one page (4096)")); 1734 /* Windows ME does this */
1735 cFYI(1,("Attempt to set readsize for mount to less than one page (4096)"));
1735 } 1736 }
1736 cifs_sb->mnt_uid = volume_info.linux_uid; 1737 cifs_sb->mnt_uid = volume_info.linux_uid;
1737 cifs_sb->mnt_gid = volume_info.linux_gid; 1738 cifs_sb->mnt_gid = volume_info.linux_gid;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index 2d50b3507d13..34f0168c4041 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -215,8 +215,18 @@ int cifs_get_inode_info(struct inode **pinode,
215 pfindData = (FILE_ALL_INFO *)buf; 215 pfindData = (FILE_ALL_INFO *)buf;
216 /* could do find first instead but this returns more info */ 216 /* could do find first instead but this returns more info */
217 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData, 217 rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
218 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & 218 cifs_sb->local_nls, cifs_sb->mnt_cifs_flags &
219 CIFS_MOUNT_MAP_SPECIAL_CHR); 219 CIFS_MOUNT_MAP_SPECIAL_CHR);
220 /* BB optimize code so we do not make the above call
221 when server claims no NT SMB support and the above call
222 failed at least once - set flag in tcon or mount */
223 if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
224 rc = SMBQueryInformation(xid, pTcon, search_path,
225 pfindData, cifs_sb->local_nls,
226 cifs_sb->mnt_cifs_flags &
227 CIFS_MOUNT_MAP_SPECIAL_CHR);
228 }
229
220 } 230 }
221 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */ 231 /* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
222 if (rc) { 232 if (rc) {