lease->new_state = 0;
        lease->flags = lctx->flags;
        lease->duration = lctx->duration;
+       memcpy(lease->parent_lease_key, lctx->parent_lease_key, SMB2_LEASE_KEY_SIZE);
+       lease->version = lctx->version;
+       lease->epoch = 0;
        INIT_LIST_HEAD(&opinfo->lease_entry);
        opinfo->o_lease = lease;
 
 
        rsp = work->response_buf;
        rsp->StructureSize = cpu_to_le16(44);
-       rsp->Reserved = 0;
+       rsp->Epoch = br_info->epoch;
        rsp->Flags = 0;
 
        if (br_info->curr_state & (SMB2_LEASE_WRITE_CACHING_LE |
 
        br_info->curr_state = lease->state;
        br_info->new_state = lease->new_state;
+       if (lease->version == 2)
+               br_info->epoch = cpu_to_le16(++lease->epoch);
+       else
+               br_info->epoch = 0;
        memcpy(br_info->lease_key, lease->lease_key, SMB2_LEASE_KEY_SIZE);
 
        work->request_buf = (char *)br_info;
        __le32 prev_op_state = 0;
 
        /* not support directory lease */
-       if (S_ISDIR(file_inode(fp->filp)->i_mode)) {
-               if (lctx)
-                       lctx->dlease = 1;
+       if (S_ISDIR(file_inode(fp->filp)->i_mode))
                return 0;
-       }
 
        opinfo = alloc_opinfo(work, pid, tid);
        if (!opinfo)
  */
 void create_lease_buf(u8 *rbuf, struct lease *lease)
 {
-       struct create_lease *buf = (struct create_lease *)rbuf;
        char *LeaseKey = (char *)&lease->lease_key;
 
-       memset(buf, 0, sizeof(struct create_lease));
-       buf->lcontext.LeaseKeyLow = *((__le64 *)LeaseKey);
-       buf->lcontext.LeaseKeyHigh = *((__le64 *)(LeaseKey + 8));
-       buf->lcontext.LeaseFlags = lease->flags;
-       buf->lcontext.LeaseState = lease->state;
-       buf->ccontext.DataOffset = cpu_to_le16(offsetof
-                                       (struct create_lease, lcontext));
-       buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
-       buf->ccontext.NameOffset = cpu_to_le16(offsetof
+       if (lease->version == 2) {
+               struct create_lease_v2 *buf = (struct create_lease_v2 *)rbuf;
+               char *ParentLeaseKey = (char *)&lease->parent_lease_key;
+
+               memset(buf, 0, sizeof(struct create_lease_v2));
+               buf->lcontext.LeaseKeyLow = *((__le64 *)LeaseKey);
+               buf->lcontext.LeaseKeyHigh = *((__le64 *)(LeaseKey + 8));
+               buf->lcontext.LeaseFlags = lease->flags;
+               buf->lcontext.LeaseState = lease->state;
+               buf->lcontext.ParentLeaseKeyLow = *((__le64 *)ParentLeaseKey);
+               buf->lcontext.ParentLeaseKeyHigh = *((__le64 *)(ParentLeaseKey + 8));
+               buf->ccontext.DataOffset = cpu_to_le16(offsetof
+                               (struct create_lease_v2, lcontext));
+               buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context_v2));
+               buf->ccontext.NameOffset = cpu_to_le16(offsetof
+                               (struct create_lease_v2, Name));
+               buf->ccontext.NameLength = cpu_to_le16(4);
+               buf->Name[0] = 'R';
+               buf->Name[1] = 'q';
+               buf->Name[2] = 'L';
+               buf->Name[3] = 's';
+       } else {
+               struct create_lease *buf = (struct create_lease *)rbuf;
+
+               memset(buf, 0, sizeof(struct create_lease));
+               buf->lcontext.LeaseKeyLow = *((__le64 *)LeaseKey);
+               buf->lcontext.LeaseKeyHigh = *((__le64 *)(LeaseKey + 8));
+               buf->lcontext.LeaseFlags = lease->flags;
+               buf->lcontext.LeaseState = lease->state;
+               buf->ccontext.DataOffset = cpu_to_le16(offsetof
+                               (struct create_lease, lcontext));
+               buf->ccontext.DataLength = cpu_to_le32(sizeof(struct lease_context));
+               buf->ccontext.NameOffset = cpu_to_le16(offsetof
                                (struct create_lease, Name));
-       buf->ccontext.NameLength = cpu_to_le16(4);
-       buf->Name[0] = 'R';
-       buf->Name[1] = 'q';
-       buf->Name[2] = 'L';
-       buf->Name[3] = 's';
+               buf->ccontext.NameLength = cpu_to_le16(4);
+               buf->Name[0] = 'R';
+               buf->Name[1] = 'q';
+               buf->Name[2] = 'L';
+               buf->Name[3] = 's';
+       }
 }
 
 /**
        } while (next != 0);
 
        if (found) {
-               struct create_lease *lc = (struct create_lease *)cc;
-               *((__le64 *)lreq->lease_key) = lc->lcontext.LeaseKeyLow;
-               *((__le64 *)(lreq->lease_key + 8)) = lc->lcontext.LeaseKeyHigh;
-               lreq->req_state = lc->lcontext.LeaseState;
-               lreq->flags = lc->lcontext.LeaseFlags;
-               lreq->duration = lc->lcontext.LeaseDuration;
+               if (sizeof(struct lease_context_v2) == le32_to_cpu(cc->DataLength)) {
+                       struct create_lease_v2 *lc = (struct create_lease_v2 *)cc;
+
+                       *((__le64 *)lreq->lease_key) = lc->lcontext.LeaseKeyLow;
+                       *((__le64 *)(lreq->lease_key + 8)) = lc->lcontext.LeaseKeyHigh;
+                       lreq->req_state = lc->lcontext.LeaseState;
+                       lreq->flags = lc->lcontext.LeaseFlags;
+                       lreq->duration = lc->lcontext.LeaseDuration;
+                       *((__le64 *)lreq->parent_lease_key) = lc->lcontext.ParentLeaseKeyLow;
+                       *((__le64 *)(lreq->parent_lease_key + 8)) = lc->lcontext.ParentLeaseKeyHigh;
+                       lreq->version = 2;
+               } else {
+                       struct create_lease *lc = (struct create_lease *)cc;
+
+                       *((__le64 *)lreq->lease_key) = lc->lcontext.LeaseKeyLow;
+                       *((__le64 *)(lreq->lease_key + 8)) = lc->lcontext.LeaseKeyHigh;
+                       lreq->req_state = lc->lcontext.LeaseState;
+                       lreq->flags = lc->lcontext.LeaseFlags;
+                       lreq->duration = lc->lcontext.LeaseDuration;
+                       lreq->version = 1;
+               }
                return lreq;
        }
 
 
        .cap_unix = 0,
        .cap_nt_find = SMB2_NT_FIND,
        .cap_large_files = SMB2_LARGE_FILES,
-       .create_lease_size = sizeof(struct create_lease),
+       .create_lease_size = sizeof(struct create_lease_v2),
        .create_durable_size = sizeof(struct create_durable_rsp),
        .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
        .create_mxac_size = sizeof(struct create_mxac_rsp),
        .cap_unix = 0,
        .cap_nt_find = SMB2_NT_FIND,
        .cap_large_files = SMB2_LARGE_FILES,
-       .create_lease_size = sizeof(struct create_lease),
+       .create_lease_size = sizeof(struct create_lease_v2),
        .create_durable_size = sizeof(struct create_durable_rsp),
        .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
        .create_mxac_size = sizeof(struct create_mxac_rsp),
        .cap_unix = 0,
        .cap_nt_find = SMB2_NT_FIND,
        .cap_large_files = SMB2_LARGE_FILES,
-       .create_lease_size = sizeof(struct create_lease),
+       .create_lease_size = sizeof(struct create_lease_v2),
        .create_durable_size = sizeof(struct create_durable_rsp),
        .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
        .create_mxac_size = sizeof(struct create_mxac_rsp),