cifs: change smb2_get_data_area_len to take a smb2_sync_hdr as argument
[linux-2.6-block.git] / fs / cifs / smb2ops.c
index b76b85881dcc668e87f99ee55b6bb4463f25510e..20cc67c3a6d009578fc8374cda7d8d1a78a564e6 100644 (file)
@@ -212,7 +212,7 @@ smb2_find_mid(struct TCP_Server_Info *server, char *buf)
 }
 
 static void
-smb2_dump_detail(void *buf)
+smb2_dump_detail(void *buf, struct TCP_Server_Info *server)
 {
 #ifdef CONFIG_CIFS_DEBUG2
        struct smb2_sync_hdr *shdr = get_sync_hdr(buf);
@@ -220,7 +220,8 @@ smb2_dump_detail(void *buf)
        cifs_dbg(VFS, "Cmd: %d Err: 0x%x Flags: 0x%x Mid: %llu Pid: %d\n",
                 shdr->Command, shdr->Status, shdr->Flags, shdr->MessageId,
                 shdr->ProcessId);
-       cifs_dbg(VFS, "smb buf %p len %u\n", buf, smb2_calc_size(buf));
+       cifs_dbg(VFS, "smb buf %p len %u\n", buf,
+                server->ops->calc_smb_size(buf, server));
 #endif
 }
 
@@ -322,6 +323,40 @@ SMB3_request_interfaces(const unsigned int xid, struct cifs_tcon *tcon)
 }
 #endif /* STATS2 */
 
+/*
+ * Open the directory at the root of a share
+ */
+int open_shroot(unsigned int xid, struct cifs_tcon *tcon, struct cifs_fid *pfid)
+{
+       struct cifs_open_parms oparams;
+       int rc;
+       __le16 srch_path = 0; /* Null - since an open of top of share */
+       u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
+
+       mutex_lock(&tcon->prfid_mutex);
+       if (tcon->valid_root_fid) {
+               cifs_dbg(FYI, "found a cached root file handle\n");
+               memcpy(pfid, tcon->prfid, sizeof(struct cifs_fid));
+               mutex_unlock(&tcon->prfid_mutex);
+               return 0;
+       }
+
+       oparams.tcon = tcon;
+       oparams.create_options = 0;
+       oparams.desired_access = FILE_READ_ATTRIBUTES;
+       oparams.disposition = FILE_OPEN;
+       oparams.fid = pfid;
+       oparams.reconnect = false;
+
+       rc = SMB2_open(xid, &oparams, &srch_path, &oplock, NULL, NULL);
+       if (rc == 0) {
+               memcpy(tcon->prfid, pfid, sizeof(struct cifs_fid));
+               tcon->valid_root_fid = true;
+       }
+       mutex_unlock(&tcon->prfid_mutex);
+       return rc;
+}
+
 static void
 smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
 {
@@ -330,6 +365,7 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
        u8 oplock = SMB2_OPLOCK_LEVEL_NONE;
        struct cifs_open_parms oparms;
        struct cifs_fid fid;
+       bool no_cached_open = tcon->nohandlecache;
 
        oparms.tcon = tcon;
        oparms.desired_access = FILE_READ_ATTRIBUTES;
@@ -338,7 +374,11 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
        oparms.fid = &fid;
        oparms.reconnect = false;
 
-       rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
+       if (no_cached_open)
+               rc = SMB2_open(xid, &oparms, &srch_path, &oplock, NULL, NULL);
+       else
+               rc = open_shroot(xid, tcon, &fid);
+
        if (rc)
                return;
 
@@ -352,7 +392,8 @@ smb3_qfs_tcon(const unsigned int xid, struct cifs_tcon *tcon)
                        FS_DEVICE_INFORMATION);
        SMB2_QFS_attr(xid, tcon, fid.persistent_fid, fid.volatile_fid,
                        FS_SECTOR_SIZE_INFORMATION); /* SMB3 specific */
