Whamcloud - gitweb
LU-12275 sec: enable client side encryption 43/36143/22
authorSebastien Buisson <sbuisson@ddn.com>
Mon, 8 Jul 2019 14:51:39 +0000 (14:51 +0000)
committerOleg Drokin <green@whamcloud.com>
Sat, 6 Jun 2020 14:02:20 +0000 (14:02 +0000)
Enable client side encryption. By default it is activated,
letting user specifies actual encryption policy to use on
a per-directory basis. It is possible to deactivate client
side encryption by using the 'noencrypt' mount option.

Also add the test dummy encryption mode option to ease
testing.

Signed-off-by: Sebastien Buisson <sbuisson@ddn.com>
Change-Id: I0e8d4db7ab8a77aba0600788cca9403f7c50f8a6
Reviewed-on: https://review.whamcloud.com/36143
Reviewed-by: John L. Hammond <jhammond@whamcloud.com>
Reviewed-by: Andreas Dilger <adilger@whamcloud.com>
Tested-by: jenkins <devops@whamcloud.com>
Tested-by: Maloo <maloo@whamcloud.com>
Reviewed-by: Oleg Drokin <green@whamcloud.com>
24 files changed:
MAINTAINERS
lustre/autoconf/lustre-core.m4
lustre/doc/mount.lustre.8
lustre/include/Makefile.am
lustre/include/lustre_crypto.h [new file with mode: 0644]
lustre/include/obd_support.h
lustre/include/uapi/linux/lustre/lustre_idl.h
lustre/include/uapi/linux/lustre/lustre_user.h
lustre/llite/Makefile.in
lustre/llite/crypto.c [new file with mode: 0644]
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/super25.c
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_object.c
lustre/osd-ldiskfs/osd_handler.c
lustre/osd-zfs/osd_internal.h
lustre/osd-zfs/osd_object.c
lustre/osd-zfs/osd_xattr.c
lustre/ptlrpc/wiretest.c
lustre/utils/mount_lustre.c
lustre/utils/wirecheck.c
lustre/utils/wiretest.c

