[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
|
Version 1.36
|
||||||
------------
|
------------
|
||||||
Add support for moounting to older pre-CIFS servers such as Windows9x and ME.
|
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
|
Add mount option for disabling the default behavior of sending byte range lock
|
||||||
requests to the server (necessary for certain applications which break with
|
requests to the server (necessary for certain applications which break with
|
||||||
mandatory lock behavior such as Evolution), and also mount option for
|
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_CLOSE 0x04 /* triv req/rsp, timestamp ignored */
|
||||||
#define SMB_COM_DELETE 0x06 /* trivial response */
|
#define SMB_COM_DELETE 0x06 /* trivial response */
|
||||||
#define SMB_COM_RENAME 0x07 /* 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_SETATTR 0x09 /* trivial response */
|
||||||
#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */
|
#define SMB_COM_LOCKING_ANDX 0x24 /* trivial response */
|
||||||
#define SMB_COM_COPY 0x29 /* trivial rsp, fail filename ignrd*/
|
#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 */
|
__u16 ByteCount; /* bct = 0 */
|
||||||
} CREATE_DIRECTORY_RSP;
|
} 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 {
|
typedef struct smb_com_setattr_req {
|
||||||
struct smb_hdr hdr; /* wct = 8 */
|
struct smb_hdr hdr; /* wct = 8 */
|
||||||
__le16 attr;
|
__le16 attr;
|
||||||
|
|
|
@ -105,6 +105,10 @@ 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,
|
||||||
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,
|
||||||
|
const unsigned char *searchName,
|
||||||
|
FILE_ALL_INFO * findData,
|
||||||
|
const struct nls_table *nls_codepage, int remap);
|
||||||
|
|
||||||
extern int CIFSSMBUnixQPathInfo(const int xid,
|
extern int CIFSSMBUnixQPathInfo(const int xid,
|
||||||
struct cifsTconInfo *tcon,
|
struct cifsTconInfo *tcon,
|
||||||
|
|
|
@ -2200,6 +2200,65 @@ GetExtAttrOut:
|
||||||
|
|
||||||
#endif /* CONFIG_POSIX */
|
#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
|
int
|
||||||
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
|
||||||
const unsigned char *searchName,
|
const unsigned char *searchName,
|
||||||
|
|
|
@ -1730,8 +1730,9 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
|
||||||
else
|
else
|
||||||
cifs_sb->wsize = CIFSMaxBufSize; /* default */
|
cifs_sb->wsize = CIFSMaxBufSize; /* default */
|
||||||
if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
|
if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
|
||||||
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_uid = volume_info.linux_uid;
|
||||||
cifs_sb->mnt_gid = volume_info.linux_gid;
|
cifs_sb->mnt_gid = volume_info.linux_gid;
|
||||||
|
|
|
@ -215,8 +215,18 @@ 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,
|
||||||
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
|
||||||
|
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)); */
|
/* dump_mem("\nQPathInfo return data",&findData, sizeof(findData)); */
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
|
Loading…
Reference in New Issue