From patchwork Thu Mar 28 10:05:35 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 10874725 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 1A543186D for ; Thu, 28 Mar 2019 10:05:50 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 06E03287F2 for ; Thu, 28 Mar 2019 10:05:50 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id EF42528B38; Thu, 28 Mar 2019 10:05:49 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FROM,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=unavailable version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 4B39F288BD for ; Thu, 28 Mar 2019 10:05:49 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727135AbfC1KFs (ORCPT ); Thu, 28 Mar 2019 06:05:48 -0400 Received: from mail-pg1-f175.google.com ([209.85.215.175]:39282 "EHLO mail-pg1-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726224AbfC1KFs (ORCPT ); Thu, 28 Mar 2019 06:05:48 -0400 Received: by mail-pg1-f175.google.com with SMTP id k3so7679382pga.6; Thu, 28 Mar 2019 03:05:47 -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=s1yoGM47WS9ZsZdX+Jw5tfDxLEfrnPOwasKkxmCMzAE=; b=J43B/bo2cje5xtKBNttWIFlTJqlVzQdbNd5dT/A9z0tJGLhciVYog4EFmTbMwLTHhb TNQuT/QJP9y7norCutCTQlhW8pBTEFwO2dhnQnKTTLj8qCkAuvkgy4XKp2ADDwmVp1rY R8Gjkkn9ZIFYt8uP4Pvejn6SyBeie3iY0Jw8ShEQzKE01rk+i4VgnhMAfTKkMVEnHuFQ B5eBQRLz+zT4z+UggFYlRz5aRljrP/TArySFeJjkEuILOZhsuwYP+CDvRKPbzPisZBjz BMs1m8qme0xPfkJ9FuNOZprRMsgVCuuOvX9Guy0MfA9tJG46xBC395El33glmJjUYA43 4klQ== 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=s1yoGM47WS9ZsZdX+Jw5tfDxLEfrnPOwasKkxmCMzAE=; b=OCM7cqylTznbHQ0Rb0HH66rRYXJeCGVXIHQG1AHEAWxfy0LYivGij7ZrCm2fFXCQ8P x34xZduyTkncp9QQE7veeYXHJfxcQj81eap31XZf2AdBAINZ/ZJm4c3oLs/e4gzjwQ39 d3Y8Y4o9k5qMsO2lQpZENl2deOw4q8ULHDGLvIDA/fCnzJosubxYFfOnFviPfos0MMK9 0tEwYO1GBFCeO6EHGZLlDMSNP8J2u9kK8mo+LxCdSeIBQR2K7+DbP8nYOImScfGzcBUU GxEJGeM4CWq9j72hPVmQbxWOBZ5cIvVmNUWzcAjDGAEBSzioA7fJhozpg3Lvppy57jPE iPbw== X-Gm-Message-State: APjAAAWBpyNs/wju4b9/Bj2MPHToQn5freaf+x9BtPa4xp/hWHiXvqiH 8r1GpI4G9qzJsPj/bMeHrid2pN88tVkREpOcOs8= X-Google-Smtp-Source: APXvYqz536WuLJchVGIbkpwraJtPwba8h/x5W3LZE4LLv8sGttltYUlC2p1DnIE5xB/ovRqVFJMw/60M8EURltrQfRY= X-Received: by 2002:a63:544f:: with SMTP id e15mr39834837pgm.344.1553767546858; Thu, 28 Mar 2019 03:05:46 -0700 (PDT) MIME-Version: 1.0 From: Steve French Date: Thu, 28 Mar 2019 05:05:35 -0500 Message-ID: Subject: [PATCH][smbinfo cifsutils] To: samba-technical , CIFS , linux-fsdevel , Pavel Shilovsky Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Patch to smbinfo tool (in cifs-utils) to allow listing previous versions (snapshots) of an SMB3 mounted share. Note that cifs.ko has a mount option "snapshot=" which can be used to mount the previous version of a share. Sample output: $ ./smbinfo list-snapshots /mnt/file Number of snapshots: 5 Number of snapshots returned: 5 Snapshot list: 1) @GMT-2019.03.27-20.52.19 2) @GMT-2019.03.27-20.50.20 3) @GMT-2019.03.16-22.25.54 4) @GMT-2019.03.16-22.22.28 5) @GMT-2018.10.12-08.30.11 From dd4650114a9b31f210f359327735dcffdc8139d9 Mon Sep 17 00:00:00 2001 From: Steve French Date: Thu, 28 Mar 2019 04:58:19 -0500 Subject: [PATCH] smbinfo: Add ability to query snapshots (previous versions) Allow listing SMB3 snapshots (previous versions of shares) Signed-off-by: Steve French --- smbinfo.c | 86 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/smbinfo.c b/smbinfo.c index 33fca95..8f6566a 100644 --- a/smbinfo.c +++ b/smbinfo.c @@ -89,6 +89,8 @@ usage(char *name) " Prints the security descriptor for a cifs file.\n" " quota:\n" " Prints the quota for a cifs file.\n" + " list-snapshots:\n" + " List the previous versions of the volume that backs this file.\n" " fsctl-getobjid:\n" " Prints the objectid of the file and GUID of the underlying volume.\n", name); @@ -966,6 +968,88 @@ quota(int f) free(qi); } + +struct smb_snapshot_array { + int32_t number_of_snapshots; + int32_t number_of_snapshots_returned; + int32_t snapshot_array_size; + char snapshot_data[0]; +}; + + +static void print_snapshots(struct smb_snapshot_array *psnap) +{ + int current_snapshot_entry = 0; + + printf("Number of snapshots: %d Number of snapshots returned: %d\n", + psnap->number_of_snapshots, + psnap->number_of_snapshots_returned); + printf("Snapshot list:"); + + for (int i = 0; i < psnap->snapshot_array_size; i++) { + if (psnap->snapshot_data[i] == '@') { + current_snapshot_entry++; + printf("\n%d) ", current_snapshot_entry); + } + printf("%c", psnap->snapshot_data[i]); + } + printf("\n"); +} + +#define CIFS_ENUMERATE_SNAPSHOTS _IOR(CIFS_IOCTL_MAGIC, 6, struct smb_snapshot_array) + +static void +list_snapshots(int f) +{ + + struct smb_snapshot_array snap_inf; + struct smb_snapshot_array *buf; + + /* + * When first field in structure we pass in here is zero, cifs.ko can + * recognize that this is the first query and that it must set the SMB3 + * FSCTL response buffer size (in the request) to exactly 16 bytes + * (which is required by some servers to process the initial query) + */ + snap_inf.number_of_snapshots = 0; + snap_inf.number_of_snapshots_returned = 0; + snap_inf.snapshot_array_size = sizeof(struct smb_snapshot_array); + + /* Query the number of snapshots so we know how much to allocate */ + if (ioctl(f, CIFS_ENUMERATE_SNAPSHOTS, &snap_inf) < 0) { + fprintf(stderr, "Querying snapshots failed with %s\n", strerror(errno)); + exit(1); + } + + if (snap_inf.number_of_snapshots == 0) + return; + + /* Now that we know the size, query the list from the server */ + + /* Make sure the buf size is big enough even to handle unexpected server behavior */ + buf = malloc(snap_inf.snapshot_array_size + 300); + + if (buf == NULL) { + printf("Failed, out of memory.\n"); + exit(1); + } + /* + * first parm is non-zero which allows cifs.ko to recognize that this is + * the second query (it has to set response buf size larger) + */ + buf->number_of_snapshots = snap_inf.number_of_snapshots; + + buf->snapshot_array_size = snap_inf.snapshot_array_size + 200; + + if (ioctl(f, CIFS_ENUMERATE_SNAPSHOTS, buf) < 0) { + fprintf(stderr, "Querying snapshots failed with %s\n", strerror(errno)); + exit(1); + } + + print_snapshots(buf); + free(buf); +} + int main(int argc, char *argv[]) { int c; @@ -1016,6 +1100,8 @@ int main(int argc, char *argv[]) secdesc(f); else if (!strcmp(argv[optind], "quota")) quota(f); + else if (!strcmp(argv[optind], "list-snapshots")) + list_snapshots(f); else if (!strcmp(argv[1], "fsctl-getobjid")) fsctlgetobjid(f); else { -- 2.17.1