index 137e272..6ca8902 100644 (file)
@@ -133,9 +133,14 @@ Lustre client side encryption
 M:     Sebastien Buisson <sbuisson@whamcloud.com>
 S:     Maintained
 F:     Documentation/client_side_encryption/*.txt
 M:     Sebastien Buisson <sbuisson@whamcloud.com>
 S:     Maintained
 F:     Documentation/client_side_encryption/*.txt
+F:     lustre/llite/crypto*.[ch]
 F:     libcfs/libcfs/crypto/*.[ch]
 F:     libcfs/include/libcfs/crypto/*.h
 F:     libcfs/include/uapi/linux/llcrypt.h
 F:     libcfs/libcfs/crypto/*.[ch]
 F:     libcfs/include/libcfs/crypto/*.h
 F:     libcfs/include/uapi/linux/llcrypt.h
+F:     lustre/include/lustre_crypto.h
+K:     fscrypt
+K:     llcrypt
+K:     HAVE_LUSTRE_CRYPTO
 
 Lustre Client VFS Interface
 R:     Oleg Drokin <green@whamcloud.com>
 
 Lustre Client VFS Interface
 R:     Oleg Drokin <green@whamcloud.com>
index ac986de..4f9ce29 100644 (file)
@@ -2655,6 +2655,8 @@ No selinux package found, unable to build selinux enabled tools
 ])
 AC_SUBST(SELINUX)
 
 ])
 AC_SUBST(SELINUX)
 
+AC_CHECK_LIB([keyutils], [add_key])
+
 # Super safe df
 AC_MSG_CHECKING([whether to report minimum OST free space])
 AC_ARG_ENABLE([mindf],
 # Super safe df
 AC_MSG_CHECKING([whether to report minimum OST free space])
 AC_ARG_ENABLE([mindf],
index f2fb607..cc1a25a 100644 (file)
@@ -221,6 +221,16 @@ Warning! 'network' option is incompatible with LNet Dynamic Peer Discovery.
 If you want to restrict client NID, please make sure LNet Dynamic Peer Discovery
 is disabled.
 .RE
 If you want to restrict client NID, please make sure LNet Dynamic Peer Discovery
 is disabled.
 .RE
+.TP
+.BI test_dummy_encryption
+Enable test dummy encryption mode.
+.RE
+.TP
+.BI noencrypt
+Disable Lustre client-side encryption. By default, Lustre client-side encryption
+is enabled, letting users define encryption policies on a per-directory basis.
+fscrypt userspace tool can be used for that purpose, see
+https://github.com/google/fscrypt
 .SH SERVER OPTIONS
 In addition to the standard mount options and backing disk type
 (e.g. ldiskfs) options listed in
 .SH SERVER OPTIONS
 In addition to the standard mount options and backing disk type
 (e.g. ldiskfs) options listed in
index 0dcd3c2..16a6cab 100644 (file)
@@ -47,6 +47,7 @@ EXTRA_DIST = \
        lustre_acl.h \
        lustre_barrier.h \
        lustre_compat.h \
        lustre_acl.h \
        lustre_barrier.h \
        lustre_compat.h \
+       lustre_crypto.h \
        lustre_debug.h \
        lustre_disk.h \
        lustre_dlm_flags.h \
        lustre_debug.h \
        lustre_disk.h \
        lustre_dlm_flags.h \
diff --git a/lustre/include/lustre_crypto.h b/lustre/include/lustre_crypto.h
new file mode 100644 (file)
index 0000000..63f7696
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2019, 2020, Whamcloud.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ */
+
+#ifndef _LUSTRE_CRYPTO_H_
+#define _LUSTRE_CRYPTO_H_
+
+struct ll_sb_info;
+bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi);
+bool ll_sbi_has_encrypt(struct ll_sb_info *sbi);
+void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set);
+
+#ifdef CONFIG_LL_ENCRYPTION
+#include <libcfs/crypto/llcrypt.h>
+#else /* !CONFIG_LL_ENCRYPTION */
+#ifdef HAVE_LUSTRE_CRYPTO
+#define __FS_HAS_ENCRYPTION 1
+#include <linux/fscrypt.h>
+
+#define llcrypt_operations     fscrypt_operations
+#define llcrypt_symlink_data   fscrypt_symlink_data
+#define llcrypt_dummy_context_enabled(inode) \
+       fscrypt_dummy_context_enabled(inode)
+#define llcrypt_has_encryption_key(inode) fscrypt_has_encryption_key(inode)
+#define llcrypt_encrypt_pagecache_blocks(page, len, offs, gfp_flags)   \
+       fscrypt_encrypt_pagecache_blocks(page, len, offs, gfp_flags)
+#define llcrypt_decrypt_pagecache_blocks(page, len, offs)      \
+       fscrypt_decrypt_pagecache_blocks(page, len, offs)
+#define llcrypt_inherit_context(parent, child, fs_data, preload)       \
+       fscrypt_inherit_context(parent, child, fs_data, preload)
+#define llcrypt_get_encryption_info(inode) fscrypt_get_encryption_info(inode)
+#define llcrypt_put_encryption_info(inode) fscrypt_put_encryption_info(inode)
+#define llcrypt_free_inode(inode)         fscrypt_free_inode(inode)
+#define llcrypt_finalize_bounce_page(pagep)  fscrypt_finalize_bounce_page(pagep)
+#define llcrypt_file_open(inode, filp) fscrypt_file_open(inode, filp)
+#define llcrypt_ioctl_set_policy(filp, arg)  fscrypt_ioctl_set_policy(filp, arg)
+#define llcrypt_ioctl_get_policy_ex(filp, arg) \
+       fscrypt_ioctl_get_policy_ex(filp, arg)
+#define llcrypt_ioctl_add_key(filp, arg)       fscrypt_ioctl_add_key(filp, arg)
+#define llcrypt_ioctl_remove_key(filp, arg)  fscrypt_ioctl_remove_key(filp, arg)
+#define llcrypt_ioctl_remove_key_all_users(filp, arg)  \
+       fscrypt_ioctl_remove_key_all_users(filp, arg)
+#define llcrypt_ioctl_get_key_status(filp, arg)        \
+       fscrypt_ioctl_get_key_status(filp, arg)
+#define llcrypt_drop_inode(inode)      fscrypt_drop_inode(inode)
+#define llcrypt_prepare_rename(olddir, olddentry, newdir, newdentry, flags) \
+       fscrypt_prepare_rename(olddir, olddentry, newdir, newdentry, flags)
+#define llcrypt_prepare_link(old_dentry, dir, dentry)  \
+       fscrypt_prepare_link(old_dentry, dir, dentry)
+#define llcrypt_prepare_setattr(dentry, attr)          \
+       fscrypt_prepare_setattr(dentry, attr)
+#define llcrypt_set_ops(sb, cop)       fscrypt_set_ops(sb, cop)
+#else /* !HAVE_LUSTRE_CRYPTO */
+#undef IS_ENCRYPTED
+#define IS_ENCRYPTED(x)        0
+#define llcrypt_dummy_context_enabled(inode)   NULL
+/* copied from include/linux/fscrypt.h */
+#define llcrypt_has_encryption_key(inode) false
+#define llcrypt_encrypt_pagecache_blocks(page, len, offs, gfp_flags)   \
+       ERR_PTR(-EOPNOTSUPP)
+#define llcrypt_decrypt_pagecache_blocks(page, len, offs)      -EOPNOTSUPP
+#define llcrypt_inherit_context(parent, child, fs_data, preload)     -EOPNOTSUPP
+#define llcrypt_get_encryption_info(inode)                     -EOPNOTSUPP
+#define llcrypt_put_encryption_info(inode)                     do {} while (0)
+#define llcrypt_free_inode(inode)                              do {} while (0)
+#define llcrypt_finalize_bounce_page(pagep)                    do {} while (0)
+static inline int llcrypt_file_open(struct inode *inode, struct file *filp)
+{
+       return IS_ENCRYPTED(inode) ? -EOPNOTSUPP : 0;
+}
+#define llcrypt_ioctl_set_policy(filp, arg)                    -EOPNOTSUPP
+#define llcrypt_ioctl_get_policy_ex(filp, arg)                 -EOPNOTSUPP
+#define llcrypt_ioctl_add_key(filp, arg)                       -EOPNOTSUPP
+#define llcrypt_ioctl_remove_key(filp, arg)                    -EOPNOTSUPP
+#define llcrypt_ioctl_remove_key_all_users(filp, arg)          -EOPNOTSUPP
+#define llcrypt_ioctl_get_key_status(filp, arg)                        -EOPNOTSUPP
+#define llcrypt_drop_inode(inode)                               0
+#define llcrypt_prepare_rename(olddir, olddentry, newdir, newdentry, flags)    0
+#define llcrypt_prepare_link(old_dentry, dir, dentry)           0
+#define llcrypt_prepare_setattr(dentry, attr)                   0
+#define llcrypt_set_ops(sb, cop)                               do {} while (0)
+#endif /* HAVE_LUSTRE_CRYPTO */
+#endif /* !CONFIG_LL_ENCRYPTION */
+
+#endif /* _LUSTRE_CRYPTO_H_ */
index d4b3585..e8a99d5 100644 (file)
@@ -965,12 +965,14 @@ do {                                                                          \
 
 static inline int lma_to_lustre_flags(__u32 lma_flags)
 {
 
 static inline int lma_to_lustre_flags(__u32 lma_flags)
 {
-       return (lma_flags & LMAI_ORPHAN) ? LUSTRE_ORPHAN_FL : 0;
+       return (((lma_flags & LMAI_ORPHAN) ? LUSTRE_ORPHAN_FL : 0) |
+               ((lma_flags & LMAI_ENCRYPT) ? LUSTRE_ENCRYPT_FL : 0));
 }
 
 static inline int lustre_to_lma_flags(__u32 la_flags)
 {
 }
 
 static inline int lustre_to_lma_flags(__u32 la_flags)
 {
-       return (la_flags & LUSTRE_ORPHAN_FL) ? LMAI_ORPHAN : 0;
+       return (((la_flags & LUSTRE_ORPHAN_FL) ? LMAI_ORPHAN : 0) |
+               ((la_flags & LUSTRE_ENCRYPT_FL) ? LMAI_ENCRYPT : 0));
 }
 
 /* Convert wire LUSTRE_*_FL to corresponding client local VFS S_* values
 }
 
 /* Convert wire LUSTRE_*_FL to corresponding client local VFS S_* values
@@ -986,6 +988,9 @@ static inline int ll_ext_to_inode_flags(int flags)
                ((flags & LUSTRE_NOATIME_FL)   ? S_NOATIME   : 0) |
                ((flags & LUSTRE_APPEND_FL)    ? S_APPEND    : 0) |
                ((flags & LUSTRE_DIRSYNC_FL)   ? S_DIRSYNC   : 0) |
                ((flags & LUSTRE_NOATIME_FL)   ? S_NOATIME   : 0) |
                ((flags & LUSTRE_APPEND_FL)    ? S_APPEND    : 0) |
                ((flags & LUSTRE_DIRSYNC_FL)   ? S_DIRSYNC   : 0) |
+#if defined(S_ENCRYPTED)
+               ((flags & LUSTRE_ENCRYPT_FL)   ? S_ENCRYPTED : 0) |
+#endif
                ((flags & LUSTRE_IMMUTABLE_FL) ? S_IMMUTABLE : 0));
 }
 
                ((flags & LUSTRE_IMMUTABLE_FL) ? S_IMMUTABLE : 0));
 }
 
@@ -995,6 +1000,9 @@ static inline int ll_inode_to_ext_flags(int iflags)
                ((iflags & S_NOATIME)   ? LUSTRE_NOATIME_FL   : 0) |
                ((iflags & S_APPEND)    ? LUSTRE_APPEND_FL    : 0) |
                ((iflags & S_DIRSYNC)   ? LUSTRE_DIRSYNC_FL   : 0) |
                ((iflags & S_NOATIME)   ? LUSTRE_NOATIME_FL   : 0) |
                ((iflags & S_APPEND)    ? LUSTRE_APPEND_FL    : 0) |
                ((iflags & S_DIRSYNC)   ? LUSTRE_DIRSYNC_FL   : 0) |
+#if defined(S_ENCRYPTED)
+               ((iflags & S_ENCRYPTED) ? LUSTRE_ENCRYPT_FL   : 0) |
+#endif
                ((iflags & S_IMMUTABLE) ? LUSTRE_IMMUTABLE_FL : 0));
 }
 
                ((iflags & S_IMMUTABLE) ? LUSTRE_IMMUTABLE_FL : 0));
 }
 
index 088dab5..6450380 100644 (file)
@@ -1199,6 +1199,8 @@ struct lov_mds_md_v1 {            /* LOV EA mds/wire data (little-endian) */
 #define XATTR_NAME_LFSCK_BITMAP "trusted.lfsck_bitmap"
 #define XATTR_NAME_DUMMY       "trusted.dummy"
 
 #define XATTR_NAME_LFSCK_BITMAP "trusted.lfsck_bitmap"
 #define XATTR_NAME_DUMMY       "trusted.dummy"
 
+#define LL_XATTR_NAME_ENCRYPTION_CONTEXT XATTR_SECURITY_PREFIX"c"
+
 #define XATTR_NAME_LFSCK_NAMESPACE "trusted.lfsck_ns"
 #define XATTR_NAME_MAX_LEN     32 /* increase this, if there is longer name. */
 
 #define XATTR_NAME_LFSCK_NAMESPACE "trusted.lfsck_ns"
 #define XATTR_NAME_MAX_LEN     32 /* increase this, if there is longer name. */
 
@@ -1775,8 +1777,9 @@ enum {
         * stored in LMA. see LMAI_XXXX */
        LUSTRE_ORPHAN_FL        = 0x00002000,
        LUSTRE_SET_SYNC_FL      = 0x00040000, /* Synchronous setattr on OSTs */
         * stored in LMA. see LMAI_XXXX */
        LUSTRE_ORPHAN_FL        = 0x00002000,
        LUSTRE_SET_SYNC_FL      = 0x00040000, /* Synchronous setattr on OSTs */
+       LUSTRE_ENCRYPT_FL       = 0x00800000, /* encrypted file */
 
 
-       LUSTRE_LMA_FL_MASKS     = LUSTRE_ORPHAN_FL,
+       LUSTRE_LMA_FL_MASKS     = LUSTRE_ENCRYPT_FL | LUSTRE_ORPHAN_FL,
 };
 
 #ifndef FS_XFLAG_SYNC
 };
 
 #ifndef FS_XFLAG_SYNC
index 6e52437..291c70e 100644 (file)
@@ -424,8 +424,9 @@ enum lma_incompat {
                                                 is on the remote MDT */
        LMAI_STRIPED            = 0x00000008, /* striped directory inode */
        LMAI_ORPHAN             = 0x00000010, /* inode is orphan */
                                                 is on the remote MDT */
        LMAI_STRIPED            = 0x00000008, /* striped directory inode */
        LMAI_ORPHAN             = 0x00000010, /* inode is orphan */
+       LMAI_ENCRYPT            = 0x00000020, /* inode is encrypted */
        LMA_INCOMPAT_SUPP       = (LMAI_AGENT | LMAI_REMOTE_PARENT | \
        LMA_INCOMPAT_SUPP       = (LMAI_AGENT | LMAI_REMOTE_PARENT | \
-                                  LMAI_STRIPED | LMAI_ORPHAN)
+                                  LMAI_STRIPED | LMAI_ORPHAN | LMAI_ENCRYPT)
 };
 
 
 };
 
 