-       SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
+       if (no_cached_open)
+               SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
        return;
 }
 
@@ -394,6 +435,9 @@ smb2_is_path_accessible(const unsigned int xid, struct cifs_tcon *tcon,
        struct cifs_open_parms oparms;
        struct cifs_fid fid;
 
+       if ((*full_path == 0) && tcon->valid_root_fid)
+               return 0;
+
        utf16_path = cifs_convert_path_to_utf16(full_path, cifs_sb);
        if (!utf16_path)
                return -ENOMEM;
@@ -589,9 +633,15 @@ smb2_query_eas(const unsigned int xid, struct cifs_tcon *tcon,
 
        SMB2_close(xid, tcon, fid.persistent_fid, fid.volatile_fid);
 
+       /*
+        * If ea_name is NULL (listxattr) and there are no EAs, return 0 as it's
+        * not an error. Otherwise, the specified ea_name was not found.
+        */
        if (!rc)
                rc = move_smb2_ea_to_cifs(ea_data, buf_size, smb2_data,
                                          SMB2_MAX_EA_BUF, ea_name);
+       else if (!ea_name && rc == -ENODATA)
+               rc = 0;
 
        kfree(smb2_data);
        return rc;
@@ -698,9 +748,11 @@ smb2_dump_share_caps(struct seq_file *m, struct cifs_tcon *tcon)
                seq_puts(m, " TRIM-support,");
 
        seq_printf(m, "\tShare Flags: 0x%x", tcon->share_flags);
+       seq_printf(m, "\n\ttid: 0x%x", tcon->tid);
        if (tcon->perf_sector_size)
                seq_printf(m, "\tOptimal sector size: 0x%x",
                           tcon->perf_sector_size);
+       seq_printf(m, "\tMaximal Access: 0x%x", tcon->maximal_access);
 }
 
 static void
@@ -1587,8 +1639,11 @@ get_smb2_acl_by_path(struct cifs_sb_info *cifs_sb,
                oparms.create_options = 0;
 
        utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
-       if (!utf16_path)
-               return ERR_PTR(-ENOMEM);
+       if (!utf16_path) {
+               rc = -ENOMEM;
+               free_xid(xid);
+               return ERR_PTR(rc);
+       }
 
        oparms.tcon = tcon;
        oparms.desired_access = READ_CONTROL;
@@ -1646,8 +1701,11 @@ set_smb2_acl(struct cifs_ntsd *pnntsd, __u32 acllen,
                access_flags = WRITE_DAC;
 
        utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
-       if (!utf16_path)
-               return -ENOMEM;
+       if (!utf16_path) {
+               rc = -ENOMEM;
+               free_xid(xid);
+               return rc;
+       }
 
        oparms.tcon = tcon;
        oparms.desired_access = access_flags;
@@ -1707,15 +1765,21 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
 
        /* if file not oplocked can't be sure whether asking to extend size */
        if (!CIFS_CACHE_READ(cifsi))
-               if (keep_size == false)
-                       return -EOPNOTSUPP;
+               if (keep_size == false) {
+                       rc = -EOPNOTSUPP;
+                       free_xid(xid);
+                       return rc;
+               }
 
        /*
         * Must check if file sparse since fallocate -z (zero range) assumes
         * non-sparse allocation
         */
-       if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE))
-               return -EOPNOTSUPP;
+       if (!(cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE)) {
+               rc = -EOPNOTSUPP;
+               free_xid(xid);
+               return rc;
+       }
 
        /*
         * need to make sure we are not asked to extend the file since the SMB3
@@ -1724,8 +1788,11 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
         * which for a non sparse file would zero the newly extended range
         */
        if (keep_size == false)
-               if (i_size_read(inode) < offset + len)
-                       return -EOPNOTSUPP;
+               if (i_size_read(inode) < offset + len) {
+                       rc = -EOPNOTSUPP;
+                       free_xid(xid);
+                       return rc;
+               }
 
        cifs_dbg(FYI, "offset %lld len %lld", offset, len);
 
@@ -1758,8 +1825,11 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
 
        /* Need to make file sparse, if not already, before freeing range. */
        /* Consider adding equivalent for compressed since it could also work */
-       if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse))
-               return -EOPNOTSUPP;
+       if (!smb2_set_sparse(xid, tcon, cfile, inode, set_sparse)) {
+               rc = -EOPNOTSUPP;
+               free_xid(xid);
+               return rc;
+       }
 
        cifs_dbg(FYI, "offset %lld len %lld", offset, len);
 
