Whamcloud - gitweb
Branch: HEAD
authorwangdi <wangdi>
Fri, 5 Aug 2005 14:45:34 +0000 (14:45 +0000)
committerwangdi <wangdi>
Fri, 5 Aug 2005 14:45:34 +0000 (14:45 +0000)
land crypto api

70 files changed:
lustre/autoconf/lustre-core.m4
lustre/cmobd/cm_mds_reint.c
lustre/cobd/cache_obd.c
lustre/include/liblustre.h
lustre/include/linux/lustre_fsfilt.h
lustre/include/linux/lustre_gs.h [new file with mode: 0644]
lustre/include/linux/lustre_idl.h
lustre/include/linux/lustre_lite.h
lustre/include/linux/lustre_mds.h
lustre/include/linux/lustre_net.h
lustre/include/linux/obd.h
lustre/include/linux/obd_class.h
lustre/include/lustre/lustre_user.h
lustre/kernel_patches/patches/ext3-mballoc2-2.6.10-fc3.patch
lustre/kernel_patches/series/2.6-fc3-uml.series
lustre/ldlm/ldlm_lib.c
lustre/ldlm/ldlm_resource.c
lustre/liblustre/llite_lib.h
lustre/llite/Makefile.in
lustre/llite/dcache.c
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_close.c
lustre/llite/llite_gs.c [new file with mode: 0644]
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/namei.c
lustre/llite/rw.c
lustre/lmv/lmv_obd.c
lustre/lov/lov_obd.c
lustre/lvfs/fsfilt_ext3.c
lustre/mdc/mdc_internal.h
lustre/mdc/mdc_lib.c
lustre/mdc/mdc_locks.c
lustre/mdc/mdc_reint.c
lustre/mdc/mdc_request.c
lustre/mds/handler.c
lustre/mds/mds_internal.h
lustre/mds/mds_lib.c
lustre/mds/mds_open.c
lustre/mds/mds_reint.c
lustre/obdclass/obd_config.c
lustre/obdfilter/filter.c
lustre/obdfilter/filter_io.c
lustre/osc/osc_create.c
lustre/osc/osc_request.c
lustre/ptlrpc/import.c
lustre/ptlrpc/pack_generic.c
lustre/ptlrpc/ptlrpc_module.c
lustre/sec/Makefile.in
lustre/sec/autoMakefile.am
lustre/sec/gks/Makefile.in [new file with mode: 0644]
lustre/sec/gks/Makefile.mk [new file with mode: 0644]
lustre/sec/gks/autoMakefile.am [new file with mode: 0644]
lustre/sec/gks/gks_client.c [new file with mode: 0644]
lustre/sec/gks/gks_internal.h [new file with mode: 0644]
lustre/sec/gks/gks_server.c [new file with mode: 0644]
lustre/sec/gks/lproc_gks.c [new file with mode: 0644]
lustre/smfs/fsfilt.c
lustre/smfs/mds_kml.c
lustre/tests/cfg/lmv.sh
lustre/tests/lgs.sh [new file with mode: 0755]
lustre/tests/sanity-crypto.sh [new file with mode: 0755]
lustre/tests/test-framework.sh
lustre/utils/lconf
lustre/utils/lctl.c
lustre/utils/lmc
lustre/utils/lustre_cfg.c
lustre/utils/obd.c
lustre/utils/obdctl.h

index cb91310..8012e79 100644 (file)
@@ -580,6 +580,8 @@ lustre/sec/Makefile
 lustre/sec/autoMakefile
 lustre/sec/gss/Makefile
 lustre/sec/gss/autoMakefile
+lustre/sec/gks/Makefile
+lustre/sec/gks/autoMakefile
 lustre/smfs/Makefile
 lustre/smfs/autoMakefile
 lustre/snapfs/Makefile
index decd816..c51923e 100644 (file)
@@ -125,7 +125,7 @@ static int cmobd_reint_setattr(struct obd_device *obd, void *record)
         ea2len = ea2 ? msg->buflens[2] : 0;
 
         rc = md_setattr(cmobd->master_exp, op_data, &iattr,
-                        ea1, ea1len, ea2, ea2len, &req);
+                        ea1, ea1len, ea2, ea2len, NULL, 0, &req);
         OBD_FREE(op_data, sizeof(*op_data));
 
         if (req)
index d7007ba..ab37de8 100644 (file)
@@ -1116,7 +1116,8 @@ static int cobd_md_link(struct obd_export *exp, struct mdc_op_data *data,
 
 static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data,
                            struct iattr *iattr, void *ea, int ealen, void *ea2, 
-                           int ea2len, struct ptlrpc_request **request)
+                           int ea2len, void *ea3, int ea3len, 
+                           struct ptlrpc_request **request)
 {
         struct obd_device *obd = class_exp2obd(exp);
         struct obd_export *cobd_exp;
@@ -1128,7 +1129,7 @@ static int cobd_md_setattr(struct obd_export *exp, struct mdc_op_data *data,
         }
         cobd_exp = cobd_get_exp(obd);
         return md_setattr(cobd_exp, data, iattr, ea,
-                          ealen, ea2, ea2len, request);
+                          ealen, ea2, ea2len, ea3, ea3len, request);
 }
 
 static int cobd_md_readpage(struct obd_export *exp,
index 72fb1aa..56ed008 100644 (file)
@@ -499,6 +499,8 @@ struct lustre_intent_data {
         void    *it_data;
         int     it_lock_mode;
         int     it_int_flags;
+        void    *it_key;
+        int     it_key_size;
 };
 
 #define LUSTRE_IT(it) ((struct lustre_intent_data *)((it)->d.fs_data))
index 5c9ecd0..86a6d76 100644 (file)
@@ -44,7 +44,8 @@ enum ea_type {
         EA_LOV   = (1 << 0),
         EA_MEA   = (1 << 1),
         EA_SID   = (1 << 2),
-        EA_MID   = (1 << 3)
+        EA_MID   = (1 << 3),
+        EA_KEY   = (1 << 4)
 };
 
 struct fsfilt_operations {
diff --git a/lustre/include/linux/lustre_gs.h b/lustre/include/linux/lustre_gs.h
new file mode 100644 (file)
index 0000000..d155efd
--- /dev/null
@@ -0,0 +1,161 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2001-2003 Cluster File Systems, Inc. <info@clusterfs.com>
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * GS data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ *
+ */
+
+#ifndef _LUSTRE_GS_H
+#define _LUSTRE_GS_H
+
+#define LUSTRE_GKS_NAME "gks"
+#define LUSTRE_GKT_NAME "gkt"
+#define LUSTRE_GKC_NAME "gkc"
+
+
+/*define gsk type*/
+#define NO_CRYPTO 0
+#define GKS_TYPE  1
+#define MKS_TYPE  2  
+
+struct crypto_ops_item {
+        struct crypto_helper_ops *cops;
+        struct list_head clist;
+        char   *ctype;
+};
+
+#define DECRYPT_DATA      0x00000001
+#define ENCRYPT_DATA      0x00000002
+struct lustre_key {
+        struct crypto_key   lk_ck;
+        atomic_t            lk_refcount;
+        __u32               lk_key_type;
+        __u32               lk_flags; 
+};
+static inline struct lustre_key *
+lustre_key_get(struct lustre_key *lkey)
+{
+        if (lkey) { 
+                atomic_inc(&lkey->lk_refcount);
+        }
+        return lkey;
+}
+
+
+static inline void
+lustre_key_release(struct lustre_key *lkey)
+{
+        if (lkey && atomic_dec_and_test(&lkey->lk_refcount))
+                kfree(lkey);
+}
+
+#define SET_CRYPTO_FLAGS(flags, type, offset, width)           \
+do {                                                           \
+        flags &= ~(((1 << width) - 1) << offset);              \
+        flags |= (type & ((1 << width) - 1)) << offset;        \
+} while(0)
+
+#define CPT_TYPE_OFFSET 0
+#define CPT_TYPE_WIDTH  2 
+#define GKS_CRYPTO_TYPE 1
+#define MKS_CRYPTO_TYPE 2
+
+#define SET_CRYPTO_TYPE(flags, type)                           \
+SET_CRYPTO_FLAGS(flags, type, CPT_TYPE_OFFSET, CPT_TYPE_WIDTH)
+
+#define IS_GKS_TYPE(flags)                                      \
+(((flags >> CPT_TYPE_OFFSET) & ((1 << CPT_TYPE_WIDTH) - 1)) == GKS_CRYPTO_TYPE)
+
+#define IS_MKS_TYPE(flags)                                      \
+(((flags >> CPT_TYPE_OFFSET) & ((1 << CPT_TYPE_WIDTH) - 1)) == MKS_CRYPTO_TYPE)
+
+#define CPT_ENCRYPT_OFFSET 2 
+#define CPT_ENCRYPT_WIDTH  1 
+#define ENABLE_ENCRYPT_FLAG 1
+#define DISABLE_ENCRYPT_FLAG 0 
+
+#define ENABLE_ENCRYPT(flag) \
+SET_CRYPTO_FLAGS(flag, ENABLE_ENCRYPT_FLAG, CPT_ENCRYPT_OFFSET, CPT_ENCRYPT_WIDTH)
+
+#define DISABLE_ENCRYPT(flag) \
+SET_CRYPTO_FLAGS(flag, DISABLE_ENCRYPT_FLAG, CPT_ENCRYPT_OFFSET, CPT_ENCRYPT_WIDTH)
+
+#define IS_ENABLE_ENCRYPT(flags)                                 \
+(((flags >> CPT_ENCRYPT_OFFSET) & ((1 << CPT_ENCRYPT_WIDTH) - 1)) \
+                                == ENABLE_ENCRYPT_FLAG)
+
+#define CPT_DECRYPT_OFFSET 3 
+#define CPT_DECRYPT_WIDTH  1 
+#define ENABLE_DECRYPT_FLAG 1
+#define DISABLE_DECRYPT_FLAG 2
+
+#define ENABLE_DECRYPT(flag) \
+SET_CRYPTO_FLAGS(flag, ENABLE_DECRYPT_FLAG, CPT_DECRYPT_OFFSET, CPT_DECRYPT_WIDTH)
+
+#define DISABLE_DECRYPT(flag) \
+SET_CRYPTO_FLAGS(flag, DISABLE_DECRYPT_FLAG, CPT_DECRYPT_OFFSET, CPT_DECRYPT_WIDTH)
+
+#define IS_ENABLE_DECRYPT(flags)                                 \
+(((flags >> CPT_DECRYPT_OFFSET) & ((1 << CPT_DECRYPT_WIDTH) - 1)) \
+                                == ENABLE_DECRYPT_FLAG)
+
+#define CPT_DECRYPTED_OFFSET 4 
+#define CPT_DECRYPTED_WIDTH  1 
+#define DECRYPTED_FLAG 1
+#define ENCRYPTED_FLAG 0 
+
+#define SET_DECRYPTED(flag) \
+SET_CRYPTO_FLAGS(flag, DECRYPTED_FLAG, CPT_DECRYPTED_OFFSET, CPT_DECRYPTED_WIDTH)
+
+#define SET_UNDECRYPTED(flag) \
+SET_CRYPTO_FLAGS(flag, ENCRYPTED_FLAG, CPT_DECRYPTED_OFFSET, CPT_DECRYPTED_WIDTH)
+
+#define IS_DECRYPTED(flags) \
+(((flags >> CPT_DECRYPTED_OFFSET) & ((1 << CPT_DECRYPTED_WIDTH) - 1)) \
+                                == DECRYPTED_FLAG)
+
+
+
+#define MD_KEY_MAGIC 0x19760218
+struct crypto_key_md {
+        struct crypto_key md_ck;
+        __u32             md_magic;
+};
+
+struct key_parms {
+        struct key_context *context;
+        struct key_perm    *perm; 
+        int                 context_size;
+        int                 perm_size;
+};
+
+static inline int crypto_kcontext_size(int acl_count) 
+{
+       return (sizeof(struct key_context) + acl_count * 
+               sizeof(struct posix_acl_entry));
+}
+static inline int crypto_kperm_size(int acl_count)
+{
+        return (sizeof(struct key_perm) + acl_count * 
+                       sizeof(struct posix_acl_entry));
+}
+#endif /*LUSTRE_GS_H*/
index e26217c..030199a 100644 (file)
@@ -61,6 +61,7 @@
 # include <linux/list.h>
 # include <linux/string.h> /* for strncpy, below */
 # include <linux/fs.h>     /* to check for FMODE_EXEC, dev_t, lest we redefine */
+# include <linux/posix_acl.h>     
 #else
 #ifdef __CYGWIN__
 # include <sys/types.h>
 #define MGMT_REPLY_PORTAL              25
 #define MGMT_CLI_REQUEST_PORTAL        26
 #define MGMT_CLI_REPLY_PORTAL          27
+#define GKS_REQUEST_PORTAL             28
+#define GKC_REPLY_PORTAL               29
 
 #define SVC_KILLED               1
 #define SVC_EVENT                2
 #define LUSTRE_DLM_VERSION  0x00040000
 #define LUSTRE_LOG_VERSION  0x00050000
 #define LUSTRE_PBD_VERSION  0x00060000
+#define LUSTRE_GKS_VERSION  0x00070000
 
 struct lustre_handle {
         __u64 cookie;
@@ -417,13 +421,14 @@ struct lov_mds_md_v0 {            /* LOV EA mds/wire data (little-endian) */
 #define OBD_MD_FLXATTRLIST (0x0000000200000000LL) /* user xattr list */
 #define OBD_MD_FLACL    (0x0000000400000000LL)    /* acl */
 #define OBD_MD_FLRMTACL (0x0000000800000000LL)    /* remote acl */
+#define OBD_MD_FLKEY        (0x0000001000000000LL)    /* mds key extended attributes */
 
 #define OBD_MD_FLNOTOBD (~(OBD_MD_FLBLOCKS | OBD_MD_LINKNAME |          \
                            OBD_MD_FLEASIZE | OBD_MD_FLHANDLE |          \
                            OBD_MD_FLCKSUM | OBD_MD_FLQOS |              \
                            OBD_MD_FLOSCOPQ | OBD_MD_FLCOOKIE |          \
                            OBD_MD_FLXATTR | OBD_MD_FLXATTRLIST |        \
-                           OBD_MD_FLACL | OBD_MD_MDS))
+                           OBD_MD_FLACL | OBD_MD_FLKEY | OBD_MD_MDS))
 
 static inline struct lustre_handle *obdo_handle(struct obdo *oa)
 {
@@ -687,6 +692,7 @@ struct lustre_md {
         struct mea             *mea;
         struct posix_acl       *posix_acl;
         struct mds_remote_perm *remote_perm;
+        struct lustre_key *key; 
 };
 
 void lustre_swab_remote_perm(struct mds_remote_perm *p);
@@ -735,6 +741,8 @@ struct mds_rec_setattr {
 #define ATTR_EA         0x00040000
 #define ATTR_EA_RM      0x00080000
 #define ATTR_EA_CMOBD   0x00100000
+#define ATTR_KEY        0x00200000
+#define ATTR_MAC        0x00400000
 extern void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa);
 
 #ifndef FMODE_READ
@@ -752,6 +760,7 @@ extern void lustre_swab_mds_rec_setattr (struct mds_rec_setattr *sa);
 #define MDS_OPEN_DIRECTORY       00200000
 
 #define MDS_OPEN_DELAY_CREATE    0100000000   /* delay initial object create */
+#define MDS_OPEN_HAS_KEY         01000000000 /* just set the EA the obj exist */
 #define MDS_OPEN_HAS_EA          010000000000 /* specify object create pattern */
 #define MDS_OPEN_HAS_OBJS        020000000000 /* just set the EA the obj exist */
 
@@ -764,6 +773,8 @@ struct mds_rec_create {
         struct lustre_id cr_replayid;
         __u64            cr_time;
         __u64            cr_rdev;
+        __u64            cr_enkey;
+        __u64            cr_mac;
 };
 
 extern void lustre_swab_mds_rec_create (struct mds_rec_create *cr);
@@ -1189,11 +1200,47 @@ typedef enum {
         SEC_LAST_OPC
 } sec_cmd_t;
 #define SEC_FIRST_OPC SEC_INIT
+/* GS opcodes*/
+typedef enum {
+        GKS_CONNECT      = 700,
+        GKS_DISCONNECT   = 701,
+        GKS_GET_KEY      = 702,
+        GKS_DECRYPT_KEY  = 703,
+        GKS_GET_MAC      = 704,
+} gks_cmd_t;
+
+#ifdef __KERNEL__
+#define KEY_SIZE        16 
+#define MAC_SIZE        16 
+
+struct crypto_key {
+        __u8    ck_mac[MAC_SIZE];
+        __u8    ck_key[KEY_SIZE];
+        __u32   ck_type;
+};
+
+struct key_perm {
+        uid_t    kp_uid;       
+        gid_t    kp_gid;
+        __u32    kp_mode;
+        __u32    kp_acl_count;
+        struct   posix_acl_entry kp_acls[0]; 
+};
 
+struct key_context {
+        struct crypto_key kc_ck;
+        __u32  kc_command;
+        __u32  kc_valid;
+        struct key_perm kc_perm;
+}; 
+typedef int (*crypt_cb_t)(struct page *page, __u64 offset, __u64 count, 
+                          int flags);
+extern void lustre_swab_key_context (struct key_context *kctxt);
+extern void lustre_swab_key_perms (struct key_perm *kperm);
+#endif /*for define __KERNEL*/
 extern void lustre_swab_lustre_id(struct lustre_id *id);
 extern void lustre_swab_lov_desc(struct lov_desc *desc);
 extern void lustre_swab_lustre_stc(struct lustre_stc *stc);
 extern void lustre_swab_lustre_fid(struct lustre_fid *fid);
 extern void lustre_swab_mds_status_req(struct mds_status_req *r);
-
 #endif
index b0ff350..66362f3 100644 (file)
@@ -114,9 +114,9 @@ struct ll_inode_info {
         __u64                   lli_open_fd_write_count;
         struct obd_client_handle *lli_mds_exec_och;
         __u64                   lli_open_fd_exec_count;
-
         struct posix_acl       *lli_posix_acl;
         struct remote_acl      *lli_remote_acl;
+        struct lustre_key      *lli_key_info;
 };
 
 // FIXME: replace the name of this with LL_I to conform to kernel stuff
@@ -177,6 +177,9 @@ struct lustre_intent_data {
         __u64   it_lock_handle;
         void    *it_data;
         int     it_lock_mode;
+        int     it_int_flags;
+        void    *it_key;
+        int     it_key_size;
 };
 #define LUSTRE_IT(it) ((struct lustre_intent_data *)((it)->d.fs_data))
 
index dcbda8a..63730a9 100644 (file)
@@ -65,6 +65,8 @@ struct mds_update_record {
         void               *ur_eadata;
         int                 ur_ea2datalen;
         void               *ur_ea2data;
+        int                 ur_ea3datalen;
+        void               *ur_ea3data;
         int                 ur_cookielen;       /* obsolete? */
         struct llog_cookie *ur_logcookies;      /* obsolete? */
         struct iattr        ur_iattr;
@@ -335,7 +337,7 @@ int mdc_getattr_lock(struct obd_export *exp, struct lustre_id *id,
                      unsigned int ea_size, struct ptlrpc_request **request);
 int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data,
                 struct iattr *iattr, void *ea, int ealen, void *ea2, int ea2len,
-                struct ptlrpc_request **request);
+                void *ea3, int ea3len, struct ptlrpc_request **request);
 int mdc_open(struct obd_export *exp, obd_id ino, int type, int flags,
              struct lov_mds_md *lmm, int lmm_size, struct lustre_handle *fh,
              struct ptlrpc_request **);
index e2bb14a..0e47bd7 100644 (file)
                                   OST_MAX_THREADS), 2UL)
 #define OST_NBUFS       (64 * smp_num_cpus)
 #define OST_BUFSIZE     (8 * 1024)
+/*GSS service parameters*/
+#define GKS_NBUFS       (64 * smp_num_cpus)
+#define GKS_BUFSIZE     (8 * 1024)
+#define GKT_MAX_THREADS 32UL
+#define GKT_NUM_THREADS max(min_t(unsigned long, num_physpages / 8192, \
+                                  GKT_MAX_THREADS), 2UL)
+
+#define GKS_MAXREQSIZE  (5 * 1024)
+
+
 /* OST_MAXREQSIZE ~= 1640 bytes =
  * lustre_msg + obdo + 16 * obd_ioobj + 64 * niobuf_remote
  *
@@ -750,7 +760,8 @@ void lustre_init_msg (struct lustre_msg *msg, int count,
                       int *lens, char **bufs);
 void *mdc_setattr_pack(struct lustre_msg *msg, int offset,
                        struct mdc_op_data *data, struct iattr *iattr,
-                       void *ea, int ealen, void *ea2, int ea2len);
+                       void *ea, int ealen, void *ea2, int ea2len, 
+                       void *ea3, int ea3len);
 void *mdc_create_pack(struct lustre_msg *msg, int offset,
                       struct mdc_op_data *op_data, __u32 mode,
                       __u64 rdev, const void *data, int datalen);
@@ -762,6 +773,7 @@ void *mdc_rename_pack(struct lustre_msg *msg, int offset,
                       struct mdc_op_data *data,
                       const char *old, int oldlen,
                       const char *new, int newlen);
+__u32 mds_pack_open_flags(__u32 flags);
 
 /* lustre id helper functions and macros. */
 static inline
