Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit acf1a1b1 authored by Steve French's avatar Steve French
Browse files

[CIFS] Level 1 QPathInfo needed for proper OS2 support



Signed-off-by: default avatarSteve French <sfrench@us.ibm.com>
parent ddae957d
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -119,6 +119,7 @@ extern int CIFSFindClose(const int, struct cifsTconInfo *tcon,
extern int CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
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,
			int legacy /* whether to use old info level */,
			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,
extern int SMBQueryInformation(const int xid, struct cifsTconInfo *tcon,
                        const unsigned char *searchName,
                        const unsigned char *searchName,
+18 −3
Original line number Original line Diff line number Diff line
@@ -2969,6 +2969,7 @@ int
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
		 const unsigned char *searchName,
		 const unsigned char *searchName,
		 FILE_ALL_INFO * pFindData,
		 FILE_ALL_INFO * pFindData,
		 int legacy /* old style infolevel */,
		 const struct nls_table *nls_codepage, int remap)
		 const struct nls_table *nls_codepage, int remap)
{
{
/* level 263 SMB_QUERY_FILE_ALL_INFO */
/* level 263 SMB_QUERY_FILE_ALL_INFO */
@@ -3017,6 +3018,9 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
	byte_count = params + 1 /* pad */ ;
	byte_count = params + 1 /* pad */ ;
	pSMB->TotalParameterCount = cpu_to_le16(params);
	pSMB->TotalParameterCount = cpu_to_le16(params);
	pSMB->ParameterCount = pSMB->TotalParameterCount;
	pSMB->ParameterCount = pSMB->TotalParameterCount;
	if(legacy)
		pSMB->InformationLevel = cpu_to_le16(SMB_INFO_STANDARD);
	else
		pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
		pSMB->InformationLevel = cpu_to_le16(SMB_QUERY_FILE_ALL_INFO);
	pSMB->Reserved4 = 0;
	pSMB->Reserved4 = 0;
	pSMB->hdr.smb_buf_length += byte_count;
	pSMB->hdr.smb_buf_length += byte_count;
@@ -3029,13 +3033,24 @@ CIFSSMBQPathInfo(const int xid, struct cifsTconInfo *tcon,
	} else {		/* decode response */
	} else {		/* decode response */
		rc = validate_t2((struct smb_t2_rsp *)pSMBr);
		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 */
			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){
		else if (pFindData){
			int size;
			__u16 data_offset = le16_to_cpu(pSMBr->t2.DataOffset);
			__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,
			memcpy((char *) pFindData,
			       (char *) &pSMBr->hdr.Protocol +
			       (char *) &pSMBr->hdr.Protocol +
			       data_offset, sizeof (FILE_ALL_INFO));
			       data_offset, size);
		} else
		} else
		    rc = -ENOMEM;
		    rc = -ENOMEM;
	}
	}
+4 −1
Original line number Original line Diff line number Diff line
@@ -338,6 +338,7 @@ 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,
			      0 /* not legacy */,
			      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
		/* 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 */
		/* get new inode */
		if (*pinode == NULL) {
		if (*pinode == NULL) {
			*pinode = new_inode(sb);
			*pinode = new_inode(sb);
			if (*pinode == NULL)
			if (*pinode == NULL) {
				kfree(buf);
				return -ENOMEM;
				return -ENOMEM;
			}
			/* Is an i_ino of zero legal? Can we use that to check
			/* Is an i_ino of zero legal? Can we use that to check
			   if the server supports returning inode numbers?  Are
			   if the server supports returning inode numbers?  Are
			   there other sanity checks we can use to ensure that
			   there other sanity checks we can use to ensure that