@@ -1790,8 +1860,10 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
 
        /* if file not oplocked can't be sure whether asking to extend size */
        if (!CIFS_CACHE_READ(cifsi))
-               if (keep_size == false)
-                       return -EOPNOTSUPP;
+               if (keep_size == false) {
+                       free_xid(xid);
+                       return rc;
+               }
 
        /*
         * Files are non-sparse by default so falloc may be a no-op
@@ -1800,14 +1872,16 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
         */
        if ((cifsi->cifsAttrs & FILE_ATTRIBUTE_SPARSE_FILE) == 0) {
                if (keep_size == true)
-                       return 0;
+                       rc = 0;
                /* check if extending file */
                else if (i_size_read(inode) >= off + len)
                        /* not extending file and already not sparse */
-                       return 0;
+                       rc = 0;
                /* BB: in future add else clause to extend file */
                else
-                       return -EOPNOTSUPP;
+                       rc = -EOPNOTSUPP;
+               free_xid(xid);
+               return rc;
        }
 
        if ((keep_size == true) || (i_size_read(inode) >= off + len)) {
@@ -1819,8 +1893,11 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,
                 * ie potentially making a few extra pages at the beginning
                 * or end of the file non-sparse via set_sparse is harmless.
                 */
-               if ((off > 8192) || (off + len + 8192 < i_size_read(inode)))
-                       return -EOPNOTSUPP;
+               if ((off > 8192) || (off + len + 8192 < i_size_read(inode))) {
+                       rc = -EOPNOTSUPP;
+                       free_xid(xid);
+                       return rc;
+               }
 
                rc = smb2_set_sparse(xid, tcon, cfile, inode, false);
        }
@@ -2029,7 +2106,7 @@ smb3_create_lease_buf(u8 *lease_key, u8 oplock)
 }
 
 static __u8
-smb2_parse_lease_buf(void *buf, unsigned int *epoch)
+smb2_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
 {
        struct create_lease *lc = (struct create_lease *)buf;
 
@@ -2040,13 +2117,16 @@ smb2_parse_lease_buf(void *buf, unsigned int *epoch)
 }
 
 static __u8
-smb3_parse_lease_buf(void *buf, unsigned int *epoch)
+smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
 {
        struct create_lease_v2 *lc = (struct create_lease_v2 *)buf;
 
        *epoch = le16_to_cpu(lc->lcontext.Epoch);
        if (lc->lcontext.LeaseFlags & SMB2_LEASE_FLAG_BREAK_IN_PROGRESS)
                return SMB2_OPLOCK_LEVEL_NOCHANGE;
+       if (lease_key)
+               memcpy(lease_key, &lc->lcontext.LeaseKeyLow,
+                      SMB2_LEASE_KEY_SIZE);
        return le32_to_cpu(lc->lcontext.LeaseState);
 }
 
@@ -2064,12 +2144,11 @@ smb2_dir_needs_close(struct cifsFileInfo *cfile)
 }
 
 static void