index 7a64c7a..5d1d006 100644 (file)
@@ -410,6 +410,7 @@ struct mds_obd {
         spinlock_t                      mds_denylist_lock;
         struct list_head                mds_denylist;
         struct semaphore                mds_create_sem;
+        int                             mds_crypto_type;
 };
 
 struct echo_obd {
@@ -538,6 +539,16 @@ struct lmv_obd {
         struct semaphore        init_sem;
         struct obd_connect_data conn_data;
 };
+struct gks_crypto_key {
+        char *key;
+        int   len; 
+};
+struct gks_obd {
+        struct ptlrpc_service    *gks_service;
+        struct crypto_tfm        *gks_mac_tfm;       
+        struct crypto_tfm        *gks_key_tfm;
+        struct gks_crypto_key    gks_key;
+};
 
 struct niobuf_local {
         __u64 offset;
@@ -700,6 +711,7 @@ struct obd_device {
                 struct lmv_obd           lmv;
                 struct cm_obd            cm;
                 struct conf_obd          conf;
+                struct gks_obd           gks;
         } u;
         
         /* fields used by LProcFS */
@@ -921,7 +933,7 @@ struct md_ops {
                         struct ptlrpc_request **);
         int (*m_setattr)(struct obd_export *, struct mdc_op_data *,
                          struct iattr *, void *, int , void *, int,
-                         struct ptlrpc_request **);
+                         void *, int, struct ptlrpc_request **);
         int (*m_sync)(struct obd_export *, struct lustre_id *,
                       struct ptlrpc_request **);
         int (*m_readpage)(struct obd_export *, struct lustre_id *,
index 592eac5..d208c2b 100644 (file)
@@ -102,6 +102,7 @@ struct lustre_profile {
         char *lp_profile;
         char *lp_lov;
         char *lp_lmv;
+        char *lp_gkc;
 };
 
 struct lustre_profile *class_get_profile(char * prof);
@@ -1349,7 +1350,7 @@ static inline int md_rename(struct obd_export *exp, struct mdc_op_data *data,
 
 static inline int md_setattr(struct obd_export *exp, struct mdc_op_data *data,
                              struct iattr *iattr, void *ea, int ealen,
-                             void *ea2, int ea2len,
+                             void *ea2, int ea2len, void *ea3, int ea3len,
                              struct ptlrpc_request **request)
 {
         int rc;
@@ -1357,7 +1358,7 @@ static inline int md_setattr(struct obd_export *exp, struct mdc_op_data *data,
         EXP_CHECK_MD_OP(exp, setattr);
         MD_COUNTER_INCREMENT(exp->exp_obd, setattr);
         rc = MDP(exp->exp_obd, setattr)(exp, data, iattr, ea, ealen,
-                                        ea2, ea2len, request);
+                                        ea2, ea2len, ea3, ea3len, request);
         RETURN(rc);
 }
 
index 65a18d4..2c1eadd 100644 (file)
 #define LL_IOC_SETFACL                  _IOW ('f', 164, long)
 
 #define LL_IOC_FLUSH_CRED               _IOW ('f', 170, long)
+#define LL_IOC_KEY_TYPE                 _IOW ('f', 171, long)
+#define LL_IOC_DISABLE_CRYPTO           _IOW ('f', 172, long)
+#define LL_IOC_ENABLE_CRYPTO            _IOW ('f', 173, long)
+
 
 #define O_LOV_DELAY_CREATE    0100000000  /* hopefully this does not conflict */
 
index 2a4bc1f..0cdbd51 100644 (file)
@@ -942,7 +942,7 @@ Index: linux-2.6.10/fs/ext3/mballoc.c
 +                       * The only thing we can do is just take first
 +                       * found block(s)
 +                       */
-+                      /*printk(KERN_ERR "EXT3-fs: and someone won our chunk\n");*/
++                      printk(KERN_ERR "EXT3-fs: and someone won our chunk\n");
 +                      ac.ac_b_ex.fe_group = 0;
 +                      ac.ac_b_ex.fe_start = 0;
 +                      ac.ac_b_ex.fe_len = 0;
index f32cf70..6abe6cc 100644 (file)
@@ -5,7 +5,7 @@ kgdb-ga.patch
 lustre_version.patch
 vfs-dcache_locking-vanilla-2.6.10-fc3.patch
 vfs-dcache_lustre_invalid-vanilla-2.6.patch
-vfs-intent_api-vanilla-2.6.10-fc3.patch
+vfs-intent_api-vanilla-2.6.10-fc3.patch 
 vfs-lookup_last-vanilla-2.6.10-fc3.patch
 vfs-raw_ops-vanilla-2.6.10-fc3.patch
 export-2.6-fc3.patch 
index f08b991..fc8519c 100644 (file)
@@ -36,6 +36,7 @@
 #include <linux/lustre_dlm.h>
 #include <linux/lustre_net.h>
 #include <linux/lustre_sec.h>
+#include <linux/lustre_gs.h>
 
 /* @priority: if non-zero, move the selected to the list head
  * @nocreate: if non-zero, only search in existed connections
@@ -197,6 +198,11 @@ int client_obd_setup(struct obd_device *obddev, obd_count len, void *buf)
                 rq_portal = MGMT_REQUEST_PORTAL;
                 rp_portal = MGMT_REPLY_PORTAL;
                 connect_op = MGMT_CONNECT;
+        } else if (!strcmp(name, LUSTRE_GKC_NAME)) {
+                rq_portal = GKS_REQUEST_PORTAL;
+                rp_portal = GKC_REPLY_PORTAL;
+                connect_op = GKS_CONNECT;
+
         } else {
                 CERROR("unknown client OBD type \"%s\", can't setup\n",
                        name);
index 3633d87..4aaaa22 100644 (file)
@@ -371,6 +371,7 @@ int ldlm_namespace_cleanup(struct ldlm_namespace *ns, int flags)
                 while (tmp != &(ns->ns_hash[i])) {
                         struct ldlm_resource *res;
                         res = list_entry(tmp, struct ldlm_resource, lr_hash);
+                        spin_unlock(&ns->ns_hash_lock);
                         ldlm_resource_getref(res);
                         spin_unlock(&ns->ns_hash_lock);
 
index 0c457a3..8a9ac28 100644 (file)
@@ -46,6 +46,7 @@ struct llu_sb_info {
         struct obd_uuid         ll_sb_uuid;
         struct obd_export      *ll_md_exp;
         struct obd_export      *ll_dt_exp;
+        struct obd_export      *ll_gt_exp;
         obd_id                  ll_rootino;
         int                     ll_flags;
         struct list_head        ll_conn_chain;
index 4b786a3..fe89a59 100644 (file)
@@ -1,5 +1,6 @@
 MODULES := llite
-llite-objs := dcache.o dir.o file.o llite_close.o llite_gns.o llite_lib.o llite_nfs.o rw.o lproc_llite.o namei.o special.o symlink.o llite_mmap.o
+llite-objs := dcache.o dir.o file.o llite_close.o llite_gns.o llite_lib.o llite_nfs.o 
+llite-objs += rw.o lproc_llite.o namei.o special.o symlink.o llite_mmap.o llite_gs.o
 
 ifeq ($(PATCHLEVEL),4)
 llite-objs += rw24.o super.o
index 0bb8b83..a40f558 100644 (file)
@@ -31,7 +31,6 @@
 #include <linux/lustre_idl.h>
 #include <linux/lustre_dlm.h>
 #include <linux/lustre_version.h>
-
 #include "llite_internal.h"
 
 /* should NOT be called with the dcache lock, see fs/dcache.c */
@@ -285,6 +284,14 @@ int ll_intent_alloc(struct lookup_intent *it)
 void ll_intent_free(struct lookup_intent *it)
 {
         if (it->d.fs_data) {
+                struct lustre_intent_data *lustre_data = 
+                        (struct lustre_intent_data *)it->d.fs_data;
+                if (lustre_data->it_key) {
+                        OBD_FREE(lustre_data->it_key, 
+                                 lustre_data->it_key_size);
+                        lustre_data->it_key = NULL;
+                        lustre_data->it_key_size = 0;
+                }
                 OBD_SLAB_FREE(it->d.fs_data, ll_intent_slab,
                               sizeof(struct lustre_intent_data));
                 it->d.fs_data = NULL;
@@ -429,7 +436,11 @@ int ll_revalidate_it(struct dentry *de, int flags, struct nameidata *nd,
 do_lock:
         ll_frob_intent(&it, &lookup_it);
         LASSERT(it != NULL);
-
+        
+        rc = ll_crypto_init_it_key(de->d_inode, it);
+        if (rc)
+                GOTO(out, rc);
+        
         rc = md_intent_lock(exp, &pid, (char *)de->d_name.name, de->d_name.len,
                             NULL, 0, &cid, it, flags, &req, ll_mdc_blocking_ast);
         /* If req is NULL, then md_intent_lock() only tried to do a lock match;
@@ -531,7 +542,9 @@ do_lookup:
                 if (ll_intent_alloc(it))
                         LBUG();
         }
-        
+        rc = ll_crypto_init_it_key(de->d_inode, it);
+        if (rc)
+               GOTO(out, rc); 
         rc = md_intent_lock(exp, &pid, (char *)de->d_name.name, de->d_name.len,
                             NULL, 0, NULL, it, 0, &req, ll_mdc_blocking_ast);
         if (rc >= 0) {
index 55e6e79..2d144d7 100644 (file)
@@ -526,7 +526,7 @@ static int ll_ioctl_setfacl(struct inode *inode,
         rc = md_setattr(ll_i2sbi(inode)->ll_md_exp, &op_data, &attr,
                         (void*) XATTR_NAME_LUSTRE_ACL,
                         sizeof(XATTR_NAME_LUSTRE_ACL),
-                        (void*) cmd, ioc->cmd_len, &req);
+                        (void*) cmd, ioc->cmd_len, NULL, 0, &req);
         if (rc) {
                 CERROR("md_setattr fails: rc = %d\n", rc);
                 GOTO(out, rc);
@@ -611,6 +611,29 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 obd_ioctl_freedata(buf, len);
                 return rc;
         }
+        case LL_IOC_KEY_TYPE: {
+                char *buf = NULL;
+                char *type;
+                int typelen, rc, len = 0;
+
+                rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
+                if (rc)
+                        RETURN(rc);
+                data = (void *)buf;
+
+                type = data->ioc_inlbuf1;
+                typelen = data->ioc_inllen1;
+
+                if (typelen < 1) {
+                        CDEBUG(D_INFO, "LL_IOC_KEY_TYPE missing filename\n");
+                        GOTO(out_free, rc = -EINVAL);
+                }
+                ll_set_sb_gksinfo(inode->i_sb, type);
+                EXIT;
+        out_free:
+                obd_ioctl_freedata(buf, len);
+                RETURN(rc);
+        }
         case LL_IOC_MDC_MKDIRSTRIPE:
                 RETURN(ll_mkdir_stripe(inode, arg));
         case LL_IOC_LOV_SETSTRIPE: {
@@ -637,7 +660,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 ll_prepare_mdc_data(op_data, inode, NULL, NULL, 0, 0);
 
                 rc = md_setattr(sbi->ll_md_exp, op_data, &attr, &lum,
-                                sizeof(lum), NULL, 0, &request);
+                                sizeof(lum), NULL, 0, NULL, 0, &request);
                 OBD_FREE(op_data, sizeof(*op_data));
                 ptlrpc_req_finished(request);
 
index 2394c4a..608606b 100644 (file)
@@ -114,7 +114,6 @@ int ll_md_och_close(struct obd_export *md_exp, struct inode *inode,
         obdo->o_fid = id_fid(&ll_i2info(inode)->lli_id);
         obdo->o_mds = id_group(&ll_i2info(inode)->lli_id);
 
-
         obdo->o_valid |= OBD_MD_FLEPOCH;
         obdo->o_easize = ll_i2info(inode)->lli_io_epoch;
 
@@ -429,7 +428,6 @@ int ll_file_open(struct inode *inode, struct file *file)
                 oit.it_flags |= 2;
 
         it = file->f_it;
-
         /*
          * sometimes LUSTRE_IT(it) may not be allocated like opening file by
          * dentry_open() from GNS stuff.
@@ -465,6 +463,10 @@ int ll_file_open(struct inode *inode, struct file *file)
                 och_usecount = &lli->lli_open_fd_read_count;
         }
 
+        rc = ll_crypto_decrypt_key(inode, it);
+        if (rc)
+                GOTO(out, rc);
+
         down(&lli->lli_och_sem);
         if (*och_p) { /* Open handle is present */
                 if (it_disposition(it, DISP_LOOKUP_POS) && /* Positive lookup */
@@ -1514,6 +1516,31 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
                 putname(filename);
                 return rc;
         }
+        case LL_IOC_KEY_TYPE: {
+                struct obd_ioctl_data *data;
+                char *buf = NULL;
+                char *type;
+                int typelen, rc, len = 0;
+
+                rc = obd_ioctl_getdata(&buf, &len, (void *)arg);
+                if (rc)
+                        RETURN(rc);
+                data = (void *)buf;
+
+                type = data->ioc_inlbuf1;
+                typelen = data->ioc_inllen1;
+
+                if (typelen < 1) {
+                        CDEBUG(D_INFO, "LL_IOC_KEY_TYPE missing filename\n");
+                        GOTO(out, rc = -EINVAL);
+                }
+                ll_set_sb_gksinfo(inode->i_sb, type);
+                EXIT;
+        out:
+                obd_ioctl_freedata(buf, len);
+                return rc;
+        }
+
         case LL_IOC_LOV_GETSTRIPE:
                 RETURN(ll_lov_getstripe(inode, arg));
         case EXT3_IOC_GETFLAGS:
@@ -1761,6 +1788,10 @@ int ll_inode_revalidate_it(struct dentry *dentry)
         rc = ll_intent_alloc(&oit);
         if (rc)
                 RETURN(-ENOMEM);
+        
+        rc = ll_crypto_init_it_key(inode, &oit);
+        if (rc)
+                GOTO(out, rc);
 
         rc = md_intent_lock(sbi->ll_md_exp, &id, NULL, 0, NULL, 0, &id,
                             &oit, 0, &req, ll_mdc_blocking_ast);
@@ -1834,7 +1865,8 @@ int ll_setxattr_internal(struct inode *inode, const char *name,
         struct ptlrpc_request *request = NULL;
         struct mdc_op_data op_data;
         struct iattr attr;
-        int rc = 0;
+        void *key = NULL;
+        int rc = 0, key_size = 0;
         ENTRY;
 
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu\n", inode->i_ino);
@@ -1847,15 +1879,24 @@ int ll_setxattr_internal(struct inode *inode, const char *name,
         attr.ia_valid |= valid;
         attr.ia_attr_flags = flags;
 
+        if (strcmp(name, XATTR_NAME_ACL_ACCESS) == 0) {
+                rc = ll_crypto_get_mac(inode, NULL, (void *)value, size, 
+                                       &key, &key_size);
+        }
+
         ll_prepare_mdc_data(&op_data, inode, NULL, NULL, 0, 0);
 
         rc = md_setattr(sbi->ll_md_exp, &op_data, &attr,
-                        (void*) name, strnlen(name, XATTR_NAME_MAX) + 1,
-                        (void*) value, size, &request);
-        if (rc)
+                        (void*) name, strnlen(name, XATTR_NAME_MAX) + 1, 
+                        (void*) value,  size, key, key_size, &request);
+        
+        if (key && key_size) 
+                OBD_FREE(key, key_size);
+        if (rc) {
+                CERROR("md_setattr fails: rc = %d\n", rc);
                 GOTO(out, rc);
-
- out:
+        }
+out:
         ptlrpc_req_finished(request);
         RETURN(rc);
 }
@@ -1909,7 +1950,6 @@ int ll_removexattr(struct dentry *dentry, const char *name)
                                     ATTR_EA_RM);
 }
 
-static
 int ll_getxattr_internal(struct inode *inode, const char *name,
                          void *value, size_t size, __u64 valid)
 {
index 7588c60..31219db 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <linux/lustre_mds.h>
 #include <linux/lustre_lite.h>
+#include <linux/lustre_gs.h>
 #include "llite_internal.h"
 
 /* record that a write is in flight */
diff --git a/lustre/llite/llite_gs.c b/lustre/llite/llite_gs.c
new file mode 100644 (file)
index 0000000..74cf8dd
--- /dev/null
@@ -0,0 +1,791 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * Copyright (C) 2004, 2005 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#define DEBUG_SUBSYSTEM S_LLITE
+
+#include <linux/fs.h>
+#include <linux/types.h>
+#include <linux/version.h>
+#include <asm/uaccess.h>
+#include <linux/file.h>
+#include <linux/kmod.h>
+#include <linux/posix_acl.h>
+#include <linux/xattr_acl.h>
+
+#include <linux/lustre_acl.h>
+#include <linux/lustre_lite.h>
+#include <linux/lustre_gs.h>
+#include "llite_internal.h"
+
+int ll_gs_intent_init(struct lookup_intent *it)
+{
+        struct lustre_intent_data *lustre_data;
+        
+        LASSERT(it->d.fs_data != NULL); 
+        lustre_data = (struct lustre_intent_data *)it->d.fs_data;
+        /*set lustre key size when there is gss server 
+         *or other configuration*/ 
+        lustre_data->it_key = NULL;
+        lustre_data->it_key_size = 0;
+        RETURN(0);
+}
+
+static int ll_get_acl_key(struct inode *inode, struct posix_acl **acl,
+                          struct lustre_key **lkey) 
+{
+        struct lookup_intent it = { .it_op = IT_GETATTR };
+        struct dentry de = { .d_inode = inode };
+        struct ll_sb_info *sbi;
+        struct lustre_id id;
+        struct ptlrpc_request *req = NULL;
+        struct ll_inode_info *lli = ll_i2info(inode);
+        int rc = 0;
+        ENTRY;
+
+        if (lli->lli_posix_acl && lli->lli_key_info) {
+                /*If they are in the local cache, just fetch them*/
+                spin_lock(&lli->lli_lock);
+                *acl = posix_acl_dup(lli->lli_posix_acl);
+                *lkey =  lustre_key_get(lli->lli_key_info);
+                spin_unlock(&lli->lli_lock);
+                RETURN(rc);
+        }
+        sbi = ll_i2sbi(inode);
+        ll_inode2id(&id, inode);
+
+        if (ll_intent_alloc(&it))
+                RETURN(-EACCES);
+
+        rc = md_intent_lock(sbi->ll_md_exp, &id, NULL, 0, NULL, 0, &id,
+                            &it, 0, &req, ll_mdc_blocking_ast);
+        if (rc < 0) {
+                ll_intent_free(&it);
+                GOTO(out, rc);
+        }
+
+        rc = revalidate_it_finish(req, 1, &it, &de);
+        if (rc) {
+                ll_intent_release(&it);
+                GOTO(out, rc);
+        }
+
+        ll_lookup_finish_locks(&it, &de);
+        ll_intent_free(&it);
+
+        spin_lock(&lli->lli_lock);
+        *acl = posix_acl_dup(lli->lli_posix_acl);
+        *lkey =  lustre_key_get(lli->lli_key_info);
+        spin_unlock(&lli->lli_lock);
+out:
+        if (req)
+                ptlrpc_req_finished(req);        
+        RETURN(rc);
+}
+
+static int ll_init_key_perm(struct key_perm *kperm, struct posix_acl *acl, 
+                            __u32 uid, __u32 gid, int mode) 
+{
+        if (acl) {
+                kperm->kp_acl_count = acl->a_count;
+                memcpy(kperm->kp_acls, acl->a_entries, 
+                       acl->a_count * sizeof(struct posix_acl_entry));
+        }
+        kperm->kp_mode = mode;
+        kperm->kp_uid = uid;
+        kperm->kp_gid = gid;
+        RETURN(0);
+}
+
+static int ll_init_key_context(struct key_context *pkc, __u32 uid, 
+                                __u32 gid, struct crypto_key *ck, 
+                                struct posix_acl *acl,  int mode, 
+                                int command, int valid)
+{
+        struct key_perm *kperm;
+        ENTRY;
+
+        pkc->kc_command = command;
+        pkc->kc_valid = valid;
+
+        if (ck)
+                memcpy(&pkc->kc_ck, ck, sizeof(*ck));
+
+        kperm = &pkc->kc_perm;      
+        ll_init_key_perm(kperm, acl, uid, gid, mode);  
+        RETURN(0);
+}
+static int ll_get_default_acl(struct inode *inode, struct posix_acl **acl, 
+                              mode_t mode) 
+{
+        int rc = 0, buf_size, ea_size;
+        char *buf = NULL;
+        ENTRY;
+
+        if (!S_ISDIR(inode->i_mode))
+                RETURN(0);
+        buf_size = xattr_acl_size(LL_ACL_MAX_ENTRIES);
+        OBD_ALLOC(buf, buf_size);
+        if (!buf)
+                RETURN(-ENOMEM);
+
+        ea_size = ll_getxattr_internal(inode, XATTR_NAME_ACL_DEFAULT, 
+                                       buf, buf_size, OBD_MD_FLXATTR);
+        if (ea_size <= 0) {
+                if (ea_size < 0 && ea_size != -ENODATA)
+                        CERROR("get default acl of ino %lu error rc %d \n",
+                                inode->i_ino, ea_size);
+                GOTO(out, rc = 0);       
+        }
+        *acl = posix_acl_from_xattr(buf, ea_size);
+        if (IS_ERR(*acl)) {
+                rc = PTR_ERR(*acl);
+                CERROR("convert xattr to acl failed: %d\n", rc);
+                GOTO(out, rc);
+        } else if (*acl) {
+                rc = posix_acl_valid(*acl);
+                if (rc) {
+                        CERROR("acl valid error: %d\n", rc);
+                        posix_acl_release(*acl);
+                        GOTO(out, rc);
+                }
+        }
+        
+        rc = posix_acl_create_masq(*acl, &mode); 
+out:
+        if (buf) 
+                OBD_FREE(buf, buf_size);
+        RETURN(rc);
+}
+
+int ll_gks_create_key(struct inode *dir, mode_t mode, void **key, 
+                      int* key_size)
+{
+        struct obd_export *gs_exp = ll_i2gsexp(dir);
+        struct key_context *kcontext = NULL;
+        struct key_parms   kparms;
+        struct posix_acl *default_acl = NULL;       
+        int    rc = 0;  
+        ENTRY;
+        OBD_ALLOC(kcontext, sizeof(struct key_context));
+        if (!kcontext)
+                GOTO(out, rc = -ENOMEM);
+
+        rc = ll_get_default_acl(dir, &default_acl, mode);
+        if (rc)
+                GOTO(out, rc);       
+        ll_init_key_context(kcontext, current->fsuid, current->fsgid, 
+                            NULL, default_acl, mode, GKS_GET_KEY, 0);
+       
+        kparms.context = kcontext;
+        kparms.context_size = sizeof(struct key_context);
+        kparms.perm = NULL;
+       
+        *key_size = sizeof(struct crypto_key);
+        OBD_ALLOC(*key, *key_size);
+        if (!*key)
+                GOTO(out, rc = -ENOMEM);
+        /*GET an encrypt key from GS server*/
+        rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
+                          key_size, *key);
+        if (rc) {
+                CERROR("get key error rc %d \n", rc);
+                GOTO(out, rc);
+        }
+        CDEBUG(D_INFO, "Get enkey %s MAC %s from exp %p \n", 
+               (char*)((struct crypto_key *)(*key))->ck_key, 
+               (char*)((struct crypto_key *)(*key))->ck_mac, 
+               gs_exp);
+out:
+        if (kcontext)
+                OBD_FREE(kcontext, sizeof(struct key_context));
+        if (default_acl)
+                posix_acl_release(default_acl);
+        RETURN(rc);
+
+}
+int ll_gks_init_it(struct inode *parent, struct lookup_intent *it)
+{
+        struct obd_export *gs_exp = ll_i2gsexp(parent);
+        struct lustre_intent_data *lustre_data;
+        mode_t mode = (it->it_create_mode | S_IFREG) & (~current->fs->umask);
+        void *key = NULL;
+        int key_size = 0, rc = 0;
+        ENTRY;
+        if (!gs_exp || !it)
+                RETURN(rc);
+
+        ll_gs_intent_init(it);
+        if (!(it->it_op & IT_CREAT))
+                RETURN(rc);
+
+        LASSERT(it->d.fs_data != NULL); 
+        lustre_data = (struct lustre_intent_data *)it->d.fs_data;
+          
+        if (lustre_data->it_key) {
+                LASSERT(lustre_data->it_key_size == 
+                         sizeof(struct crypto_key));
+                OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
+        }
+
+        rc = ll_gks_create_key(parent, mode, &key, &key_size); 
+        if (rc)
+                GOTO(out, rc);
+
+        lustre_data->it_key = key; 
+        lustre_data->it_key_size = key_size; 
+out:
+        if (rc) {
+                if (key && key_size)
+                        OBD_FREE(key, key_size);
+        }
+        RETURN(rc); 
+}
+
+int ll_gks_decrypt_key(struct inode *inode, struct lookup_intent *it)
+{
+        struct obd_export *gs_exp = ll_i2gsexp(inode);
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct key_context *kcontext = NULL;
+        struct key_perm *kperm = NULL;
+        struct key_parms kparms;
+        struct lustre_key *lkey =  NULL;
+        struct crypto_key *ckey = NULL;
+        struct posix_acl *acl = NULL;
+        __u32 flags = 0; 
+        int rc = 0, ck_size = 0, kcontext_size = 0, acl_count;
+        
+        ENTRY;
+        if (!gs_exp)
+                RETURN(rc);
+       
+        rc = ll_get_acl_key(inode, &acl, &lkey);
+        if (rc)
+                GOTO(out, rc);       
+        if (!lkey || IS_DECRYPTED(lkey->lk_flags))
+                GOTO(out, rc = 0);
+       
+        acl_count = acl ? acl->a_count : 0;  
+        kcontext_size = crypto_kcontext_size(acl_count); 
+        OBD_ALLOC(kcontext, kcontext_size);
+        if (!kcontext)
+                GOTO(out, rc = -ENOMEM);
+        
+        flags = mds_pack_open_flags(it->it_flags); 
+
+        spin_lock(&lli->lli_lock); 
+        ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, 
+                            acl, inode->i_mode, GKS_DECRYPT_KEY, flags);
+       
+        spin_unlock(&lli->lli_lock); 
+        
+        OBD_ALLOC(kperm, sizeof(struct key_perm));
+        ll_init_key_perm(kperm, NULL, current->uid, current->gid, 0);
+    
+        kparms.context = kcontext;
+        kparms.context_size = kcontext_size;
+        kparms.perm = kperm;       
+        kparms.perm_size = sizeof(struct key_perm); 
+
+        ck_size = sizeof(*ckey);
+        OBD_ALLOC(ckey, ck_size);
+        if (!ckey)
+                GOTO(out, rc = -ENOMEM);
+        /*GET an encrypt key from GS server*/
+        rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
+                          &ck_size, ckey);
+        if (rc) {
+                CERROR("decrypt key error rc %d \n", rc);
+                GOTO(out, rc);
+        }
+        CDEBUG(D_INFO, "decrypt key %s MAC %s from exp %p \n", 
+               ckey->ck_mac, ckey->ck_mac, gs_exp);        
+      
+        /*copy the decrypt key from kcontext to the lustre key*/
+        
+        spin_lock(&lli->lli_lock); 
+        memcpy(&lkey->lk_ck, ckey, sizeof(*ckey));
+        SET_DECRYPTED(lkey->lk_flags);
+        spin_unlock(&lli->lli_lock); 
+out:
+        if (acl)
+                posix_acl_release(acl);
+        if (lkey)
+                lustre_key_release(lkey); 
+        if (kperm)
+                OBD_FREE(kperm, sizeof(struct key_perm));
+        if (kcontext)
+                OBD_FREE(kcontext, kcontext_size);
+        if (ckey)
+                OBD_FREE(ckey, ck_size);
+        RETURN(rc); 
+}
+
+int ll_gks_get_mac(struct inode *inode, struct iattr *iattr, void *value, 
+                   int size, void **key, int *key_size)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct obd_export *gs_exp = ll_i2gsexp(inode);
+        struct key_context *kcontext = NULL;
+        struct key_perm *kperm = NULL;
+        struct key_parms kparms;
+        struct lustre_key *lkey =  NULL;
+        struct posix_acl *acl = NULL, *new_acl = NULL; 
+        int rc = 0,  kperm_size = 0, kcontext_size = 0; 
+        mode_t mac_mode;
+        int acl_count = 0;
+        
+        ENTRY;
+        if (!gs_exp)
+                RETURN(rc);
+       
+        rc = ll_get_acl_key(inode, &acl, &lkey);
+        if (rc)
+                GOTO(out, rc);       
+        if (!lkey)
+                RETURN(rc);
+        
+        acl_count = acl ? acl->a_count : 0;  
+        kcontext_size = crypto_kcontext_size(acl_count); 
+        OBD_ALLOC(kcontext, kcontext_size);
+        if (!kcontext)
+                GOTO(out, rc = -ENOMEM);
+        spin_lock(&lli->lli_lock);
+        ll_init_key_context(kcontext, inode->i_uid, inode->i_gid, &lkey->lk_ck, 
+                            acl, inode->i_mode, GKS_GET_MAC, iattr->ia_valid);
+        spin_unlock(&lli->lli_lock);
+        if (value) {
+                new_acl = posix_acl_from_xattr(value, size);
+                if (IS_ERR(new_acl)) {
+                        rc = PTR_ERR(new_acl);
+                        CERROR("convert from xattr to acl error: %d",rc);
+                        new_acl = NULL;
+                        GOTO(out, rc);
+                } else if (new_acl) {
+                        rc = posix_acl_valid(new_acl);
+                        if (rc) {
+                                CERROR("acl valid error: %d", rc);
+                                GOTO(out, rc);
+                        }
+                }
+        } 
+        acl_count = acl ? acl->a_count : 0;  
+        kperm_size = crypto_kperm_size(acl_count);
+        OBD_ALLOC(kperm, kperm_size);
+        if (iattr->ia_valid & ATTR_MODE)
+                mac_mode = iattr->ia_mode;
+        else
+                mac_mode = inode->i_mode; 
+        ll_init_key_perm(kperm, new_acl, iattr->ia_uid, iattr->ia_gid, 
+                         mac_mode);
+        kparms.context = kcontext;
+        kparms.context_size = kcontext_size;
+        kparms.perm = kperm;       
+        kparms.perm_size = kperm_size; 
+
+        *key_size = sizeof(struct crypto_key);
+        OBD_ALLOC(*key, *key_size);
+        if (!*key)
+                GOTO(out, rc = -ENOMEM);
+        /*GET an encrypt key from GS server*/
+        rc = obd_get_info(gs_exp, sizeof(struct key_parms), (void *)&kparms,
+                          key_size, *key);
+        if (rc) {
+                CERROR("decrypt key error rc %d \n", rc);
+                GOTO(out, rc);
+        }
+        /*copy the decrypt key from kcontext to the lustre key*/
+        spin_lock(&lli->lli_lock);
+        memcpy(&lkey->lk_ck, *key, *key_size);
+        iattr->ia_valid |= ATTR_MAC;
+        spin_unlock(&lli->lli_lock);
+out:
+        if (acl)
+                posix_acl_release(acl);
+        if (new_acl)
+                posix_acl_release(new_acl);
+        if (lkey)
+                lustre_key_release(lkey); 
+        if (kperm)
+                OBD_FREE(kperm, kperm_size);
+        if (kcontext)
+                OBD_FREE(kcontext, kcontext_size);
+        RETURN(rc); 
+}
+
+/*key function for calculate the key for countermode method*/
+static int ll_crypt_cb(struct page *page, __u64 offset, __u64 count,
+                       int flags)
+{
+        struct inode *inode = page->mapping->host;
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct lustre_key *lkey = ll_i2info(inode)->lli_key_info;
+        unsigned char *ptr;
+        char *key_ptr;
+        int index = page->index;
+        __u64 data_key = 0; 
+        int i;
+        ENTRY;
+
+        if (!lkey)
+                RETURN(0);
+        if (!IS_DECRYPTED(lkey->lk_flags))
+                RETURN(-EFAULT);
+        if (flags == ENCRYPT_DATA && !IS_ENABLE_ENCRYPT(lkey->lk_flags))
+                RETURN(-EFAULT);
+        if (flags == DECRYPT_DATA && !IS_ENABLE_DECRYPT(lkey->lk_flags))
+                RETURN(-EFAULT);
+        
+        /*FIXME: tmp calculate method, should calculate 
+          the key according to KEY_TYPE*/
+        
+        spin_lock(&lli->lli_lock);
+        key_ptr = &lkey->lk_ck.ck_key[0];
+        for (i=0; i < KEY_SIZE; i++) 
+                data_key += *key_ptr++; 
+        spin_unlock(&lli->lli_lock);
+        data_key += index;
+
+        CDEBUG(D_INFO, "data_key is "LPU64" \n", data_key);
+        /*encrypt the data*/
+        ptr = (char *)kmap(page);
+        ptr += offset; 
+        CDEBUG(D_INFO, "ptr is %s \n", ptr);
+        for (i = 0; i < count; i++) 
+                *ptr++ ^= data_key; 
+        CDEBUG(D_INFO, "encrypted ptr is %s \n", ptr);
+        kunmap(page);
+        
+        RETURN(0); 
+} 
+
+int ll_gs_init_inode_key(struct inode *inode, void  *mkey)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct crypto_key *key = (struct crypto_key*)mkey;
+        struct lustre_key *lkey = NULL;
+        ENTRY;        
+
+        if (!key)
+                RETURN(0);
+        
+        if (lli->lli_key_info == NULL) {
+                OBD_ALLOC(lkey, sizeof(struct lustre_key));
+                if (!lkey)
+                        RETURN(-ENOMEM); 
+                memcpy(&lkey->lk_ck, key, sizeof(*key));
+                atomic_set(&lkey->lk_refcount, 1);
+                SET_UNDECRYPTED(lkey->lk_flags); 
+                ENABLE_ENCRYPT(lkey->lk_flags);  
+                ENABLE_DECRYPT(lkey->lk_flags); 
+                spin_lock(&lli->lli_lock);
+                lli->lli_key_info = lkey; 
+                spin_unlock(&lli->lli_lock);
+        } else {
+                lkey = lustre_key_get(lli->lli_key_info);
+                if (!IS_DECRYPTED(lkey->lk_flags)) {
+                        if (memcmp(&lkey->lk_ck, key, sizeof(*key))) {
+                                CWARN("already have key_info %p in ino %ld \n",
+                                      lli->lli_key_info, inode->i_ino);
+                        }
+                } else {
+                        spin_lock(&lli->lli_lock);
+                        SET_UNDECRYPTED(lkey->lk_flags); 
+                        memcpy(&lkey->lk_ck, key, sizeof(*key));
+                        spin_unlock(&lli->lli_lock);
+                }
+                lustre_key_release(lkey);
+        }
+        CDEBUG(D_INFO, "set key %s mac %s in inode %lu \n", 
+               lli->lli_key_info->lk_ck.ck_mac, 
+               lli->lli_key_info->lk_ck.ck_key, 
+               inode->i_ino);
+        RETURN(0);
+}
+
+static int ll_gs_destroy_key(struct inode *inode)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+       
+        spin_lock(&lli->lli_lock);
+        if (lli->lli_key_info) {
+                LASSERTF(atomic_read(&lli->lli_key_info->lk_refcount) == 1, 
+                         "lk_refcount %d != 1 when destory\n", 
+                         atomic_read(&lli->lli_key_info->lk_refcount));
+                lustre_key_release(lli->lli_key_info);
+                lli->lli_key_info = NULL;
+        }
+        spin_unlock(&lli->lli_lock);
+        RETURN(0);
+}
+
+struct crypto_helper_ops ll_cgs_ops = { 
+       .init_it_key     = ll_gks_init_it,
+       .create_key      = ll_gks_create_key,
+       .init_inode_key  = ll_gs_init_inode_key, 
+       .get_mac         = ll_gks_get_mac,
+       .decrypt_key     = ll_gks_decrypt_key, 
+       .destroy_key     = ll_gs_destroy_key,
+};
+
+int ll_mks_create_key(struct inode *inode, struct lookup_intent *it)
+{
+        struct lustre_intent_data *lustre_data;
+        struct crypto_key         *crypto_key;
+        int    rc = 0;       
+        ENTRY;
+       
+        LASSERT(it->d.fs_data != NULL); 
+        lustre_data = (struct lustre_intent_data *)it->d.fs_data;
+       
+        if (lustre_data->it_key) {
+                OBD_FREE(lustre_data->it_key, sizeof(struct crypto_key));
+        }
+        OBD_ALLOC(crypto_key, sizeof(struct crypto_key));
+        
+        lustre_data->it_key = crypto_key; 
+        lustre_data->it_key_size = sizeof(struct crypto_key); 
+        RETURN(rc);
+}
+
+int ll_mks_init_it(struct inode *parent, struct lookup_intent *it)
+{
+        struct obd_export *gs_exp = ll_i2gsexp(parent);
+        int rc = 0;
+        ENTRY;
+        if (!gs_exp || !it)
+                RETURN(0);
+
+        ll_gs_intent_init(it);
+        if (it->it_op & IT_CREAT) {
+                ll_mks_create_key(parent, it);
+        }
+        RETURN(rc); 
+}
+
+int ll_mks_decrypt_key(struct inode *inode, struct lookup_intent *it)
+{
+        struct ll_inode_info *lli = ll_i2info(inode);
+        struct obd_export *gs_exp = ll_i2gsexp(inode);
+        struct lustre_key *lkey =  NULL;
+        struct posix_acl *acl = NULL;
+        int rc = 0;
+        
+        ENTRY;
+        if (!gs_exp)
+                RETURN(rc);
+       
+        rc = ll_get_acl_key(inode, &acl, &lkey);
+        if (rc || !lkey)
+                RETURN(rc);      
+        spin_lock(&lli->lli_lock); 
+        SET_DECRYPTED(lkey->lk_flags); 
+        spin_unlock(&lli->lli_lock); 
+        RETURN(rc);
+}
+struct crypto_helper_ops ll_cmd_ops = { 
+       .init_it_key     = ll_mks_init_it,
+       .init_inode_key  = ll_gs_init_inode_key, 
+       .decrypt_key     = ll_mks_decrypt_key,
+       .destroy_key     = ll_gs_destroy_key,
+};
+
+
+static int ll_register_cops(struct ll_crypto_info *llci, char *type,
+                            struct crypto_helper_ops *cops)
+{
+        struct list_head *list = &llci->ll_cops_list;
+        struct crypto_ops_item *opi = NULL, *tmp;
+        char   *opi_name = NULL;        
+        int rc = 0;
+        ENTRY;
+        
+        list_for_each_entry(tmp, list, clist) {
+                if (!strcmp(type, tmp->ctype)) {
+                        CWARN("%s is already registered\n", type);
+                        rc = -EEXIST;
+                        GOTO(exit, rc); 
+                }
+        }
+        
+        OBD_ALLOC(opi, sizeof(*opi));
+       
+        OBD_ALLOC(opi_name, strlen(type) + 1); 
+       
+        LASSERT(opi && opi_name);
+
+        memcpy(opi_name, type, strlen(type));
+
+        opi->ctype = opi_name;
+        opi->cops = cops;
+  
+        list_add_tail(&opi->clist, list);
+exit:
+        RETURN(rc);
+}
+
+static int ll_init_sb_crypto(struct super_block *sb)
+{
+        struct ll_crypto_info *llci = NULL;
+        int rc = 0;
+        ENTRY;
+
+        OBD_ALLOC(llci, sizeof(*llci));
+        
+        if (!llci)
+                RETURN(-ENOMEM);
+
+        INIT_LIST_HEAD(&llci->ll_cops_list);
+        
+        ll_register_cops(llci, "gks", &ll_cgs_ops);
+        ll_register_cops(llci, "mks", &ll_cmd_ops);
+
+        ll_s2sbi(sb)->ll_crypto_info = llci;
+
+        RETURN(rc);
+}         
+
+static int ll_unregister_cops(struct ll_crypto_info *llci)
+{
+        struct list_head *list = &llci->ll_cops_list;
+        struct crypto_ops_item *tmp, *item;
+
+        list_for_each_entry_safe(item, tmp, list, clist) {       
+                list_del_init(&item->clist);       
+                OBD_FREE(item->ctype, strlen(item->ctype) + 1);
+                OBD_FREE(item, sizeof(*item));
+        }
+        RETURN(0);
+}
+
+int lustre_destroy_crypto(struct super_block *sb)
+{
+        struct ll_crypto_info *llci = ll_s2crpi(sb);
+        ENTRY;       
+
+        if (!llci)
+                RETURN(0);
+
+        if (llci->ll_gt_exp)
+                obd_disconnect(llci->ll_gt_exp, 0);
+        ll_unregister_cops(llci);
+        OBD_FREE(llci, sizeof(*llci)); 
+        RETURN(0);
+}
+
+int lustre_init_crypto(struct super_block *sb, char *gkc, 
+                       struct obd_connect_data *data,
+                       int async)
+{
+        struct obd_device *obd = NULL;
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        struct lustre_handle gt_conn;
+        int rc = 0;
+        ENTRY;
+
+        rc = ll_init_sb_crypto(sb);
+        if (rc)
+                RETURN(rc);
+
+        if (!gkc || !strcmp(gkc, "null")) {
+                CDEBUG(D_INFO, "No gks Server\n"); 
+                RETURN(rc);
+        }
+        
+        obd = class_name2obd(gkc);
+        if (!obd) {
+                CERROR("GSC %s: not setup or attached\n", gkc);
+                GOTO(out, rc = -EINVAL);
+        }
+        
+        obd_set_info(obd->obd_self_export, strlen("async"), "async",
+                     sizeof(async), &async);
+        
+        rc = obd_connect(&gt_conn, obd, &sbi->ll_sb_uuid, data,
+                          OBD_OPT_REAL_CLIENT);
+        if (rc) {
+                CERROR("cannot connect to %s: rc = %d\n", gkc, rc);
+                GOTO(out, rc);
+        }
+        ll_s2crpi(sb)->ll_gt_exp = class_conn2export(&gt_conn);
+out:
+        if (rc)
+                lustre_destroy_crypto(sb); 
+        RETURN(rc);
+}
+struct crypto_helper_ops *
+ll_gks_find_ops(struct ll_crypto_info *llc_info, char *type)
+{
+        struct list_head *list = &llc_info->ll_cops_list;
+        struct crypto_ops_item *tmp;
+        ENTRY;
+
+        list_for_each_entry(tmp, list, clist) {
+                if (!strcmp(type, tmp->ctype)) {
+                        EXIT;
+                        return (tmp->cops);            
+                }
+        }
+        CERROR("can not find crypto api %s \n", type);
+        RETURN(NULL);
+}
+
+int ll_set_sb_gksinfo(struct super_block *sb, char *type)
+{
+        struct ll_crypto_info *llci = ll_s2crpi(sb);
+        struct obd_export *md_exp = ll_s2mdexp(sb);
+        struct obd_export *dt_exp = ll_s2dtexp(sb);
+        struct crypto_helper_ops *ops;
+        int rc = 0;
+        ENTRY;
+        
+        /*try to find the helper ops according to the type*/
+        ops = ll_gks_find_ops(llci, type);
+        if (!ops) {
+                CERROR("can not find the crypto ops by type %s \n", type);
+                RETURN(-EINVAL);
+        }
+        llci->ll_cops = ops;
+        /*set crypto type */
+        rc = obd_set_info(md_exp, strlen("crypto_type"), "crypto_type",
+                          strlen(type), type);
+
+        /*set crypt call back func*/
+
+        rc = obd_set_info(dt_exp, strlen("crypto_cb"), "crypto_cb",
+                          sizeof(crypt_cb_t), &ll_crypt_cb);
+  
+        RETURN(rc);
+}
+
index bfe6e11..d0bca7a 100644 (file)
@@ -108,6 +108,7 @@ struct ll_sb_info {
 
         /* mount object entry name */
         char                      ll_gns_oname[PATH_MAX];
+        void                      *ll_crypto_info;
 };
 
 struct ll_gns_ctl {
@@ -257,9 +258,10 @@ void ll_removepage(struct page *page);
 int ll_readpage(struct file *file, struct page *page);
 struct ll_async_page *llap_from_cookie(void *cookie);
 struct ll_async_page *llap_from_page(struct page *page, unsigned origin);
-struct ll_async_page *llap_cast_private(struct page *page);
 void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras);
 