index ec5ab34..3a5293f 100644 (file)
@@ -7,7 +7,7 @@ lustre-objs += glimpse.o
 lustre-objs += lcommon_cl.o
 lustre-objs += lcommon_misc.o
 lustre-objs += vvp_dev.o vvp_page.o vvp_io.o vvp_object.o
 lustre-objs += lcommon_cl.o
 lustre-objs += lcommon_misc.o
 lustre-objs += vvp_dev.o vvp_page.o vvp_io.o vvp_object.o
-lustre-objs += range_lock.o pcc.o
+lustre-objs += range_lock.o pcc.o crypto.o
 
 EXTRA_DIST := $(lustre-objs:.o=.c) xattr.c rw26.c super25.c
 EXTRA_DIST += llite_internal.h vvp_internal.h range_lock.h pcc.h
 
 EXTRA_DIST := $(lustre-objs:.o=.c) xattr.c rw26.c super25.c
 EXTRA_DIST += llite_internal.h vvp_internal.h range_lock.h pcc.h
diff --git a/lustre/llite/crypto.c b/lustre/llite/crypto.c
new file mode 100644 (file)
index 0000000..5ccbedf
--- /dev/null
@@ -0,0 +1,153 @@
+/*
+ * GPL HEADER START
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License version 2 for more details (a copy is included
+ * in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License
+ * version 2 along with this program; If not, see
+ * http://www.gnu.org/licenses/gpl-2.0.html
+ *
+ * GPL HEADER END
+ */
+/*
+ * Copyright (c) 2019, 2020, Whamcloud.
+ */
+/*
+ * This file is part of Lustre, http://www.lustre.org/
+ */
+
+#include "llite_internal.h"
+
+#ifdef HAVE_LUSTRE_CRYPTO
+
+static int ll_get_context(struct inode *inode, void *ctx, size_t len)
+{
+       struct dentry *dentry;
+       int rc;
+
+       if (hlist_empty(&inode->i_dentry))
+               return -ENODATA;
+
+       hlist_for_each_entry(dentry, &inode->i_dentry, d_alias) {
+               break;
+       }
+
+       rc = ll_vfs_getxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
+                            ctx, len);
+
+       return rc;
+}
+
+static int ll_set_context(struct inode *inode, const void *ctx, size_t len,
+                         void *fs_data)
+{
+       unsigned int ext_flags;
+       struct dentry *dentry;
+       struct md_op_data *op_data;
+       struct ptlrpc_request *req = NULL;
+       int rc;
+
+       if (inode == NULL)
+               return 0;
+
+       ext_flags = ll_inode_to_ext_flags(inode->i_flags) | LUSTRE_ENCRYPT_FL;
+       dentry = (struct dentry *)fs_data;
+
+       /* Encrypting the root directory is not allowed */
+       if (inode->i_ino == inode->i_sb->s_root->d_inode->i_ino)
+               return -EPERM;
+
+       op_data = ll_prep_md_op_data(NULL, inode, NULL, NULL, 0, 0,
+                                    LUSTRE_OPC_ANY, NULL);
+       if (IS_ERR(op_data))
+               return PTR_ERR(op_data);
+
+       op_data->op_attr_flags = LUSTRE_ENCRYPT_FL;
+       op_data->op_xvalid |= OP_XVALID_FLAGS;
+       rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, op_data, NULL, 0, &req);
+       ll_finish_md_op_data(op_data);
+       ptlrpc_req_finished(req);
+       if (rc)
+               return rc;
+
+       rc = ll_vfs_setxattr(dentry, inode, LL_XATTR_NAME_ENCRYPTION_CONTEXT,
+                            ctx, len, XATTR_CREATE);
+       if (rc)
+               return rc;
+
+       ll_update_inode_flags(inode, ext_flags);
+       return 0;
+}
+
+inline bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi)
+{
+       return unlikely(sbi->ll_flags & LL_SBI_TEST_DUMMY_ENCRYPTION);
+}
+
+static bool ll_dummy_context(struct inode *inode)
+{
+       struct ll_sb_info *sbi = ll_i2sbi(inode);
+
+       return sbi ? ll_sbi_has_test_dummy_encryption(sbi) : false;
+}
+
+inline bool ll_sbi_has_encrypt(struct ll_sb_info *sbi)
+{
+       return sbi->ll_flags & LL_SBI_ENCRYPT;
+}
+
+inline void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set)
+{
+       if (set)
+               sbi->ll_flags |= LL_SBI_ENCRYPT;
+       else
+               sbi->ll_flags &=
+                       ~(LL_SBI_ENCRYPT | LL_SBI_TEST_DUMMY_ENCRYPTION);
+}
+
+static bool ll_empty_dir(struct inode *inode)
+{
+       /* used by llcrypt_ioctl_set_policy(), because a policy can only be set
+        * on an empty dir.
+        */
+       /* Here we choose to return true, meaning we always call .set_context.
+        * Then we rely on server side, with mdd_fix_attr() that calls
+        * mdd_dir_is_empty() when setting encryption flag on directory.
+        */
+       return true;
+}
+
+const struct llcrypt_operations lustre_cryptops = {
+       .key_prefix             = "lustre:",
+       .get_context            = ll_get_context,
+       .set_context            = ll_set_context,
+       .dummy_context          = ll_dummy_context,
+       .empty_dir              = ll_empty_dir,
+       .max_namelen            = NAME_MAX,
+};
+#else /* !HAVE_LUSTRE_CRYPTO */
+inline bool ll_sbi_has_test_dummy_encryption(struct ll_sb_info *sbi)
+{
+       return false;
+}
+
+inline bool ll_sbi_has_encrypt(struct ll_sb_info *sbi)
+{
+       return false;
+}
+
+inline void ll_sbi_set_encrypt(struct ll_sb_info *sbi, bool set)
+{
+}
+#endif
+
index 76db0b0..cb0ebf2 100644 (file)
@@ -45,6 +45,7 @@
 #include <linux/compat.h>
 #include <linux/aio.h>
 #include <lustre_compat.h>
 #include <linux/compat.h>
 #include <linux/aio.h>
 #include <lustre_compat.h>