-fill_transform_hdr(struct TCP_Server_Info *server,
-                  struct smb2_transform_hdr *tr_hdr, struct smb_rqst *old_rq)
+fill_transform_hdr(struct smb2_transform_hdr *tr_hdr, unsigned int orig_len,
+                  struct smb_rqst *old_rq)
 {
        struct smb2_sync_hdr *shdr =
                        (struct smb2_sync_hdr *)old_rq->rq_iov[1].iov_base;
-       unsigned int orig_len = get_rfc1002_length(old_rq->rq_iov[0].iov_base);
 
        memset(tr_hdr, 0, sizeof(struct smb2_transform_hdr));
        tr_hdr->ProtocolId = SMB2_TRANSFORM_PROTO_NUM;
@@ -2077,8 +2156,6 @@ fill_transform_hdr(struct TCP_Server_Info *server,
        tr_hdr->Flags = cpu_to_le16(0x01);
        get_random_bytes(&tr_hdr->Nonce, SMB3_AES128CMM_NONCE);
        memcpy(&tr_hdr->SessionId, &shdr->SessionId, 8);
-       inc_rfc1001_len(tr_hdr, sizeof(struct smb2_transform_hdr) - server->vals->header_preamble_size);
-       inc_rfc1001_len(tr_hdr, orig_len);
 }
 
 /* We can not use the normal sg_set_buf() as we will sometimes pass a
@@ -2090,11 +2167,16 @@ static inline void smb2_sg_set_buf(struct scatterlist *sg, const void *buf,
        sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf));
 }
 
+/* Assumes:
+ * rqst->rq_iov[0]  is rfc1002 length
+ * rqst->rq_iov[1]  is tranform header
+ * rqst->rq_iov[2+] data to be encrypted/decrypted
+ */
 static struct scatterlist *
 init_sg(struct smb_rqst *rqst, u8 *sign)
 {
-       unsigned int sg_len = rqst->rq_nvec + rqst->rq_npages + 1;
-       unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 24;
+       unsigned int sg_len = rqst->rq_nvec + rqst->rq_npages;
+       unsigned int assoc_data_len = sizeof(struct smb2_transform_hdr) - 20;
        struct scatterlist *sg;
        unsigned int i;
        unsigned int j;
@@ -2104,10 +2186,10 @@ init_sg(struct smb_rqst *rqst, u8 *sign)
                return NULL;
 
        sg_init_table(sg, sg_len);
-       smb2_sg_set_buf(&sg[0], rqst->rq_iov[0].iov_base + 24, assoc_data_len);
-       for (i = 1; i < rqst->rq_nvec; i++)
-               smb2_sg_set_buf(&sg[i], rqst->rq_iov[i].iov_base,
-                                               rqst->rq_iov[i].iov_len);
+       smb2_sg_set_buf(&sg[0], rqst->rq_iov[1].iov_base + 20, assoc_data_len);
+       for (i = 1; i < rqst->rq_nvec - 1; i++)
+               smb2_sg_set_buf(&sg[i], rqst->rq_iov[i+1].iov_base,
+                                               rqst->rq_iov[i+1].iov_len);
        for (j = 0; i < sg_len - 1; i++, j++) {
                unsigned int len = (j < rqst->rq_npages - 1) ? rqst->rq_pagesz
                                                        : rqst->rq_tailsz;
@@ -2139,9 +2221,10 @@ smb2_get_enc_key(struct TCP_Server_Info *server, __u64 ses_id, int enc, u8 *key)
 }
 /*
  * Encrypt or decrypt @rqst message. @rqst has the following format:
- * iov[0] - transform header (associate data),
- * iov[1-N] and pages - data to encrypt.
- * On success return encrypted data in iov[1-N] and pages, leave iov[0]
+ * iov[0] - rfc1002 length
+ * iov[1] - transform header (associate data),
+ * iov[2-N] and pages - data to encrypt.
+ * On success return encrypted data in iov[2-N] and pages, leave iov[0-1]
  * untouched.
  */
 static int
@@ -2236,6 +2319,10 @@ free_req:
        return rc;
 }
 
+/*
+ * This is called from smb_send_rqst. At this point we have the rfc1002
+ * header as the first element in the vector.
+ */
 static int
 smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq,
                       struct smb_rqst *old_rq)
