From patchwork Tue Mar 1 16:08:12 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Anand Jain X-Patchwork-Id: 8466571 Return-Path: X-Original-To: patchwork-linux-btrfs@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 9B527C0554 for ; Tue, 1 Mar 2016 16:08:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BC95E201EC for ; Tue, 1 Mar 2016 16:08:52 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9953C202FF for ; Tue, 1 Mar 2016 16:08:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754784AbcCAQIs (ORCPT ); Tue, 1 Mar 2016 11:08:48 -0500 Received: from aserp1040.oracle.com ([141.146.126.69]:32237 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754523AbcCAQIq (ORCPT ); Tue, 1 Mar 2016 11:08:46 -0500 Received: from userv0022.oracle.com (userv0022.oracle.com [156.151.31.74]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u21G8cIL032285 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Tue, 1 Mar 2016 16:08:39 GMT Received: from userv0121.oracle.com (userv0121.oracle.com [156.151.31.72]) by userv0022.oracle.com (8.14.4/8.13.8) with ESMTP id u21G8cd8029864 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL); Tue, 1 Mar 2016 16:08:38 GMT Received: from abhmp0004.oracle.com (abhmp0004.oracle.com [141.146.116.10]) by userv0121.oracle.com (8.13.8/8.13.8) with ESMTP id u21G8cqZ017027; Tue, 1 Mar 2016 16:08:38 GMT Received: from localhost.localdomain (/42.60.24.64) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Tue, 01 Mar 2016 08:08:37 -0800 From: Anand Jain To: linux-btrfs@vger.kernel.org Cc: clm@fb.com, dsterba@suse.cz, Anand Jain Subject: [RFC PATCH 2/2] btrfs-progs: Encryption: add encrypt sub cli Date: Wed, 2 Mar 2016 00:08:12 +0800 Message-Id: <1456848492-4814-4-git-send-email-anand.jain@oracle.com> X-Mailer: git-send-email 2.7.0 In-Reply-To: <1456848492-4814-1-git-send-email-anand.jain@oracle.com> References: <1456848492-4814-1-git-send-email-anand.jain@oracle.com> MIME-Version: 1.0 X-Source-IP: userv0022.oracle.com [156.151.31.74] Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP *** Warning: Experimental cli and codes *** This is the btrfs-progs part of btrfs encryption. The branch is based on btrfs-progs v4.4.1. Depends on keyctl-utils and libscrypt packages. Signed-off-by: Anand Jain --- Makefile.in | 5 +- btrfs-list.c | 33 +++++ cmds-subvolume.c | 107 ++++++++++++++-- commands.h | 1 + encrypt.c | 383 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ encrypt.h | 33 +++++ props.c | 3 + subvolume.h | 2 + 8 files changed, 551 insertions(+), 16 deletions(-) create mode 100644 encrypt.c create mode 100644 encrypt.h diff --git a/Makefile.in b/Makefile.in index 6faf94dedf90..9c77461b76c6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -34,7 +34,7 @@ DISABLE_DOCUMENTATION = @DISABLE_DOCUMENTATION@ DISABLE_BTRFSCONVERT = @DISABLE_BTRFSCONVERT@ EXTRA_CFLAGS := -EXTRA_LDFLAGS := +EXTRA_LDFLAGS := /usr/lib/libscrypt.so.0 /usr/lib/libkeyutils.so # Common build flags CFLAGS = @CFLAGS@ \ @@ -70,7 +70,8 @@ objects = ctree.o disk-io.o radix-tree.o extent-tree.o print-tree.o \ extent-cache.o extent_io.o volumes.o utils.o repair.o \ qgroup.o raid6.o free-space-cache.o list_sort.o props.o \ ulist.o qgroup-verify.o backref.o string-table.o task-utils.o \ - inode.o file.o find-root.o free-space-tree.o help.o subvolume.o + inode.o file.o find-root.o free-space-tree.o help.o subvolume.o \ + encrypt.o cmds_objects = cmds-subvolume.o cmds-filesystem.o cmds-device.o cmds-scrub.o \ cmds-inspect.o cmds-balance.o cmds-send.o cmds-receive.o \ cmds-quota.o cmds-qgroup.o cmds-replace.o cmds-check.o \ diff --git a/btrfs-list.c b/btrfs-list.c index 2da54bf706f3..feffddd9c2cf 100644 --- a/btrfs-list.c +++ b/btrfs-list.c @@ -1912,3 +1912,36 @@ int btrfs_list_get_path_rootid(int fd, u64 *treeid) *treeid = args.treeid; return 0; } + +int wait_for_commit(int fd) +{ + int ret; + + ret = ioctl(fd, BTRFS_IOC_START_SYNC, NULL); + if (ret < 0) + return ret; + return ioctl(fd, BTRFS_IOC_WAIT_SYNC, NULL); +} + +/* + * A kind of workaround as of now, fixme to a per subvol only sync + * instead of entire FS. + */ +int wait_for_commit_subvol(char *subvol) +{ + int fd; + int ret; + DIR *ds; + + fd = open_file_or_dir3(subvol, &ds, O_RDWR); + if (fd == -1) { + ret = -errno; + fprintf(stderr, "ERROR: open '%s' failed: %s\n", + subvol, strerror(-ret)); + return ret; + } + + ret = wait_for_commit(fd); + close_file_or_dir(fd, ds); + return ret; +} diff --git a/cmds-subvolume.c b/cmds-subvolume.c index f9953ab7adb7..02a26778ccd2 100644 --- a/cmds-subvolume.c +++ b/cmds-subvolume.c @@ -27,6 +27,8 @@ #include #include #include +#include +#include #include "kerncompat.h" #include "ioctl.h" @@ -38,6 +40,7 @@ #include "btrfs-list.h" #include "utils.h" #include "subvolume.h" +#include "encrypt.h" static int is_subvolume_cleaned(int fd, u64 subvolid) { @@ -113,6 +116,8 @@ static const char * const cmd_subvol_create_usage[] = { "", "-i add the newly created subvolume to a qgroup. This", " option can be given multiple times.", + "-e encrypt file data in this subvol with ", + " as of now only 'aes' type is supported", NULL }; @@ -127,10 +132,11 @@ static int cmd_subvol_create(int argc, char **argv) char *dst; struct btrfs_qgroup_inherit *inherit = NULL; DIR *dirstream = NULL; + int encrypt = 0; optind = 1; while (1) { - int c = getopt(argc, argv, "c:i:v"); + int c = getopt(argc, argv, "ec:i:v"); if (c < 0) break; @@ -149,6 +155,10 @@ static int cmd_subvol_create(int argc, char **argv) goto out; } break; + case 'e': + encrypt = 1; + /* as of now no optarg just use default encrypt type AES*/ + break; default: usage(cmd_subvol_create_usage); } @@ -215,6 +225,10 @@ static int cmd_subvol_create(int argc, char **argv) goto out; } + if (encrypt && btrfs_set_subvol_encrypt(dst)) + fprintf(stderr, + "Failed to set encrypt flag, try using property command\n"); + retval = 0; /* success */ out: close_file_or_dir(fddst, dirstream); @@ -225,16 +239,6 @@ out: return retval; } -static int wait_for_commit(int fd) -{ - int ret; - - ret = ioctl(fd, BTRFS_IOC_START_SYNC, NULL); - if (ret < 0) - return ret; - return ioctl(fd, BTRFS_IOC_WAIT_SYNC, NULL); -} - static const char * const cmd_subvol_delete_usage[] = { "btrfs subvolume delete [options] [...]", "Delete subvolume(s)", @@ -911,6 +915,9 @@ static int cmd_subvol_show(int argc, char **argv) int fd = -1; int ret = 1; DIR *dirstream1 = NULL; + key_serial_t key_serial; + char key_algo[BTRFS_KEY_ALGO_MAX_LEN + 1]; + char key_tag[BTRFS_KEY_TAG_MAX_LEN + 1]; clean_args_no_options(argc, argv, cmd_subvol_show_usage); @@ -921,7 +928,7 @@ static int cmd_subvol_show(int argc, char **argv) if (!fullpath) { error("cannot find real path for '%s': %s", argv[optind], strerror(errno)); - goto out; + return ret; } ret = btrfs_get_subvol_info(fullpath, &get_ri); @@ -931,6 +938,7 @@ static int cmd_subvol_show(int argc, char **argv) fullpath, strerror(ret)): fprintf(stderr, "Failed to get subvol info %s: %d\n", fullpath, ret); + free(fullpath); return ret; } @@ -976,6 +984,23 @@ static int cmd_subvol_show(int argc, char **argv) else printf("\tFlags: \t\t\t-\n"); + key_serial = 0; + memset(key_algo, '\0', BTRFS_KEY_ALGO_MAX_LEN + 1); + memset(key_tag, '\0', BTRFS_KEY_TAG_MAX_LEN + 1); + + ret = btrfs_subvol_key_info(fullpath, key_algo, key_tag, &key_serial); + if (strlen(key_tag)) { + char key_state[256] = {0}; + if (key_serial == -1) + snprintf(key_state, 256, "(%s)", strerror(-ret)); + else + snprintf(key_state, 256, "(%d)", key_serial); + + printf("\tEncryption: \t\t%s@%s %s\n", key_algo, key_tag, key_state); + } else { + printf("\tEncryption: \t\t%s\n", "none"); + } + /* print the snapshots of the given subvol if any*/ printf("\tSnapshot(s):\n"); filter_set = btrfs_list_alloc_filter_set(); @@ -990,19 +1015,72 @@ static int cmd_subvol_show(int argc, char **argv) } btrfs_list_subvols_print(fd, filter_set, NULL, BTRFS_LIST_LAYOUT_RAW, 1, raw_prefix); + btrfs_list_free_filter_set(filter_set); + close_file_or_dir(fd, dirstream1); out: /* clean up */ free(get_ri.path); free(get_ri.name); free(get_ri.full_path); - btrfs_list_free_filter_set(filter_set); - close_file_or_dir(fd, dirstream1); free(fullpath); return !!ret; } +static const char * const cmd_subvol_encrypt_usage[] = { + "btrfs subvolume encrypt