+#include <lustre_crypto.h>
 
 #include "vvp_internal.h"
 #include "range_lock.h"
 
 #include "vvp_internal.h"
 #include "range_lock.h"
@@ -585,6 +586,8 @@ enum stats_track_type {
                                         2.10, abandoned */
 #define LL_SBI_TINY_WRITE   0x2000000 /* tiny write support */
 #define LL_SBI_FILE_HEAT    0x4000000 /* file heat support */
                                         2.10, abandoned */
 #define LL_SBI_TINY_WRITE   0x2000000 /* tiny write support */
 #define LL_SBI_FILE_HEAT    0x4000000 /* file heat support */
+#define LL_SBI_TEST_DUMMY_ENCRYPTION    0x8000000 /* test dummy encryption */
+#define LL_SBI_ENCRYPT    0x10000000 /* client side encryption */
 #define LL_SBI_FLAGS {         \
        "nolck",        \
        "checksum",     \
 #define LL_SBI_FLAGS {         \
        "nolck",        \
        "checksum",     \
@@ -613,6 +616,8 @@ enum stats_track_type {
        "pio",          \
        "tiny_write",   \
        "file_heat",    \
        "pio",          \
        "tiny_write",   \
        "file_heat",    \
+       "test_dummy_encryption", \
+       "noencrypt",    \
 }
 
 /* This is embedded into llite super-blocks to keep track of connect
 }
 
 /* This is embedded into llite super-blocks to keep track of connect
@@ -1639,4 +1644,9 @@ static inline struct pcc_super *ll_info2pccs(struct ll_inode_info *lli)
        return ll_i2pccs(ll_info2i(lli));
 }
 
        return ll_i2pccs(ll_info2i(lli));
 }
 
+#ifdef HAVE_LUSTRE_CRYPTO
+/* crypto.c */
+extern const struct llcrypt_operations lustre_cryptops;
+#endif
+
 #endif /* LLITE_INTERNAL_H */
 #endif /* LLITE_INTERNAL_H */
index 254a641..78ff536 100644 (file)
@@ -166,6 +166,7 @@ static struct ll_sb_info *ll_init_sbi(void)
        sbi->ll_flags |= LL_SBI_AGL_ENABLED;
        sbi->ll_flags |= LL_SBI_FAST_READ;
        sbi->ll_flags |= LL_SBI_TINY_WRITE;
        sbi->ll_flags |= LL_SBI_AGL_ENABLED;
        sbi->ll_flags |= LL_SBI_FAST_READ;
        sbi->ll_flags |= LL_SBI_TINY_WRITE;
+       ll_sbi_set_encrypt(sbi, true);
 
        /* root squash */
        sbi->ll_squash.rsi_uid = 0;
 
        /* root squash */
        sbi->ll_squash.rsi_uid = 0;
@@ -559,6 +560,9 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
 #if THREAD_SIZE >= 8192 /*b=17630*/
        sb->s_export_op = &lustre_export_operations;
 #endif
 #if THREAD_SIZE >= 8192 /*b=17630*/
        sb->s_export_op = &lustre_export_operations;
 #endif
+#ifdef HAVE_LUSTRE_CRYPTO
+       llcrypt_set_ops(sb, &lustre_cryptops);
+#endif
 
        /* make root inode
         * XXX: move this to after cbd setup? */
 
        /* make root inode
         * XXX: move this to after cbd setup? */
@@ -944,6 +948,25 @@ static int ll_options(char *options, struct ll_sb_info *sbi)
                        *flags |= tmp;
                        goto next;
                }
                        *flags |= tmp;
                        goto next;
                }