+struct lpage_data *lpd_cast_private(struct page *page);
+
 void ll_ra_accounting(struct page *page, struct address_space *mapping);
 void ll_truncate(struct inode *inode);
 
@@ -275,6 +277,8 @@ int ll_getxattr(struct dentry *, const char *, void *, size_t);
 int ll_listxattr(struct dentry *, char *, size_t);
 int ll_removexattr(struct dentry *, const char *);
 extern int ll_inode_permission(struct inode *, int, struct nameidata *);
+int ll_get_acl(struct inode *, struct posix_acl **acl, 
+               struct ptlrpc_request **req);
 int ll_refresh_lsm(struct inode *inode, struct lov_stripe_md *lsm);
 int ll_extent_lock(struct ll_file_data *, struct inode *,
                    struct lov_stripe_md *, int mode, ldlm_policy_data_t *,
@@ -295,6 +299,8 @@ int ll_md_och_close(struct obd_export *md_exp, struct inode *inode,
 void ll_och_fill(struct inode *inode, struct lookup_intent *it,
                  struct obd_client_handle *och);
 
+int ll_getxattr_internal(struct inode *inode, const char *name,
+                         void *value, size_t size, __u64 valid);
 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
 int ll_getattr(struct vfsmount *mnt, struct dentry *de, struct kstat *stat);
 #endif
@@ -334,8 +340,8 @@ extern struct super_operations lustre_super_operations;
 
 char *ll_read_opt(const char *opt, char *data);
 int ll_set_opt(const char *opt, char *data, int fl);
-void ll_options(char *options, char **ost, char **mds, char **mds_sec,
-                char **oss_sec, int *async, int *flags);
+void ll_options(char *options, char **ost, char **mds, char **gss, 
+                char **mds_sec, char **oss_sec, int *async, int *flags);
 void ll_lli_init(struct ll_inode_info *lli);
 int ll_fill_super(struct super_block *sb, void *data, int silent);
 int lustre_fill_super(struct super_block *sb, void *data, int silent);
@@ -486,7 +492,6 @@ static inline struct obd_export *ll_i2mdexp(struct inode *inode)
 {
         return ll_s2mdexp(inode->i_sb);
 }
-
 static inline int ll_mds_max_easize(struct super_block *sb)
 {
         return sbi2md(ll_s2sbi(sb))->cl_max_mds_easize;
@@ -497,6 +502,7 @@ static inline __u64 ll_file_maxbytes(struct inode *inode)
         return ll_i2info(inode)->lli_maxbytes;
 }
 
+
 static inline void
 ll_inode2id(struct lustre_id *id, struct inode *inode)
 {
@@ -530,8 +536,135 @@ ll_prepare_mdc_data(struct mdc_op_data *data, struct inode *i1,
         data->mod_time = LTIME_S(CURRENT_TIME);
 }
 
-/* pass this flag to ll_md_real_close() to send close rpc right away */
-#define FMODE_SYNC               00000010
+struct crypto_helper_ops {
+       int (*init_it_key)(struct inode *inode, struct lookup_intent *it);
+       int (*create_key)(struct inode *dir, mode_t mode, void **key, 
+                         int* key_size);
+       int (*get_mac)(struct inode *inode, struct iattr *iattr, void*value, 
+                      int size, void **key, int* key_size);
+       int (*decrypt_key)(struct inode *inode, struct lookup_intent *it);
+       int (*init_inode_key)(struct inode *inode, void *md_key);
+       int (*destroy_key)(struct inode *inode);
+}; 
+
+/*llite crypto ops for crypto api*/
+struct ll_crypto_info {
+        struct obd_export    *ll_gt_exp;
+        struct list_head     ll_cops_list;
+        struct crypto_helper_ops *ll_cops;
+        int    ll_c_flags;
+};
+#define ll_page2key(page)  ((ll_i2info(page->mapping->host))->lli_key_info)
+static inline struct ll_crypto_info* ll_s2crpi(struct super_block *sb)
+{
+        return (struct ll_crypto_info*)ll_s2sbi(sb)->ll_crypto_info;
+}
+static inline struct ll_crypto_info* ll_i2crpi(struct inode *inode)
+{
+        return (struct ll_crypto_info*)ll_i2sbi(inode)->ll_crypto_info;
+}
+
+static inline struct crypto_helper_ops* ll_i2crpops(struct inode *inode)
+{
+        return ll_i2crpi(inode)->ll_cops; 
+}
 
+static inline struct crypto_helper_ops* ll_s2crpops(struct super_block *sb)
+{
+        return ll_s2crpi(sb)->ll_cops; 
+}
 
+static inline struct obd_export *ll_s2gsexp(struct super_block *sb)
+{
+        struct ll_crypto_info *llci = ll_s2crpi(sb);
+        if (llci)
+                return llci->ll_gt_exp;
+        return NULL;
+}
+static inline struct obd_export *ll_i2gsexp(struct inode *inode)
+{
+        return ll_s2gsexp(inode->i_sb);
+}
+
+static inline 
+int ll_crypto_init_it_key(struct inode *inode, struct lookup_intent *it) 
+{
+        struct ll_crypto_info *lci = ll_i2crpi(inode);
+        if (lci) {
+                struct crypto_helper_ops *ops = lci->ll_cops;;
+                if (ops && ops->init_it_key)
+                        return ops->init_it_key(inode, it); 
+        } 
+        return 0;
+}
+
+static inline 
+int ll_crypto_create_key(struct inode *inode, mode_t mode, void **key, 
+                         int* key_size) 
+{
+        struct ll_crypto_info *lci = ll_i2crpi(inode);
+        if (lci) {
+                struct crypto_helper_ops *ops = lci->ll_cops;;
+                if (ops && ops->create_key)
+                        return ops->create_key(inode, mode, key, key_size); 
+        } 
+        return 0;
+}
+
+static inline 
+int ll_crypto_get_mac(struct inode *inode, struct iattr *attr, void *acl, 
+                      int acl_size, void **mac, int *mac_size) 
+{
+        struct ll_crypto_info *lci = ll_i2crpi(inode);
+        if (lci) {
+                struct crypto_helper_ops *ops = lci->ll_cops;
+                if (ops && ops->get_mac)
+                        return ops->get_mac(inode, attr, acl, acl_size, 
+                                            mac, mac_size);
+        }  
+        return 0;
+}
+
+static inline 
+int ll_crypto_decrypt_key(struct inode *inode, struct lookup_intent *it) 
+{
+        struct ll_crypto_info *lci = ll_i2crpi(inode);
+        if (lci) {
+                struct crypto_helper_ops *ops = lci->ll_cops;
+                if (ops && ops->decrypt_key)
+                        return ops->decrypt_key(inode, it);  
+        }
+        return 0; 
+}
+
+static inline 
+int ll_crypto_init_inode_key(struct inode *inode, void *md_key) 
+{
+        struct ll_crypto_info *lci = ll_i2crpi(inode);
+        if (lci) {
+                struct crypto_helper_ops *ops = lci->ll_cops;
+                if (ops && ops->init_inode_key)
+                        return ops->init_inode_key(inode, md_key);  
+        }
+        return 0; 
+}
+
+static inline 
+int ll_crypto_destroy_inode_key(struct inode *inode) 
+{
+        struct ll_crypto_info *lci = ll_i2crpi(inode);
+        if (lci) {
+                struct crypto_helper_ops *ops = lci->ll_cops;
+                if (ops && ops->destroy_key)
+                        return ops->destroy_key(inode);  
+        }
+        return 0; 
+}
+
+int lustre_init_crypto(struct super_block *sb, char *gkc, 
+                       struct obd_connect_data *data, int async);
+int lustre_destroy_crypto(struct super_block *sb);
+int ll_set_sb_gksinfo(struct super_block *sb, char *type);
+/* pass this flag to ll_md_real_close() to send close rpc right away */
+#define FMODE_SYNC               00000010
 #endif /* LLITE_INTERNAL_H */
index cf515f4..ce919b7 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/lustre_dlm.h>
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_acl.h>
+#include <linux/lustre_gs.h>
 #include <linux/lustre_sec.h>
 #include "llite_internal.h"
 
@@ -128,63 +129,40 @@ int lustre_init_dt_desc(struct ll_sb_info *sbi)
         RETURN(rc);
 }
 
-extern struct dentry_operations ll_d_ops;
-
-int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
-                             int async,  char *mds_security,  char *oss_security,
-                             __u32 *nllu, int pag, __u64 *remote)
+static int lustre_connect_mds(struct super_block *sb, char *lmv,
+                              struct obd_connect_data *data,
+                              char *mds_security, int async, int pag)
 {
         struct ll_sb_info *sbi = ll_s2sbi(sb);
-        struct ptlrpc_request *request = NULL;
-        struct lustre_handle dt_conn = {0, };
         struct lustre_handle md_conn = {0, };
-        struct obd_connect_data *data;
-        struct inode *root = NULL;
-        struct obd_device *obd;
+        struct obd_device *md_obd;
         struct obd_statfs osfs;
-        struct lustre_md md;
         unsigned long sec_flags;
         __u32 valsize;
-        int err;
-        ENTRY;
-
-        obd = class_name2obd(lmv);
-        if (!obd) {
+        int    err = 0;
+        ENTRY;       
+        md_obd = class_name2obd(lmv);
+        if (!md_obd) {
                 CERROR("MDC %s: not setup or attached\n", lmv);
                 RETURN(-EINVAL);
         }
-        obd_set_info(obd->obd_self_export, strlen("async"), "async",
-                     sizeof(async), &async);
 
-        if ((*remote & (OBD_CONNECT_LOCAL | OBD_CONNECT_REMOTE)) ==
-            (OBD_CONNECT_LOCAL | OBD_CONNECT_REMOTE)) {
-                CERROR("wrong remote flag "LPX64"\n", *remote);
-                RETURN(-EINVAL);
-        }
-
-        OBD_ALLOC(data, sizeof(*data));
-        if (!data)
-                RETURN(-ENOMEM);
-
-        data->ocd_connect_flags |= *remote & (OBD_CONNECT_LOCAL |
-                                              OBD_CONNECT_REMOTE);
-        memcpy(data->ocd_nllu, nllu, sizeof(data->ocd_nllu));
-
-        if (mds_security == NULL)
-                mds_security = "null";
+        obd_set_info(md_obd->obd_self_export, strlen("async"), "async",
+                     sizeof(async), &async);
 
-        err = obd_set_info(obd->obd_self_export, strlen("sec"), "sec",
+        err = obd_set_info(md_obd->obd_self_export, strlen("sec"), "sec",
                            strlen(mds_security), mds_security);
+        
         if (err) {
                 CERROR("LMV %s: failed to set security %s, err %d\n",
                         lmv, mds_security, err);
-                OBD_FREE(data, sizeof(*data));
                 RETURN(err);
         }
 
         if (pag) {
                 sec_flags = PTLRPC_SEC_FL_PAG;
-                err = obd_set_info(obd->obd_self_export,
+                err = obd_set_info(md_obd->obd_self_export,
                                    strlen("sec_flags"), "sec_flags",
                                    sizeof(sec_flags), &sec_flags);
                 if (err) {
@@ -193,14 +171,7 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
                 }
         }
 
-        if (proc_lustre_fs_root) {
-                err = lprocfs_register_mountpoint(proc_lustre_fs_root,
-                                                  sb, lov, lmv);
-                if (err < 0)
-                        CERROR("could not register mount in /proc/lustre");
-        }
-
-        err = obd_connect(&md_conn, obd, &sbi->ll_sb_uuid, data,
+        err = obd_connect(&md_conn, md_obd, &sbi->ll_sb_uuid, data,
                           OBD_OPT_REAL_CLIENT);
         if (err == -EBUSY) {
                 CERROR("An MDS (lmv %s) is performing recovery, of which this"
@@ -211,14 +182,16 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
                 CERROR("cannot connect to %s: rc = %d\n", lmv, err);
                 GOTO(out, err);
         }
+
         sbi->ll_md_exp = class_conn2export(&md_conn);
-        err = obd_statfs(obd, &osfs, jiffies - HZ);
+       
+        err = obd_statfs(md_obd, &osfs, jiffies - HZ);
         if (err)
-                GOTO(out_lmv, err);
+                GOTO(out_disconnect, err);
 
         if (!osfs.os_bsize) {
                 CERROR("Invalid block size is detected.");
-                GOTO(out_lmv, err);
+                GOTO(out_disconnect, err);
         }
 
         sb->s_magic = LL_SUPER_MAGIC;
@@ -246,13 +219,29 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
                            &valsize, &sbi->ll_remote);
         if (err) {
                 CERROR("fail to obtain remote flag\n");
-                GOTO(out, err);
+                GOTO(out_disconnect, err);
         }
 
+out_disconnect:
+        if (err)
+                obd_disconnect(sbi->ll_md_exp, 0);
+out:
+        RETURN(err);
+}
+static int lustre_connect_ost(struct super_block *sb, char *lov, 
+                              struct obd_connect_data *data, 
+                              char *oss_security, int async, int pag)
+{
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        struct lustre_handle dt_conn = {0, };
+        struct obd_device *obd = NULL;
+        unsigned long sec_flags;
+        int err, mdsize; 
+
         obd = class_name2obd(lov);
         if (!obd) {
                 CERROR("OSC %s: not setup or attached\n", lov);
-                GOTO(out_lmv, err);
+                GOTO(out, err = -EINVAL);
         }
         obd_set_info(obd->obd_self_export, strlen("async"), "async",
                      sizeof(async), &async);
@@ -265,7 +254,6 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
         if (err) {
                 CERROR("LOV %s: failed to set security %s, err %d\n",
                         lov, oss_security, err);
-                OBD_FREE(data, sizeof(*data));
                 RETURN(err);
         }
 
@@ -288,22 +276,38 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
                 GOTO(out, err);
         } else if (err) {
                 CERROR("cannot connect to %s: rc = %d\n", lov, err);
-                GOTO(out_lmv, err);
+                GOTO(out, err);
         }
         sbi->ll_dt_exp = class_conn2export(&dt_conn);
 
         err = lustre_init_dt_desc(sbi);
-        if (err == 0) {
-                int mdsize = obd_size_diskmd(sbi->ll_dt_exp, NULL);
-                obd_init_ea_size(sbi->ll_md_exp, mdsize,
-                                 sbi->ll_dt_desc.ld_tgt_count *
-                                 sizeof(struct llog_cookie));
+       
+        if (err) {
+                CWARN("init dt_desc error %d \n", err);
+                GOTO(out, err = 0);
         }
-        
+        mdsize = obd_size_diskmd(sbi->ll_dt_exp, NULL);
+        obd_init_ea_size(sbi->ll_md_exp, mdsize, sbi->ll_dt_desc.ld_tgt_count *
+                         sizeof(struct llog_cookie));
+out:
+        RETURN(err);
+}
+
+extern struct dentry_operations ll_d_ops;
+
+static int lustre_init_root_inode(struct super_block *sb)
+{
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        struct ptlrpc_request *request = NULL;
+        struct inode *root = NULL;
+        struct lustre_md md;
+        int err = 0;
+        ENTRY;
+
         err = md_getstatus(sbi->ll_md_exp, &sbi->ll_rootid);
         if (err) {
                 CERROR("cannot mds_connect: rc = %d\n", err);
-                GOTO(out_lov, err);
+                GOTO(out, err);
         }
         CDEBUG(D_SUPER, "rootid "DLID4"\n", OLID4(&sbi->ll_rootid));
 
@@ -315,7 +319,7 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
                          NULL, NULL, 0, 0, &request);
         if (err) {
                 CERROR("md_getattr failed for root: rc = %d\n", err);
-                GOTO(out_lov, err);
+                GOTO(out, err);
         }
 
         err = mdc_req2lustre_md(sbi->ll_md_exp, request, 0, 
@@ -323,7 +327,7 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
         if (err) {
                 CERROR("failed to understand root inode md: rc = %d\n", err);
                 ptlrpc_req_finished(request);
-                GOTO(out_lov, err);
+                GOTO(out, err);
         }
 
         LASSERT(id_ino(&sbi->ll_rootid) != 0);
@@ -340,6 +344,66 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
                 CERROR("lustre_lite: bad iget4 for root\n");
                 GOTO(out_root, err = -EBADF);
         }
+        sb->s_root = d_alloc_root(root);
+        sb->s_root->d_op = &ll_d_ops;
+out_root:
+        if (err)
+                iput(root);
+out:
+        RETURN(err);
+}
+
+int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
+                             char *gkc, int async,  char *mds_security,  
+                             char *oss_security, __u32 *nllu, int pag, 
+                             __u64 *remote)
+{
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        struct obd_connect_data *data;
+        int err;
+        ENTRY;
+
+        /*process the connect flags*/
+        if ((*remote & (OBD_CONNECT_LOCAL | OBD_CONNECT_REMOTE)) ==
+                       (OBD_CONNECT_LOCAL | OBD_CONNECT_REMOTE)) {
+                CERROR("wrong remote flag "LPX64"\n", *remote);
+                RETURN(-EINVAL);
+        }
+
+        OBD_ALLOC(data, sizeof(*data));
+        if (!data)
+                RETURN(-ENOMEM);
+
+        data->ocd_connect_flags |= *remote & (OBD_CONNECT_LOCAL |
+                                              OBD_CONNECT_REMOTE);
+        memcpy(data->ocd_nllu, nllu, sizeof(data->ocd_nllu));
+
+        if (proc_lustre_fs_root) {
+                err = lprocfs_register_mountpoint(proc_lustre_fs_root, 
+                                                  sb, lov, lmv);
+                if (err < 0)
+                        CERROR("could not register mount in /proc/lustre");
+        }
+
+        /*connect mds */ 
+        err = lustre_connect_mds(sb, lmv, data, mds_security, async, pag);
+        if (err)
+                GOTO(out, err);
+
+        /*connect OST*/
+        err = lustre_connect_ost(sb, lov, data, oss_security, async, pag);
+        if (err)
+                GOTO(out_lmv, err);
+
+        err = lustre_init_crypto(sb, gkc, data, async);
+        if (err) {
+                CERROR("Could not connect to GSS err %d\n", err);
+                err = 0;
+        }
+        /*connect GSS*/
+        err = lustre_init_root_inode(sb);
+        if (err)
+                GOTO(out_gks, err);
 
         err = ll_close_thread_start(&sbi->ll_lcq);
         if (err) {
@@ -357,31 +421,26 @@ int lustre_common_fill_super(struct super_block *sb, char *lmv, char *lov,
         /* bug 2805 - set VM readahead to zero */
         vm_max_readahead = vm_min_readahead = 0;
 #endif
-
-        sb->s_root = d_alloc_root(root);
-        sb->s_root->d_op = &ll_d_ops;
-
         sb->s_flags |= MS_POSIXACL;
 #ifdef S_PDIROPS
         CWARN("Enabling PDIROPS\n");
         sb->s_flags |= S_PDIROPS;
 #endif
-
         if (data != NULL)
                 OBD_FREE(data, sizeof(*data));
         RETURN(err);
 out_root:
-        if (root)
-                iput(root);
-out_lov:
-        obd_disconnect(sbi->ll_dt_exp, 0);
+        if (sb->s_root)
+                dput(sb->s_root);
+out_gks:
+        lustre_destroy_crypto(sb);
 out_lmv:
         obd_disconnect(sbi->ll_md_exp, 0);
 out:
         if (data != NULL)
                 OBD_FREE(data, sizeof(*data));
         lprocfs_unregister_mountpoint(sbi);
-        return err;
+        RETURN(err);
 }
 
 void lustre_common_put_super(struct super_block *sb)
@@ -393,6 +452,8 @@ void lustre_common_put_super(struct super_block *sb)
         ll_gns_del_timer(sbi);
         ll_close_thread_shutdown(sbi->ll_lcq);
 
+        lustre_destroy_crypto(sb);
+
         list_del(&sbi->ll_conn_chain);
         obd_disconnect(sbi->ll_dt_exp, 0);
 
@@ -449,8 +510,8 @@ int ll_set_opt(const char *opt, char *data, int fl)
                 RETURN(fl);
 }
 
-void ll_options(char *options, char **lov, char **lmv, char **mds_sec,
-                char **oss_sec, int *async, int *flags)
+void ll_options(char *options, char **lov, char **lmv, char **gkc,
+                char **mds_sec, char **oss_sec, int *async, int *flags)
 {
         char *this_char;
 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
@@ -476,6 +537,8 @@ void ll_options(char *options, char **lov, char **lmv, char **mds_sec,
                         continue;
                 if (!*lmv && (*lmv = ll_read_opt("mdc", this_char)))
                         continue;
+                if (!*gkc && (*gkc = ll_read_opt("gkc", this_char)))
+                        continue;
                 if (!strncmp(this_char, "lasync", strlen("lasync"))) {
                         *async = 1;
                         continue;
@@ -511,13 +574,13 @@ void ll_lli_init(struct ll_inode_info *lli)
         lli->lli_mds_exec_och = NULL;
         lli->lli_open_fd_read_count = lli->lli_open_fd_write_count = 0;
         lli->lli_open_fd_exec_count = 0;
+        lli->lli_key_info = NULL;
 }
 
 int ll_fill_super(struct super_block *sb, void *data, int silent)
 {
         struct ll_sb_info *sbi;
-        char *lov = NULL;
-        char *lmv = NULL;
+        char *lov = NULL, *lmv = NULL, *gkc = NULL;
         char *mds_sec = NULL;
         char *oss_sec = NULL;
         int async, err;
@@ -532,21 +595,16 @@ int ll_fill_super(struct super_block *sb, void *data, int silent)
                 RETURN(-ENOMEM);
 
         sbi->ll_flags |= LL_SBI_READAHEAD;
-        ll_options(data, &lov, &lmv, &mds_sec, &oss_sec,
+        ll_options(data, &lov, &lmv, &gkc, &mds_sec, &oss_sec,
                    &async, &sbi->ll_flags);
 
-        if (!lov) {
-                CERROR("no osc\n");
-                GOTO(out, err = -EINVAL);
-        }
-
-        if (!lmv) {
-                CERROR("no mdc\n");
+        if (!lov || !lmv) {
+                CERROR("no osc %p or no mdc %p\n", lov, lmv);
                 GOTO(out, err = -EINVAL);
         }
         
-        err = lustre_common_fill_super(sb, lmv, lov, async, mds_sec, oss_sec,
-                                       nllu, 0, &remote_flag);
+        err = lustre_common_fill_super(sb, lmv, lov, gkc, async, mds_sec, 
+                                       oss_sec, nllu, 0, &remote_flag);
         EXIT;
 out:
         if (err)
@@ -738,8 +796,7 @@ static void lustre_manual_cleanup(struct ll_sb_info *sbi)
         struct obd_device *obd;
         int next = 0;
 
-        while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) != NULL)
-        {
+        while ((obd = class_devices_in_group(&sbi->ll_sb_uuid, &next)) != NULL) {
                 int err;
 
                 lustre_cfg_bufs_reset(&bufs, obd->obd_name);
@@ -763,10 +820,115 @@ static void lustre_manual_cleanup(struct ll_sb_info *sbi)
                 class_del_profile(sbi->ll_lmd->lmd_profile);
 }
 
+static int lustre_process_profile(struct super_block *sb, 
+                                  struct lustre_mount_data *lmd,
+                                  char **lov, char **lmv, char **gkc)  
+{
+        struct ll_sb_info *sbi = ll_s2sbi(sb);
+        struct lustre_profile *lprof;
+        struct config_llog_instance cfg;
+        int len, err = 0;
+        
+        ENTRY;
+
+        if (!lmd->lmd_profile)
+                RETURN(0);
+        if (lmd->lmd_mds[0] == '\0') {
+                CERROR("no mds name\n");
+                GOTO(out, err = -EINVAL);
+        }
+        lmd->lmd_mds_security[sizeof(lmd->lmd_mds_security) - 1] = 0;
+        lmd->lmd_oss_security[sizeof(lmd->lmd_oss_security) - 1] = 0;
+
+        OBD_ALLOC(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
+        if (sbi->ll_lmd == NULL)
+                GOTO(out, err = -ENOMEM);
+        memcpy(sbi->ll_lmd, lmd, sizeof(*lmd));
+
+        /* generate a string unique to this super, let's try
+         the address of the super itself.*/
+        len = (sizeof(sb) * 2) + 1;
+        OBD_ALLOC(sbi->ll_instance, len);
+        if (sbi->ll_instance == NULL)
+                GOTO(out, err = -ENOMEM);
+        sprintf(sbi->ll_instance, "%p", sb);
+
+        cfg.cfg_instance = sbi->ll_instance;
+        cfg.cfg_uuid = sbi->ll_sb_uuid;
+        cfg.cfg_local_nid = lmd->lmd_local_nid;
+        err = lustre_process_log(lmd, lmd->lmd_profile, &cfg, 0);
+        if (err < 0) {
+                CERROR("Unable to process log: %s\n", lmd->lmd_profile);
+                GOTO(out, err);
+        }
+
+        lprof = class_get_profile(lmd->lmd_profile);
+        if (lprof == NULL) {
+                CERROR("No profile found: %s\n", lmd->lmd_profile);
+                GOTO(out, err = -EINVAL);
+        }
+
+        OBD_ALLOC(*lov, strlen(lprof->lp_lov) +
+                  strlen(sbi->ll_instance) + 2);
+        sprintf(*lov, "%s-%s", lprof->lp_lov, sbi->ll_instance);
+
+        OBD_ALLOC(*lmv, strlen(lprof->lp_lmv) +
+                  strlen(sbi->ll_instance) + 2);
+        sprintf(*lmv, "%s-%s", lprof->lp_lmv, sbi->ll_instance);
+
+        if (lprof->lp_gkc) {
+               OBD_ALLOC(*gkc, strlen(lprof->lp_gkc) +
+                               strlen(sbi->ll_instance) + 2);
+               sprintf(*gkc, "%s-%s", lprof->lp_gkc, sbi->ll_instance); 
+        }
+out: 
+        RETURN(err); 
+}
+
+static int lustre_clean_profile(struct ll_sb_info *sbi, int force_umount)
+{
+        struct lustre_mount_data *lmd = sbi->ll_lmd;
+        struct config_llog_instance cfg;
+        char *cl_prof;
+        int len, err = 0;
+        ENTRY; 
+        if (!lmd)
+                RETURN(err);
+
+        len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean") + 1;
+        
+        if (force_umount) {
+                CERROR("force umount, doing manual cleanup\n");
+                lustre_manual_cleanup(sbi);
+                GOTO(free_lmd, 0);
+                
+        }
+        if (sbi->ll_instance != NULL) {
+                cfg.cfg_instance = sbi->ll_instance;
+                cfg.cfg_uuid = sbi->ll_sb_uuid;
+
+                OBD_ALLOC(cl_prof, len);
+                sprintf(cl_prof, "%s-clean", lmd->lmd_profile);
+                err = lustre_process_log(lmd, cl_prof, &cfg, 0);
+                if (err < 0) {
+                        CERROR("Unable to process log: %s\n", cl_prof);
+                        lustre_manual_cleanup(sbi);
+                }
+                OBD_FREE(cl_prof, len);
+        }
+free_lmd:
+        if (sbi->ll_instance)
+                OBD_FREE(sbi->ll_instance, strlen(sbi->ll_instance) + 1);
+        OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
+        RETURN(err);
+}
+
 int lustre_fill_super(struct super_block *sb, void *data, int silent)
 {
         struct lustre_mount_data * lmd = data;
-        char *lov = NULL, *lmv = NULL;
+        char *lov = NULL, *lmv = NULL, *gkc = NULL;
         struct ll_sb_info *sbi;
         int err;
         ENTRY;
@@ -781,69 +943,17 @@ int lustre_fill_super(struct super_block *sb, void *data, int silent)
 
         sbi->ll_flags |= LL_SBI_READAHEAD;
 
-        if (lmd->lmd_profile) {
-                struct lustre_profile *lprof;
-                struct config_llog_instance cfg;
-                int len;
-
-                if (lmd->lmd_mds[0] == '\0') {
-                        CERROR("no mds name\n");
-                        GOTO(out_free, err = -EINVAL);
-                }
-                lmd->lmd_mds_security[sizeof(lmd->lmd_mds_security) - 1] = 0;
-                lmd->lmd_oss_security[sizeof(lmd->lmd_oss_security) - 1] = 0;
-
-                OBD_ALLOC(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
-                if (sbi->ll_lmd == NULL)
-                        GOTO(out_free, err = -ENOMEM);
-                memcpy(sbi->ll_lmd, lmd, sizeof(*lmd));
-
-                /* generate a string unique to this super, let's try
-                 the address of the super itself.*/
-                len = (sizeof(sb) * 2) + 1;
-                OBD_ALLOC(sbi->ll_instance, len);
-                if (sbi->ll_instance == NULL)
-                        GOTO(out_free, err = -ENOMEM);
-                sprintf(sbi->ll_instance, "%p", sb);
-
-                cfg.cfg_instance = sbi->ll_instance;
-                cfg.cfg_uuid = sbi->ll_sb_uuid;
-                cfg.cfg_local_nid = lmd->lmd_local_nid;
-                err = lustre_process_log(lmd, lmd->lmd_profile, &cfg, 0);
-                if (err < 0) {
-                        CERROR("Unable to process log: %s\n", lmd->lmd_profile);
-                        GOTO(out_free, err);
-                }
-
-                lprof = class_get_profile(lmd->lmd_profile);
-                if (lprof == NULL) {
-                        CERROR("No profile found: %s\n", lmd->lmd_profile);
-                        GOTO(out_free, err = -EINVAL);
-                }
-                if (lov)
-                        OBD_FREE(lov, strlen(lov) + 1);
-                OBD_ALLOC(lov, strlen(lprof->lp_lov) +
-                          strlen(sbi->ll_instance) + 2);
-                sprintf(lov, "%s-%s", lprof->lp_lov, sbi->ll_instance);
-
-                if (lmv)
-                        OBD_FREE(lmv, strlen(lmv) + 1);
-                OBD_ALLOC(lmv, strlen(lprof->lp_lmv) +
-                          strlen(sbi->ll_instance) + 2);
-                sprintf(lmv, "%s-%s", lprof->lp_lmv, sbi->ll_instance);
-        }
-
-        if (!lov) {
-                CERROR("no osc\n");
-                GOTO(out_free, err = -EINVAL);
+        err = lustre_process_profile(sb, lmd, &lov, &lmv, &gkc);
+        if (err) {
+                CERROR("Can not process the profile err %d \n", err);
+                GOTO(out_free, err);
         }
-
-        if (!lmv) {
-                CERROR("no mdc\n");
+        if (!lov || !lmv) {
+                CERROR("no osc %p or no mdc %p \n", lov, lmv);
                 GOTO(out_free, err = -EINVAL);
         }
 
-        err = lustre_common_fill_super(sb, lmv, lov, lmd->lmd_async,
+        err = lustre_common_fill_super(sb, lmv, lov, gkc, lmd->lmd_async,
                                        lmd->lmd_mds_security,
                                        lmd->lmd_oss_security,
                                        &lmd->lmd_nllu, lmd->lmd_pag,
@@ -857,36 +967,15 @@ out_dev:
                 OBD_FREE(lmv, strlen(lmv) + 1);
         if (lov)
                 OBD_FREE(lov, strlen(lov) + 1);
-
+        if (gkc)
+                OBD_FREE(gkc, strlen(gkc) + 1);
+        
         RETURN(err);
-
 out_free:
-        if (sbi->ll_lmd) {
-                int len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean")+1;
-                int err;
-
-                if (sbi->ll_instance != NULL) {
-                        struct lustre_mount_data *lmd = sbi->ll_lmd;
-                        struct config_llog_instance cfg;
-                       char *cl_prof;
-
-                        cfg.cfg_instance = sbi->ll_instance;
-                        cfg.cfg_uuid = sbi->ll_sb_uuid;
-
-                        OBD_ALLOC(cl_prof, len);
-                        sprintf(cl_prof, "%s-clean", lmd->lmd_profile);
-                        err = lustre_process_log(lmd, cl_prof, &cfg, 0);
-                        if (err < 0) {
-                                CERROR("Unable to process log: %s\n", cl_prof);
-                                lustre_manual_cleanup(sbi);
-                        }
-                        OBD_FREE(cl_prof, len);
-                        OBD_FREE(sbi->ll_instance, strlen(sbi->ll_instance) + 1);
-                }
-                OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
-        }
+        lustre_clean_profile(sbi, 0);
         lustre_free_sbi(sb);
-        goto out_dev;
+        GOTO(out_dev, err);
+
 } /* lustre_fill_super */
 
 void lustre_put_super(struct super_block *sb)
@@ -903,36 +992,7 @@ void lustre_put_super(struct super_block *sb)
         obd = NULL;
 
         lustre_common_put_super(sb);
-        if (sbi->ll_lmd != NULL) {
-                char *cl_prof;
-                int len = strlen(sbi->ll_lmd->lmd_profile) + sizeof("-clean")+1;
-                int err;
-                struct config_llog_instance cfg;
-
-                if (force_umount) {
-                        CERROR("force umount, doing manual cleanup\n");
-                        lustre_manual_cleanup(sbi);
-                        GOTO(free_lmd, 0);
-                }
-
-                cfg.cfg_instance = sbi->ll_instance;
-                cfg.cfg_uuid = sbi->ll_sb_uuid;
-
-                OBD_ALLOC(cl_prof, len);
-                sprintf(cl_prof, "%s-clean", sbi->ll_lmd->lmd_profile);
-                err = lustre_process_log(sbi->ll_lmd, cl_prof, &cfg, 0);
-                if (err < 0) {
-                        CERROR("Unable to process log: %s, doing manual cleanup"
-                               "\n", cl_prof);
-                        lustre_manual_cleanup(sbi);
-                }
-
-                OBD_FREE(cl_prof, len);
-        free_lmd:
-                OBD_FREE(sbi->ll_lmd, sizeof(*sbi->ll_lmd));
-                OBD_FREE(sbi->ll_instance, strlen(sbi->ll_instance) + 1);
-        }
-
+        lustre_clean_profile(sbi, force_umount);
         lustre_free_sbi(sb);
 
         EXIT;
@@ -1093,7 +1153,7 @@ void ll_clear_inode(struct inode *inode)
                                (struct lov_stripe_md **) &lli->lli_mea);
                 lli->lli_mea = NULL;
         }
-
+        ll_crypto_destroy_inode_key(inode);
         if (lli->lli_symlink_name) {
                 OBD_FREE(lli->lli_symlink_name,
                          strlen(lli->lli_symlink_name) + 1);
@@ -1187,22 +1247,31 @@ int ll_setattr_raw(struct inode *inode, struct iattr *attr)
          * inode ourselves so we can call obdo_from_inode() always. */
         if (ia_valid & (lsm ? ~(ATTR_SIZE | ATTR_FROM_OPEN /*| ATTR_RAW*/) : ~0)) {
                 struct lustre_md md;
+                void *key = NULL;
+                int  key_size = 0; 
 
                 OBD_ALLOC(op_data, sizeof(*op_data));
                 if (op_data == NULL)
                         RETURN(-ENOMEM);
                 ll_prepare_mdc_data(op_data, inode, NULL, NULL, 0, 0);
 
+                if (ia_valid & (ATTR_UID | ATTR_GID)) {
+                        rc = ll_crypto_get_mac(inode, attr, NULL, 0, &key, 
+                                               &key_size);
+                }
                 rc = md_setattr(sbi->ll_md_exp, op_data,
-                                attr, NULL, 0, NULL, 0, &request);
+                                attr, key, key_size, NULL, 0, NULL, 
+                                0, &request);
                 OBD_FREE(op_data, sizeof(*op_data));
+                
+                if (key && key_size) 
+                        OBD_FREE(key, key_size);
                 if (rc) {
                         ptlrpc_req_finished(request);
                         if (rc != -EPERM && rc != -EACCES)
                                 CERROR("md_setattr fails: rc = %d\n", rc);
                         RETURN(rc);
                 }
-
                 rc = mdc_req2lustre_md(sbi->ll_md_exp, request, 0, 
                                        sbi->ll_dt_exp, &md);
                 if (rc) {
@@ -1834,6 +1903,7 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
         struct mea *mea = md->mea;
         struct posix_acl *posix_acl = md->posix_acl;
         struct ll_sb_info *sbi = ll_i2sbi(inode);
+        struct lustre_key *mkey = md->key;
         ENTRY;
 
         LASSERT((lsm != NULL) == ((body->valid & OBD_MD_FLEASIZE) != 0));
@@ -1969,6 +2039,11 @@ void ll_update_inode(struct inode *inode, struct lustre_md *md)
         if (body->valid & OBD_MD_FLSIZE)
                 set_bit(LLI_F_HAVE_MDS_SIZE_LOCK, &lli->lli_flags);
 
+        if (mkey != NULL) {
+                LASSERT(body->valid & OBD_MD_FLKEY);
+                ll_crypto_init_inode_key(inode, mkey);  
+        }
+
 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
         inode->i_dev = (kdev_t)id_group(&lli->lli_id);
 #endif
@@ -2139,7 +2214,7 @@ int ll_iocontrol(struct inode *inode, struct file *file,
                 attr.ia_valid |= ATTR_ATTR_FLAG;
 
                 rc = md_setattr(sbi->ll_md_exp, op_data,
-                                &attr, NULL, 0, NULL, 0, &req);
+                                &attr, NULL, 0, NULL, 0, NULL, 0, &req);
                 OBD_FREE(op_data, sizeof(*op_data));
                 if (rc) {
                         ptlrpc_req_finished(req);
@@ -2305,7 +2380,6 @@ int ll_get_fid(struct obd_export *exp, struct lustre_id *idp,
 
         return rc;
 }
-
 int ll_flush_cred(struct inode *inode)
 {
         struct ll_sb_info *sbi = ll_i2sbi(inode);
index 9cad4e7..113b902 100644 (file)
@@ -383,7 +383,12 @@ static struct dentry *ll_lookup_it(struct inode *parent, struct dentry *dentry,
         icbd.icbd_childp = &dentry;
         icbd.icbd_parent = parent;
         ll_inode2id(&pid, parent);
-
+        /*ONLY need key for open_create file*/
+        rc = ll_crypto_init_it_key(parent, it);
+        if (rc != 0) 
+                GOTO(out, retval = ERR_PTR(rc)); 
+        
         rc = md_intent_lock(ll_i2mdexp(parent), &pid, (char *)dentry->d_name.name,
                             dentry->d_name.len, NULL, 0, NULL, it, flags, &req,
                             ll_mdc_blocking_ast);
@@ -576,7 +581,8 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
         struct inode *dir = nd->dentry->d_inode;
         struct ll_sb_info *sbi = ll_i2sbi(dir);
         struct mdc_op_data *op_data;
-        int err = -EMLINK;
+        int err = -EMLINK, key_size = 0;
+        void *key = NULL;
         ENTRY;
 
         CDEBUG(D_VFSTRACE, "VFS Op:name=%.*s,dir=%lu/%u(%p)\n",
@@ -587,8 +593,9 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
 
         switch (mode & S_IFMT) {
         case 0:
-        case S_IFREG:
+        case S_IFREG: 
                 mode |= S_IFREG; /* for mode = 0 case, fallthrough */
+                ll_crypto_create_key(dir, mode, &key, &key_size);
         case S_IFCHR:
         case S_IFBLK:
         case S_IFIFO:
@@ -599,8 +606,7 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
                 ll_prepare_mdc_data(op_data, dir, NULL,
                                     (char *)nd->last.name, 
                                    nd->last.len, 0);
-                
-                err = md_create(sbi->ll_md_exp, op_data, NULL, 0, mode,
+                err = md_create(sbi->ll_md_exp, op_data, key, key_size, mode,
                                 current->fsuid, current->fsgid, rdev,
                                 &request);
                 OBD_FREE(op_data, sizeof(*op_data));
@@ -614,6 +620,8 @@ static int ll_mknod_raw(struct nameidata *nd, int mode, dev_t rdev)
         default:
                 err = -EINVAL;
         }
+        if (key && key_size)
+                OBD_FREE(key, key_size);
         RETURN(err);
 }
 
@@ -637,6 +645,7 @@ static int ll_mknod(struct inode *dir, struct dentry *dchild,
         case 0:
         case S_IFREG:
                 mode |= S_IFREG; /* for mode = 0 case, fallthrough */
+                
         case S_IFCHR:
         case S_IFBLK:
         case S_IFIFO:
index 434febc..634a454 100644 (file)
@@ -183,6 +183,16 @@ out_unlock:
         up(&lli->lli_size_sem);
 } /* ll_truncate */
 
+struct ll_async_page *llap_cast_private(struct page *page)
+{
+        struct ll_async_page *llap = (struct ll_async_page *)page->private;
+
+        LASSERTF(llap == NULL || llap->llap_magic == LLAP_MAGIC, 
+                 "page %p private %lu gave magic %d which != %d\n",
+                 page, page->private, llap->llap_magic, LLAP_MAGIC);
+        return llap;
+}
+
 int ll_prepare_write(struct file *file, struct page *page,
                      unsigned from, unsigned to)
 {
@@ -384,17 +394,6 @@ static struct obd_async_page_ops ll_async_page_ops = {
 };
 
 
-struct ll_async_page *llap_cast_private(struct page *page)
-{
-        struct ll_async_page *llap = (struct ll_async_page *)page->private;
-
-        LASSERTF(llap == NULL || llap->llap_magic == LLAP_MAGIC,
-                 "page %p private %lu gave magic %d which != %d\n",
-                 page, page->private, llap->llap_magic, LLAP_MAGIC);
-
-        return llap;
-}
-
 /* XXX have the exp be an argument? */
 struct ll_async_page *llap_from_page(struct page *page, unsigned origin)
 {
@@ -408,16 +407,17 @@ struct ll_async_page *llap_from_page(struct page *page, unsigned origin)
         LASSERTF(origin < LLAP__ORIGIN_MAX, "%u\n", origin);
 
         llap = llap_cast_private(page);
-        if (llap != NULL)
+        if (llap != NULL) {
                 GOTO(out, llap);
-
+        }
         exp = ll_i2dtexp(page->mapping->host);
         if (exp == NULL)
                 RETURN(ERR_PTR(-EINVAL));
-
+        
         OBD_ALLOC(llap, sizeof(*llap));
-        if (llap == NULL)
+        if (llap == NULL) {
                 RETURN(ERR_PTR(-ENOMEM));
+        }
         llap->llap_magic = LLAP_MAGIC;
         INIT_LIST_HEAD(&llap->llap_pending_write);
         rc = obd_prep_async_page(exp, ll_i2info(inode)->lli_smd, NULL, page,
@@ -430,8 +430,10 @@ struct ll_async_page *llap_from_page(struct page *page, unsigned origin)
 
         CDEBUG(D_CACHE, "llap %p page %p cookie %p obj off "LPU64"\n", llap,
                page, llap->llap_cookie, (obd_off)page->index << PAGE_SHIFT);
-        /* also zeroing the PRIVBITS low order bitflags */
+       
         __set_page_ll_data(page, llap);
+       
+         /* also zeroing the PRIVBITS low order bitflags */
         llap->llap_page = page;
 
         spin_lock(&sbi->ll_lock);
@@ -469,7 +471,6 @@ static int queue_or_sync_write(struct obd_export *exp,
         rc = oig_init(&oig);
         if (rc)
                 GOTO(out, rc);
-
         rc = obd_queue_group_io(exp, lsm, NULL, oig, llap->llap_cookie,
                                 OBD_BRW_WRITE, 0, to, 0, ASYNC_READY |
                                 ASYNC_URGENT | ASYNC_COUNT_STABLE |
@@ -703,7 +704,6 @@ void ll_removepage(struct page *page)
                 EXIT;
                 return;
         }
-
         llap = llap_from_page(page, 0);
         if (IS_ERR(llap)) {
                 CERROR("page %p ind %lu couldn't find llap: %ld\n", page,
@@ -765,10 +765,11 @@ static int ll_issue_page_read(struct obd_export *exp,
         page_cache_get(page);
         llap->llap_defer_uptodate = defer;
         llap->llap_ra_used = 0;
+        
         rc = obd_queue_group_io(exp, ll_i2info(page->mapping->host)->lli_smd,
                                 NULL, oig, llap->llap_cookie, OBD_BRW_READ, 0,
                                 PAGE_SIZE, 0, ASYNC_COUNT_STABLE | ASYNC_READY
-                                              | ASYNC_URGENT);
+                                | ASYNC_URGENT);
         if (rc) {
                 LL_CDEBUG_PAGE(D_ERROR, page, "read queue failed: rc %d\n", rc);
                 page_cache_release(page);
@@ -1057,7 +1058,7 @@ int ll_readpage(struct file *filp, struct page *page)
         llap = llap_from_page(page, LLAP_ORIGIN_READPAGE);
         if (IS_ERR(llap))
                 GOTO(out, rc = PTR_ERR(llap));
-
+        
         if (ll_i2sbi(inode)->ll_flags & LL_SBI_READAHEAD)
                 ras_update(ll_i2sbi(inode), &fd->fd_ras, page->index,
                            llap->llap_defer_uptodate);
index ff27c5c..02198dc 100644 (file)
@@ -1357,7 +1357,8 @@ request:
 
 static int lmv_setattr(struct obd_export *exp, struct mdc_op_data *data,
                        struct iattr *iattr, void *ea, int ealen, void *ea2,
-                       int ea2len, struct ptlrpc_request **request)
+                       int ea2len, void *ea3, int ea3len, 
+                       struct ptlrpc_request **request)
 {
         struct obd_device *obd = exp->exp_obd;
         struct lmv_obd *lmv = &obd->u.lmv;
@@ -1381,7 +1382,8 @@ static int lmv_setattr(struct obd_export *exp, struct mdc_op_data *data,
                         data->id1 = obj->objs[i].id;
                         
                         rc = md_setattr(lmv->tgts[id_group(&data->id1)].ltd_exp, 
-                                        data, iattr, ea, ealen, ea2, ea2len, &req);
+                                        data, iattr, ea, ealen, ea2, ea2len, 
+                                        ea3, ea3len, &req);
 
                         if (id_equal_fid(&obj->id, &obj->objs[i].id)) {
                                 /*
@@ -1400,7 +1402,8 @@ static int lmv_setattr(struct obd_export *exp, struct mdc_op_data *data,
         } else {
                 LASSERT(id_group(&data->id1) < lmv->desc.ld_tgt_count);
                 rc = md_setattr(lmv->tgts[id_group(&data->id1)].ltd_exp,
-                                data, iattr, ea, ealen, ea2, ea2len, request); 
+                                data, iattr, ea, ealen, ea2, ea2len, ea3,
+                                ea3len, request); 
                 if (rc == 0) {
                         body = lustre_msg_buf((*request)->rq_repmsg, 0,
                                               sizeof(*body));
@@ -1999,8 +2002,10 @@ int lmv_set_info(struct obd_export *exp, obd_count keylen,
                 RETURN(rc);
         }
 
-        if ((keylen == strlen("flush_cred") &&
-             strcmp(key, "flush_cred") == 0)) {
+        if (((keylen == strlen("flush_cred") &&
+             strcmp(key, "flush_cred") == 0)) || 
+             ((keylen == strlen("crypto_type") &&
+             strcmp(key, "crypto_type") == 0))) {
                 int rc = 0, i;
 
                 for (i = 0, tgt = lmv->tgts; i < lmv->desc.ld_tgt_count;
index 2388527..12791c1 100644 (file)
@@ -2013,6 +2013,7 @@ static int lov_get_info(struct obd_export *exp, __u32 keylen,
                 }
                 LDLM_ERROR(data->lock, "lock on inode without such object");
                 dump_lsm(D_ERROR, data->lsm);
+                portals_debug_dumpstack(NULL);
                 RETURN(-ENXIO);
         } else if (keylen >= strlen("size_to_stripe") &&
                    strcmp(key, "size_to_stripe") == 0) {
@@ -2139,7 +2140,7 @@ static int lov_set_info(struct obd_export *exp, obd_count keylen,
                 spin_unlock(&lov->lov_lock);
 
                 RETURN(rc);
-        } else if (KEY_IS("flush_cred")) {
+        } else if (KEY_IS("flush_cred") || KEY_IS("crypto_cb")) {
                 struct lov_tgt_desc *tgt;
                 int rc = 0, i;
 
index 481a5b7..52dde66 100644 (file)
@@ -79,6 +79,7 @@ struct fsfilt_cb_data {
 #define XATTR_LUSTRE_MDS_MEA_EA         "mea"
 #define XATTR_LUSTRE_MDS_MID_EA         "mid"
 #define XATTR_LUSTRE_MDS_SID_EA         "sid"
+#define XATTR_LUSTRE_MDS_KEY_EA         "key"
 
 /*
  * We don't currently need any additional blocks for rmdir and
@@ -512,6 +513,11 @@ static int fsfilt_ext3_set_md(struct inode *inode, void *handle,
                                            XATTR_LUSTRE_MDS_MID_EA,
                                            lmm, lmm_size);
                 break;
+        case EA_KEY:
+                rc = fsfilt_ext3_set_xattr(inode, handle,
+                                           XATTR_LUSTRE_MDS_KEY_EA,
+                                           lmm, lmm_size);
+                break;
         default:
                 return -EINVAL;
         }
@@ -545,6 +551,11 @@ static int fsfilt_ext3_get_md(struct inode *inode, void *lmm,
                                            XATTR_LUSTRE_MDS_MID_EA,
                                            lmm, lmm_size);
                 break;
+        case EA_KEY:
+                rc = fsfilt_ext3_get_xattr(inode, 
+                                           XATTR_LUSTRE_MDS_KEY_EA,
+                                           lmm, lmm_size);
+                break;
         default:
                 return -EINVAL;
         }
index 587a24e..6a0abe9 100644 (file)
@@ -29,9 +29,11 @@ int mdc_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp,
 
 void mdc_getattr_pack(struct lustre_msg *msg, int offset,
                       __u64 valid, int flags, struct mdc_op_data *data);
+
 void mdc_open_pack(struct lustre_msg *msg, int offset,
-                   struct mdc_op_data *op_data, __u32 mode, __u64 rdev,
-                   __u32 flags, const void *lmm, int lmmlen);
+                   struct mdc_op_data *op_data, __u32 mode,
+                   __u64 rdev, __u32 flags, const void *lmm,
+                   int lmmlen, void *key, int keylen);
 void mdc_readdir_pack(struct ptlrpc_request *req, int req_offset,
                       __u64 offset, __u32 size, struct lustre_id *mdc_id);
 void mdc_close_pack(struct ptlrpc_request *req, int offset, struct obdo *oa,
index 07a6195..901e4a1 100644 (file)
@@ -50,26 +50,11 @@ void mdc_readdir_pack(struct ptlrpc_request *req, int req_offset,
         b->nlink = size;                        /* !! */
 }
 
-static __u32 mds_pack_open_flags(__u32 flags)
-{
-        return
-                (flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC |
-                          MDS_OPEN_DELAY_CREATE | MDS_OPEN_HAS_EA |
-                          MDS_OPEN_HAS_OBJS)) |
-                ((flags & O_CREAT) ? MDS_OPEN_CREAT : 0) |
-                ((flags & O_EXCL) ? MDS_OPEN_EXCL : 0) |
-                ((flags & O_TRUNC) ? MDS_OPEN_TRUNC : 0) |
-                ((flags & O_APPEND) ? MDS_OPEN_APPEND : 0) |
-                ((flags & O_SYNC) ? MDS_OPEN_SYNC : 0) |
-                ((flags & O_DIRECTORY) ? MDS_OPEN_DIRECTORY : 0) |
-                0;
-}
-
 /* packing of MDS records */
 void mdc_open_pack(struct lustre_msg *msg, int offset,
                    struct mdc_op_data *op_data, __u32 mode,
                    __u64 rdev, __u32 flags, const void *lmm,
-                   int lmmlen)
+                   int lmmlen, void *key, int keylen)
 {
         struct mds_rec_create *rec;
         char *tmp;
@@ -97,6 +82,11 @@ void mdc_open_pack(struct lustre_msg *msg, int offset,
                 tmp = lustre_msg_buf(msg, offset + 2, lmmlen);
                 memcpy (tmp, lmm, lmmlen);
         }
+        if (key) {
+                rec->cr_flags |= MDS_OPEN_HAS_KEY;
+                tmp = lustre_msg_buf(msg, offset + 3, keylen);
+                memcpy(tmp, key, keylen); 
+        }
 }
 
 void mdc_getattr_pack(struct lustre_msg *msg, int offset,
index b0856bb..e89e46c 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/lustre_sec.h>
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_acl.h>
+#include <linux/lustre_gs.h>
 #include <linux/lustre_lite.h>
 #include "mdc_internal.h"
 
@@ -239,13 +240,18 @@ int mdc_enqueue(struct obd_export *exp,
         reqsize[0] = lustre_secdesc_size();
 
         if (it->it_op & IT_OPEN) {
+                struct lustre_intent_data *lustre_data = 
+                                   (struct lustre_intent_data *) it->d.fs_data;  
                 it->it_create_mode |= S_IFREG;
                 it->it_create_mode &= ~current->fs->umask;
 
                 reqsize[req_buffers++] = sizeof(struct mds_rec_create);
                 reqsize[req_buffers++] = data->namelen + 1;
                 reqsize[req_buffers++] = obddev->u.cli.cl_max_mds_easize;
-
+                /*pack the lustre key*/
+                if (lustre_data->it_key_size > 0 && lustre_data->it_key)
+                        reqsize[req_buffers++] = lustre_data->it_key_size; 
+                
                 req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_DLM_VERSION,
                                       LDLM_ENQUEUE, req_buffers, reqsize, NULL);
                 if (!req)
@@ -262,15 +268,18 @@ int mdc_enqueue(struct obd_export *exp,
 
                 /* pack the intended request */
                 mdc_open_pack(req->rq_reqmsg, MDS_REQ_INTENT_REC_OFF, data,
-                              it->it_create_mode, 0, it->it_flags, lmm, lmmsize);
+                              it->it_create_mode, 0, it->it_flags, lmm, lmmsize,
+                              lustre_data->it_key, lustre_data->it_key_size);
                 /* get ready for the reply */
-                repsize[3] = 4;
-                repsize[4] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
-                reply_buffers = 5;
-                req->rq_replen = lustre_msg_size(5, repsize);
+                reply_buffers = 3;
+                repsize[reply_buffers++] = sizeof(int);
+                repsize[reply_buffers++] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
+                repsize[reply_buffers++] = sizeof(int);
+                repsize[reply_buffers++] = sizeof(struct crypto_key);
+                req->rq_replen = lustre_msg_size(reply_buffers, repsize);
         } else if (it->it_op & (IT_GETATTR | IT_LOOKUP | IT_CHDIR)) {
                 __u64 valid = data->valid | OBD_MD_FLNOTOBD | OBD_MD_FLEASIZE |
-                              OBD_MD_FLACL;
+                            OBD_MD_FLACL | OBD_MD_FLKEY;
 
                 /* we don't expect xattr retrieve could reach here */
                 LASSERT(!(valid & (OBD_MD_FLXATTR | OBD_MD_FLXATTRLIST)));
@@ -297,10 +306,12 @@ int mdc_enqueue(struct obd_export *exp,
                                  valid, it->it_flags, data);
                 
                 /* get ready for the reply */
-                repsize[3] = 4;
-                repsize[4] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
-                reply_buffers = 5;
-                req->rq_replen = lustre_msg_size(5, repsize);
+                reply_buffers = 3;
+                repsize[reply_buffers++] = sizeof(int);
+                repsize[reply_buffers++] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
+                repsize[reply_buffers++] = sizeof(int);
+                repsize[reply_buffers++] = sizeof(struct crypto_key);
+                req->rq_replen = lustre_msg_size(reply_buffers, repsize);
         } else if (it->it_op == IT_READDIR) {
                 policy.l_inodebits.bits = MDS_INODELOCK_UPDATE;
                 req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_DLM_VERSION,
@@ -404,7 +415,8 @@ int mdc_enqueue(struct obd_export *exp,
 
         /* We know what to expect, so we do any byte flipping required here */
         LASSERT(reply_buffers == 5 || reply_buffers == 4 || 
-                reply_buffers == 3 || reply_buffers == 1);
+                reply_buffers == 3 || reply_buffers == 1 || 
+                reply_buffers == 6 || reply_buffers == 7);
         if (reply_buffers >= 3) {
                 struct mds_body *body;
 
@@ -433,7 +445,8 @@ int mdc_enqueue(struct obd_export *exp,
                                 LASSERT(replayea);
                                 memcpy(replayea, eadata, body->eadatasize);
 
-                                LASSERT(req->rq_reqmsg->bufcount == 6);
+                                LASSERT(req->rq_reqmsg->bufcount == 6 || 
+                                        req->rq_reqmsg->bufcount == 7);
                                 req->rq_reqmsg->buflens[5] = body->eadatasize;
                                 /* If this isn't the last buffer, we might
                                  * have to shift other data around. */
index 88ec501..b349b88 100644 (file)
@@ -71,7 +71,8 @@ static int mdc_reint(struct ptlrpc_request *request,
  * setattr portal. */
 int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data,
                 struct iattr *iattr, void *ea, int ealen, void *ea2,
-                int ea2len, struct ptlrpc_request **request)
+                int ea2len, void *ea3, int ea3len, 
+                struct ptlrpc_request **request)
 {
         struct ptlrpc_request *req;
         struct mds_rec_setattr *rec;
@@ -87,6 +88,8 @@ int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data,
                 bufcount++;
                 if (ea2len > 0)
                         bufcount++;
+                if (ea3len > 0)
+                        bufcount++;
         }
 
         req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_MDS_VERSION,
@@ -107,7 +110,7 @@ int mdc_setattr(struct obd_export *exp, struct mdc_op_data *data,
                 CDEBUG(D_INODE, "setting mtime %lu, ctime %lu\n",
                        LTIME_S(iattr->ia_mtime), LTIME_S(iattr->ia_ctime));
         mdc_setattr_pack(req->rq_reqmsg, 1, data, iattr, ea, ealen,
-                         ea2, ea2len);
+                         ea2, ea2len, ea3, ea3len);
 
         /* prepare the reply buffer
          */
index 21dd245..8362bd8 100644 (file)
@@ -39,6 +39,7 @@
 #include <linux/lustre_sec.h>
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_acl.h>
+#include <linux/lustre_gs.h>
 #include "mdc_internal.h"
 
 #define REQUEST_MINOR 244
@@ -121,6 +122,11 @@ int mdc_getattr_common(struct obd_export *exp, unsigned int ea_size,
         reqbody = lustre_msg_buf(req->rq_reqmsg, 1, sizeof(*reqbody));
         LASSERT(!(reqbody->valid & OBD_MD_FLACL));
 
+        if (reqbody->valid & OBD_MD_FLKEY) {
+                repsize[bufcount++] = 5;
+                repsize[bufcount++] = sizeof(struct lustre_key);
+        }
+
         req->rq_replen = lustre_msg_size(bufcount, repsize);
 
         mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
@@ -322,16 +328,82 @@ int mdc_store_inode_generation(struct obd_export *exp,
         return 0;
 }
 
+static int mdc_unpack_acl(struct obd_export *exp_lmv, struct ptlrpc_request *req, 
+                          unsigned int *offset, struct lustre_md *md)
+{
+        struct posix_acl *acl;
+        struct mds_remote_perm *perm;
+        int    size, acl_off = 0, rc = 0;       
+        void   *buf;
+        /* if anything wrong when unpacking md, we don't check acl
+         * stuff, for simplicity
+         */
+        if (md->body->valid & OBD_MD_FLACL) {
+                acl_off = *offset;
+                if (md->body->valid & OBD_MD_FLRMTACL) {
+                        
+                        buf = lustre_swab_repbuf(req, acl_off++, sizeof(*perm),
+                                                 lustre_swab_remote_perm);
+                        if (buf == NULL) {
+                                CERROR("Can't unpack remote perm\n");
+                                RETURN(0);
+                        }
+                        OBD_ALLOC(perm, sizeof(*perm));
+                        if (!perm)
+                                RETURN(-ENOMEM);
+                        memcpy(perm, buf, sizeof(*perm));
+                        md->remote_perm = perm;
+                        *offset = acl_off; 
+                } else {
+                        size = le32_to_cpu(*(__u32 *) lustre_msg_buf(
+                                           req->rq_repmsg, acl_off++, 4));
+                        buf = lustre_msg_buf(req->rq_repmsg, acl_off++, size);
+
+                        acl = posix_acl_from_xattr(buf, size);
+                        *offset = acl_off;
+                        if (IS_ERR(acl)) {
+                                rc = PTR_ERR(acl);
+                                CERROR("convert xattr to acl failed: %d\n", rc);
+                                RETURN(0);
+                        } else if (acl) {
+                                rc = posix_acl_valid(acl);
+                                if (rc) {
+                                        CERROR("acl valid error: %d\n", rc);
+                                        posix_acl_release(acl);
+                                        RETURN(0);
+                                }
+                        }
+                        md->posix_acl = acl;
+                }
+        }
+        RETURN(rc);
+}
+static int mdc_unpack_gskey(struct obd_export *exp_lmv, struct ptlrpc_request *req, 
+                            unsigned int *offset, struct lustre_md *md)
+{ 
+        int key_off = 0, rc = 0, size = 0;
+        void *buf;
+        
+        key_off = *offset;
+        if (md->body->valid & OBD_MD_FLKEY) {
+                size = le32_to_cpu(*(__u32 *) lustre_msg_buf(req->rq_repmsg, 
+                                   key_off++, 4));
+                buf = lustre_msg_buf(req->rq_repmsg, key_off++, size);
+                
+                CDEBUG(D_INFO, "buf %p key_off %d size %d \n", 
+                       buf, key_off, size);
+                md->key = (struct lustre_key *)buf; 
+                *offset = key_off; 
+        }  
+        RETURN(rc);
+}
 int mdc_req2lustre_md(struct obd_export *exp_lmv, struct ptlrpc_request *req, 
                       unsigned int offset, struct obd_export *exp_lov, 
                       struct lustre_md *md)
 {
         struct lov_mds_md *lmm;
-        struct posix_acl *acl;
-        struct mds_remote_perm *perm;
-        void *buf;
-        int size, acl_off;
-        int rc = 0;
+        int rc = 0, reply_off;
         ENTRY;
 
         LASSERT(md != NULL);
@@ -395,53 +467,17 @@ int mdc_req2lustre_md(struct obd_export *exp_lmv, struct ptlrpc_request *req,
                         S_ISSOCK(md->body->mode));
         }
 
-        /* if anything wrong when unpacking md, we don't check acl
-         * stuff, for simplicity
-         */
-        if (rc)
-                RETURN(rc);
-
-        if (md->body->valid & OBD_MD_FLACL) {
-                acl_off = (md->body->valid & OBD_MD_FLEASIZE) ?
+        reply_off = (md->body->valid & OBD_MD_FLEASIZE) ?
                                 (offset + 2) : (offset + 1);
-
-                if (md->body->valid & OBD_MD_FLRMTACL) {
-
-                        buf = lustre_swab_repbuf(req, acl_off, sizeof(*perm),
-                                                 lustre_swab_remote_perm);
-                        if (buf == NULL) {
-                                CERROR("Can't unpack remote perm\n");
-                                RETURN(0);
-                        }
-
-                        OBD_ALLOC(perm, sizeof(*perm));
-                        if (!perm)
-                                RETURN(0);
-                        memcpy(perm, buf, sizeof(*perm));
-
-                        md->remote_perm = perm;
-                } else {
-                        size = le32_to_cpu(*(__u32 *) lustre_msg_buf(
-                                           req->rq_repmsg, acl_off, 4));
-                        buf = lustre_msg_buf(req->rq_repmsg, acl_off + 1, size);
-
-                        acl = posix_acl_from_xattr(buf, size);
-                        if (IS_ERR(acl)) {
-                                rc = PTR_ERR(acl);
-                                CERROR("convert xattr to acl failed: %d\n", rc);
-                                RETURN(0);
-                        } else if (acl) {
-                                rc = posix_acl_valid(acl);
-                                if (rc) {
-                                        CERROR("acl valid error: %d\n", rc);
-                                        posix_acl_release(acl);
-                                        RETURN(0);
-                                }
-                        }
-
-                        md->posix_acl = acl;
-                }
+        rc = mdc_unpack_acl(exp_lmv, req, &reply_off, md);
+        if (rc) {
+                CERROR("upack acl error %d \n", rc);
+                RETURN(rc);
         }
+        
+        rc = mdc_unpack_gskey(exp_lmv, req, &reply_off, md);
+        if (rc)
+                RETURN(rc);
 
         RETURN(rc);
 }
@@ -847,8 +883,8 @@ int mdc_set_info(struct obd_export *exp, obd_count keylen,
                        exp->exp_obd->obd_name,
                        imp->imp_initial_recov);
                 RETURN(0);
-        } else if (keylen >= strlen("mds_type") &&
-                   strcmp(key, "mds_type") == 0) {
+        } else if ((keylen >= strlen("crypto_type")) && 
+                    strcmp(key, "crypto_type") == 0) {
                 struct ptlrpc_request *req;
                 char *bufs[2] = {key, val};
                 int rc, size[2] = {keylen, vallen};
index bd29028..41b73c5 100644 (file)
@@ -56,6 +56,7 @@
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_commit_confd.h>
 #include <linux/lustre_acl.h>
+#include <linux/lustre_gs.h>
 #include "mds_internal.h"
 #include <linux/lustre_sec.h>
 
@@ -1059,20 +1060,26 @@ int mds_pack_xattr_list(struct dentry *dentry, struct ptlrpc_request *req,
 }
 
 static
-int mds_pack_posix_acl(struct lustre_msg *repmsg, int offset,
+int mds_pack_posix_acl(struct lustre_msg *repmsg, int *offset,
                        struct mds_body *body, struct inode *inode)
 {
         struct dentry de = { .d_inode = inode };
         __u32 buflen, *sizep;
         void *buf;
-        int size;
+        int size, pack_off = *offset;
         ENTRY;
 
+        sizep = lustre_msg_buf(repmsg, pack_off++, 4);
+        if (!sizep) {
+                CERROR("can't locate returned acl size buf\n");
+                RETURN(-EPROTO);
+        }
+        
         if (!inode->i_op->getxattr)
                 RETURN(0);
 
-        buflen = repmsg->buflens[offset + 1];
-        buf = lustre_msg_buf(repmsg, offset + 1, buflen);
+        buflen = repmsg->buflens[pack_off];
+        buf = lustre_msg_buf(repmsg, pack_off++, buflen);
 
         size = inode->i_op->getxattr(&de, XATTR_NAME_ACL_ACCESS, buf, buflen);
         if (size == -ENODATA || size == -EOPNOTSUPP)
@@ -1080,25 +1087,20 @@ int mds_pack_posix_acl(struct lustre_msg *repmsg, int offset,
         if (size < 0)
                 RETURN(size);
         LASSERT(size);
-
-        sizep = lustre_msg_buf(repmsg, offset, 4);
-        if (!sizep) {
-                CERROR("can't locate returned acl size buf\n");
-                RETURN(-EPROTO);
-        }
-
-        *sizep = cpu_to_le32(size);
         body->valid |= OBD_MD_FLACL;
 
+        *sizep = cpu_to_le32(size);
+        
+        *offset = pack_off;
         RETURN(0);
 }
 
-static
-int mds_pack_remote_perm(struct ptlrpc_request *req, int reply_off,
+int mds_pack_remote_perm(struct ptlrpc_request *req, int *reply_off,
                          struct mds_body *body, struct inode *inode)
 {
         struct lustre_sec_desc *lsd;
         struct mds_remote_perm *perm;
+        int pack_off = *reply_off;
         __u32 lsd_perms;
 
         LASSERT(inode->i_op);
@@ -1106,7 +1108,7 @@ int mds_pack_remote_perm(struct ptlrpc_request *req, int reply_off,
         LASSERT(req->rq_export->exp_mds_data.med_remote);
 
         perm = (struct mds_remote_perm *)
-                        lustre_msg_buf(req->rq_repmsg, reply_off, sizeof(perm));
+                       lustre_msg_buf(req->rq_repmsg, pack_off++, sizeof(perm));
         if (!perm)
                 return -EINVAL;
 
@@ -1143,11 +1145,13 @@ int mds_pack_remote_perm(struct ptlrpc_request *req, int reply_off,
                 perm->mrp_perm |= MAY_READ;
 
         body->valid |= (OBD_MD_FLACL | OBD_MD_FLRMTACL);
+        
+        *reply_off = pack_off;
 
         RETURN(0);
 }
 
-int mds_pack_acl(struct ptlrpc_request *req, int reply_off,
+int mds_pack_acl(struct ptlrpc_request *req, int *reply_off,
                  struct mds_body *body, struct inode *inode)
 {
         int rc;
@@ -1168,7 +1172,7 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry,
         struct mds_export_data *med = &req->rq_export->u.eu_mds_data;
         struct inode *inode = dentry->d_inode;
         struct mds_body *body;
-        int rc = 0;
+        int rc = 0, offset = 0;
         ENTRY;
 
         if (inode == NULL && !(dentry->d_flags & DCACHE_CROSS_REF))
@@ -1212,10 +1216,15 @@ static int mds_getattr_internal(struct obd_device *obd, struct dentry *dentry,
                 rc = mds_pack_xattr_list(dentry, req, body, reply_off);
         }
         
+        offset = reply_off + ((reqbody->valid & OBD_MD_FLEASIZE) ? 2 : 1);
         if (reqbody->valid & OBD_MD_FLACL) {
-                int inc = (reqbody->valid & OBD_MD_FLEASIZE) ? 2 : 1;
-                rc = mds_pack_acl(req, reply_off + inc, body, inode);
-        }
+                rc = mds_pack_acl(req, &offset, body, inode);
+        }                
+
+        if (reqbody->valid & OBD_MD_FLKEY) {
+                rc = mds_pack_gskey(obd, req->rq_repmsg, &offset, 
+                                    body, inode);
+        }                
 
         if (rc == 0)
                 mds_body_do_reverse_map(med, body);
@@ -1333,11 +1342,16 @@ static int mds_getattr_pack_msg(struct ptlrpc_request *req, struct dentry *de,
                 if (req->rq_export->exp_mds_data.med_remote) {
                         size[bufcount++] = sizeof(struct mds_remote_perm);
                 } else {
-                        size[bufcount++] = 4;
+                        size[bufcount++] = sizeof(int);
                         size[bufcount++] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
                 }
         }
 
+        if (body->valid & OBD_MD_FLKEY) {
+                size[bufcount++] = sizeof(int);
+                size[bufcount++] = sizeof(struct crypto_key);
+        }
+
         if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETATTR_PACK)) {
                 CERROR("failed MDS_GETATTR_PACK test\n");
                 req->rq_status = -ENOMEM;
@@ -1699,7 +1713,6 @@ out_pop:
         mds_exit_ucred(&uc);
         return rc;
 }
-
 static int mds_access_check(struct ptlrpc_request *req, int offset)
 {
         struct obd_device *obd = req->rq_export->exp_obd;
@@ -1710,7 +1723,7 @@ static int mds_access_check(struct ptlrpc_request *req, int offset)
         struct lvfs_ucred uc;
         int rep_size[2] = {sizeof(*body),
                            sizeof(struct mds_remote_perm)};
-        int rc = 0;
+        int rc = 0, rep_offset;
         ENTRY;
 
         if (!req->rq_export->exp_mds_data.med_remote) {
@@ -1756,7 +1769,9 @@ static int mds_access_check(struct ptlrpc_request *req, int offset)
         body = lustre_msg_buf(req->rq_repmsg, 0, sizeof(*body));
         LASSERT(body);
 
-        rc = mds_pack_remote_perm(req, 1, body, de->d_inode);
+        rep_offset = 1;
+        rc = mds_pack_remote_perm(req, &rep_offset, body, de->d_inode);
+
         EXIT;
 
 out_dput:
@@ -2689,6 +2704,12 @@ static int mds_set_info(struct obd_export *exp, __u32 keylen,
                                   "mds_conn", valsize, &group);
                 RETURN(rc);
         }
+        if (keylen >= strlen("crypto_type") &&
+             memcmp(key, "crypto_type", keylen) == 0) {
+                rc = mds_set_crypto_type(obd, val, vallen); 
+                RETURN(rc);
+        }
+
         CDEBUG(D_IOCTL, "invalid key\n");
         RETURN(-EINVAL);
 }
@@ -2707,8 +2728,10 @@ static int mdt_set_info(struct ptlrpc_request *req)
         }
         keylen = req->rq_reqmsg->buflens[0];
 
-        if (keylen == strlen("mds_type") &&
-            memcmp(key, "mds_type", keylen) == 0) {
+        if ((keylen == strlen("mds_type") &&
+            memcmp(key, "mds_type", keylen) == 0) ||
+            (keylen == strlen("crypto_type") &&
+            memcmp(key, "crypto_type", keylen) == 0)) {
                 rc = lustre_pack_reply(req, 0, NULL, NULL);
                 if (rc)
                         RETURN(rc);
@@ -3624,7 +3647,9 @@ static int mds_setup(struct obd_device *obd, obd_count len, void *buf)
         ptlrpc_init_client(LDLM_CB_REQUEST_PORTAL, LDLM_CB_REPLY_PORTAL,
                            "mds_ldlm_client", &obd->obd_ldlm_client);
         obd->obd_replayable = 1;
-
+        
+        mds->mds_crypto_type = NO_CRYPTO;
+        
         rc = mds_postsetup(obd);
         if (rc)
                 GOTO(err_fs, rc);
@@ -4021,6 +4046,37 @@ void intent_set_disposition(struct ldlm_reply *rep, int flag)
         rep->lock_policy_res1 |= flag;
 }
 
+static int mds_intent_prepare_reply_buffers(struct ptlrpc_request *req, 
+                                            struct ldlm_intent *it)
+{
+        struct mds_obd *mds = &req->rq_export->exp_obd->u.mds;
+        int rc, reply_buffers;
+        int repsize[5] = {sizeof(struct ldlm_reply),
+                          sizeof(struct mds_body),
+                          mds->mds_max_mdsize};
+        ENTRY;       
+        reply_buffers = 3;
+        if (it->opc & ( IT_OPEN | IT_GETATTR | IT_LOOKUP | IT_CHDIR )) {
+                if (req->rq_export->exp_mds_data.med_remote) {
+                        repsize[reply_buffers++] = 
+                                sizeof(struct mds_remote_perm);
+                } else {
+                        repsize[reply_buffers++] = sizeof(int);
+                        repsize[reply_buffers++] = 
+                                xattr_acl_size(LL_ACL_MAX_ENTRIES);
+                }
+                /*FIXME: ugly here, should be optimize for there 
+                 * is no crypto key*/
+                repsize[reply_buffers++] = sizeof(int);
+                repsize[reply_buffers++] = sizeof(struct crypto_key); 
+        }
+
+        rc = lustre_pack_reply(req, reply_buffers, repsize, NULL);
+
+        RETURN(rc);
+}
+
 static int mds_intent_policy(struct ldlm_namespace *ns,
                              struct ldlm_lock **lockp, void *req_cookie,
                              ldlm_mode_t mode, int flags, void *data)
@@ -4028,15 +4084,11 @@ static int mds_intent_policy(struct ldlm_namespace *ns,
         struct ptlrpc_request *req = req_cookie;
         struct ldlm_lock *lock = *lockp;
         struct ldlm_intent *it;
-        struct mds_obd *mds = &req->rq_export->exp_obd->u.mds;
         struct ldlm_reply *rep;
         struct lustre_handle lockh[2] = {{0}, {0}};
         struct ldlm_lock *new_lock = NULL;
         int getattr_part = MDS_INODELOCK_UPDATE;
-        int rc, reply_buffers;
-        int repsize[5] = {sizeof(struct ldlm_reply),
-                          sizeof(struct mds_body),
-                          mds->mds_max_mdsize};
+        int rc;
 
         int offset = MDS_REQ_INTENT_REC_OFF; 
         ENTRY;
@@ -4061,19 +4113,8 @@ static int mds_intent_policy(struct ldlm_namespace *ns,
 
         LDLM_DEBUG(lock, "intent policy, opc: %s", ldlm_it2str(it->opc));
 
-        reply_buffers = 3;
-        if (it->opc & ( IT_OPEN | IT_GETATTR | IT_LOOKUP | IT_CHDIR )) {
-                if (req->rq_export->exp_mds_data.med_remote) {
-                        reply_buffers = 4;
-                        repsize[3] = sizeof(struct mds_remote_perm);
-                } else {
-                        reply_buffers = 5;
-                        repsize[3] = 4;
-                        repsize[4] = xattr_acl_size(LL_ACL_MAX_ENTRIES);
-                }
-        }
+        rc = mds_intent_prepare_reply_buffers(req, it);
 
-        rc = lustre_pack_reply(req, reply_buffers, repsize, NULL);
         if (rc)
                 RETURN(req->rq_status = rc);
 
index 535ff71..79c01d7 100644 (file)
@@ -133,6 +133,12 @@ int mds_init_ucred(struct lvfs_ucred *ucred, struct ptlrpc_request *req,
                    struct mds_req_sec_desc *rsd);
 void mds_exit_ucred(struct lvfs_ucred *ucred);
 
+int mds_set_gskey(struct obd_device *obd, void *handle, 
+                  struct inode *inode, void *key, int key_len, int valid); 
+int mds_set_crypto_type(struct obd_device *obd, void *val, __u32 vallen);
+
+int mds_pack_gskey(struct obd_device *obd, struct lustre_msg *repmsg, 
+                   int *offset, struct mds_body *body, struct inode *inode);
 /* mds/mds_unlink_open.c */
 int mds_cleanup_orphans(struct obd_device *obd);
 
@@ -259,8 +265,9 @@ int mds_pack_xattr(struct dentry *dentry, struct ptlrpc_request *req,
                    struct mds_body *repbody, int req_off, int reply_off);
 int mds_pack_xattr_list(struct dentry *dentry, struct ptlrpc_request *req,
                         struct mds_body *repbody, int reply_off);
-int mds_pack_acl(struct ptlrpc_request *req, int reply_off,
+int mds_pack_acl(struct ptlrpc_request *req, int *reply_off,
                  struct mds_body *body, struct inode *inode);
+
 int mds_pack_inode2id(struct obd_device *, struct lustre_id *,
                       struct inode *, int);
 
@@ -272,6 +279,7 @@ void mds_pack_dentry2id(struct obd_device *, struct lustre_id *,
 
 void mds_pack_dentry2body(struct obd_device *, struct mds_body *b,
                           struct dentry *, int);
+
 #endif
 
 /* mds/mds_lmv.c */
index eb3231b..b92cbe0 100644 (file)
 #include <asm/uaccess.h>
 #include <linux/slab.h>
 #include <asm/segment.h>
+#include <linux/random.h>
 
 #include <linux/obd_support.h>
 #include <linux/lustre_lib.h>
 #include <linux/lustre_sec.h>
 #include <linux/lustre_ucache.h>
+#include <linux/lustre_gs.h>
+#include <linux/lustre_fsfilt.h>
 #include "mds_internal.h"
 
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,4)
@@ -214,6 +217,132 @@ int mds_pack_inode2id(struct obd_device *obd,
         RETURN(rc);
 }
 
+int mds_pack_gskey(struct obd_device *obd, struct lustre_msg *repmsg, 
+                  int *offset, struct mds_body *body, struct inode *inode)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        struct crypto_key_md *md_key;
+        struct crypto_key *ckey;
+        __u32 buflen, *sizep;
+        void *buf;
+        int size, rc = 0;
+        ENTRY;
+        if ((mds->mds_crypto_type != MKS_TYPE && 
+             mds->mds_crypto_type != GKS_TYPE))
+                RETURN(rc);
+
+        sizep = lustre_msg_buf(repmsg, (*offset)++, 4);
+        if (!sizep) {
+                CERROR("can't locate returned ckey size buf\n");
+                RETURN(-EPROTO);
+        }
+        *sizep = cpu_to_le32(sizeof(*ckey));
+
+        OBD_ALLOC(md_key, sizeof(*md_key));
+      
+        buflen = repmsg->buflens[*offset];
+        buf = lustre_msg_buf(repmsg, (*offset)++, buflen);
+
+        size = fsfilt_get_md(obd, inode, md_key, sizeof(*md_key), 
+                           EA_KEY);
+        if (size < 0) {
+                CERROR("Can not get gskey from MDS ino %lu rc %d\n", 
+                       inode->i_ino, size);
+                GOTO(out, rc = size); 
+        }
+        if (le32_to_cpu(md_key->md_magic) != MD_KEY_MAGIC) {
+                CDEBUG(D_INFO, "given match %x != magic %x\n",
+                       md_key->md_magic, MD_KEY_MAGIC);
+                GOTO(out, rc = 0); 
+        }       
+        CDEBUG(D_INFO, "get key %s mac %s for ino %lu  size %d \n",
+               md_key->md_ck.ck_key, md_key->md_ck.ck_mac, inode->i_ino, size);
+        ckey=(struct crypto_key*)buf;
+
+        memcpy(ckey, &md_key->md_ck, sizeof(*ckey));
+        body->valid |= OBD_MD_FLKEY;
+out:                
+        OBD_FREE(md_key, sizeof(*md_key));
+        RETURN(rc);
+}
+
+static int mds_get_gskey(struct inode *inode, struct crypto_key *ckey)
+{
+        LASSERT(ckey);
+        /*tmp create gs key here*/
+        get_random_bytes(ckey->ck_key, KEY_SIZE);       
+        ckey->ck_type = MKS_TYPE; 
+        RETURN(0); 
+}
+
+int mds_set_gskey(struct obd_device *obd, void *handle, 
+                  struct inode *inode, void *key, int key_len, 
+                  int valid) 
+{
+        struct crypto_key_md *md_key = NULL;
+        struct crypto_key *ckey = (struct crypto_key *)key; 
+        struct mds_obd *mds = &obd->u.mds;
+        int rc = 0;       
+        ENTRY;
+
+        if ((mds->mds_crypto_type != MKS_TYPE && 
+             mds->mds_crypto_type != GKS_TYPE) || key_len == 0)
+                RETURN(rc);
+        
+        OBD_ALLOC(md_key, sizeof(*md_key)); 
+        LASSERT(ckey != NULL);
+        if (mds->mds_crypto_type == MKS_TYPE) { 
+                mds_get_gskey(inode, ckey);
+        }
+        rc = fsfilt_get_md(obd, inode, md_key, sizeof(*md_key), 
+                           EA_KEY);
+        if (rc < 0)
+                GOTO(free, rc);
+        LASSERT(le32_to_cpu(md_key->md_magic) == MD_KEY_MAGIC || 
+                md_key->md_magic == 0);
+        if (le32_to_cpu(md_key->md_magic) == MD_KEY_MAGIC) {
+                CDEBUG(D_INFO, "reset key %s mac %s", md_key->md_ck.ck_mac,
+                       md_key->md_ck.ck_key);
+        } 
+        md_key->md_magic = cpu_to_le32(MD_KEY_MAGIC);
+        if (valid & ATTR_MAC) { 
+                memcpy(md_key->md_ck.ck_mac, ckey->ck_mac, MAC_SIZE);
+                CDEBUG(D_INFO, "set mac %s for ino %lu \n",
+                       md_key->md_ck.ck_mac, inode->i_ino);
+        }
+        if (valid & ATTR_KEY) { 
+                memcpy(md_key->md_ck.ck_key, ckey->ck_key, KEY_SIZE);
+                CDEBUG(D_INFO, "set key %s for ino %lu \n",
+                       md_key->md_ck.ck_key, inode->i_ino);
+        }
+        rc = fsfilt_set_md(obd, inode, handle, md_key,
+                           sizeof(*md_key), EA_KEY);
+free:
+        if (md_key)
+                OBD_FREE(md_key, sizeof(*md_key));
+        RETURN(rc);
+}
+
+int mds_set_crypto_type(struct obd_device *obd, void *val, __u32 vallen)
+{
+        struct mds_obd *mds = &obd->u.mds;
+        ENTRY;       
+        if (vallen >= strlen("mks") &&
+             memcmp(val, "mks", vallen) == 0) {
+                mds->mds_crypto_type = MKS_TYPE;         
+        } 
+        if (vallen >= strlen("gks") &&
+             memcmp(val, "gks", vallen) == 0) {
+                mds->mds_crypto_type = GKS_TYPE;         
+        } 
+
+        CDEBUG(D_IOCTL, "invalid key\n");
+        RETURN(0);
+} 
 /* Note that we can copy all of the fields, just some will not be "valid" */
 void mds_pack_inode2body(struct obd_device *obd, struct mds_body *b,
                          struct inode *inode, int fid)
@@ -252,6 +381,7 @@ void mds_pack_inode2body(struct obd_device *obd, struct mds_body *b,
                 b->valid |= OBD_MD_FID;
         
         mds_pack_inode2id(obd, &b->id1, inode, fid);
+
 }
 
 /* unpacking */
@@ -295,6 +425,14 @@ static int mds_setattr_unpack(struct ptlrpc_request *req, int offset,
                 r->ur_ea2datalen = req->rq_reqmsg->buflens[offset + 2];
         }
 
+        if (req->rq_reqmsg->bufcount > offset + 3) {
+                r->ur_ea3data = lustre_msg_buf(req->rq_reqmsg, offset + 3, 0);
+                if (r->ur_ea3data == NULL)
+                        RETURN (-EFAULT);
+
+                r->ur_ea3datalen = req->rq_reqmsg->buflens[offset + 3];
+        }
+
         RETURN(0);
 }
 
@@ -446,7 +584,7 @@ static int mds_open_unpack(struct ptlrpc_request *req, int offset,
         r->ur_rdev = rec->cr_rdev;
         r->ur_time = rec->cr_time;
         r->ur_flags = rec->cr_flags;
-
         LASSERT_REQSWAB (req, offset + 1);
         r->ur_name = lustre_msg_string (req->rq_reqmsg, offset + 1, 0);
         if (r->ur_name == NULL)
@@ -454,12 +592,19 @@ static int mds_open_unpack(struct ptlrpc_request *req, int offset,
         r->ur_namelen = req->rq_reqmsg->buflens[offset + 1];
 
         LASSERT_REQSWAB (req, offset + 2);
-        if (req->rq_reqmsg->bufcount > offset + 2) {
+       
+        if (req->rq_reqmsg->bufcount > offset + 2) { 
                 r->ur_eadata = lustre_msg_buf(req->rq_reqmsg, offset + 2, 0);
                 if (r->ur_eadata == NULL)
                         RETURN(-EFAULT);
                 r->ur_eadatalen = req->rq_reqmsg->buflens[offset + 2];
         }
+        
+        if (rec->cr_flags & MDS_OPEN_HAS_KEY) {
+                LASSERT(req->rq_reqmsg->bufcount > offset + 3);
+                r->ur_ea2data = lustre_msg_buf(req->rq_reqmsg, offset + 3, 0);
+                r->ur_ea2datalen = req->rq_reqmsg->buflens[offset + 3];  
+        }
         RETURN(0);
 }
 
index 42a6e12..baba9d1 100644 (file)
@@ -43,6 +43,7 @@
 #include <linux/obd_lov.h>
 #include <linux/lustre_fsfilt.h>
 #include <linux/lprocfs_status.h>
+#include <linux/lustre_gs.h>
 
 #include "mds_internal.h"
 
@@ -700,7 +701,7 @@ static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild,
         struct mds_file_data *mfd = NULL;
         obd_id *ids = NULL;
         unsigned mode;
-        int rc = 0;
+        int rc = 0, reply_off;
         ENTRY;
 
         /* atomically create objects if necessary */
@@ -748,13 +749,23 @@ static int mds_finish_open(struct ptlrpc_request *req, struct dentry *dchild,
                         }
                 }
         }
-        rc = mds_pack_acl(req, 3, body, dchild->d_inode);
+
+        reply_off = 3;
+        rc = mds_pack_acl(req, &reply_off, body, dchild->d_inode);
+
         if (rc < 0) {
                 CERROR("pack posix acl: rc = %d\n", rc);
                 up(&dchild->d_inode->i_sem);
                 RETURN(rc);
         }
 
+        rc = mds_pack_gskey(obd, req->rq_repmsg, &reply_off, body, 
+                            dchild->d_inode); 
+        if (rc < 0) {
+                CERROR("mds_pack_gskey: rc = %d\n", rc);
+                up(&dchild->d_inode->i_sem);
+                RETURN(rc);
+        }
         /* If the inode has no EA data, then MDSs hold size, mtime */
         if (S_ISREG(dchild->d_inode->i_mode) &&
             !(body->valid & OBD_MD_FLEASIZE)) {
@@ -1202,7 +1213,16 @@ got_child:
                 else {
                         MD_COUNTER_INCREMENT(obd, create);
                 }
-
+                
+                if ((rec->ur_flags & MDS_OPEN_HAS_KEY) || 
+                     mds->mds_crypto_type == MKS_TYPE) {
+                        rc = mds_set_gskey(obd, handle, dchild->d_inode, 
+                                           rec->ur_ea2data, rec->ur_ea2datalen, 
+                                           ATTR_KEY | ATTR_MAC);
+                        if (rc) {
+                                CERROR("error in set gs key rc %d\n", rc); 
+                        }
+                }
                 if (ino) {
                         rc = mds_update_inode_sid(obd, dchild->d_inode,
                                                   handle, rec->ur_id2);
@@ -1888,6 +1908,7 @@ int mds_close(struct ptlrpc_request *req, int offset)
         RETURN(0);
 }
 
+
 int mds_done_writing(struct ptlrpc_request *req, int offset)
 {
         struct mds_body *body;
index 51c1a24..dee71d8 100644 (file)
@@ -472,6 +472,7 @@ static int mds_get_md_type(char *name)
                 RETURN(EA_SID);
         RETURN(0);
 }
+
 /* In the raw-setattr case, we lock the child inode.
  * In the write-back case or if being called from open, the client holds a lock
  * already.
@@ -589,10 +590,9 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
                                                 flags);
                 } else if (rec->ur_iattr.ia_valid & ATTR_EA_RM) {
                         rc = -EOPNOTSUPP;
-                        if (!med->med_remote && inode->i_op &&
-                            inode->i_op->removexattr) 
-                                rc = inode->i_op->removexattr(
-                                                de, rec->ur_eadata);
+                        if (inode->i_op && inode->i_op->removexattr) 
+                                rc = inode->i_op->removexattr(de, 
+                                                  rec->ur_eadata);
                 } else if (rec->ur_iattr.ia_valid & ATTR_EA_CMOBD) {
                         char *name;
                         int type;
@@ -608,7 +608,9 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
                                                    rec->ur_ea2datalen, type);
                         if (rc)
                                 GOTO(cleanup, rc);               
-                } else if (S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) {
+                } else if ((S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode)) &&
+                           !((rec->ur_iattr.ia_valid & ATTR_KEY) || 
+                             (rec->ur_iattr.ia_valid & ATTR_MAC))) {
                         struct lov_stripe_md *lsm = NULL;
                         struct lov_user_md *lum = NULL;
 
@@ -640,7 +642,19 @@ static int mds_reint_setattr(struct mds_update_record *rec, int offset,
                                                 GOTO(cleanup, rc);
                                 }
                         }
-                }    
+                }   
+                if ((rec->ur_iattr.ia_valid & ATTR_KEY) || 
+                    (rec->ur_iattr.ia_valid & ATTR_MAC)) {
+                        void *key;
+                        int keylen;
+                        LASSERT(rec->ur_eadatalen || rec->ur_ea3datalen); 
+                        LASSERT(rec->ur_eadata || rec->ur_ea3data); 
+                        key = rec->ur_eadata ? rec->ur_eadata : rec->ur_ea3data;
+                        keylen = rec->ur_eadatalen ? rec->ur_eadatalen : 
+                                                     rec->ur_ea3datalen;
+                        mds_set_gskey(obd, handle, inode, key, keylen, 
+                                      rec->ur_iattr.ia_valid); 
+                }
         }
 
         body = lustre_msg_buf(req->rq_repmsg, 0, sizeof (*body));
@@ -905,6 +919,14 @@ static int mds_reint_create(struct mds_update_record *rec, int offset,
                 if (IS_ERR(handle))
                         GOTO(cleanup, rc = PTR_ERR(handle));
                 rc = ll_vfs_create(dir, dchild, rec->ur_mode, NULL);
+                if (rec->ur_eadata && rec->ur_eadatalen && 
+                    (rc == 0) && (dchild->d_inode != NULL)) {
+                        /*Assumption: When ur_eadata is not NULL, 
+                         *ur_eadata is crypto key, should fix it later, Wangdi*/
+                        mds_set_gskey(obd, handle, dchild->d_inode, 
+                                      rec->ur_eadata, rec->ur_eadatalen, 
+                                      ATTR_MAC | ATTR_KEY); 
+                }
                 EXIT;
                 break;
         }
index d5f59ec..0d825c7 100644 (file)
@@ -423,7 +423,8 @@ struct lustre_profile *class_get_profile(char * prof)
 
 int class_add_profile(int proflen, char *prof,
                       int lovlen, char *lov,
-                      int lmvlen, char *lmv)
+                      int lmvlen, char *lmv,
+                      int gkclen, char *gkc)
 {
         struct lustre_profile *lprof;
         int err = 0;
@@ -452,9 +453,15 @@ int class_add_profile(int proflen, char *prof,
                         GOTO(out, err = -ENOMEM);
                 memcpy(lprof->lp_lmv, lmv, lmvlen);
         }
-
+        if (gkclen > 0 ) {
+                LASSERT(gkclen == (strlen(gkc) + 1));
+                OBD_ALLOC(lprof->lp_gkc, gkclen);
+                if (lprof->lp_gkc == NULL)
+                        GOTO(out, err = -ENOMEM);
+                memcpy(lprof->lp_gkc, gkc, gkclen);
+        }
+        
         list_add(&lprof->lp_list, &lustre_profile_list);
-
 out:
         RETURN(err);
 }
@@ -510,10 +517,11 @@ int class_process_config(struct lustre_cfg *lcfg)
                 GOTO(out, err);
         }
         case LCFG_MOUNTOPT: {
-                CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s\n",
+                CDEBUG(D_IOCTL, "mountopt: profile %s osc %s mdc %s gkc %s \n",
                        lustre_cfg_string(lcfg, 1),
                        lustre_cfg_string(lcfg, 2),
-                       lustre_cfg_string(lcfg, 3));
+                       lustre_cfg_string(lcfg, 3),
+                       lustre_cfg_string(lcfg, 4));
                 /* set these mount options somewhere, so ll_fill_super
                  * can find them. */
                 err = class_add_profile(LUSTRE_CFG_BUFLEN(lcfg, 1),
@@ -521,7 +529,9 @@ int class_process_config(struct lustre_cfg *lcfg)
                                         LUSTRE_CFG_BUFLEN(lcfg, 2),
                                         lustre_cfg_string(lcfg, 2),
                                         LUSTRE_CFG_BUFLEN(lcfg, 3),
-                                        lustre_cfg_string(lcfg, 3));
+                                        lustre_cfg_string(lcfg, 3),
+                                        LUSTRE_CFG_BUFLEN(lcfg, 4),
+                                        lustre_cfg_string(lcfg, 4));
                 GOTO(out, err);
         }
         case LCFG_DEL_MOUNTOPT: {
index 42f4736..1b13258 100644 (file)
@@ -2180,6 +2180,8 @@ int filter_setattr(struct obd_export *exp, struct obdo *oa,
         struct filter_obd *filter;
         struct ldlm_resource *res;
         struct dentry *dentry;
+        obd_uid uid;
+        obd_gid gid;
         int rc;
         ENTRY;
 
@@ -2188,7 +2190,6 @@ int filter_setattr(struct obd_export *exp, struct obdo *oa,
         filter = &exp->exp_obd->u.filter;
         push_ctxt(&saved, &exp->exp_obd->obd_lvfs_ctxt, NULL);
 
-        
         /* make sure that object is allocated. */
         dentry = filter_crow_object(exp->exp_obd, oa);
         if (IS_ERR(dentry))
@@ -2434,7 +2435,6 @@ filter_crow_object(struct obd_device *obd, struct obdo *oa)
                 RETURN(dentry);
 
         f_dput(dentry);
-        
         CDEBUG(D_INODE, "OSS object "LPU64"/"LPU64
                " does not exists - allocate it now\n",
                oa->o_id, oa->o_gr);
index 643a427..3d505ec 100644 (file)
@@ -506,6 +506,8 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa,
         struct fsfilt_objinfo fso;
         struct obd_device *obd;
         obd_size left;
+        obd_uid uid;
+        obd_gid gid;
         void *iobuf; 
         
         ENTRY;
@@ -522,6 +524,9 @@ static int filter_preprw_write(int cmd, struct obd_export *exp, struct obdo *oa,
         obd = exp->exp_obd;
         push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
 
+        uid = oa->o_valid & OBD_MD_FLUID ? oa->o_uid : 0;
+        gid = oa->o_valid & OBD_MD_FLGID ? oa->o_gid : 0;
+        
         /* make sure that object is already allocated */
         dentry = filter_crow_object(obd, oa);
         if (IS_ERR(dentry))
index 4202edc..7596682 100644 (file)
@@ -128,6 +128,49 @@ int osc_create(struct obd_export *exp, struct obdo *oa,
                 spin_unlock(&oscc->oscc_lock);
                 RETURN(rc);
         }
+        while (try_again) {
+                /* If orphans are being recovered, then we must wait until
+                   it is finished before we can continue with create. */
+                if (oscc_recovering(oscc)) {
+                        struct l_wait_info lwi;
+
+                        CDEBUG(D_HA,"%p: oscc recovery in progress, waiting\n",
+                               oscc);
+
+                        lwi = LWI_TIMEOUT(MAX(obd_timeout*HZ/4, 1), NULL, NULL);
+                        rc = l_wait_event(oscc->oscc_waitq,
+                                          !oscc_recovering(oscc), &lwi);
+                        LASSERT(rc == 0 || rc == -ETIMEDOUT);
+                        if (rc == -ETIMEDOUT) {
+                                CDEBUG(D_ERROR,"%p: timeout waiting on recovery\n",
+                                       oscc);
+                                RETURN(rc);
+                        }
+                        CDEBUG(D_HA, "%p: oscc recovery over, waking up\n",
+                               oscc);
+                }
+
+                spin_lock(&oscc->oscc_lock);
+                if (oscc->oscc_flags & OSCC_FLAG_EXITING) {
+                        spin_unlock(&oscc->oscc_lock);
+                        break;
+                }
+
+                if (oscc->oscc_flags & OSCC_FLAG_NOSPC) {
+                        rc = -ENOSPC;
+                        spin_unlock(&oscc->oscc_lock);
+                        break;
+                }
+
+                oscc->oscc_next_id++;
+                oa->o_id = oscc->oscc_next_id;
+                try_again = 0;
+                spin_unlock(&oscc->oscc_lock);
+
+                CDEBUG(D_HA, "%s: returning objid "LPU64"\n",
+                       oscc->oscc_obd->u.cli.cl_import->imp_target_uuid.uuid,
+                       oa->o_id);
+        }
 
         while (try_again) {
                 /* If orphans are being recovered, then we must wait until
index 9dc9d44..12fd279 100644 (file)
@@ -63,6 +63,7 @@
 #include <linux/lustre_ha.h>
 #include <linux/lprocfs_status.h>
 #include <linux/lustre_log.h>
+#include <linux/lustre_gs.h>
 #include "osc_internal.h"
 
 /* Pack OSC object metadata for disk storage (LE byte order). */
@@ -730,6 +731,28 @@ static obd_count cksum_pages(int nob, obd_count page_count,
 }
 #endif
 
+#define osc_encrypt_page(page, off, count)  \
+        osc_crypt_page(page, off, count, ENCRYPT_DATA)
+#define osc_decrypt_page(page, off, count)  \
+        osc_crypt_page(page, off, count, DECRYPT_DATA)
+
+/*Put a global call back var here is Ugly, but put it to client_obd 
+ *also seems not a good idea, WangDi*/ 
+crypt_cb_t  osc_crypt_cb = NULL;     
+   
+static int osc_crypt_page(struct page *page, obd_off page_off, obd_off count, 
+                          int flags)
+{
+        int rc = 0;
+        ENTRY;
+
+        if (osc_crypt_cb != NULL)
+                rc = osc_crypt_cb(page, page_off, count, flags);
+        if (rc != 0) 
+                CERROR("crypt page error %d \n", rc);
+        RETURN(rc); 
+}
+
 static int osc_brw_prep_request(int cmd, struct obd_import *imp,struct obdo *oa,
                                 struct lov_stripe_md *lsm, obd_count page_count,
                                 struct brw_page *pga, int *requested_nobp,
@@ -798,6 +821,10 @@ static int osc_brw_prep_request(int cmd, struct obd_import *imp,struct obdo *oa,
                          pg->pg, pg->pg->private, pg->pg->index, pg->disk_offset,
                          pg_prev->pg, pg_prev->pg->private, pg_prev->pg->index,
                          pg_prev->disk_offset);
+                
+                if (opc == OST_WRITE) {
+                        osc_encrypt_page(pg->pg, pg->page_offset, pg->count);
+                } 
 
                 ptlrpc_prep_bulk_page(desc, pg->pg,
                                       pg->page_offset & ~PAGE_MASK, pg->count);
@@ -868,7 +895,8 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, struct obdo *oa,
                         RETURN(-EPROTO);
                 }
                 LASSERT (req->rq_bulk->bd_nob == requested_nob);
-
+                osc_decrypt_page(pga->pg, pga->page_offset, 
+                                 pga->count);
                 RETURN(check_write_rcs(req, requested_nob, niocount,
                                        page_count, pga));
         }
@@ -919,6 +947,7 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, struct obdo *oa,
                                req->rq_import->imp_connection->c_peer.peer_id.nid);
         }
 #endif
+        osc_decrypt_page(pga->pg, pga->page_offset, pga->count);
         RETURN(0);
 }
 
@@ -2949,6 +2978,12 @@ static int osc_set_info(struct obd_export *exp, obd_count keylen,
                         ptlrpcs_import_flush_current_creds(cli->cl_import);
                 RETURN(0);
         }
+        if (keylen == strlen("crypto_cb") &&
+            memcmp(key, "crypto_cb", keylen) == 0) {
+                LASSERT(vallen == sizeof(crypt_cb_t));
+                osc_crypt_cb = (crypt_cb_t)val; 
+                RETURN(0);
+        }
 
         if (keylen < strlen("mds_conn") ||
             memcmp(key, "mds_conn", keylen) != 0)
index 78c79b4..6ede5d6 100644 (file)
@@ -746,6 +746,7 @@ int ptlrpc_disconnect_import(struct obd_import *imp)
         case OST_CONNECT: rq_opc = OST_DISCONNECT; break;
         case MDS_CONNECT: rq_opc = MDS_DISCONNECT; break;
         case MGMT_CONNECT: rq_opc = MGMT_DISCONNECT; break;
+        case GKS_CONNECT:  rq_opc = GKS_DISCONNECT; break;
         default:
                 CERROR("don't know how to disconnect from %s (connect_op %d)\n",
                        imp->imp_target_uuid.uuid, imp->imp_connect_op);
index 99b667b..5db619a 100644 (file)
@@ -35,6 +35,7 @@
 #include <linux/lustre_net.h>
 #include <linux/lustre_sec.h>
 #include <linux/fcntl.h>
+#include <linux/posix_acl.h>
 
 
 #define HDR_SIZE(count) \
@@ -481,9 +482,25 @@ void *mdc_create_pack(struct lustre_msg *msg, int offset,
         return ((void*)tmp + size_round(datalen));
 }
 
+__u32 mds_pack_open_flags(__u32 flags)
+{
+        return
+                (flags & (FMODE_READ | FMODE_WRITE | FMODE_EXEC |
+                          MDS_OPEN_DELAY_CREATE | MDS_OPEN_HAS_EA |
+                          MDS_OPEN_HAS_OBJS)) |
+                ((flags & O_CREAT) ? MDS_OPEN_CREAT : 0) |
+                ((flags & O_EXCL) ? MDS_OPEN_EXCL : 0) |
+                ((flags & O_TRUNC) ? MDS_OPEN_TRUNC : 0) |
+                ((flags & O_APPEND) ? MDS_OPEN_APPEND : 0) |
+                ((flags & O_SYNC) ? MDS_OPEN_SYNC : 0) |
+                ((flags & O_DIRECTORY) ? MDS_OPEN_DIRECTORY : 0) |
+                0;
+}
+
 void *mdc_setattr_pack(struct lustre_msg *msg, int offset,
                        struct mdc_op_data *data, struct iattr *iattr,
-                       void *ea, int ealen, void *ea2, int ea2len)
+                       void *ea, int ealen, void *ea2, int ea2len, 
+                       void *ea3, int ea3len)
 {
         struct mds_rec_setattr *rec = lustre_msg_buf(msg, offset, sizeof(*rec));
         char *tmp = NULL;
@@ -515,6 +532,13 @@ void *mdc_setattr_pack(struct lustre_msg *msg, int offset,
 
         memcpy(lustre_msg_buf(msg, offset + 2, ea2len), ea2, ea2len);
         tmp += size_round(ea2len);
+
+        if (ea3len == 0)
+                return (void*)tmp;
+
+        memcpy(lustre_msg_buf(msg, offset + 3, ea3len), ea3, ea3len);
+        tmp += size_round(ea3len);
+
         return (void*)tmp;
 }
 
@@ -883,4 +907,23 @@ int llog_log_swabbed(struct llog_log_hdr *hdr)
 void lustre_assert_wire_constants(void)
 {
 }
-
+/* for gks key rec */
+void lustre_swab_key_perms(struct key_perm *kperm)
+{
+        int i;
+        __swab32s(&kperm->kp_uid);
+        __swab32s(&kperm->kp_gid);
+        __swab32s(&kperm->kp_mode);
+        __swab32s(&kperm->kp_acl_count);
+        for (i = 0; i < kperm->kp_acl_count; i++) {
+                __swab16s(&kperm->kp_acls[i].e_tag); 
+                __swab16s(&kperm->kp_acls[i].e_perm); 
+                __swab32s(&kperm->kp_acls[i].e_id); 
+        }  
+}
+void lustre_swab_key_context (struct key_context *kctxt)
+{
+        __swab32s (&kctxt->kc_command);
+        __swab32s (&kctxt->kc_valid); /* for use with open */
+        lustre_swab_key_perms(&kctxt->kc_perm);
+}
index dac116b..d2056ac 100644 (file)
@@ -196,11 +196,14 @@ EXPORT_SYMBOL(lustre_swab_ldlm_reply);
 EXPORT_SYMBOL(lustre_swab_ptlbd_op);
 EXPORT_SYMBOL(lustre_swab_ptlbd_niob);
 EXPORT_SYMBOL(lustre_swab_ptlbd_rsp);
+EXPORT_SYMBOL(lustre_swab_key_context);
+EXPORT_SYMBOL(lustre_swab_key_perms);
 EXPORT_SYMBOL(mdc_create_pack);
 EXPORT_SYMBOL(mdc_setattr_pack);
 EXPORT_SYMBOL(mdc_unlink_pack);
 EXPORT_SYMBOL(mdc_link_pack);
 EXPORT_SYMBOL(mdc_rename_pack);
+EXPORT_SYMBOL(mds_pack_open_flags);
 
 /* recover.c */
 EXPORT_SYMBOL(ptlrpc_run_recovery_over_upcall);
index 224d66b..172e651 100644 (file)
@@ -1,6 +1,6 @@
 MODULES := ptlrpcs
 ptlrpcs-objs := sec.o sec_null.o svcsec.o svcsec_null.o upcall_cache.o
 
-@GSS_TRUE@subdir-m += gss
+@GSS_TRUE@subdir-m += gss gks
 
 @INCLUDE_RULES@
index c14dbfe..740c33f 100644 (file)
@@ -4,7 +4,7 @@
 # See the file COPYING in this distribution
 
 if GSS
-SUBDIRS = . gss #kcrypto 
+SUBDIRS = . gss  gks #kcrypto 
 endif
 
 if LIBLUSTRE
diff --git a/lustre/sec/gks/Makefile.in b/lustre/sec/gks/Makefile.in
new file mode 100644 (file)
index 0000000..cc439d0
--- /dev/null
@@ -0,0 +1,6 @@
+MODULES := gks gkc
+gks-objs := lproc_gks.o gks_server.o
+gkc-objs := lproc_gks.o gks_client.o
+@INCLUDE_RULES@
+
+
diff --git a/lustre/sec/gks/Makefile.mk b/lustre/sec/gks/Makefile.mk
new file mode 100644 (file)
index 0000000..9ce0737
--- /dev/null
@@ -0,0 +1,11 @@
+# Copyright (C) 2004  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+include $(src)/../../portals/Kernelenv
+
+#obj-y += ptlrpcs_gss.o ptlrpcs_gss_krb5.o
+obj-y += gks.o gkc.o
+gks-objs := lprocfs_gks.o gks_server.o
+gkc-objs := lprofs_gks.o gks_client.o 
diff --git a/lustre/sec/gks/autoMakefile.am b/lustre/sec/gks/autoMakefile.am
new file mode 100644 (file)
index 0000000..b073b46
--- /dev/null
@@ -0,0 +1,13 @@
+# Copyright (C) 2004  Cluster File Systems, Inc.
+#
+# This code is issued under the GNU General Public License.
+# See the file COPYING in this distribution
+
+
+if MODULES
+modulefs_DATA = gks$(KMODEXT) gkc$(KMODEXT)
+endif
+
+DIST_SOURCES = gks_client.c gks_server.c lproc_gks.c gks_internal.h 
+MOSTLYCLEANFILES := @MOSTLYCLEANFILES@
+
diff --git a/lustre/sec/gks/gks_client.c b/lustre/sec/gks/gks_client.c
new file mode 100644 (file)
index 0000000..161f938
--- /dev/null
@@ -0,0 +1,201 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre GS client 
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_GSS
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/obd_class.h>
+#include <linux/lustre_gs.h>
+
+#include "gks_internal.h"
+
+static int gkc_get_key(struct obd_export *exp, struct key_parms *kparms,
+                       struct crypto_key *ckey, int op)
+{
+        struct ptlrpc_request *req;
+        struct crypto_key *rep_key;
+        int rc, bufcount = 1, size[3] = {0, 0, 0};
+        void *buf;
+        ENTRY;
+
+        size[0] = lustre_secdesc_size();
+
+        size[bufcount++] = kparms->context_size;
+        if (kparms->perm && kparms->perm_size > 0) {
+                size[bufcount++] = kparms->perm_size;
+        }
+        req = ptlrpc_prep_req(class_exp2cliimp(exp), LUSTRE_GKS_VERSION,
+                              op, bufcount, size, NULL);
+        if (req == NULL)
+                RETURN(-ENOMEM);
+
+        lustre_pack_secdesc(req, size[0]);
+        
+        buf = lustre_msg_buf(req->rq_reqmsg, 1, kparms->context_size);
+        memcpy(buf, kparms->context, kparms->context_size);
+
+        if (kparms->perm && kparms->perm_size) {
+                buf = lustre_msg_buf(req->rq_reqmsg, 2, kparms->perm_size);
+                memcpy(buf, kparms->perm, kparms->perm_size);
+        } 
+        
+        size[0] = sizeof(struct crypto_key);
+        req->rq_replen = lustre_msg_size(1, size);
+
+        rc = ptlrpc_queue_wait(req);
+        
+        rep_key = lustre_msg_buf(req->rq_repmsg, 0, sizeof(struct crypto_key)); 
+
+        memcpy(ckey, rep_key, sizeof(*rep_key));
+
+        CDEBUG(D_INFO, "get enkey %s, mac %s\n", ckey->ck_key, ckey->ck_mac); 
+        ptlrpc_req_finished(req);
+        
+        RETURN(rc);
+}
+
+static int gkc_set_info(struct obd_export *exp, obd_count keylen,
+                        void *key, obd_count vallen, void *val)
+{
+        int rc = -EINVAL;
+        if (keylen == strlen("async") && memcmp(key, "async", keylen) == 0) {
+                struct client_obd *cl = &exp->exp_obd->u.cli;
+                if (vallen != sizeof(int))
+                        RETURN(-EINVAL);
+                cl->cl_async = *(int *)val;
+                CDEBUG(D_HA, "%s: set async = %d\n",
+                       exp->exp_obd->obd_name, cl->cl_async);
+                RETURN(0);
+        }
+        RETURN(rc);
+}
+
+static int gkc_get_info(struct obd_export *exp, __u32 keylen,
+                        void *key, __u32 *vallen, void *val)
+{
+        struct key_parms *kparms = (struct key_parms *)key;
+        struct crypto_key *ckey = (struct crypto_key *)val;
+        int rc = 0;
+        
+        ENTRY;
+       
+        LASSERT(*vallen == sizeof(*ckey));
+
+        switch (kparms->context->kc_command) {
+        case GKS_GET_KEY:
+        case GKS_DECRYPT_KEY:
+        case GKS_GET_MAC:
+                break;
+        default:
+                CERROR("Unknow op %d \n", kparms->context->kc_command);
+                rc = -EINVAL; 
+                RETURN(rc);
+        }
+        rc = gkc_get_key(exp, kparms, ckey, kparms->context->kc_command);
+        RETURN(rc); 
+}  
+static int gkc_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        struct client_obd *cli = &obd->u.cli;
+        int rc;
+        ENTRY;
+
+        OBD_ALLOC(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
+        if (!cli->cl_rpc_lock)
+                RETURN(-ENOMEM);
+        gkc_init_rpc_lock(cli->cl_rpc_lock);
+
+        ptlrpcd_addref();
+
+        rc = client_obd_setup(obd, len, buf);
+        if (rc)
+                GOTO(err_rpc_lock, rc);
+
+        RETURN(rc);
+err_rpc_lock:
+        OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
+        ptlrpcd_decref();
+        RETURN(rc);
+}
+
+static int gkc_cleanup(struct obd_device *obd, int flags)
+{
+        struct client_obd *cli = &obd->u.cli;
+
+        OBD_FREE(cli->cl_rpc_lock, sizeof (*cli->cl_rpc_lock));
+
+        ptlrpcd_decref();
+
+        return client_obd_cleanup(obd, 0);
+}
+
+static int gkc_attach(struct obd_device *dev, obd_count len, void *data)
+{
+        struct lprocfs_static_vars lvars;
+
+        lprocfs_init_vars(gkc, &lvars);
+        return lprocfs_obd_attach(dev, lvars.obd_vars);
+}
+
+static int gkc_detach(struct obd_device *dev)
+{
+        return lprocfs_obd_detach(dev);
+}
+
+static struct obd_ops gkc_obd_ops = {
+        .o_owner           = THIS_MODULE,
+        .o_connect         = client_connect_import,
+        .o_disconnect      = client_disconnect_export,
+        .o_attach          = gkc_attach,
+        .o_detach          = gkc_detach,
+        .o_setup           = gkc_setup,
+        .o_cleanup         = gkc_cleanup,
+        .o_get_info         = gkc_get_info,
+        .o_set_info        = gkc_set_info,
+};
+
+static int __init gkc_init(void)
+{
+        struct lprocfs_static_vars lvars;
+
+        lprocfs_init_vars(gkc, &lvars);
+        class_register_type(&gkc_obd_ops, NULL, lvars.module_vars,
+                            LUSTRE_GKC_NAME);
+        return 0;
+}
+
+static void gkc_exit(void)
+{
+        class_unregister_type(LUSTRE_GKC_NAME);
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre GS Client (GS)");
+MODULE_LICENSE("GPL");
+
+module_init(gkc_init);
+module_exit(gkc_exit);
+
diff --git a/lustre/sec/gks/gks_internal.h b/lustre/sec/gks/gks_internal.h
new file mode 100644 (file)
index 0000000..eae5dbc
--- /dev/null
@@ -0,0 +1,46 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+
+#ifndef _GKS_INTERNAL_H
+#define _GKS_INTERNAL_H
+
+#define GKS_SERVICE_WATCHDOG_TIMEOUT 30000
+struct mdc_rpc_lock {
+        struct semaphore rpcl_sem;
+        struct lookup_intent *rpcl_it;
+};
+
+static inline void gkc_init_rpc_lock(struct mdc_rpc_lock *lck)
+{
+        sema_init(&lck->rpcl_sem, 1);
+        lck->rpcl_it = NULL;
+}
+
+static inline void gkc_get_rpc_lock(struct mdc_rpc_lock *lck,
+                                    struct lookup_intent *it)
+{
+        ENTRY;
+        down(&lck->rpcl_sem);
+        if (it) {
+                lck->rpcl_it = it;
+        }
+}
+
+static inline void gkc_put_rpc_lock(struct mdc_rpc_lock *lck,
+                                    struct lookup_intent *it)
+{
+        EXIT;
+        if (it == NULL) {
+                LASSERT(it == lck->rpcl_it);
+                up(&lck->rpcl_sem);
+                return;
+        }
+        if (it) {
+                LASSERT(it == lck->rpcl_it);
+                lck->rpcl_it = NULL;
+                up(&lck->rpcl_sem);
+        }
+}
+
+#endif /* _GKS_INTERNAL_H */
diff --git a/lustre/sec/gks/gks_server.c b/lustre/sec/gks/gks_server.c
new file mode 100644 (file)
index 0000000..1a9ec27
--- /dev/null
@@ -0,0 +1,503 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ * lustre GS server
+ *  Copyright (c) 2001-2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef EXPORT_SYMTAB
+# define EXPORT_SYMTAB
+#endif
+#define DEBUG_SUBSYSTEM S_GKS
+
+#include <linux/module.h>
+#include <linux/crypto.h>
+#include <linux/random.h>
+#include <linux/init.h>
+#include <linux/obd_class.h>
+#include <linux/lustre_gs.h>
+
+#include "gks_internal.h"
+
+#define GKS_KEY "19760218"
+#define GKS_KEY_LEN 8 
+#define GKS_MAC_ALG "sha1"
+#define GKS_KEY_ALG "des"
+#define GKS_KEY_ALG_MODE CRYPTO_TFM_MODE_CBC
+
+static int gks_cleanup(struct obd_device *obd, int flags)
+{
+        struct gks_obd *gks = &obd->u.gks;
+        ENTRY;     
+
+        if (gks->gks_mac_tfm) {
+                crypto_free_tfm(gks->gks_mac_tfm);
+        }
+        if (gks->gks_key.key) {
+                OBD_FREE(gks->gks_key.key, gks->gks_key.len);
+        }  
+        if (gks->gks_key_tfm) {
+                crypto_free_tfm(gks->gks_key_tfm);
+        }
+
+        RETURN(0);
+}
+
+static int gks_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        struct gks_obd *gks = &obd->u.gks;
+        int rc = 0;
+
+        gks->gks_mac_tfm = crypto_alloc_tfm(GKS_MAC_ALG, 0);
+        if (!gks->gks_mac_tfm)
+                RETURN(-ENOSYS);
+        /*Now: we only keep an unchanged key in the whole system*/
+        gks->gks_key.len = GKS_KEY_LEN;
+        
+        OBD_ALLOC(gks->gks_key.key, GKS_KEY_LEN);
+
+        LASSERT(gks->gks_key.key);
+        
+        memcpy(gks->gks_key.key, GKS_KEY, GKS_KEY_LEN); 
+        /*set gks cipher type*/
+
+        gks->gks_key_tfm = crypto_alloc_tfm(GKS_KEY_ALG, GKS_KEY_ALG_MODE);
+        if (!gks->gks_key_tfm)
+                GOTO(out, rc = -ENOSYS);                
+        if (crypto_cipher_setkey(gks->gks_key_tfm, gks->gks_key.key, 
+                                 gks->gks_key.len))
+                GOTO(out, rc = -ENOSYS);
+out:
+        if (rc) {
+                gks_cleanup(obd, 0);
+        }
+        RETURN(rc);
+}
+
+static int gks_connect(struct lustre_handle *conn, struct obd_device *obd,
+                       struct obd_uuid *cluuid, struct obd_connect_data *data,
+                       unsigned long flags)
+{
+        int rc;
+        ENTRY;
+
+        if (!conn || !obd || !cluuid)
+                RETURN(-EINVAL);
+
+        rc = class_connect(conn, obd, cluuid);
+
+        RETURN(rc);
+}
+
+static int gks_disconnect(struct obd_export *exp, unsigned long flags)
+{
+        int rc = 0;
+        ENTRY;
+
+        rc = class_disconnect(exp, flags);
+        
+        target_destroy_export(exp);
+        
+        RETURN(rc);
+}
+
+static int gks_msg_check_version(struct lustre_msg *msg)
+{
+        int rc = 0;
+        ENTRY;
+
+        switch (msg->opc) {
+        case GKS_CONNECT:
+        case GKS_DISCONNECT:
+                rc = lustre_msg_check_version(msg, LUSTRE_OBD_VERSION);
+                if (rc)
+                        CERROR("bad opc %u version %08x, expecting %08x\n",
+                               msg->opc, msg->version, LUSTRE_OBD_VERSION);
+                break;
+        case GKS_GET_KEY:
+        case GKS_DECRYPT_KEY:
+        case GKS_GET_MAC:
+                rc = lustre_msg_check_version(msg, LUSTRE_GKS_VERSION);
+                if (rc)
+                        CERROR("bad opc %u version %08x, expecting %08x\n",
+                               msg->opc, msg->version, LUSTRE_GKS_VERSION);
+                break;
+        default:
+                CERROR("GKS unknown opcode %d\n", msg->opc);
+                rc = -ENOTSUPP;
+                break;
+        }
+
+        RETURN(rc);
+}
+
+static int crypto_get_gks_mac(struct ptlrpc_request *req, 
+                              struct key_perm *kperm, 
+                              __u8 *hmac)
+{
+        struct obd_device *obd = req->rq_export->exp_obd;
+        struct gks_obd *gks = &obd->u.gks;
+        int perm_size = crypto_kperm_size(kperm->kp_acl_count);
+        struct scatterlist sl = {
+                .page   = virt_to_page(kperm),
+                .offset = (unsigned long)(kperm) % PAGE_SIZE,
+                .length = perm_size 
+        };
+        __u8 *key = gks->gks_key.key; 
+        int keylen = gks->gks_key.len;
+        struct crypto_tfm *tfm = gks->gks_mac_tfm;
+
+        ENTRY;
+        LASSERT(tfm);
+        
+        crypto_hmac(tfm, key, &keylen, &sl, 1, hmac);
+       
+        CDEBUG(D_INFO, "compute mac mac %s by uid %d gid %d" 
+               "mode %d acl_count %d acl %p perm_size %d\n",
+               hmac, kperm->kp_uid, kperm->kp_gid, kperm->kp_mode, 
+               kperm->kp_acl_count, kperm->kp_acls, perm_size);
+        
+        RETURN(0); 
+}
+#define crypto_decrypt_gks_key(req, data, len) \
+crypto_crypt_gks_key(req, data, len, DECRYPT_DATA)
+
+#define crypto_encrypt_gks_key(req, data, len) \
+crypto_crypt_gks_key(req, data, len, ENCRYPT_DATA)
+
+static int crypto_crypt_gks_key(struct ptlrpc_request *req, 
+                                __u8 *data, int len, int mode) 
+{
+        struct obd_device *obd = req->rq_export->exp_obd;
+        struct gks_obd *gks = &obd->u.gks;
+        struct scatterlist sl = {
+                .page   = virt_to_page(data),
+                .offset = (unsigned long)(data) % PAGE_SIZE,
+                .length = len 
+        };
+        struct crypto_tfm *tfm = gks->gks_key_tfm;
+        __u8 local_iv[16] = {0};
+
+        ENTRY;
+        LASSERT(tfm);
+       
+        if (mode == ENCRYPT_DATA) 
+                crypto_cipher_encrypt_iv(tfm, &sl, &sl, (unsigned int)len, 
+                                         local_iv);
+        else
+                crypto_cipher_decrypt_iv(tfm, &sl, &sl, (unsigned int)len, 
+                                         local_iv);
+        RETURN(0); 
+}
+
+static int gks_create_key(struct ptlrpc_request *req, int offset)
+{
+        struct key_context *kctxt;
+        struct crypto_key  *ckey;
+
+        kctxt = lustre_swab_reqbuf(req, offset, sizeof (*kctxt),
+                                   lustre_swab_key_context);
+     
+        ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, 
+                                                   sizeof (*ckey));
+        
+        crypto_get_gks_mac(req, &kctxt->kc_perm, ckey->ck_mac);
+
+        CDEBUG(D_INFO, "compute mac mac %s by uid %d gid %d mode %d \n",
+               ckey->ck_mac, kctxt->kc_perm.kp_uid, kctxt->kc_perm.kp_gid,
+               kctxt->kc_perm.kp_mode);
+       
+        get_random_bytes(ckey->ck_key, KEY_SIZE);        
+        
+        ckey->ck_type = GKS_TYPE;
+        
+        CDEBUG(D_INFO, "get key %s\n", ckey->ck_key);
+
+        crypto_encrypt_gks_key(req, ckey->ck_key, KEY_SIZE);
+
+        CDEBUG(D_INFO, "encrypt key %s\n", ckey->ck_key);
+        
+        RETURN(0); 
+}
+
+static int gks_mac_verification(struct ptlrpc_request *req, 
+                                struct crypto_key *key, 
+                                struct key_perm *kperm)
+{
+        __u8 *tmp_mac;
+        ENTRY;
+
+        OBD_ALLOC(tmp_mac, MAC_SIZE);
+
+        crypto_get_gks_mac(req, kperm, tmp_mac);
+
+        if (!memcmp(tmp_mac, key->ck_mac, MAC_SIZE)) {
+                OBD_FREE(tmp_mac, MAC_SIZE);
+                RETURN(0); 
+        }
+        OBD_FREE(tmp_mac, MAC_SIZE);
+        RETURN(-EPERM);
+}
+
+static int gks_permission_check(struct key_context *kctxt,
+                                struct key_perm *kperm)
+{
+        RETURN(0); 
+}
+
+static int gks_decrypt_key(struct ptlrpc_request *req, int offset)
+{
+        struct key_context *kctxt;
+        struct key_perm    *kperm;
+        struct crypto_key  *ckey;
+        int                rc = 0;
+
+        kctxt = lustre_swab_reqbuf(req, offset, sizeof(*kctxt),
+                                   lustre_swab_key_context);
+        
+        /*authiticating the ops of the mac*/
+        rc = gks_mac_verification(req, &kctxt->kc_ck, &kctxt->kc_perm);
+        if (rc != 0) {
+                CERROR("Not my authorization mac %s\n", kctxt->kc_ck.ck_mac);
+                RETURN(rc);
+        }
+
+        kperm = lustre_swab_reqbuf(req, offset + 1, sizeof(*kperm),
+                                   lustre_swab_key_perms);
+
+        rc = gks_permission_check(kctxt, kperm);
+        if (rc != 0) {
+                CERROR("permssion check failed\n");
+                RETURN(rc);
+        }
+        ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, 
+                                                   sizeof (*ckey));
+        memcpy(ckey, &kctxt->kc_ck, sizeof(*ckey));
+
+        rc = crypto_decrypt_gks_key(req, ckey->ck_key, KEY_SIZE);
+        if (rc != 0) {
+                CERROR("permssion check failed\n");
+                RETURN(rc);
+        }
+        
+        RETURN(0); 
+}
+
+static int gks_get_mac(struct ptlrpc_request *req, int offset)
+{
+        struct key_context *kctxt;
+        struct key_perm    *kperm;
+        struct crypto_key  *ckey;
+        int                rc = 0;
+
+        kctxt = lustre_swab_reqbuf(req, offset, sizeof(*kctxt),
+                                   lustre_swab_key_context);
+        
+        /*authiticating the ops of the mac*/
+        rc = gks_mac_verification(req, &kctxt->kc_ck, &kctxt->kc_perm);
+        if (rc != 0) {
+                CERROR("Not my authorization mac %s\n", kctxt->kc_ck.ck_mac);
+                RETURN(rc);
+        }
+
+        kperm = lustre_swab_reqbuf(req, offset + 1, sizeof(*kperm),
+                                   lustre_swab_key_perms);
+
+        rc = gks_permission_check(kctxt, kperm);
+        if (rc != 0) {
+                CERROR("permssion check failed\n");
+                RETURN(rc);
+        }
+        ckey = (struct crypto_key *)lustre_msg_buf(req->rq_repmsg, 0, 
+                                                   sizeof (*ckey));
+
+        memcpy(ckey, &kctxt->kc_ck, sizeof(*ckey));
+
+        rc = crypto_get_gks_mac(req, kperm, ckey->ck_mac);
+        if (rc != 0) {
+                CERROR("get new mac error %d \n", rc);
+                RETURN(rc);
+        }
+
+        RETURN(rc);
+}
+
+int gks_handle(struct ptlrpc_request *req)
+{
+        int fail = OBD_FAIL_MDS_ALL_REPLY_NET;
+        int rc;
+        ENTRY;
+
+        rc = gks_msg_check_version(req->rq_reqmsg);
+        if (rc) {
+                CERROR("GKS drop mal-formed request\n");
+                RETURN(rc);
+        }
+        switch (req->rq_reqmsg->opc) {
+        case GKS_CONNECT:
+                DEBUG_REQ(D_INODE, req, "connect");
+                rc = target_handle_connect(req);
+                req->rq_status = rc;            /* superfluous? */
+                break;
+        case GKS_DISCONNECT:
+                DEBUG_REQ(D_INODE, req, "disconnect");
+                rc = target_handle_disconnect(req);
+                req->rq_status = rc;            /* superfluous? */
+                break;
+
+        case GKS_GET_KEY: {
+                int size[1] = {sizeof(struct crypto_key)};
+                int bufcount = 1;
+                DEBUG_REQ(D_INODE, req, "get_key");
+                lustre_pack_reply(req, bufcount, size, NULL);
+                rc = gks_create_key(req, MDS_REQ_REC_OFF);      
+                req->rq_status = rc;            /* superfluous? */
+                break;     
+        }  
+        case GKS_DECRYPT_KEY: {
+                int size[1] = {sizeof(struct crypto_key)};
+                int bufcount = 1;
+                DEBUG_REQ(D_INODE, req, "decrypt_key");
+                lustre_pack_reply(req, bufcount, size, NULL);
+                rc = gks_decrypt_key(req, MDS_REQ_REC_OFF);      
+                req->rq_status = rc;            /* superfluous? */
+                break;     
+        }  
+        case GKS_GET_MAC: {
+                int size[1] = {sizeof(struct crypto_key)};
+                int bufcount = 1;
+                  
+                DEBUG_REQ(D_INODE, req, "get_mac");
+                lustre_pack_reply(req, bufcount, size, NULL);
+                rc = gks_get_mac(req, MDS_REQ_REC_OFF);      
+                req->rq_status = rc;            /* superfluous? */
+                break;
+        }
+        default:
+                req->rq_status = -ENOTSUPP;
+                rc = ptlrpc_error(req);
+                RETURN(rc);
+        } 
+        target_send_reply(req, rc, fail);
+        RETURN(rc);
+}
+
+static int gkt_setup(struct obd_device *obd, obd_count len, void *buf)
+{
+        struct gks_obd *gks = &obd->u.gks;
+        int rc = 0;
+        ENTRY;
+
+        gks->gks_service =
+                ptlrpc_init_svc(GKS_NBUFS, GKS_BUFSIZE, GKS_MAXREQSIZE,
+                                GKS_REQUEST_PORTAL, GKC_REPLY_PORTAL,
+                                GKS_SERVICE_WATCHDOG_TIMEOUT,
+                                gks_handle, "gks", obd->obd_proc_entry);
+        if (!gks->gks_service) {
+                CERROR("failed to start service\n");
+                RETURN(-ENOMEM);
+        }
+
+        rc = ptlrpc_start_n_threads(obd, gks->gks_service, GKT_NUM_THREADS,
+                                    "ll_gkt");
+        
+        RETURN(rc);
+}
+
+static int gkt_cleanup(struct obd_device *obd, int flags)
+{
+        struct gks_obd *gks = &obd->u.gks;
+
+        ptlrpc_stop_all_threads(gks->gks_service);
+        ptlrpc_unregister_service(gks->gks_service);
+        RETURN(0);
+}
+
+int gks_attach(struct obd_device *dev, obd_count len, void *data)
+{
+        struct lprocfs_static_vars lvars;
+
+        lprocfs_init_vars(gks, &lvars);
+        return lprocfs_obd_attach(dev, lvars.obd_vars);
+}
+
+int gks_detach(struct obd_device *dev)
+{
+        return lprocfs_obd_detach(dev);
+}
+
+int gkt_attach(struct obd_device *dev, obd_count len, void *data)
+{
+        struct lprocfs_static_vars lvars;
+
+        lprocfs_init_vars(gkt, &lvars);
+        return lprocfs_obd_attach(dev, lvars.obd_vars);
+}
+
+int gkt_detach(struct obd_device *dev)
+{
+        return lprocfs_obd_detach(dev);
+}
+
+static struct obd_ops gks_obd_ops = {
+        .o_owner           = THIS_MODULE,
+        .o_attach          = gks_attach,
+        .o_detach          = gks_detach,
+        .o_setup           = gks_setup,
+        .o_cleanup         = gks_cleanup,
+        .o_connect         = gks_connect,
+        .o_disconnect         = gks_disconnect,
+};
+
+static struct obd_ops gkt_obd_ops = {
+        .o_owner           = THIS_MODULE,
+        .o_attach          = gkt_attach,
+        .o_detach          = gkt_detach,
+        .o_setup           = gkt_setup,
+        .o_cleanup         = gkt_cleanup,
+};
+
+static int __init gks_init(void)
+{
+        struct lprocfs_static_vars lvars;
+
+        lprocfs_init_vars(gks, &lvars);
+        class_register_type(&gks_obd_ops, NULL, lvars.module_vars,
+                            LUSTRE_GKS_NAME);
+        
+        lprocfs_init_vars(gkt, &lvars);
+        class_register_type(&gkt_obd_ops, NULL, lvars.module_vars,
+                            LUSTRE_GKT_NAME);
+        RETURN(0);
+}
+
+static void gks_exit(void)
+{
+        class_unregister_type(LUSTRE_GKS_NAME);
+        class_unregister_type(LUSTRE_GKT_NAME);
+}
+
+MODULE_AUTHOR("Cluster File Systems, Inc. <info@clusterfs.com>");
+MODULE_DESCRIPTION("Lustre GS Server (GS)");
+MODULE_LICENSE("GPL");
+
+module_init(gks_init);
+module_exit(gks_exit);
+
diff --git a/lustre/sec/gks/lproc_gks.c b/lustre/sec/gks/lproc_gks.c
new file mode 100644 (file)
index 0000000..4849941
--- /dev/null
@@ -0,0 +1,38 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2002 Cluster File Systems, Inc.
+ *
+ *   This file is part of Lustre, http://www.lustre.org.
+ *
+ *   Lustre is free software; you can redistribute it and/or
+ *   modify it under the terms of version 2 of the GNU General Public
+ *   License as published by the Free Software Foundation.
+ *
+ *   Lustre 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 for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with Lustre; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#define DEBUG_SUBSYSTEM S_CLASS
+
+#include <linux/lprocfs_status.h>
+#include <linux/obd_class.h>
+
+static struct lprocfs_vars lprocfs_gks_module_vars[] = { {0} };
+static struct lprocfs_vars lprocfs_gks_obd_vars[] = { {0} };
+
+static struct lprocfs_vars lprocfs_gkt_module_vars[] = { {0} };
+static struct lprocfs_vars lprocfs_gkt_obd_vars[] = { {0} };
+
+static struct lprocfs_vars lprocfs_gkc_module_vars[] = { {0} };
+static struct lprocfs_vars lprocfs_gkc_obd_vars[] = { {0} };
+
+LPROCFS_INIT_VARS(gks, lprocfs_gks_module_vars, lprocfs_gks_obd_vars)
+LPROCFS_INIT_VARS(gkt, lprocfs_gkt_module_vars, lprocfs_gkt_obd_vars)
+LPROCFS_INIT_VARS(gkc, lprocfs_gkc_module_vars, lprocfs_gkc_obd_vars)
index 7dbfd03..977069b 100644 (file)
@@ -750,6 +750,7 @@ static int fsfilt_smfs_get_xattr(struct inode *inode, char *name,
 #define XATTR_LUSTRE_MDS_MEA_EA         "mea"
 #define XATTR_LUSTRE_MDS_MID_EA         "mid"
 #define XATTR_LUSTRE_MDS_SID_EA         "sid"
+#define XATTR_LUSTRE_MDS_KEY_EA         "key"
 
 static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
                               void *lmm, int lmm_size, enum ea_type type)
@@ -777,6 +778,11 @@ static int fsfilt_smfs_set_md(struct inode *inode, void *handle,
                                            XATTR_LUSTRE_MDS_MID_EA,
                                            lmm, lmm_size);
                 break;
+        case EA_KEY:
+                rc = fsfilt_smfs_set_xattr(inode, handle,
+                                           XATTR_LUSTRE_MDS_KEY_EA,
+                                           lmm, lmm_size);
+                break;
         default:
                 rc = -EINVAL;
         }
index ff88cba..196a392 100644 (file)
@@ -107,7 +107,7 @@ static int mds_rec_setxattr_pack(char *buffer, struct dentry *dentry,
         LASSERT(kbuf && name);
 
         tmp = mdc_setattr_pack(msg, 0, op_data, NULL, name, strlen(name), 
-                               kbuf->buf, kbuf->buf_size);
+                               kbuf->buf, kbuf->buf_size, NULL, 0);
         OBD_FREE(op_data, sizeof(*op_data));
 
         rec = (struct mds_rec_setattr *)lustre_msg_buf(msg, 0, 0);
@@ -152,7 +152,8 @@ static int mds_rec_setattr_pack(char *buffer, struct dentry *dentry,
         msg = (struct lustre_msg *)(buffer + sizeof(*mkpi));
         lustre_init_msg(msg, mkpi->mpi_bufcount, mkpi->mpi_size, NULL);
 
-        tmp = mdc_setattr_pack(msg, 0, op_data, iattr, ea, ealen, NULL, 0);
+        tmp = mdc_setattr_pack(msg, 0, op_data, iattr, ea, ealen, 
+                               NULL, 0, NULL, 0);
         OBD_FREE(op_data, sizeof(*op_data));
 
         /* FIXME-WANGDI: there are maybe some better ways to set the time
index 99cbfdd..d1cd232 100644 (file)
@@ -9,6 +9,8 @@ mds3_HOST=$mds1_HOST
 ost_HOST=${ost_HOST:-$OSTNODE}
 ost2_HOST=${ost2_HOST:-$ost_HOST}
 client_HOST=${client_HOST:-$CLIENT}
+gsk_HOST=${gsk_HOST:-$MDSNODE}
+
 NETTYPE=${NETTYPE:-tcp}
 
 MOUNT=${MOUNT:-"/mnt/lustre"}
diff --git a/lustre/tests/lgs.sh b/lustre/tests/lgs.sh
new file mode 100755 (executable)
index 0000000..f0f893b
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/bash
+
+set -e
+
+export PATH=`dirname $0`/../utils:$PATH
+
+config=${1:-lgs.xml}
+
+LMC=${LMC:-lmc}
+TMP=${TMP:-/tmp}
+
+MDSSIZE=${MDSSIZE:-100000}
+MDSCOUNT=${MDSCOUNT:-3}
+OSTDEV=${OSTDEV:-$TMP/ost1-`hostname`}
+OSTSIZE=${OSTSIZE:-200000}
+OSTCOUNT=${OSTCOUNT:-1}
+
+DEF_FSTYPE=`test "x$(uname -r | grep -o '2.6')" = "x2.6" && echo "ldiskfs" || echo "ext3"`
+FSTYPE=${FSTYPE:-$DEF_FSTYPE}
+#used only if FSTYPE == smfs, otherwise ignored by lconf
+MDS_BACKFSTYPE=${MDS_BACKFSTYPE:-$DEF_FSTYPE}
+OST_BACKFSTYPE=${OST_BACKFSTYPE:-$DEF_FSTYPE}
+
+# 1 to config an echo client instead of llite
+ECHO_CLIENT=${ECHO_CLIENT:-}
+
+STRIPE_BYTES=65536
+STRIPES_PER_OBJ=0
+
+MOUNT=${MOUNT:-/mnt/lustre}
+
+# specific journal size for the ost, in MB
+JSIZE=${JSIZE:-0}
+JARG=""
+[ "$JSIZE" -gt 0 ] && JARG="--journal_size $JSIZE"
+
+rm -f $config
+
+# create nodes
+${LMC} -m $config --add node --node localhost || exit 10
+${LMC} -m $config --add net --node localhost --nid `hostname` --nettype tcp || exit 11
+
+# configure mds server
+${LMC} -m $config --add lmv --lmv lmv1 || exit 12
+
+for num in `seq $MDSCOUNT`; do
+    MDSDEV=$TMP/mds${num}-`hostname`
+    ${LMC} -m $config --format --add mds --node localhost --mds mds${num} \
+        --lmv lmv1 --fstype $FSTYPE --backfstype $MDS_BACKFSTYPE --dev $MDSDEV \
+        --size $MDSSIZE || exit 13
+done
+
+${LMC} -m $config --add lov --lov lov1 --lmv lmv1 --stripe_sz $STRIPE_BYTES --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0 || exit 20
+
+# configure ost
+for num in `seq $OSTCOUNT`; do
+    OST=ost$num
+    DEVPTR=OSTDEV$num
+    eval $DEVPTR=${!DEVPTR:=$TMP/$OST-`hostname`}
+    ${LMC} -m $config --add ost --node localhost --lov lov1 --ost $OST --fstype $FSTYPE --backfstype $OST_BACKFSTYPE --dev ${!DEVPTR} --size $OSTSIZE $JARG || exit 30
+done
+
+${LMC} -m $config --add gks --gks gks1 --node localhost || exit 13
+
+${LMC} -m $config --add mtpt --node localhost --path $MOUNT --lmv lmv1 --lov lov1 --gks gks1 || exit 40
diff --git a/lustre/tests/sanity-crypto.sh b/lustre/tests/sanity-crypto.sh
new file mode 100755 (executable)
index 0000000..1aaba39
--- /dev/null
@@ -0,0 +1,112 @@
+#!/bin/sh
+
+set -e
+
+#
+# This test needs to be run on the client
+#
+
+LUSTRE=${LUSTRE:-`dirname $0`/..}
+. $LUSTRE/tests/test-framework.sh
+
+init_test_env $@
+
+. ${CONFIG:=$LUSTRE/tests/cfg/lmv.sh}
+
+build_test_filter
+
+assert_env MDSCOUNT
+
+if [ `using_krb5_sec $SECURITY` == 'n' ] ; then
+    ALWAYS_EXCEPT="0c $ALWAYS_EXCEPT"
+fi
+
+
+gen_config() {
+    rm -f $XMLCONFIG
+
+    if [ "$MDSCOUNT" -gt 1 ]; then
+        add_lmv lmv1_svc
+        for mds in `mds_list`; do
+            MDSDEV=$TMP/${mds}-`hostname`
+            add_mds $mds --dev $MDSDEV --size $MDSSIZE --lmv lmv1_svc
+        done
+        add_lov_to_lmv lov1 lmv1_svc --stripe_sz $STRIPE_BYTES \
+           --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+       MDS=lmv1
+    else
+        add_mds $SINGLEMDS --dev $MDSDEV --size $MDSSIZE
+        if [ ! -z "$$SINGLEMDSfailover_HOST" ]; then
+            add_mdsfailover $SINGLEMDS --dev $MDSDEV --size $MDSSIZE
+        fi
+       add_lov lov1 $SINGLEMDS --stripe_sz $STRIPE_BYTES \
+           --stripe_cnt $STRIPES_PER_OBJ --stripe_pattern 0
+       MDS=$SINGLEMDS_svc
+    fi
+    add_ost ost --lov lov1 --dev $OSTDEV --size $OSTSIZE
+    add_ost ost2 --lov lov1 --dev ${OSTDEV}-2 --size $OSTSIZE
+    add_gsk gsk     
+    add_client client $MDS --lov lov1 --gss gsk_svc --path $MOUNT
+}
+
+build_test_filter
+
+cleanup() {
+    # make sure we are using the primary MDS, so the config log will
+    # be able to clean up properly.
+    activemds=`facet_active $SINGLEMDS`
+    if [ $activemds != "$SINGLEMDS" ]; then
+        fail $SINGLEMDS
+    fi
+    
+    umount $MOUNT2 || true
+    umount $MOUNT || true
+    rmmod llite
+
+    stop_gsk gsk 
+    for mds in `mds_list`; do
+       stop $mds ${FORCE} $MDSLCONFARGS
+    done
+    stop ost2 ${FORCE} --dump cleanup.log
+    stop ost ${FORCE} --dump cleanup.log
+    stop_lgssd
+    stop_lsvcgssd
+}
+
+if [ "$ONLY" == "cleanup" ]; then
+    sysctl -w portals.debug=0 || true
+    cleanup
+    exit
+fi
+
+SETUP=${SETUP:-"setup"}
+CLEANUP=${CLEANUP:-"cleanup"}
+
+setup() {
+    gen_config
+
+    start_krb5_kdc || exit 1
+    start_lsvcgssd || exit 2
+    start_lgssd || exit 3
+    start ost --reformat $OSTLCONFARGS 
+    start ost2 --reformat $OSTLCONFARGS 
+    [ "$DAEMONFILE" ] && $LCTL debug_daemon start $DAEMONFILE $DAEMONSIZE
+    for mds in `mds_list`; do
+       start $mds --reformat $MDSLCONFARGS
+    done
+    set -vx 
+    start_gsk gsk || exit 4
+    set -e
+    grep " $MOUNT " /proc/mounts || zconf_mount `hostname` $MOUNT
+    grep " $MOUNT2 " /proc/mounts || zconf_mount `hostname` $MOUNT2
+}
+
+$SETUP
+
+if [ "$ONLY" == "setup" ]; then
+    exit 0
+fi
+
+mkdir -p $DIR
+$CLEANUP
+
index c560100..a720fa3 100644 (file)
@@ -76,7 +76,7 @@ start() {
     facet=$1
     shift
     active=`facet_active $facet`
-    do_facet $facet $LCONF --select ${facet}_svc=${active}_facet \
+    do_facet $facet $LCONF --select ${facet}_svc=${active}_facet -v \
         --node ${active}_facet  --ptldebug $PTLDEBUG --subsystem $SUBSYSTEM \
         --mds_sec $SECURITY $@ $XMLCONFIG
 }
@@ -377,6 +377,26 @@ del_ost() {
     shift
     do_lmc --delete ost --node ${facet}_facet --ost ${facet}_svc $*
 }
+start_gsk() {
+    facet=$1
+    shift
+    rm -f ${facet}active
+    add_facet $facet
+    do_facet $facet $LCONF --node ${facet}_facet  --ptldebug $PTLDEBUG $* $XMLCONFIG 
+}
+stop_gsk() {
+    facet=$1
+    shift
+    do_facet $facet $LCONF --node ${facet}_facet  --cleanup $* $XMLCONFIG 
+}
+
+add_gsk() {
+    facet=$1
+    shift
+    rm -f ${facet}active
+    add_facet $facet
+    do_lmc --add gss --gss ${facet}_svc --node ${facet}_facet $*
+}
 add_cmobd() {
     facet=$1
     cache_facet=$2
index bd47b63..f6f36f3 100755 (executable)
@@ -714,10 +714,10 @@ class LCTLInterface:
         return out
 
     # dump mount options
-    def mount_option(self, profile, osc, mdc):
+    def mount_option(self, profile, osc, mdc, gkc):
         cmds = """
-  mount_option %s %s %s
-  quit""" % (profile, osc, mdc)
+  mount_option %s %s %s %s
+  quit""" % (profile, osc, mdc, gkc)
         self.run(cmds)
 
     # delete mount options
@@ -1726,6 +1726,66 @@ class LMV(Module):
     def correct_level(self, level, op=None):
         return level
 
+class GKD(Module):
+    def __init__(self,db):
+        Module.__init__(self, 'GKD', db)
+        target_uuid = self.db.get_first_ref('target')
+        self.target = self.db.lookup(target_uuid)
+        self.name = self.target.getName()
+
+        active_uuid = get_active_target(self.target)
+        if not active_uuid:
+            panic("No target device found:", target_uuid)
+        if active_uuid == self.uuid:
+            self.active = 1
+        else:
+            self.active = 0
+      
+       self.uuid = target_uuid  
+    def prepare(self):
+        if is_prepared(self.name):
+            return
+        if not self.active:
+            debug(self.uuid, "not active")
+            return
+        run_acceptors()
+
+       lctl.newdev("gks", self.name, self.uuid, setup ="") 
+       if not is_prepared('GKT'):
+           lctl.newdev("gkt", 'GKT', 'GKT_UUID', setup ="")
+
+    def cleanup(self):
+        if not self.active:
+            debug(self.uuid, "not active")
+            return
+        self.info()
+        if is_prepared(self.name):
+            try:
+                lctl.cleanup(self.name, self.uuid, config.force,
+                             config.failover)
+            except CommandError, e:
+                log(self.module_name, "cleanup failed: ", self.name)
+                e.dump()
+                cleanup_error(e.rc)
+                Module.cleanup(self)
+        if is_prepared('GKT'):
+            try:
+                lctl.cleanup("GKT", "GKT_UUID", config.force,
+                             config.failover)
+            except CommandError, e:
+                print "cleanup failed: ", self.name
+                e.dump()
+                cleanup_error(e.rc)
+        
+    def add_module(self, manager):
+       if self.active:
+           manager.add_lustre_module('sec/gks', 'gks')
+           manager.add_lustre_module('sec/gks', 'gkc')
+
+    def correct_level(self, level, op=None):
+        return level
+
+
 class CONFDEV(Module):
     def __init__(self, db, name, target_uuid, uuid):
         Module.__init__(self, 'CONFDEV', db)
@@ -1960,7 +2020,7 @@ class CONFDEV(Module):
             lctl.clear_log(self.name, self.target.getName())
             lctl.record(self.name, self.target.getName())
             client.prepare()
-            lctl.mount_option(self.target.getName(), client.get_name(), "")
+            lctl.mount_option(self.target.getName(), client.get_name(), "", "")
             lctl.end_record()
 
             config.cleanup = 1
@@ -2522,6 +2582,13 @@ class Client(Module):
             e.dump()
             cleanup_error(e.rc)
 
+class GKC(Client):
+    def __init__(self, db, uuid, fs_name):
+         Client.__init__(self, db, uuid, 'gkc', fs_name)
+
+    def permits_inactive(self):
+        return 0
+
 class MDC(Client):
     def __init__(self, db, uuid, fs_name):
          Client.__init__(self, db, uuid, 'mdc', fs_name)
@@ -2808,7 +2875,15 @@ class Mountpoint(Module):
        if not self.mds_uuid:
            self.mds_uuid = fs.get_first_ref('mds')
         self.obd_uuid = fs.get_first_ref('obd')
-        client_uuid = generate_client_uuid(self.name)
+        self.gks_uuid =fs.get_first_ref('gks')
+       client_uuid = generate_client_uuid(self.name)
+
+        self.oss_sec = self.db.get_val('oss_sec','null')
+        self.mds_sec = self.db.get_val('mds_sec','null')
+        if config.mds_sec:
+            self.mds_sec = config.mds_sec
+        if config.oss_sec:
+            self.oss_sec = config.oss_sec
 
         self.oss_sec = self.db.get_val('oss_sec','null')
         self.mds_sec = self.db.get_val('mds_sec','null')
@@ -2827,7 +2902,9 @@ class Mountpoint(Module):
        
         self.vosc = VOSC(ost, client_uuid, self.name, self.name)
        self.vmdc = VMDC(mds, client_uuid, self.name, self.name)
-        
+
+       if self.gks_uuid:
+           self.gkc = get_gkc(db, client_uuid, self.name, self.gks_uuid)      
     def prepare(self):
         if not config.record and fs_is_mounted(self.path):
             log(self.path, "already mounted.")
@@ -2836,12 +2913,18 @@ class Mountpoint(Module):
 
        self.vosc.prepare()
         self.vmdc.prepare()
+       if self.gks_uuid:
+          self.gkc.prepare()
 
         self.info(self.path, self.mds_uuid, self.obd_uuid)
         if config.record or config.lctl_dump:
-            lctl.mount_option(local_node_name, self.vosc.get_name(), 
-                             self.vmdc.get_name())
-            return
+           if self.gks_uuid:
+               lctl.mount_option(local_node_name, self.vosc.get_name(), 
+                                 self.vmdc.get_name(), self.gkc.get_name())
+            else:
+               lctl.mount_option(local_node_name, self.vosc.get_name(), 
+                                 self.vmdc.get_name(), "")
+           return
 
         if config.clientoptions:
             if self.clientoptions:
@@ -2854,8 +2937,12 @@ class Mountpoint(Module):
             # so replace it with Lustre async
             self.clientoptions = string.replace(self.clientoptions, "async", "lasync")
 
-        cmd = "mount -t lustre_lite -o osc=%s,mdc=%s,mds_sec=%s,oss_sec=%s%s %s %s" % \
-              (self.vosc.get_name(), self.vmdc.get_name(), self.mds_sec,
+       if self.gks_uuid:
+           gkc_name = self.gkc.get_name();
+       else:
+           gkc_name = "null"   
+        cmd = "mount -t lustre_lite -o osc=%s,mdc=%s,gkc=%s,mds_sec=%s,oss_sec=%s%s %s %s" % \
+              (self.vosc.get_name(), self.vmdc.get_name(), gkc_name, self.mds_sec,
               self.oss_sec, self.clientoptions, config.config, self.path)
         run("mkdir", self.path)
         ret, val = run(cmd)
@@ -2883,12 +2970,15 @@ class Mountpoint(Module):
 
         self.vmdc.cleanup()
         self.vosc.cleanup()
+       if self.gks_uuid:
+           self.gkc.cleanup()    
 
     def add_module(self, manager):
         self.vosc.add_module(manager)
         self.vmdc.add_module(manager)
         manager.add_lustre_module('llite', 'llite')
-
+       if self.gks_uuid:
+           manager.add_lustre_module('sec/gks', 'gkc')
     def correct_level(self, level, op=None):
         return level
 
@@ -2924,8 +3014,10 @@ def getServiceLevel(self):
         ret = 30
     elif type in ('mdsdev',):
         ret = 40
-    elif type in ('lmv',):
+    elif type in ('lmv', 'cobd',):
         ret = 45
+    elif type in ('gkd'):
+       ret = 50
     elif type in ('cmobd', 'cobd',):
         ret = 60 
     elif type in ('mountpoint', 'echoclient'):
@@ -2972,6 +3064,13 @@ def get_mdc(db, fs_name, mds_uuid):
     mdc = MDC(mds_db, mds_uuid, fs_name)
     return mdc
 
+def get_gkc(db, uuid, fs_name, gks_uuid):
+    gks_db = db.lookup(gks_uuid);
+    if not gks_db:
+        error("no gks:", gks_uuid)
+    gkc = GKC(gks_db, uuid, fs_name)
+    return gkc
+
 ############################################################
 # routing ("rooting")
 
@@ -3110,6 +3209,8 @@ def newService(db):
         n = ECHO_CLIENT(db)
     elif type == 'lmv':
         n = LMV(db)
+    elif type == 'gkd':
+       n = GKD(db)
     else:
         panic ("unknown service type:", type)
     return n
index 8ff3dcc..807a01b 100644 (file)
@@ -315,7 +315,7 @@ command_t cmdlist[] = {
          "setup mds/ost from the llog file\n"
          "usage: start <profilename>"},
         {"mount_option", jt_lcfg_mount_option, 0, 
-         "usage: mount_option profile osc_name [mdc_name] \n"},
+         "usage: mount_option profile osc_name [mdc_name] [gsc_name] \n"},
         {"del_mount_option", jt_lcfg_del_mount_option, 0,
          "usage: del_mount_option profile\n"},
         {"set_timeout", jt_lcfg_set_timeout, 0,
@@ -365,12 +365,15 @@ command_t cmdlist[] = {
         {"llog_remove", jt_llog_remove, 0,
          "remove one log from catalog, erase it from disk.\n"
          "usage: llog_remove <catalog id|catalog name> <log id>"},
-
+        
         /* Misc commands */
         {"flush_cred", jt_flush_cred, 0,
          "flush the client side credential.\n"
          "usage: flush_cred [mountpoint]..."},
-
+        {"set_crypt", jt_set_lkey_type, 0,
+         "set lustre key management type, only support gsk and mdk\n"
+         "usage: set_crypt [dir] [gsk|mdk]...."},
+        
         /* Debug commands */
         {"======== debug =========", jt_noop, 0, "debug"},
         {"debug_daemon", jt_dbg_debug_daemon, 0,
index 620936a..b50b376 100755 (executable)
@@ -178,6 +178,9 @@ Object creation command summary:
   --master_obd obd_name
   --cache_obd obd_name
 
+--add gks
+  --gks gks_name  
+
 --commit - Close a configuration version, and start a new one
 """
 
@@ -283,6 +286,10 @@ lmc_options = [
 
     # lmv
     ('lmv', "Specify LMV name.", PARAM,""),
+    
+    #gks name
+    ('gks', "Specify gks name.", PARAM,""),
+
     ]
 
 def error(*args):
@@ -536,6 +543,17 @@ class GenConfig:
         lmv = self.newService("lmv", name, uuid)
         return lmv
 
+    def gks(self, name, uuid, gkd_uuid):
+        gks = self.newService("gks", name, uuid)
+        gks.appendChild(self.ref("active", gkd_uuid))
+        return gks 
+
+    def gkd(self, name, uuid, node_uuid, gks_uuid):
+        gkd = self.newService("gkd", name, uuid)
+        gkd.appendChild(self.ref("node", node_uuid))
+        gkd.appendChild(self.ref("target", gks_uuid))
+       return gkd
+    
     def mds(self, name, uuid, mdd_uuid, group="", lmv=""):
         mds = self.newService("mds", name, uuid)
         mds.appendChild(self.ref("active", mdd_uuid))
@@ -611,10 +629,11 @@ class GenConfig:
             self.addElement(mtpt, "oss_sec", oss_sec)
         return mtpt
 
-    def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid):
+    def filesystem(self, name, uuid, mds_uuid, obd_uuid, mgmt_uuid, gks_uuid):
         fs = self.newService("filesystem", name, uuid)
         fs.appendChild(self.ref("mds", mds_uuid))
         fs.appendChild(self.ref("obd", obd_uuid))
+        fs.appendChild(self.ref("gks", gks_uuid))
         if mgmt_uuid:
             fs.appendChild(self.ref("mgmt", mgmt_uuid))
         return fs
@@ -978,6 +997,37 @@ def add_route(gen, lustre, options):
         node_add_profile(gen, node, "routetbl", rtbl_uuid)
     rtbl.appendChild(gen.route(gw_net_type, gw, gw_cluster_id, tgt_cluster_id,
                                lo, hi))
+def add_gks(gen, lustre, options):
+    """ create a gks """
+    node_name = get_option(options, 'node')
+    gks_name = get_option(options, 'gks')
+    if not gks_name:
+        gks_name = new_name('GKS_'+ node_name)
+    
+    gkd_name = new_name("GKD_" + gks_name + "_" + node_name)
+    gkd_uuid = new_uuid(gkd_name)
+    
+    gks_uuid = name2uuid(lustre, gks_name, 'gks', fatal=0)
+
+    if not gks_uuid:
+        gks_uuid = new_uuid(gks_name)
+        gks = gen.gks(gks_name, gks_uuid, gkd_uuid)
+        lustre.appendChild(gks)
+    else:
+        gks = lookup(lustre, gks_uuid)
+
+    # add gkd profile
+    node_uuid = name2uuid(lustre, node_name, 'node')
+    node = findByName(lustre, node_name, "node")
+    node_add_profile(gen, node, "gkd", gkd_uuid)
+    net_uuid = get_net_uuid(lustre, node_name)
+    if not net_uuid:
+        error("NODE: ", node_name, "not found")
+
+    gkd = gen.gkd(gkd_name, gkd_uuid, node_uuid, gks_uuid)
+    lustre.appendChild(gkd)
+
 
 def add_mds(gen, lustre, options):
     node_name = get_option(options, 'node')
@@ -1450,7 +1500,7 @@ def add_lmv(gen, lustre, options):
 
     lmv = gen.lmv(name, uuid)
     lustre.appendChild(lmv)
-    
+   
 def find_client(lustre, mds_uuid, client_uuid):
     mds = lookup(lustre, mds_uuid)
     clients = mds.getElementsByTagName('client_ref')
@@ -1461,7 +1511,7 @@ def find_client(lustre, mds_uuid, client_uuid):
                return 1
     return 0
     
-def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
+def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid, gks_uuid):
     fs_name = new_name("FS_fsname")
     fs_uuid = new_uuid(fs_name)
     
@@ -1472,12 +1522,12 @@ def new_filesystem(gen, lustre, mds_uuid, obd_uuid, mgmt_uuid):
        mds.appendChild(gen.ref("client", obd_uuid))
 
     fs = gen.filesystem(fs_name, fs_uuid, mds_uuid, 
-                       obd_uuid, mgmt_uuid)
+                       obd_uuid, mgmt_uuid, gks_uuid)
                        
     lustre.appendChild(fs)
     return fs_uuid
 
-def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
+def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name, gks_name):
     mds_uuid = name2uuid(lustre, mds_name, tag='mds', fatal=0)
     if not mds_uuid:
         mds_uuid = name2uuid(lustre, mds_name, tag='lmv', fatal=0)
@@ -1499,10 +1549,14 @@ def get_fs_uuid(gen, lustre, mds_name, obd_name, mgmt_name):
     else:
         mgmt_uuid = ''
 
+    if gks_name:
+       gks_uuid = name2uuid(lustre, gks_name, tag='gks', fatal=1)
+    else: 
+       gks_uuid = ''
     fs_uuid = lookup_filesystem(lustre, mds_uuid, obd_uuid)
     if not fs_uuid:
         fs_uuid = new_filesystem(gen, lustre, mds_uuid, 
-                                 obd_uuid, mgmt_uuid)
+                                 obd_uuid, mgmt_uuid, gks_uuid)
     return fs_uuid
 
 def add_mtpt(gen, lustre, options):
@@ -1518,6 +1572,7 @@ def add_mtpt(gen, lustre, options):
     lov_name = get_option(options, 'lov')
     ost_name = get_option(options, 'ost')
     mds_name = get_option(options, 'mds')
+    gks_name = get_option(options, 'gks')
     if mds_name == '':
         mds_name = get_option(options, 'lmv')
         if mds_name == '':
@@ -1537,7 +1592,7 @@ def add_mtpt(gen, lustre, options):
 
     if fs_name == '':
         mgmt_name = get_option(options, 'mgmt')
-        fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name)
+        fs_uuid = get_fs_uuid(gen, lustre, mds_name, lov_name, mgmt_name, gks_name)
     else:
         fs_uuid = name2uuid(lustre, fs_name, tag='filesystem')
 
@@ -1698,6 +1753,8 @@ def add(devtype, gen, lustre, options):
         add_mgmt(gen, lustre, options)
     elif devtype == 'lmv':
         add_lmv(gen, lustre, options)
+    elif devtype == 'gks':
+       add_gks(gen, lustre, options)
     else:
         error("unknown device type:", devtype)
 
index acb3bee..e446d55 100644 (file)
@@ -550,7 +550,7 @@ int jt_lcfg_mount_option(int argc, char **argv)
         struct lustre_cfg *lcfg;
         int i;
 
-        if (argc < 3 || argc > 4)
+        if (argc < 3 || argc > 5)
                 return CMD_HELP;
 
         lustre_cfg_bufs_reset(&bufs, lcfg_devname);
index ebed1b3..80b7130 100644 (file)
@@ -1981,6 +1981,104 @@ int jt_obd_recover(int argc, char **argv)
 
         return rc;
 }
+int jt_set_lkey_type(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        char *dir, *type;
+        int rc, fd;
+
+        if (argc < 3 || argc > 4)
+                return CMD_HELP;
+
+        dir = argv[1];
+        type = argv[2];
+
+        IOC_INIT(data);
+
+        data.ioc_inllen1 = strlen(type) + 1;
+        data.ioc_inlbuf1 = type;
+
+        IOC_PACK(argv[0], data);
+
+        fd = open(dir, O_RDONLY);
+        if (fd < 0) {
+                fprintf(stderr, "open \"%s\" failed: %s\n", dir,
+                        strerror(errno));
+                return -1;
+        }
+
+        rc = ioctl(fd, LL_IOC_KEY_TYPE, buf);
+        if (rc < 0) {
+                fprintf(stderr, "error: %s: ioctl error: %s\n",
+                        jt_cmdname(argv[0]), strerror(rc = errno));
+        }
+        close(fd);
+        return rc;
+}
+
+int jt_disable_crypto(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        char *file;
+        int rc, fd;
+
+        if (argc < 2 || argc > 3)
+                return CMD_HELP;
+
+        file = argv[1];
+
+        IOC_INIT(data);
+
+        IOC_PACK(argv[0], data);
+
+        fd = open(file, O_RDONLY);
+        if (fd < 0) {
+                fprintf(stderr, "open \"%s\" failed: %s\n", file,
+                        strerror(errno));
+                return -1;
+        }
+
+        rc = ioctl(fd, LL_IOC_DISABLE_CRYPTO, buf);
+        if (rc < 0) {
+                fprintf(stderr, "error: %s: ioctl error: %s\n",
+                        jt_cmdname(argv[0]), strerror(rc = errno));
+        }
+        close(fd);
+        
+        return rc;
+}
+
+int jt_enable_crypto(int argc, char **argv)
+{
+        struct obd_ioctl_data data;
+        char *file;
+        int rc, fd;
+
+        if (argc < 3 || argc > 4)
+                return CMD_HELP;
+
+        file = argv[1];
+
+        IOC_INIT(data);
+
+        IOC_PACK(argv[0], data);
+
+        fd = open(file, O_RDONLY);
+        if (fd < 0) {
+                fprintf(stderr, "open \"%s\" failed: %s\n", file,
+                        strerror(errno));
+                return -1;
+        }
+
+        rc = ioctl(fd, LL_IOC_ENABLE_CRYPTO, buf);
+        if (rc < 0) {
+                fprintf(stderr, "error: %s: ioctl error: %s\n",
+                        jt_cmdname(argv[0]), strerror(rc = errno));
+        }
+        close(fd);
+        return rc;
+}
+
 
 int jt_obd_mdc_lookup(int argc, char **argv)
 {
index 02fbe8a..e507a7e 100644 (file)
@@ -95,7 +95,9 @@ int jt_obd_reint_sync(int argc, char **argv);
 int jt_obd_cache_on(int argc, char **argv);
 int jt_obd_cache_off(int argc, char **argv);
 int jt_obd_snap_add(int argc, char **argv);
-
+int jt_set_lkey_type(int argc, char **argv);
+int jt_disable_crypto(int argc, char **argv);
+int jt_enable_crypto(int argc, char **argv);
 int lcfg_ioctl(char * func, int dev_id, struct lustre_cfg *lcfg);
 int parse_devname(char *func, char *name);
 char *jt_cmdname(char *func);