Commit 6b8edfe0 authored by Steve French's avatar Steve French
Browse files

[CIFS] Support for mounting to older servers part 2. Add support for


legacy getattr (lookup).

Signed-off-by: default avatarSteve French <(sfrench@us.ibm.com)>
parent a10faeb2
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
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
+17 −0
Original line number Diff line number Diff line
@@ -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;
+4 −0
Original line number Diff line number Diff line
@@ -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,
+59 −0
Original line number Diff line number Diff line
@@ -2200,6 +2200,65 @@ CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,

#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,
+3 −2
Original line number Diff line number Diff line
@@ -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;
Loading