+               tmp = ll_set_opt("test_dummy_encryption", s1,
+                                LL_SBI_TEST_DUMMY_ENCRYPTION);
+               if (tmp) {
+#ifdef HAVE_LUSTRE_CRYPTO
+                       *flags |= tmp;
+#else
+                       LCONSOLE_WARN("Test dummy encryption mount option ignored: encryption not supported\n");
+#endif
+                       goto next;
+               }
+               tmp = ll_set_opt("noencrypt", s1, LL_SBI_ENCRYPT);
+               if (tmp) {
+#ifdef HAVE_LUSTRE_CRYPTO
+                       *flags &= ~tmp;
+#else
+                       LCONSOLE_WARN("noencrypt mount option ignored: encryption not supported\n");
+#endif
+                       goto next;
+               }
                 LCONSOLE_ERROR_MSG(0x152, "Unknown option '%s', won't mount.\n",
                                    s1);
                 RETURN(-EINVAL);
                 LCONSOLE_ERROR_MSG(0x152, "Unknown option '%s', won't mount.\n",
                                    s1);
                 RETURN(-EINVAL);
@@ -1635,6 +1658,8 @@ void ll_clear_inode(struct inode *inode)
         */
        cl_inode_fini(inode);
 
         */
        cl_inode_fini(inode);
 
+       llcrypt_put_encryption_info(inode);
+
        EXIT;
 }
 
        EXIT;
 }
 
@@ -2042,6 +2067,8 @@ void ll_inode_size_unlock(struct inode *inode)
 
 void ll_update_inode_flags(struct inode *inode, int ext_flags)
 {
 
 void ll_update_inode_flags(struct inode *inode, int ext_flags)
 {
+       /* do not clear encryption flag */
+       ext_flags |= ll_inode_to_ext_flags(inode->i_flags) & LUSTRE_ENCRYPT_FL;
        inode->i_flags = ll_ext_to_inode_flags(ext_flags);
        if (ext_flags & LUSTRE_PROJINHERIT_FL)
                ll_file_set_flag(ll_i2info(inode), LLIF_PROJECT_INHERIT);
        inode->i_flags = ll_ext_to_inode_flags(ext_flags);
        if (ext_flags & LUSTRE_PROJINHERIT_FL)
                ll_file_set_flag(ll_i2info(inode), LLIF_PROJECT_INHERIT);
@@ -2793,6 +2820,14 @@ int ll_show_options(struct seq_file *seq, struct dentry *dentry)
        if (sbi->ll_flags & LL_SBI_ALWAYS_PING)
                seq_puts(seq, ",always_ping");
 
        if (sbi->ll_flags & LL_SBI_ALWAYS_PING)
                seq_puts(seq, ",always_ping");
 
+       if (ll_sbi_has_test_dummy_encryption(sbi))
+               seq_puts(seq, ",test_dummy_encryption");
+
+       if (ll_sbi_has_encrypt(sbi))
+               seq_puts(seq, ",encrypt");
+       else
+               seq_puts(seq, ",noencrypt");
+
        RETURN(0);
 }
 
        RETURN(0);
 }
 
index befd246..30397af 100644 (file)
@@ -61,6 +61,7 @@ static void ll_inode_destroy_callback(struct rcu_head *head)
 {
        struct inode *inode = container_of(head, struct inode, i_rcu);
        struct ll_inode_info *ptr = ll_i2info(inode);
 {
        struct inode *inode = container_of(head, struct inode, i_rcu);
        struct ll_inode_info *ptr = ll_i2info(inode);
+       llcrypt_free_inode(inode);
        OBD_SLAB_FREE_PTR(ptr, ll_inode_cachep);
 }
 
        OBD_SLAB_FREE_PTR(ptr, ll_inode_cachep);
 }
 
index 0006f16..8f45fb9 100644 (file)
@@ -356,8 +356,7 @@ int mdd_is_subdir(const struct lu_env *env, struct md_object *mo,
  *           -ve        other error
  *
  */
  *           -ve        other error
  *
  */
-static int mdd_dir_is_empty(const struct lu_env *env,
-                            struct mdd_object *dir)
+int mdd_dir_is_empty(const struct lu_env *env, struct mdd_object *dir)
 {
        struct dt_it     *it;
        struct dt_object *obj;
 {
        struct dt_it     *it;
        struct dt_object *obj;
index a5bc753..5a502f9 100644 (file)
@@ -312,6 +312,7 @@ int mdd_orphan_declare_insert(const struct lu_env *env, struct mdd_object *obj,
                              umode_t mode, struct thandle *thandle);
 int mdd_orphan_declare_delete(const struct lu_env *env, struct mdd_object *obj,
                              struct thandle *thandle);
                              umode_t mode, struct thandle *thandle);
 int mdd_orphan_declare_delete(const struct lu_env *env, struct mdd_object *obj,
                              struct thandle *thandle);
+int mdd_dir_is_empty(const struct lu_env *env, struct mdd_object *dir);
 
 /* mdd_lproc.c */
 int mdd_procfs_init(struct mdd_device *mdd, const char *name);
 
 /* mdd_lproc.c */
 int mdd_procfs_init(struct mdd_device *mdd, const char *name);
index df5bea0..d30599a 100644 (file)
@@ -735,8 +735,17 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj,
                    !md_capable(uc, CFS_CAP_LINUX_IMMUTABLE))
                        RETURN(-EPERM);
 
                    !md_capable(uc, CFS_CAP_LINUX_IMMUTABLE))
                        RETURN(-EPERM);
 
