From patchwork Fri Aug 10 07:38:31 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 956022 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-cifs-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="SrZFUY7K"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 41mxng0N9Mz9s7Q for ; Fri, 10 Aug 2018 17:38:47 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727102AbeHJKHY (ORCPT ); Fri, 10 Aug 2018 06:07:24 -0400 Received: from mail-pg1-f180.google.com ([209.85.215.180]:36616 "EHLO mail-pg1-f180.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726975AbeHJKHY (ORCPT ); Fri, 10 Aug 2018 06:07:24 -0400 Received: by mail-pg1-f180.google.com with SMTP id h12-v6so4011698pgs.3 for ; Fri, 10 Aug 2018 00:38:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to; bh=OfOZz7P9QwF5jt7VCmM3JzkLaGbLYp7I21NpibaBErg=; b=SrZFUY7KGnqVrPVtLKOU6+gLgctiq6YRDwdwYWtZqScrfgq7n7pebTB8yN2r6i+uP5 ttWSfce7yNuuFhPr+iqvbcIJOQfxBEBa3nveET3igi9dN0JaGsOHkRkcxpUDt9GLB+PC 9e3K3luVNiHZj3jpDrTeIizoWSrV3dxkVCzY8HBUhFGdUKyzOzzA7jNXybienJkFWpLH PYfcl2ZpKzMDTTW4PNGP5bdoqrHJjjI2axbWrAdgfnLUJhTMRT8bqLKGOj9LXjMWuBAK 5gmzdNvdHyp7gKIQIz62uNQ2k7H1xGyFzAyhvdhfacbjTA9aHCT7aB7NIwX6kTxZS3RR 7nig== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:from:date:message-id:subject:to; bh=OfOZz7P9QwF5jt7VCmM3JzkLaGbLYp7I21NpibaBErg=; b=KoswKt4ItVypu/uHvKjLxZupUUcfzYXsW2AjZPW42T5qMviNaPxJMwd/dLJ2gwlm0N P23e4w3jzKkW+K6Ka977WS6cXf+Fixby/zxhKTsEL74QqrZduBjtb8TB8P0xGg/UcSqr xNlNhUOVxZ93CGttkcescEvuNx4+XNpb7U5HZm3UxghmJjU16kd6MNUNxHIvLKRchHsj 2H5HKkgSIr2biT8rMdszYjMwN0Wf7LLeVyizo8Sf7KJH+y9eUnzBvh5RRtG9kvPnmW3r vuytX6zWahRsWok75gzoqkEI/jJgw5GwkRXGcDEoLKg9QBLkk3RkPP+Ob/Cf0ZbP1DB7 k5gQ== X-Gm-Message-State: AOUpUlE//IvK82Bhru7x4R4t8ocL4Yj2SooFu023vGhw60y+7cr5qW5M NM0BUIisTVR1obIt76BePhx10BknhwPmbbKWfXebqgdW X-Google-Smtp-Source: AA+uWPxrQPjQE0O0bwyCBUDhVR9csh6vOlRMb2BdgS09xLwK9OpTWXQJ48m8sMZfTP4tmZST3f4QhI2lZ96kRE5eAdY= X-Received: by 2002:a63:4857:: with SMTP id x23-v6mr5443525pgk.30.1533886724572; Fri, 10 Aug 2018 00:38:44 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Fri, 10 Aug 2018 02:38:31 -0500 Message-ID: Subject: [SMB3][PATCH] snapshots work from Linux! To: CIFS , samba-technical Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org mounting with the "snapshots=" mount parm allows a read-only view of a previous version of a file system (see MS-SMB2 and "timewarp" tokens, section 2.2.13.2.6) based on the timestamp passed in on the snapshots mount parm. Add processing to optionally send this create context. Example output: /mnt1 is mounted with "snapshots=..." and will see an earlier version of the directory, with three fewer files than /mnt2 the current version of the directory. root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# cat /proc/mounts | grep cifs //172.22.149.186/public /mnt1 cifs ro,relatime,vers=default,cache=strict,username=smfrench,uid=0,noforceuid,gid=0,noforcegid,addr=172.22.149.186,file_mode=0755,dir_mode=0755,soft,nounix,mapposix,rsize=1048576,wsize=1048576,echo_interval=60,snapshot=131748608570000000,actimeo=1 //172.22.149.186/public /mnt2 cifs rw,relatime,vers=default,cache=strict,username=smfrench,uid=0,noforceuid,gid=0,noforcegid,addr=172.22.149.186,file_mode=0755,dir_mode=0755,soft,nounix,mapposix,rsize=1048576,wsize=1048576,echo_interval=60,actimeo=1 root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# ls /mnt1 EmptyDir newerdir root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# ls /mnt1/newerdir root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# ls /mnt2 EmptyDir file newerdir newestdir timestamp-trace.cap root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# ls /mnt2/newerdir new-file-not-in-snapshot Snapshots are extremely useful for comparing previous versions of files or directories, and recovering from data corruptions or mistakes. See attached patch From 85097d72d3d993cbfc62bcdb206a96ce2268dae1 Mon Sep 17 00:00:00 2001 From: Steve French Date: Fri, 10 Aug 2018 02:25:06 -0500 Subject: [PATCH] smb3: allow previous versions to be mounted with snapshot= mount parm mounting with the "snapshots=" mount parm allows a read-only view of a previous version of a file system (see MS-SMB2 and "timewarp" tokens, section 2.2.13.2.6) based on the timestamp passed in on the snapshots mount parm. Add processing to optionally send this create context. Example output: /mnt1 is mounted with "snapshots=..." and will see an earlier version of the directory, with three fewer files than /mnt2 the current version of the directory. root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# cat /proc/mounts | grep cifs //172.22.149.186/public /mnt1 cifs ro,relatime,vers=default,cache=strict,username=smfrench,uid=0,noforceuid,gid=0,noforcegid,addr=172.22.149.186,file_mode=0755,dir_mode=0755,soft,nounix,mapposix,rsize=1048576,wsize=1048576,echo_interval=60,snapshot=131748608570000000,actimeo=1 //172.22.149.186/public /mnt2 cifs rw,relatime,vers=default,cache=strict,username=smfrench,uid=0,noforceuid,gid=0,noforcegid,addr=172.22.149.186,file_mode=0755,dir_mode=0755,soft,nounix,mapposix,rsize=1048576,wsize=1048576,echo_interval=60,actimeo=1 root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# ls /mnt1 EmptyDir newerdir root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# ls /mnt1/newerdir root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# ls /mnt2 EmptyDir file newerdir newestdir timestamp-trace.cap root@Ubuntu-17-Virtual-Machine:~/cifs-2.6# ls /mnt2/newerdir new-file-not-in-snapshot Snapshots are extremely useful for comparing previous versions of files or directories, and recovering from data corruptions or mistakes. Signed-off-by: Steve French --- fs/cifs/smb2pdu.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++ fs/cifs/smb2pdu.h | 8 +++++++ 2 files changed, 68 insertions(+) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index faf2b779e5cb..2f1938011395 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -1856,6 +1856,51 @@ add_durable_context(struct kvec *iov, unsigned int *num_iovec, return 0; } +/* See MS-SMB2 2.2.13.2.7 */ +static struct crt_twarp_ctxt * +create_twarp_buf(__u64 timewarp) +{ + struct crt_twarp_ctxt *buf; + + buf = kzalloc(sizeof(struct crt_twarp_ctxt), GFP_KERNEL); + if (!buf) + return NULL; + + buf->ccontext.DataOffset = cpu_to_le16(offsetof + (struct crt_twarp_ctxt, Timestamp)); + buf->ccontext.DataLength = cpu_to_le32(8); + buf->ccontext.NameOffset = cpu_to_le16(offsetof + (struct crt_twarp_ctxt, Name)); + buf->ccontext.NameLength = cpu_to_le16(4); + /* SMB2_CREATE_TIMEWARP_TOKEN is "TWrp" */ + buf->Name[0] = 'T'; + buf->Name[1] = 'W'; + buf->Name[2] = 'r'; + buf->Name[3] = 'p'; + buf->Timestamp = cpu_to_le64(timewarp); + return buf; +} + +/* See MS-SMB2 2.2.13.2.7 */ +static int +add_twarp_context(struct kvec *iov, unsigned int *num_iovec, __u64 timewarp) +{ + struct smb2_create_req *req = iov[0].iov_base; + unsigned int num = *num_iovec; + + iov[num].iov_base = create_twarp_buf(timewarp); + if (iov[num].iov_base == NULL) + return -ENOMEM; + iov[num].iov_len = sizeof(struct crt_twarp_ctxt); + if (!req->CreateContextsOffset) + req->CreateContextsOffset = cpu_to_le32( + sizeof(struct smb2_create_req) + + iov[num - 1].iov_len); + le32_add_cpu(&req->CreateContextsLength, sizeof(struct crt_twarp_ctxt)); + *num_iovec = num + 1; + return 0; +} + static int alloc_path_with_tree_prefix(__le16 **out_path, int *out_size, int *out_len, const char *treename, const __le16 *path) @@ -2168,6 +2213,21 @@ SMB2_open_init(struct cifs_tcon *tcon, struct smb_rqst *rqst, __u8 *oplock, return rc; } + if (tcon->snapshot_time) { + cifs_dbg(FYI, "adding snapshot context\n"); + if (n_iov > 2) { + struct create_context *ccontext = + (struct create_context *)iov[n_iov-1].iov_base; + ccontext->Next = + cpu_to_le32(iov[n_iov-1].iov_len); + } + + rc = add_twarp_context(iov, &n_iov, tcon->snapshot_time); + if (rc) + return rc; + } + + rqst->rq_nvec = n_iov; return 0; } diff --git a/fs/cifs/smb2pdu.h b/fs/cifs/smb2pdu.h index cf37c2f3f3b8..a2eeae9e0432 100644 --- a/fs/cifs/smb2pdu.h +++ b/fs/cifs/smb2pdu.h @@ -767,6 +767,14 @@ struct create_durable_handle_reconnect_v2 { struct durable_reconnect_context_v2 dcontext; } __packed; +/* See MS-SMB2 2.2.13.2.5 */ +struct crt_twarp_ctxt { + struct create_context ccontext; + __u8 Name[8]; + __le64 Timestamp; + +} __packed; + #define COPY_CHUNK_RES_KEY_SIZE 24 struct resume_key_req { char ResumeKey[COPY_CHUNK_RES_KEY_SIZE]; -- 2.17.1