[CIFS] Support for mounting to older servers part 2. Add support for
legacy getattr (lookup). Signed-off-by: Steve French (sfrench@us.ibm.com)
This commit is contained in:
parent
a10faeb2a3
commit
6b8edfe0f9
|
@ -1,6 +1,8 @@
|
|||
Version 1.36
|
||||
------------
|
||||
Add support for moounting to older pre-CIFS servers such as Windows9x and ME.
|
||||
For these older servers, add option for passing netbios name of server in
|
||||
on mount (servernetbiosname).
|
||||
Add mount option for disabling the default behavior of sending byte range lock
|
||||
requests to the server (necessary for certain applications which break with
|
||||
mandatory lock behavior such as Evolution), and also mount option for
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#define SMB_COM_CLOSE 0x04 /* triv req/rsp, timestamp ignored */
|
||||
#define SMB_COM_DELETE 0x06 /* trivial response */
|
||||
#define SMB_COM_RENAME 0x07 /* trivial response */
|
||||
#define SMB_COM_QUERY_INFORMATION 0x08 /* aka getattr */
|
||||
#define SMB_COM_SETATTR 0x09 /* trivial response */
|
||||
#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */
|
||||
#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/
|
||||
|
@ -885,6 +886,22 @@ typedef struct smb_com_create_directory_rsp {
|
|||
__u16 ByteCount; /* bct = 0 */
|
||||
} CREATE_DIRECTORY_RSP;
|
||||
|
||||
typedef struct smb_com_query_information_req {
|
||||
struct smb_hdr hdr; /* wct = 0 */
|
||||
__le16 ByteCount; /* 1 + namelen + 1 */
|
||||
__u8 BufferFormat; /* 4 = ASCII */
|
||||
unsigned char FileName[1];
|
||||
} QUERY_INFORMATION_REQ;
|
||||
|
||||
typedef struct smb_com_query_information_rsp {
|
||||
struct smb_hdr hdr; /* wct = 10 */
|
||||
__le16 attr;
|
||||
__le32 last_write_time;
|
||||
__le32 size;
|
||||
__u16 reserved[5];
|
||||
__le16 ByteCount; /* bcc = 0 */
|
||||
} QUERY_INFORMATION_RSP;
|
||||
|
||||
typedef struct smb_com_setattr_req {
|
||||
struct smb_hdr hdr; /* wct = 8 */
|
||||
__le16 attr;
|
||||
|
|
|
@ -105,6 +105,10 @@ extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
|||
const unsigned char *searchName,
|
||||
FILE_ALL_INFO * findData,
|
||||
const struct nls_table *nls_codepage, int remap);
|
||||
extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_ALL_INFO * findData,
|
||||
const struct nls_table *nls_codepage, int remap);
|
||||
|
||||
extern int CIFSSMBUnixQPathInfo(const int xid,
|
||||
struct cifsTconInfo *tcon,
|
||||
|
|
|
@ -2200,6 +2200,65 @@ GetExtAttrOut:
|
|||
|
||||
#endif /* CONFIG_POSIX */
|
||||
|
||||
/* Legacy Query Path Information call for lookup to old servers such
|
||||
as Win9x/WinME */
|
||||
int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
|
||||
const unsigned char *searchName,
|
||||
FILE_ALL_INFO * pFinfo,
|
||||
const struct nls_table *nls_codepage, int remap)
|
||||
{
|
||||
QUERY_INFORMATION_REQ * pSMB;
|
||||
QUERY_INFORMATION_RSP * pSMBr;
|
||||
int rc = 0;
|
||||
int bytes_returned;
|
||||
int name_len;
|
||||
|
||||
cFYI(1, ("In SMBQPath path %s", searchName));
|
||||
QInfRetry:
|
||||
rc = smb_init(SMB_COM_QUERY_INFORMATION, 0, tcon, (void **) &pSMB,
|
||||
(void **) &pSMBr);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) {
|
||||
name_len =
|
||||
cifsConvertToUCS((__le16 *) pSMB->FileName, searchName,
|
||||
PATH_MAX, nls_codepage, remap);
|
||||
name_len++; /* trailing null */
|
||||
name_len *= 2;
|
||||
} else {
|
||||
name_len = strnlen(searchName, PATH_MAX);
|
||||
name_len++; /* trailing null */
|
||||
strncpy(pSMB->FileName, searchName, name_len);
|
||||
}
|
||||
pSMB->BufferFormat = 0x04;
|
||||
name_len++; /* account for buffer type byte */
|
||||
pSMB->hdr.smb_buf_length += (__u16) name_len;
|
||||
pSMB->ByteCount = cpu_to_le16(name_len);
|
||||
|
||||
rc = SendReceive(xid, tcon->ses, (struct smb_hdr *) pSMB,
|
||||
(struct smb_hdr *) pSMBr, &bytes_returned, 0);
|
||||
if (rc) {
|
||||
cFYI(1, ("Send error in QueryInfo = %d", rc));
|
||||
} else if (pFinfo) { /* decode response */
|
||||
memset(pFinfo, 0, sizeof(FILE_ALL_INFO));
|
||||
pFinfo->AllocationSize = (__le64) pSMBr->size;
|
||||
pFinfo->EndOfFile = (__le64) pSMBr->size;
|
||||
pFinfo->Attributes = (__le32) pSMBr->attr;
|
||||
} else
|
||||
rc = -EIO; /* bad buffer passed in */
|
||||
|
||||
cifs_buf_release(pSMB);
|
||||
|
||||
if (rc == -EAGAIN)
|
||||
goto QInfRetry;
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||
const unsigned char *searchName,
|
||||
|
|
|
@ -1731,7 +1731,8 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
|
|||
cifs_sb->wsize = CIFSMaxBufSize; /* default */
|
||||
if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
|
||||
cifs_sb->rsize = PAGE_CACHE_SIZE;
|
||||
cERROR(1,("Attempt to set readsize for mount to less than one page (4096)"));
|
||||
/* Windows ME does this */
|
||||
cFYI(1,("Attempt to set readsize for mount to less than one page (4096)"));
|
||||
}
|
||||
cifs_sb->mnt_uid = volume_info.linux_uid;
|
||||
cifs_sb->mnt_gid = volume_info.linux_gid;
|
||||
|
|
|
@ -217,6 +217,16 @@ int cifs_get_inode_info(struct inode **pinode,
|
|||
rc = CIFSSMBQPathInfo(xid, pTcon, search_path, pfindData,
|
||||
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
|
||||
when server claims no NT SMB support and the above call
|
||||
failed at least once - set flag in tcon or mount */
|
||||
if((rc == -EOPNOTSUPP) || (rc == -EINVAL)) {
|
||||
rc = SMBQueryInformation(xid, pTcon, search_path,
|
||||
pfindData, cifs_sb->local_nls,
|
||||
cifs_sb->mnt_cifs_flags &
|
||||
CIFS_MOUNT_MAP_SPECIAL_CHR);
|
||||
}
|
||||
|
||||
}
|
||||
/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
|
||||
if (rc) {
|
||||
|
|
Loading…
Reference in New Issue