-               if (!S_ISDIR(oattr->la_mode))
+               if (!S_ISDIR(oattr->la_mode)) {
                        la->la_flags &= ~(LUSTRE_DIRSYNC_FL | LUSTRE_TOPDIR_FL);
                        la->la_flags &= ~(LUSTRE_DIRSYNC_FL | LUSTRE_TOPDIR_FL);
+               } else if (la->la_flags & LUSTRE_ENCRYPT_FL) {
+                       /* when trying to add encryption flag on dir,
+                        * make sure it is empty
+                        */
+                       rc = mdd_dir_is_empty(env, obj);
+                       if (rc)
+                               RETURN(rc);
+                       rc = 0;
+               }
        }
 
        if (oattr->la_flags & (LUSTRE_IMMUTABLE_FL | LUSTRE_APPEND_FL) &&
        }
 
        if (oattr->la_flags & (LUSTRE_IMMUTABLE_FL | LUSTRE_APPEND_FL) &&
index 027ded0..88f3576 100644 (file)
@@ -2704,6 +2704,10 @@ static int osd_attr_get(const struct lu_env *env, struct dt_object *dt,
                attr->la_valid |= LA_FLAGS;
                attr->la_flags |= LUSTRE_ORPHAN_FL;
        }
                attr->la_valid |= LA_FLAGS;
                attr->la_flags |= LUSTRE_ORPHAN_FL;
        }
+       if (obj->oo_lma_flags & LUSTRE_ENCRYPT_FL) {
+               attr->la_valid |= LA_FLAGS;
+               attr->la_flags |= LUSTRE_ENCRYPT_FL;
+       }
        spin_unlock(&obj->oo_guard);
 
        if (S_ISDIR(obj->oo_inode->i_mode) &&
        spin_unlock(&obj->oo_guard);
 
        if (S_ISDIR(obj->oo_inode->i_mode) &&
index 737ec68..9887b58 100644 (file)
@@ -715,6 +715,8 @@ int __osd_xattr_get_large(const struct lu_env *env, struct osd_device *osd,
                          const char *name, int *sizep);
 int osd_xattr_get_internal(const struct lu_env *env, struct osd_object *obj,
                           struct lu_buf *buf, const char *name, int *sizep);
                          const char *name, int *sizep);
 int osd_xattr_get_internal(const struct lu_env *env, struct osd_object *obj,
                           struct lu_buf *buf, const char *name, int *sizep);
+int osd_xattr_get_lma(const struct lu_env *env, struct osd_object *obj,
+                     struct lu_buf *buf);
 int osd_xattr_get(const struct lu_env *env, struct dt_object *dt,
                  struct lu_buf *buf, const char *name);
 int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt,
 int osd_xattr_get(const struct lu_env *env, struct dt_object *dt,
                  struct lu_buf *buf, const char *name);
 int osd_declare_xattr_set(const struct lu_env *env, struct dt_object *dt,
index cce661c..8293a01 100644 (file)
@@ -186,9 +186,11 @@ osd_object_sa_bulk_update(struct osd_object *obj, sa_bulk_attr_t *attrs,
 static int __osd_object_attr_get(const struct lu_env *env, struct osd_device *o,
                                 struct osd_object *obj, struct lu_attr *la)
 {
 static int __osd_object_attr_get(const struct lu_env *env, struct osd_device *o,
                                 struct osd_object *obj, struct lu_attr *la)
 {
-       struct osa_attr *osa = &osd_oti_get(env)->oti_osa;
-       sa_bulk_attr_t  *bulk = osd_oti_get(env)->oti_attr_bulk;
-       int              cnt = 0;
+       struct osa_attr *osa = &osd_oti_get(env)->oti_osa;
+       sa_bulk_attr_t *bulk = osd_oti_get(env)->oti_attr_bulk;
+       struct lustre_mdt_attrs *lma;
+       struct lu_buf buf;
+       int cnt = 0;
        int              rc;
        ENTRY;
 
        int              rc;
        ENTRY;
 
@@ -244,27 +246,22 @@ static int __osd_object_attr_get(const struct lu_env *env, struct osd_device *o,
        la->la_flags = attrs_zfs2fs(osa->flags);
        la->la_size = osa->size;
 
        la->la_flags = attrs_zfs2fs(osa->flags);
        la->la_size = osa->size;
 
-       /* Try to get extra flag from LMA. Right now, only LMAI_ORPHAN
-        * flags is stored in LMA, and it is only for orphan directory */
-       if (S_ISDIR(la->la_mode) && dt_object_exists(&obj->oo_dt)) {
-               struct osd_thread_info *info = osd_oti_get(env);
-               struct lustre_mdt_attrs *lma;
-               struct lu_buf buf;
-
-               lma = (struct lustre_mdt_attrs *)info->oti_buf;
-               buf.lb_buf = lma;
-               buf.lb_len = sizeof(info->oti_buf);
-               rc = osd_xattr_get(env, &obj->oo_dt, &buf, XATTR_NAME_LMA);
-               if (rc > 0) {
-                       rc = 0;
-                       lma->lma_incompat = le32_to_cpu(lma->lma_incompat);
-                       obj->oo_lma_flags =
-                               lma_to_lustre_flags(lma->lma_incompat);
-
-               } else if (rc == -ENODATA) {
-                       rc = 0;
-               }
+       /* Try to get extra flags from LMA */
+       lma = (struct lustre_mdt_attrs *)osd_oti_get(env)->oti_buf;
+       buf.lb_buf = lma;
+       buf.lb_len = sizeof(osd_oti_get(env)->oti_buf);
+       down_read(&obj->oo_guard);
+       rc = osd_xattr_get_lma(env, obj, &buf);
+       if (!rc) {
+               lma->lma_incompat = le32_to_cpu(lma->lma_incompat);
+               obj->oo_lma_flags =
+                       lma_to_lustre_flags(lma->lma_incompat);
+       } else if (rc == -ENODATA ||
+                  !(S_ISDIR(la->la_mode) &&
+                    dt_object_exists(&obj->oo_dt))) {
+               rc = 0;
        }
        }
+       up_read(&obj->oo_guard);
 
        if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode)) {
                rc = -sa_lookup(obj->oo_sa_hdl, SA_ZPL_RDEV(o), &osa->rdev, 8);
 
        if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode)) {
                rc = -sa_lookup(obj->oo_sa_hdl, SA_ZPL_RDEV(o), &osa->rdev, 8);
@@ -1013,6 +1010,10 @@ static int osd_attr_get(const struct lu_env *env, struct dt_object *dt,
                attr->la_valid |= LA_FLAGS;
                attr->la_flags |= LUSTRE_ORPHAN_FL;
        }
                attr->la_valid |= LA_FLAGS;
                attr->la_flags |= LUSTRE_ORPHAN_FL;
        }
+       if (obj->oo_lma_flags & LUSTRE_ENCRYPT_FL) {
+               attr->la_valid |= LA_FLAGS;
+               attr->la_flags |= LUSTRE_ENCRYPT_FL;
+       }
        read_unlock(&obj->oo_attr_lock);
        if (attr->la_valid & LA_FLAGS && attr->la_flags & LUSTRE_ORPHAN_FL)
                CDEBUG(D_INFO, "%s: set orphan flag on "DFID" (%llx/%x)\n",
        read_unlock(&obj->oo_attr_lock);
        if (attr->la_valid & LA_FLAGS && attr->la_flags & LUSTRE_ORPHAN_FL)
                CDEBUG(D_INFO, "%s: set orphan flag on "DFID" (%llx/%x)\n",
@@ -1339,6 +1340,9 @@ static int osd_attr_set(const struct lu_env *env, struct dt_object *dt,
                                CWARN("%s: failed to set LMA flags: rc = %d\n",
                                       osd->od_svname, rc);
                                GOTO(out, rc);
                                CWARN("%s: failed to set LMA flags: rc = %d\n",
                                       osd->od_svname, rc);
                                GOTO(out, rc);
+                       } else {
+                               obj->oo_lma_flags =
+                                       la->la_flags & LUSTRE_LMA_FL_MASKS;
                        }
                }
        }
                        }
                }
        }
