CIFS: Add readdir support for SMB2
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / fs / cifs / smb2misc.c
index a4ff5d547554d174466bc48eb7c8fccb48c8f668..78225f517a60a6447235ae375b98e39fdb662100 100644 (file)
@@ -52,7 +52,8 @@ check_smb2_hdr(struct smb2_hdr *hdr, __u64 mid)
                        cERROR(1, "Bad protocol string signature header %x",
                                  *(unsigned int *) hdr->ProtocolId);
                if (mid != hdr->MessageId)
-                       cERROR(1, "Mids do not match");
+                       cERROR(1, "Mids do not match: %llu and %llu", mid,
+                                 hdr->MessageId);
        }
        cERROR(1, "Bad SMB detected. The Mid=%llu", hdr->MessageId);
        return 1;
@@ -107,7 +108,7 @@ smb2_check_message(char *buf, unsigned int length)
         * ie Validate the wct via smb2_struct_sizes table above
         */
 
-       if (length < 2 + sizeof(struct smb2_hdr)) {
+       if (length < sizeof(struct smb2_pdu)) {
                if ((length >= sizeof(struct smb2_hdr)) && (hdr->Status != 0)) {
                        pdu->StructureSize2 = 0;
                        /*
@@ -121,15 +122,15 @@ smb2_check_message(char *buf, unsigned int length)
                return 1;
        }
        if (len > CIFSMaxBufSize + MAX_SMB2_HDR_SIZE - 4) {
-               cERROR(1, "SMB length greater than maximum, mid=%lld", mid);
+               cERROR(1, "SMB length greater than maximum, mid=%llu", mid);
                return 1;
        }
 
        if (check_smb2_hdr(hdr, mid))
                return 1;
 
-       if (hdr->StructureSize != SMB2_HEADER_SIZE) {
-               cERROR(1, "Illegal structure size %d",
+       if (hdr->StructureSize != SMB2_HEADER_STRUCTURE_SIZE) {
+               cERROR(1, "Illegal structure size %u",
                          le16_to_cpu(hdr->StructureSize));
                return 1;
        }
@@ -161,8 +162,9 @@ smb2_check_message(char *buf, unsigned int length)
        if (4 + len != clc_len) {
                cFYI(1, "Calculated size %u length %u mismatch mid %llu",
                        clc_len, 4 + len, mid);
-               if (clc_len == 4 + len + 1) /* BB FIXME (fix samba) */
-                       return 0; /* BB workaround Samba 3 bug SessSetup rsp */
+               /* server can return one byte more */
+               if (clc_len == 4 + len + 1)
+                       return 0;
                return 1;
        }
        return 0;
@@ -242,7 +244,15 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
                    ((struct smb2_query_info_rsp *)hdr)->OutputBufferLength);
                break;
        case SMB2_READ:
+               *off = ((struct smb2_read_rsp *)hdr)->DataOffset;
+               *len = le32_to_cpu(((struct smb2_read_rsp *)hdr)->DataLength);
+               break;
        case SMB2_QUERY_DIRECTORY:
+               *off = le16_to_cpu(
+                 ((struct smb2_query_directory_rsp *)hdr)->OutputBufferOffset);
+               *len = le32_to_cpu(
+                 ((struct smb2_query_directory_rsp *)hdr)->OutputBufferLength);
+               break;
        case SMB2_IOCTL:
        case SMB2_CHANGE_NOTIFY:
        default:
@@ -285,8 +295,9 @@ smb2_get_data_area_len(int *off, int *len, struct smb2_hdr *hdr)
  * portion, the number of word parameters and the data portion of the message.
  */
 unsigned int
-smb2_calc_size(struct smb2_hdr *hdr)
+smb2_calc_size(void *buf)
 {
+       struct smb2_hdr *hdr = (struct smb2_hdr *)buf;
        struct smb2_pdu *pdu = (struct smb2_pdu *)hdr;
        int offset; /* the offset from the beginning of SMB to data area */
        int data_length; /* the length of the variable length data area */