@@ -2244,6 +2331,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq,
        struct page **pages;
        struct smb2_transform_hdr *tr_hdr;
        unsigned int npages = old_rq->rq_npages;
+       unsigned int orig_len = get_rfc1002_length(old_rq->rq_iov[0].iov_base);
        int i;
        int rc = -ENOMEM;
 
@@ -2262,24 +2350,34 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, struct smb_rqst *new_rq,
                        goto err_free_pages;
        }
 
-       iov = kmalloc_array(old_rq->rq_nvec, sizeof(struct kvec), GFP_KERNEL);
+       /* Make space for one extra iov to hold the transform header */
+       iov = kmalloc_array(old_rq->rq_nvec + 1, sizeof(struct kvec),
+                           GFP_KERNEL);
        if (!iov)
                goto err_free_pages;
 
        /* copy all iovs from the old except the 1st one (rfc1002 length) */
-       memcpy(&iov[1], &old_rq->rq_iov[1],
+       memcpy(&iov[2], &old_rq->rq_iov[1],
                                sizeof(struct kvec) * (old_rq->rq_nvec - 1));
+       /* copy the rfc1002 iov */
+       iov[0].iov_base = old_rq->rq_iov[0].iov_base;
+       iov[0].iov_len  = old_rq->rq_iov[0].iov_len;
+
        new_rq->rq_iov = iov;
-       new_rq->rq_nvec = old_rq->rq_nvec;
+       new_rq->rq_nvec = old_rq->rq_nvec + 1;
 
        tr_hdr = kmalloc(sizeof(struct smb2_transform_hdr), GFP_KERNEL);
        if (!tr_hdr)
                goto err_free_iov;
 
-       /* fill the 1st iov with a transform header */
-       fill_transform_hdr(server, tr_hdr, old_rq);
-       new_rq->rq_iov[0].iov_base = tr_hdr;
-       new_rq->rq_iov[0].iov_len = sizeof(struct smb2_transform_hdr);
+       /* fill the 2nd iov with a transform header */
+       fill_transform_hdr(tr_hdr, orig_len, old_rq);
+       new_rq->rq_iov[1].iov_base = tr_hdr;
+       new_rq->rq_iov[1].iov_len = sizeof(struct smb2_transform_hdr);
+
+       /* Update rfc1002 header */
+       inc_rfc1001_len(new_rq->rq_iov[0].iov_base,
+                       sizeof(struct smb2_transform_hdr));
 
        /* copy pages form the old */
        for (i = 0; i < npages; i++) {
@@ -2319,7 +2417,7 @@ smb3_free_transform_rq(struct smb_rqst *rqst)
                put_page(rqst->rq_pages[i]);
        kfree(rqst->rq_pages);
        /* free transform header */
-       kfree(rqst->rq_iov[0].iov_base);
+       kfree(rqst->rq_iov[1].iov_base);
        kfree(rqst->rq_iov);
 }
 
@@ -2336,18 +2434,19 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
                 unsigned int buf_data_size, struct page **pages,
                 unsigned int npages, unsigned int page_data_size)
 {
-       struct kvec iov[2];
+       struct kvec iov[3];
        struct smb_rqst rqst = {NULL};
-       struct smb2_hdr *hdr;
        int rc;
 
-       iov[0].iov_base = buf;
-       iov[0].iov_len = sizeof(struct smb2_transform_hdr);
-       iov[1].iov_base = buf + sizeof(struct smb2_transform_hdr);
-       iov[1].iov_len = buf_data_size;
+       iov[0].iov_base = NULL;
+       iov[0].iov_len = 0;
+       iov[1].iov_base = buf;
+       iov[1].iov_len = sizeof(struct smb2_transform_hdr);
+       iov[2].iov_base = buf + sizeof(struct smb2_transform_hdr);
+       iov[2].iov_len = buf_data_size;
 
        rqst.rq_iov = iov;
-       rqst.rq_nvec = 2;
+       rqst.rq_nvec = 3;
        rqst.rq_pages = pages;
        rqst.rq_npages = npages;
        rqst.rq_pagesz = PAGE_SIZE;
@@ -2359,10 +2458,9 @@ decrypt_raw_data(struct TCP_Server_Info *server, char *buf,
        if (rc)
                return rc;
 
-       memmove(buf + server->vals->header_preamble_size, iov[1].iov_base, buf_data_size);
-       hdr = (struct smb2_hdr *)buf;
-       hdr->smb2_buf_length = cpu_to_be32(buf_data_size + page_data_size);
-       server->total_read = buf_data_size + page_data_size + server->vals->header_preamble_size;
+       memmove(buf + server->vals->header_preamble_size, iov[2].iov_base, buf_data_size);
+
+       server->total_read = buf_data_size + page_data_size;
 
        return rc;
 }
@@ -3116,8 +3214,8 @@ struct smb_version_values smb20_values = {
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
-       .header_size = sizeof(struct smb2_hdr),
-       .header_preamble_size = 4,
+       .header_size = sizeof(struct smb2_sync_hdr),
+       .header_preamble_size = 0,
        .max_header_size = MAX_SMB2_HDR_SIZE,
        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
        .lock_cmd = SMB2_LOCK,
@@ -3137,8 +3235,8 @@ struct smb_version_values smb21_values = {
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
-       .header_size = sizeof(struct smb2_hdr),
-       .header_preamble_size = 4,
+       .header_size = sizeof(struct smb2_sync_hdr),
+       .header_preamble_size = 0,
        .max_header_size = MAX_SMB2_HDR_SIZE,
        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
        .lock_cmd = SMB2_LOCK,
@@ -3158,8 +3256,8 @@ struct smb_version_values smb3any_values = {
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
-       .header_size = sizeof(struct smb2_hdr),
-       .header_preamble_size = 4,
+       .header_size = sizeof(struct smb2_sync_hdr),
+       .header_preamble_size = 0,
        .max_header_size = MAX_SMB2_HDR_SIZE,
        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
        .lock_cmd = SMB2_LOCK,
@@ -3179,8 +3277,8 @@ struct smb_version_values smbdefault_values = {
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
-       .header_size = sizeof(struct smb2_hdr),
-       .header_preamble_size = 4,
+       .header_size = sizeof(struct smb2_sync_hdr),
+       .header_preamble_size = 0,
        .max_header_size = MAX_SMB2_HDR_SIZE,
        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
        .lock_cmd = SMB2_LOCK,
@@ -3200,8 +3298,8 @@ struct smb_version_values smb30_values = {
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
-       .header_size = sizeof(struct smb2_hdr),
-       .header_preamble_size = 4,
+       .header_size = sizeof(struct smb2_sync_hdr),
+       .header_preamble_size = 0,
        .max_header_size = MAX_SMB2_HDR_SIZE,
        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
        .lock_cmd = SMB2_LOCK,
@@ -3221,8 +3319,8 @@ struct smb_version_values smb302_values = {
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
-       .header_size = sizeof(struct smb2_hdr),
-       .header_preamble_size = 4,
+       .header_size = sizeof(struct smb2_sync_hdr),
+       .header_preamble_size = 0,
        .max_header_size = MAX_SMB2_HDR_SIZE,
        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
        .lock_cmd = SMB2_LOCK,
@@ -3243,8 +3341,8 @@ struct smb_version_values smb311_values = {
        .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE_LOCK,
        .shared_lock_type = SMB2_LOCKFLAG_SHARED_LOCK,
        .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
-       .header_size = sizeof(struct smb2_hdr),
-       .header_preamble_size = 4,
+       .header_size = sizeof(struct smb2_sync_hdr),
+       .header_preamble_size = 0,
        .max_header_size = MAX_SMB2_HDR_SIZE,
        .read_rsp_size = sizeof(struct smb2_read_rsp) - 1,
        .lock_cmd = SMB2_LOCK,