index 91ed638..e50f23f 100644 (file)
@@ -223,6 +223,46 @@ int osd_xattr_get_internal(const struct lu_env *env, struct osd_object *obj,
                                     buf, name, sizep);
 }
 
                                     buf, name, sizep);
 }
 
+/**
+ * Copy LMA extended attribute into provided buffer
+ *
+ * Note that no locking is done here.
+ *
+ * \param[in] env      execution environment
+ * \param[in] obj      object for which to retrieve xattr
+ * \param[out] buf     buffer to store xattr value in
+ *
+ * \retval 0           on success
+ * \retval negative    negated errno on failure
+ */
+int osd_xattr_get_lma(const struct lu_env *env, struct osd_object *obj,
+                     struct lu_buf *buf)
+{
+       int size = 0;
+       int rc = -ENOENT;
+
+       if (!buf)
+               return 0;
+
+       if (unlikely(obj->oo_destroyed))
+               goto out_lma;
+
+       /* check SA_ZPL_DXATTR first then fallback to directory xattr */
+       rc = __osd_sa_xattr_get(env, obj, buf, XATTR_NAME_LMA, &size);
+       if (!rc && unlikely(size < sizeof(struct lustre_mdt_attrs)))
+               rc = -EINVAL;
+       if (rc != -ENOENT)
+               goto out_lma;
+
+       rc = __osd_xattr_get_large(env, osd_obj2dev(obj), obj->oo_xattr,
+                                    buf, XATTR_NAME_LMA, &size);
+       if (!rc && unlikely(size < sizeof(struct lustre_mdt_attrs)))
+               rc = -EINVAL;
+
+out_lma:
+       return rc;
+}
+
 static int osd_get_pfid_from_lma(const struct lu_env *env,
                                 struct osd_object *obj,
                                 struct lu_buf *buf, int *sizep)
 static int osd_get_pfid_from_lma(const struct lu_env *env,
                                 struct osd_object *obj,
                                 struct lu_buf *buf, int *sizep)
index 019d45e..50cef04 100644 (file)
@@ -451,6 +451,8 @@ void lustre_assert_wire_constants(void)
                (unsigned)LMAI_STRIPED);
        LASSERTF(LMAI_ORPHAN == 0x00000010UL, "found 0x%.8xUL\n",
                (unsigned)LMAI_ORPHAN);
                (unsigned)LMAI_STRIPED);
        LASSERTF(LMAI_ORPHAN == 0x00000010UL, "found 0x%.8xUL\n",
                (unsigned)LMAI_ORPHAN);
+       LASSERTF(LMAI_ENCRYPT == 0x00000020UL, "found 0x%.8xUL\n",
+                (unsigned)LMAI_ENCRYPT);
 
        /* Checks for struct lustre_ost_attrs */
        LASSERTF((int)sizeof(struct lustre_ost_attrs) == 64, "found %lld\n",
 
        /* Checks for struct lustre_ost_attrs */
        LASSERTF((int)sizeof(struct lustre_ost_attrs) == 64, "found %lld\n",
@@ -2575,6 +2577,8 @@ void lustre_assert_wire_constants(void)
                (unsigned)LUSTRE_INLINE_DATA_FL);
        LASSERTF(LUSTRE_SET_SYNC_FL == 0x00040000UL, "found 0x%.8xUL\n",
                (unsigned)LUSTRE_SET_SYNC_FL);
                (unsigned)LUSTRE_INLINE_DATA_FL);
        LASSERTF(LUSTRE_SET_SYNC_FL == 0x00040000UL, "found 0x%.8xUL\n",
                (unsigned)LUSTRE_SET_SYNC_FL);
+       LASSERTF(LUSTRE_ENCRYPT_FL == 0x00800000UL, "found 0x%.8xUL\n",
+                (unsigned)LUSTRE_ENCRYPT_FL);
        LASSERTF(MDS_INODELOCK_LOOKUP == 0x00000001UL, "found 0x%.8xUL\n",
                (unsigned)MDS_INODELOCK_LOOKUP);
        LASSERTF(MDS_INODELOCK_UPDATE == 0x00000002UL, "found 0x%.8xUL\n",
        LASSERTF(MDS_INODELOCK_LOOKUP == 0x00000001UL, "found 0x%.8xUL\n",
                (unsigned)MDS_INODELOCK_LOOKUP);
        LASSERTF(MDS_INODELOCK_UPDATE == 0x00000002UL, "found 0x%.8xUL\n",
index 566a8d5..820dc7f 100644 (file)
@@ -52,6 +52,9 @@
 #include <linux/lustre/lustre_ver.h>
 #include <ctype.h>
 #include <limits.h>
 #include <linux/lustre/lustre_ver.h>
 #include <ctype.h>
 #include <limits.h>
+#if defined(HAVE_LUSTRE_CRYPTO) && defined(HAVE_LIBKEYUTILS)
+#include <keyutils.h>
+#endif
 #include <linux/lnet/nidstr.h>
 #include <libcfs/util/string.h>
 
 #include <linux/lnet/nidstr.h>
 #include <libcfs/util/string.h>
 
@@ -116,6 +119,12 @@ void usage(FILE *out)
                "\t\t(no)lazystatfs: disable or enable* statfs to work if OST is unavailable\n"
                "\t\t32bitapi: return only 32-bit inode numbers to userspace\n"
                "\t\t(no)verbose: disable or enable* messages at filesystem (un,re)mount\n"
                "\t\t(no)lazystatfs: disable or enable* statfs to work if OST is unavailable\n"
                "\t\t32bitapi: return only 32-bit inode numbers to userspace\n"
                "\t\t(no)verbose: disable or enable* messages at filesystem (un,re)mount\n"
+#ifdef HAVE_LUSTRE_CRYPTO
+#ifdef HAVE_LIBKEYUTILS
+               "\t\ttest_dummy_encryption: enable test dummy encryption mode\n"
+#endif
+               "\t\tnoencrypt: disable client side encryption\n"
+#endif
                );
        exit((out != stdout) ? EINVAL : 0);
 }
                );
        exit((out != stdout) ? EINVAL : 0);
 }
@@ -345,6 +354,52 @@ int parse_options(struct mount_opts *mop, char *orig_options,
                        strncpy(mop->mo_skpath, val + 1,
                                sizeof(mop->mo_skpath) - 1);
 #endif
                        strncpy(mop->mo_skpath, val + 1,
                                sizeof(mop->mo_skpath) - 1);
 #endif
+#ifdef HAVE_LUSTRE_CRYPTO
+               } else if (strncmp(arg, "test_dummy_encryption", 21) == 0) {
+#ifdef HAVE_LIBKEYUTILS
+                       /* Using dummy encryption mode requires inserting a
+                        * special dummy key into the session keyring.
+                        * Key type is "logon", key description is
+                        * "fscrypt:4242424242424242", and key payload has to be
+                        * in the form <mode><raw><size>, where:
+                        * <mode> is "\x00\x00\x00\x00"
+                        * <raw> is "$(printf ""\\\\x%02x"" {0..63})"
+                        * <size> is "\x40\x00\x00\x00" for little endian,
+                        * "\x00\x00\x00\x40" for big endian.
+                        */
+                       char payload[72];
+                       int *p = (int *)payload;
+                       char *q = (char *)(p + 1);
+                       int i = 0;
+                       key_serial_t key;
+
+                       *p = 0;
+                       while (i < 0x40)
+                               *(q++) = i++;
+                       p = (int *)q;
+                       *p = 0x40;
+
+                       key = add_key("logon", "fscrypt:4242424242424242",
+                                     (const void *)payload, sizeof(payload),
+                                     KEY_SPEC_SESSION_KEYRING);
+
+                       if (key == -1) {
+                               fprintf(stderr,
+                                       "%s: test dummy encryption option ignored: could not insert dummy encryption key into session keyring\n",
+                                       progname);
+                       } else {
+                               /* pass this on as an option */
+                               rc = append_option(options, options_len, opt,
+                                                  NULL);
+                               if (rc != 0)
+                                       goto out_options;
+                       }
+#else /* HAVE_LIBKEYUTILS */
+                       fprintf(stderr,
+                               "%s: test dummy encryption option ignored: Lustre not built with libkeyutils support\n",
+                               progname);
+#endif
+#endif
                } else if (parse_one_option(opt, flagp) == 0) {
                        /* pass this on as an option */
                        rc = append_option(options, options_len, opt, NULL);
                } else if (parse_one_option(opt, flagp) == 0) {
                        /* pass this on as an option */
                        rc = append_option(options, options_len, opt, NULL);
index c4d5e33..5f200da 100644 (file)
@@ -221,6 +221,7 @@ check_lustre_mdt_attrs(void)
        CHECK_VALUE_X(LMAI_REMOTE_PARENT);
        CHECK_VALUE_X(LMAI_STRIPED);
        CHECK_VALUE_X(LMAI_ORPHAN);
        CHECK_VALUE_X(LMAI_REMOTE_PARENT);
        CHECK_VALUE_X(LMAI_STRIPED);
        CHECK_VALUE_X(LMAI_ORPHAN);
+       CHECK_VALUE_X(LMAI_ENCRYPT);
 }
 
 static void
 }
 
 static void
@@ -1178,6 +1179,7 @@ check_mdt_body(void)
        CHECK_VALUE_X(LUSTRE_TOPDIR_FL);
        CHECK_VALUE_X(LUSTRE_INLINE_DATA_FL);
        CHECK_VALUE_X(LUSTRE_SET_SYNC_FL);
        CHECK_VALUE_X(LUSTRE_TOPDIR_FL);
        CHECK_VALUE_X(LUSTRE_INLINE_DATA_FL);
        CHECK_VALUE_X(LUSTRE_SET_SYNC_FL);
+       CHECK_VALUE_X(LUSTRE_ENCRYPT_FL);
 
        CHECK_VALUE_X(MDS_INODELOCK_LOOKUP);
        CHECK_VALUE_X(MDS_INODELOCK_UPDATE);
 
        CHECK_VALUE_X(MDS_INODELOCK_LOOKUP);
        CHECK_VALUE_X(MDS_INODELOCK_UPDATE);
index 3c9d0a4..6ff30e6 100644 (file)
@@ -477,6 +477,8 @@ void lustre_assert_wire_constants(void)
                (unsigned)LMAI_STRIPED);
        LASSERTF(LMAI_ORPHAN == 0x00000010UL, "found 0x%.8xUL\n",
                (unsigned)LMAI_ORPHAN);
                (unsigned)LMAI_STRIPED);
        LASSERTF(LMAI_ORPHAN == 0x00000010UL, "found 0x%.8xUL\n",
                (unsigned)LMAI_ORPHAN);
+       LASSERTF(LMAI_ENCRYPT == 0x00000020UL, "found 0x%.8xUL\n",
+                (unsigned)LMAI_ENCRYPT);
 
        /* Checks for struct lustre_ost_attrs */
        LASSERTF((int)sizeof(struct lustre_ost_attrs) == 64, "found %lld\n",
 
        /* Checks for struct lustre_ost_attrs */
        LASSERTF((int)sizeof(struct lustre_ost_attrs) == 64, "found %lld\n",
@@ -2601,6 +2603,8 @@ void lustre_assert_wire_constants(void)
                (unsigned)LUSTRE_INLINE_DATA_FL);
        LASSERTF(LUSTRE_SET_SYNC_FL == 0x00040000UL, "found 0x%.8xUL\n",
                (unsigned)LUSTRE_SET_SYNC_FL);
                (unsigned)LUSTRE_INLINE_DATA_FL);
        LASSERTF(LUSTRE_SET_SYNC_FL == 0x00040000UL, "found 0x%.8xUL\n",
                (unsigned)LUSTRE_SET_SYNC_FL);
+       LASSERTF(LUSTRE_ENCRYPT_FL == 0x00800000UL, "found 0x%.8xUL\n",
+                (unsigned)LUSTRE_ENCRYPT_FL);
        LASSERTF(MDS_INODELOCK_LOOKUP == 0x00000001UL, "found 0x%.8xUL\n",
                (unsigned)MDS_INODELOCK_LOOKUP);
        LASSERTF(MDS_INODELOCK_UPDATE == 0x00000002UL, "found 0x%.8xUL\n",
        LASSERTF(MDS_INODELOCK_LOOKUP == 0x00000001UL, "found 0x%.8xUL\n",
                (unsigned)MDS_INODELOCK_LOOKUP);
        LASSERTF(MDS_INODELOCK_UPDATE == 0x00000002UL, "found 0x%.8xUL\n",