Whamcloud - gitweb
land b_colibri_devel on HEAD:
authorericm <ericm>
Tue, 29 Jan 2008 21:24:51 +0000 (21:24 +0000)
committerericm <ericm>
Tue, 29 Jan 2008 21:24:51 +0000 (21:24 +0000)
- redesigned remote acl support, by FanYong
  b=11842
  r=pravin.shelar, eric.mei
- new sptlrpc configure interface
  b=13642
  r=yong.fan, rahul.deshmukh
- split kerberos keytab for lustre_root
  b=13873
  r=yong.fan, h.huang
- fix setuid for gss with linux keyring
  b=13899
  r=yong.fan, h.huang

130 files changed:
lustre/ChangeLog
lustre/autoconf/kerberos5.m4
lustre/include/Makefile.am
lustre/include/linux/lustre_acl.h
lustre/include/linux/lustre_mds.h
lustre/include/linux/lvfs.h
lustre/include/lustre/liblustreapi.h
lustre/include/lustre/lustre_idl.h
lustre/include/lustre/lustre_user.h
lustre/include/lustre_cfg.h
lustre/include/lustre_disk.h
lustre/include/lustre_eacl.h [new file with mode: 0644]
lustre/include/lustre_export.h
lustre/include/lustre_idmap.h [new file with mode: 0644]
lustre/include/lustre_import.h
lustre/include/lustre_mdc.h
lustre/include/lustre_mdt.h
lustre/include/lustre_net.h
lustre/include/lustre_param.h
lustre/include/lustre_sec.h
lustre/include/lustre_ucache.h
lustre/include/md_object.h
lustre/include/obd.h
lustre/include/obd_class.h
lustre/kernel_patches/kernel_configs/kernel-2.6.16-2.6-sles10-i686-bigsmp.config
lustre/kernel_patches/kernel_configs/kernel-2.6.16-2.6-sles10-i686.config
lustre/kernel_patches/kernel_configs/kernel-2.6.16-2.6-sles10-x86_64-smp.config
lustre/kernel_patches/kernel_configs/kernel-2.6.16-2.6-sles10-x86_64.config
lustre/ldlm/ldlm_lib.c
lustre/ldlm/ldlm_lockd.c
lustre/llite/Makefile.in
lustre/llite/dir.c
lustre/llite/file.c
lustre/llite/llite_internal.h
lustre/llite/llite_lib.c
lustre/llite/llite_nfs.c
lustre/llite/llite_rmtacl.c [new file with mode: 0644]
lustre/llite/namei.c
lustre/llite/remote_perm.c
lustre/llite/xattr.c
lustre/lmv/lmv_obd.c
lustre/mdc/lproc_mdc.c
lustre/mdc/mdc_internal.h
lustre/mdc/mdc_lib.c
lustre/mdc/mdc_request.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_object.c
lustre/mdd/mdd_permission.c
lustre/mds/handler.c
lustre/mdt/Makefile.in
lustre/mdt/mdt_handler.c
lustre/mdt/mdt_identity.c
lustre/mdt/mdt_idmap.c
lustre/mdt/mdt_internal.h
lustre/mdt/mdt_lib.c
lustre/mdt/mdt_lproc.c
lustre/mdt/mdt_rmtacl.c [deleted file]
lustre/mdt/mdt_xattr.c
lustre/mgc/mgc_request.c
lustre/mgs/lproc_mgs.c
lustre/mgs/mgs_handler.c
lustre/mgs/mgs_internal.h
lustre/mgs/mgs_llog.c
lustre/obdclass/Makefile.in
lustre/obdclass/acl.c [new file with mode: 0644]
lustre/obdclass/genops.c
lustre/obdclass/idmap.c [new file with mode: 0644]
lustre/obdclass/obd_config.c
lustre/obdclass/obd_mount.c
lustre/obdfilter/filter.c
lustre/osc/lproc_osc.c
lustre/osc/osc_request.c
lustre/ost/ost_handler.c
lustre/ptlrpc/Makefile.in
lustre/ptlrpc/autoMakefile.am
lustre/ptlrpc/gss/autoMakefile.am
lustre/ptlrpc/gss/gss_api.h
lustre/ptlrpc/gss/gss_bulk.c
lustre/ptlrpc/gss/gss_cli_upcall.c
lustre/ptlrpc/gss/gss_internal.h
lustre/ptlrpc/gss/gss_keyring.c
lustre/ptlrpc/gss/gss_krb5_mech.c
lustre/ptlrpc/gss/gss_mech_switch.c
lustre/ptlrpc/gss/gss_pipefs.c
lustre/ptlrpc/gss/gss_rawobj.c
lustre/ptlrpc/gss/gss_svc_upcall.c
lustre/ptlrpc/gss/sec_gss.c
lustre/ptlrpc/import.c
lustre/ptlrpc/layout.c
lustre/ptlrpc/niobuf.c
lustre/ptlrpc/pack_generic.c
lustre/ptlrpc/ptlrpc_internal.h
lustre/ptlrpc/sec.c
lustre/ptlrpc/sec_bulk.c
lustre/ptlrpc/sec_config.c [new file with mode: 0644]
lustre/ptlrpc/sec_gc.c
lustre/ptlrpc/sec_lproc.c
lustre/ptlrpc/sec_null.c
lustre/ptlrpc/sec_plain.c
lustre/ptlrpc/service.c
lustre/tests/Makefile.am
lustre/tests/acceptance-small.sh
lustre/tests/conf-sanity.sh
lustre/tests/krb5_login.sh
lustre/tests/replay-dual.sh
lustre/tests/rmtacl/README [new file with mode: 0644]
lustre/tests/rmtacl/cp.test [new file with mode: 0644]
lustre/tests/rmtacl/getfacl-noacl.test [new file with mode: 0644]
lustre/tests/rmtacl/inheritance.test [new file with mode: 0644]
lustre/tests/rmtacl/make-tree [new file with mode: 0755]
lustre/tests/rmtacl/misc.test [new file with mode: 0644]
lustre/tests/rmtacl/permissions.test [new file with mode: 0644]
lustre/tests/rmtacl/run [new file with mode: 0755]
lustre/tests/rmtacl/setfacl.test [new file with mode: 0644]
lustre/tests/sanity-gss.sh
lustre/tests/sanity-sec.sh
lustre/tests/sanity.sh
lustre/tests/test-framework.sh
lustre/utils/Makefile.am
lustre/utils/gss/lgss_keyring.c
lustre/utils/gss/lgss_krb5_utils.c
lustre/utils/gss/lsupport.c
lustre/utils/gss/lsupport.h
lustre/utils/gss/nfs-utils-1.0.11-lustre.diff
lustre/utils/gss/svcgssd_proc.c
lustre/utils/l_facl.c [deleted file]
lustre/utils/l_getidentity.c
lustre/utils/lfs.c
lustre/utils/liblustreapi.c
lustre/utils/module_setup.sh

index 3422dfb..b0b0823 100644 (file)
@@ -61,6 +61,14 @@ Details    : If an OST is down the MDS will hang indefinitely in
             MDS QOS usage of statfs, it should not stuck in waiting.
 
 Severity   : enhancement
+Bugzilla   : 11842
+Description: remote_acl support
+Details    : Support ACL-based permission check for remote user.
+             Support setfacl/getfacl for remote user with the utils
+             "lfs {l,r}{s,g}etfacl" which follow the same parameter format as
+             the system "{s,g}etfacl" utils.
+
+Severity   : enhancement
 Bugzilla   : 14288
 Description: Update to RHEL4 U6 kernel-2.6.9-67.EL.
 
index 1dac9f0..dfa5738 100644 (file)
@@ -36,6 +36,8 @@ AC_DEFUN([AC_KERBEROS_V5],[
       AC_DEFINE_UNQUOTED(KRB5_VERSION, $K5VERS, [Define this as the Kerberos version number])
       if test -f $dir/include/gssapi/gssapi_krb5.h -a \
                 \( -f $dir/lib/libgssapi_krb5.a -o \
+                   -f $dir/lib64/libgssapi_krb5.a -o \
+                   -f $dir/lib64/libgssapi_krb5.so -o \
                    -f $dir/lib/libgssapi_krb5.so \) ; then
          AC_DEFINE(HAVE_KRB5, 1, [Define this if you have MIT Kerberos libraries])
          KRBDIR="$dir"
@@ -91,6 +93,14 @@ AC_DEFUN([AC_KERBEROS_V5],[
   AC_CHECK_LIB($gssapi_lib, gss_krb5_ccache_name,
     AC_DEFINE(HAVE_GSS_KRB5_CCACHE_NAME, 1, [Define this if the Kerberos GSS library supports gss_krb5_ccache_name]), ,$KRBLIBS)
 
+  dnl Check for newer error message facility
+  AC_CHECK_LIB($gssapi_lib, krb5_get_error_message,
+    AC_DEFINE(HAVE_KRB5_GET_ERROR_MESSAGE, 1, [Define this if the function krb5_get_error_message is available]), ,$KRBLIBS)
+
+  dnl Check for function to specify addressless tickets
+  AC_CHECK_LIB($gssapi_lib, krb5_get_init_creds_opt_set_addressless,
+    AC_DEFINE(HAVE_KRB5_GET_INIT_CREDS_OPT_SET_ADDRESSLESS, 1, [Define this if the function krb5_get_init_creds_opt_set_addressless is available]), ,$KRBLIBS)
+
   dnl If they specified a directory and it didn't work, give them a warning
   if test "x$krb5_with" != "x" -a "$krb5_with" != "$KRBDIR"; then
     AC_MSG_WARN(Using $KRBDIR instead of requested value of $krb5_with for Kerberos!)
index adf7c6e..27e62fc 100644 (file)
@@ -15,5 +15,5 @@ EXTRA_DIST = ioctl.h liblustre.h lprocfs_status.h lustre_cfg.h        \
             obd_cache.h obd_class.h obd_echo.h obd.h obd_lov.h \
             obd_ost.h obd_support.h lustre_ver.h lu_object.h lu_time.h  \
              md_object.h dt_object.h lustre_param.h lustre_mdt.h \
-             lustre_fid.h lustre_fld.h lustre_req_layout.h lustre_capa.h
-
+             lustre_fid.h lustre_fld.h lustre_req_layout.h lustre_capa.h \
+             lustre_idmap.h lustre_eacl.h
index 0583ea4..153ac74 100644 (file)
 # ifdef CONFIG_FS_POSIX_ACL
 #  ifdef HAVE_XATTR_ACL
 #   include <linux/xattr_acl.h>
-#  endif
+#  endif /* HAVE_XATTR_ACL */
 #  ifdef HAVE_LINUX_POSIX_ACL_XATTR_H
 #   include <linux/posix_acl_xattr.h>
-#  endif
-# endif
+#  endif /* HAVE_LINUX_POSIX_ACL_XATTR_H */
+# endif /* CONFIG_FS_POSIX_ACL */
 # ifndef HAVE_VFS_INTENT_PATCHES
 #  include <linux/lustre_intent.h>
 # endif
-#endif
+#endif /* __KERNEL__ */
 
 /* ACL */
 #ifdef CONFIG_FS_POSIX_ACL
@@ -42,8 +42,8 @@
 
 # define LUSTRE_POSIX_ACL_MAX_SIZE   XATTR_ACL_SIZE
 
-#else /* CONFIG_FS_POSIX_ACL */
+# else /* CONFIG_FS_POSIX_ACL */
 # define LUSTRE_POSIX_ACL_MAX_SIZE      0
-#endif /* CONFIG_FS_POSIX_ACL */
+# endif /* CONFIG_FS_POSIX_ACL */
 
 #endif /* _LUSTRE_ACL_H */
index 8e7c372..ce48c0d 100644 (file)
 # ifdef CONFIG_FS_POSIX_ACL
 #  ifdef HAVE_XATTR_ACL
 #   include <linux/xattr_acl.h>
-#  endif 
+#  endif /* HAVE_XATTR_ACL */ 
 #  ifdef HAVE_LINUX_POSIX_ACL_XATTR_H
 #   include <linux/posix_acl_xattr.h>
-#  endif
-# endif
+#  endif /* HAVE_LINUX_POSIX_ACL_XATTR_H */
+# endif /* CONFIG_FS_POSIX_ACL */
 # ifndef HAVE_VFS_INTENT_PATCHES
 #  include <linux/lustre_intent.h>
 # endif
-#endif
+#endif /* __KERNEL__ */
 
 struct mds_obd;
 struct ptlrpc_request;
index 1cc27c4..e66a3a2 100644 (file)
@@ -52,7 +52,7 @@ struct lvfs_ucred {
         __u32                   luc_cap;
         __u32                   luc_umask;
        struct group_info      *luc_ginfo;
-       struct mdt_identity    *luc_identity;
+       struct md_identity     *luc_identity;
 };
 
 struct lvfs_callback_ops {
index cf63180..0e5b2bf 100644 (file)
@@ -110,6 +110,10 @@ extern int llapi_quotacheck(char *mnt, int check_type);
 extern int llapi_poll_quotacheck(char *mnt, struct if_quotacheck *qchk);
 extern int llapi_quotactl(char *mnt, struct if_quotactl *qctl);
 extern int llapi_target_iterate(int type_num, char **obd_type, void *args, llapi_cb_t cb);
-extern int llapi_getfacl(char *fname, char *cmd);
-extern int llapi_setfacl(char *fname, char *cmd);
+extern int llapi_lsetfacl(int argc, char *argv[]);
+extern int llapi_lgetfacl(int argc, char *argv[]);
+extern int llapi_rsetfacl(int argc, char *argv[]);
+extern int llapi_rgetfacl(int argc, char *argv[]);
+extern int llapi_cp(int argc, char *argv[]);
+extern int llapi_ls(int argc, char *argv[]);
 #endif
index d308bbc..c877670 100644 (file)
@@ -753,9 +753,6 @@ extern void lustre_swab_lov_mds_md(struct lov_mds_md *llm);
 #define XATTR_NAME_ACL_DEFAULT  "system.posix_acl_default"
 #define XATTR_NAME_LOV          "trusted.lov"
 
-/* remote ACL */
-#define XATTR_NAME_LUSTRE_ACL   "system.lustre_acl"
-
 #define OBD_MD_FLID        (0x00000001ULL) /* object ID */
 #define OBD_MD_FLATIME     (0x00000002ULL) /* access time */
 #define OBD_MD_FLMTIME     (0x00000004ULL) /* data modification time */
@@ -803,6 +800,11 @@ extern void lustre_swab_lov_mds_md(struct lov_mds_md *llm);
 #define OBD_MD_FLCKSPLIT   (0x0000080000000000ULL) /* Check split on server */
 #define OBD_MD_FLCROSSREF  (0x0000100000000000ULL) /* Cross-ref case */
 
+#define OBD_MD_FLRMTLSETFACL    (0x0001000000000000ULL) /* lfs lsetfacl case */
+#define OBD_MD_FLRMTLGETFACL    (0x0002000000000000ULL) /* lfs lgetfacl case */
+#define OBD_MD_FLRMTRSETFACL    (0x0004000000000000ULL) /* lfs rsetfacl case */
+#define OBD_MD_FLRMTRGETFACL    (0x0008000000000000ULL) /* lfs rgetfacl case */
+
 #define OBD_MD_FLGETATTR (OBD_MD_FLID    | OBD_MD_FLATIME | OBD_MD_FLMTIME | \
                           OBD_MD_FLCTIME | OBD_MD_FLSIZE  | OBD_MD_FLBLKSZ | \
                           OBD_MD_FLMODE  | OBD_MD_FLTYPE  | OBD_MD_FLUID   | \
@@ -1164,10 +1166,13 @@ struct mds_remote_perm {
         __u32           rp_access_perm; /* MAY_READ/WRITE/EXEC */
 };
 
-/* setxid permissions for mds_setxid_perm.mp_perm */
-#define LUSTRE_SETUID_PERM 0x01
-#define LUSTRE_SETGID_PERM 0x02
-#define LUSTRE_SETGRP_PERM 0x04
+/* permissions for md_perm.mp_perm */
+enum {
+        CFS_SETUID_PERM = 0x01,
+        CFS_SETGID_PERM = 0x02,
+        CFS_SETGRP_PERM = 0x04,
+        CFS_RMTACL_PERM = 0x08
+};
 
 extern void lustre_swab_mds_remote_perm(struct mds_remote_perm *p);
 
@@ -1294,6 +1299,8 @@ extern void lustre_swab_mdt_rec_setattr (struct mdt_rec_setattr *sa);
 #define MAY_VTX_PART    (1 << 12)
 /* full VTX permission check */
 #define MAY_VTX_FULL    (1 << 13)
+/* lfs rgetfacl permission check */
+#define MAY_RGETFACL    (1 << 14)
 
 enum {
         MDS_CHECK_SPLIT  = 1 << 0,
index 8c17bc5..0dc8b87 100644 (file)
@@ -59,8 +59,7 @@ struct obd_statfs;
 #define IOC_OBD_STATFS                  _IOWR('f', 164, struct obd_statfs *)
 #define IOC_LOV_GETINFO                 _IOWR('f', 165, struct lov_user_mds_data *)
 #define LL_IOC_FLUSHCTX                 _IOW ('f', 166, long)
-#define LL_IOC_GETFACL                  _IOWR('f', 167, struct rmtacl_ioctl_data *)
-#define LL_IOC_SETFACL                  _IOWR('f', 168, struct rmtacl_ioctl_data *)
+#define LL_IOC_RMTACL                   _IOW ('f', 167, long)
 
 #define LL_IOC_LLOOP_ATTACH             _IOWR('f', 169, long)
 #define LL_IOC_LLOOP_DETACH             _IOWR('f', 170, long)
@@ -89,6 +88,7 @@ struct obd_statfs;
 #define LL_FILE_IGNORE_LOCK             0x00000001
 #define LL_FILE_GROUP_LOCKED            0x00000002
 #define LL_FILE_READAHEAD               0x00000004
+#define LL_FILE_RMTACL                  0x00000008
 
 #define LOV_USER_MAGIC_V1 0x0BD10BD0
 #define LOV_USER_MAGIC    LOV_USER_MAGIC_V1
@@ -188,10 +188,10 @@ struct if_quotacheck {
 
 #define IDENTITY_DOWNCALL_MAGIC 0x6d6dd620
 
-/* setxid permission */
-#define N_SETXID_PERMS_MAX      64
+/* permission */
+#define N_PERMS_MAX      64
 
-struct setxid_perm_downcall_data {
+struct perm_downcall_data {
         __u64 pdd_nid;
         __u32 pdd_perm;
 };
@@ -202,21 +202,22 @@ struct identity_downcall_data {
         __u32                            idd_uid;
         __u32                            idd_gid;
         __u32                            idd_nperms;
-        struct setxid_perm_downcall_data idd_perms[N_SETXID_PERMS_MAX];
+        struct perm_downcall_data idd_perms[N_PERMS_MAX];
         __u32                            idd_ngroups;
         __u32                            idd_groups[0];
 };
 
-#define RMTACL_DOWNCALL_MAGIC 0x6d6dd620
-#define RMTACL_SIZE_MAX     (4096)
+/* for non-mapped uid/gid */
+#define NOBODY_UID      99
+#define NOBODY_GID      99
 
-struct rmtacl_downcall_data {
-        __u32           add_magic;
-        __u32           add_handle;
-        __u64           add_key;
-        __u32           add_buflen;
-        __u32           add_padding;
-        __u8            add_buf[0];
+#define INVALID_ID      (-1)
+
+enum {
+        RMT_LSETFACL    = 1,
+        RMT_LGETFACL    = 2,
+        RMT_RSETFACL    = 3,
+        RMT_RGETFACL    = 4
 };
 
 #ifdef NEED_QUOTA_DEFS
@@ -284,12 +285,4 @@ struct if_quotactl {
 # define offsetof(typ,memb)     ((unsigned long)((char *)&(((typ *)0)->memb)))
 #endif
 
-/* remote acl ioctl */
-struct rmtacl_ioctl_data {
-        char           *cmd;            /* IN */
-        unsigned long   cmd_len;
-        char           *res;            /* OUT */
-        unsigned long   res_len;
-};
-
 #endif /* _LUSTRE_USER_H */
index 89c5447..5432519 100644 (file)
@@ -58,7 +58,7 @@ enum lcfg_command_type {
         LCFG_LOV_ADD_INA    = 0x00ce013,
         LCFG_ADD_MDC        = 0x00cf014,
         LCFG_DEL_MDC        = 0x00cf015,
-        LCFG_SEC_FLAVOR     = 0x00ce016,
+        LCFG_SPTLRPC_CONF   = 0x00cf016,
 };
 
 struct lustre_cfg_bufs {
@@ -256,9 +256,8 @@ static inline int lustre_cfg_sanity_check(void *buf, int len)
         RETURN(0);
 }
 
-/* default value for nllu/nllg for llite */
-#define NOBODY_UID      99
-#define NOBODY_GID      99
+#include <lustre/lustre_user.h>
+
 #define INVALID_UID     (-1)
 
 #endif // _LUSTRE_CFG_H
index fd8c664..98ede40 100644 (file)
@@ -141,10 +141,6 @@ struct lustre_mount_data {
         int        lmd_exclude_count;
         char      *lmd_dev;           /* device name */
         char      *lmd_profile;       /* client only */
-        char      *lmd_sec_mdt;       /* sec from mdt (to ost/mdt) */
-        char      *lmd_sec_cli;       /* sec from client (to ost/mdt) */
-        uid_t      lmd_nllu;          /* non-lustre-local-user id */
-        gid_t      lmd_nllg;          /* non-lustre-local-group id */
         char      *lmd_opts;          /* lustre mount options (as opposed to 
                                          _device_ mount options) */
         __u32     *lmd_exclude;       /* array of OSTs to ignore */
diff --git a/lustre/include/lustre_eacl.h b/lustre/include/lustre_eacl.h
new file mode 100644 (file)
index 0000000..dddfde5
--- /dev/null
@@ -0,0 +1,80 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *   This file is part of Lustre, http://www.lustre.org
+ *
+ * MDS data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ */
+
+#ifndef _LUSTRE_EACL_H
+#define _LUSTRE_EACL_H
+
+#ifdef CONFIG_FS_POSIX_ACL
+
+# ifdef HAVE_XATTR_ACL
+#  include <linux/xattr_acl.h>
+# endif /* HAVE_XATTR_ACL */
+# ifdef HAVE_LINUX_POSIX_ACL_XATTR_H
+#  include <linux/posix_acl_xattr.h>
+# endif /* HAVE_LINUX_POSIX_ACL_XATTR_H */
+
+#include <lustre_idmap.h>
+#include <md_object.h>
+#include <lu_object.h>
+
+typedef struct {
+        __u16                   e_tag;
+        __u16                   e_perm;
+        __u32                   e_id;
+        __u32                   e_stat;
+} ext_acl_xattr_entry;
+
+typedef struct {
+        __u32                   a_count;
+        ext_acl_xattr_entry     a_entries[0];
+} ext_acl_xattr_header;
+
+#define CFS_ACL_XATTR_SIZE(count, prefix) \
+        (sizeof(prefix ## _header) + (count) * sizeof(prefix ## _entry))
+
+#define CFS_ACL_XATTR_COUNT(size, prefix) \
+        (((size) - sizeof(prefix ## _header)) / sizeof(prefix ## _entry))
+
+extern int lustre_posix_acl_permission(struct md_ucred *mu, struct lu_attr *la,
+                                       int want, posix_acl_xattr_entry *entry,
+                                       int count);
+extern int lustre_posix_acl_chmod_masq(posix_acl_xattr_entry *entry,
+                                       __u32 mode, int count);
+extern int lustre_posix_acl_create_masq(posix_acl_xattr_entry *entry,
+                                        __u32 *pmode, int count);
+
+extern ext_acl_xattr_header *
+lustre_posix_acl_xattr_2ext(posix_acl_xattr_header *header, int size);
+extern int
+lustre_posix_acl_xattr_filter(posix_acl_xattr_header *header, int size,
+                              posix_acl_xattr_header **out);
+extern int
+lustre_posix_acl_xattr_id2client(struct md_ucred *mu,
+                                 struct lustre_idmap_table *t,
+                                 posix_acl_xattr_header *header,
+                                 int size, int flags);
+extern void
+lustre_posix_acl_xattr_free(posix_acl_xattr_header *header, int size);
+extern int
+lustre_ext_acl_xattr_id2server(struct md_ucred *mu,
+                               struct lustre_idmap_table *t,
+                               ext_acl_xattr_header *header);
+extern void
+lustre_ext_acl_xattr_free(ext_acl_xattr_header *header);
+extern int
+lustre_acl_xattr_merge2posix(posix_acl_xattr_header *posix_header, int size,
+                             ext_acl_xattr_header *ext_header,
+                             posix_acl_xattr_header **out);
+extern ext_acl_xattr_header *
+lustre_acl_xattr_merge2ext(posix_acl_xattr_header *posix_header, int size,
+                           ext_acl_xattr_header *ext_header);
+
+#endif /* CONFIG_FS_POSIX_ACL */
+
+#endif
index 047c98c..c87468b 100644 (file)
@@ -23,9 +23,8 @@ struct mds_export_data {
         loff_t                  med_lr_off;
         int                     med_lr_idx;
         unsigned int            med_rmtclient:1; /* remote client? */
-        __u32                   med_nllu;
-        __u32                   med_nllg;
-        struct mds_idmap_table *med_idmap;
+        struct semaphore           med_idmap_sem;
+        struct lustre_idmap_table *med_idmap;
 };
 
 struct mdt_export_data {
@@ -37,9 +36,8 @@ struct mdt_export_data {
         loff_t                  med_lr_off;
         int                     med_lr_idx;
         unsigned int            med_rmtclient:1; /* remote client? */
-        __u32                   med_nllu;
-        __u32                   med_nllg;
-        struct mdt_idmap_table *med_idmap;
+        struct semaphore           med_idmap_sem;
+        struct lustre_idmap_table *med_idmap;
 };
 
 struct osc_creator {
@@ -111,7 +109,15 @@ struct obd_export {
                                   exp_req_replay_needed:1,
                                   exp_lock_replay_needed:1,
                                   exp_need_sync:1,
+                                  exp_flvr_changed:1,
+                                  exp_flvr_adapt:1,
                                   exp_libclient:1; /* liblustre client? */
+        /* also protected by exp_lock */
+        enum lustre_sec_part      exp_sp_peer;
+        struct sptlrpc_flavor     exp_flvr;             /* current */
+        struct sptlrpc_flavor     exp_flvr_old[2];      /* about-to-expire */
+        cfs_time_t                exp_flvr_expire[2];   /* seconds */
+
         union {
                 struct mds_export_data    eu_mds_data;
                 struct mdt_export_data    eu_mdt_data;
diff --git a/lustre/include/lustre_idmap.h b/lustre/include/lustre_idmap.h
new file mode 100644 (file)
index 0000000..fa1a6cc
--- /dev/null
@@ -0,0 +1,63 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *   This file is part of Lustre, http://www.lustre.org
+ *
+ * MDS data structures.
+ * See also lustre_idl.h for wire formats of requests.
+ */
+
+#ifndef _LUSTRE_IDMAP_H
+#define _LUSTRE_IDMAP_H
+
+#include <md_object.h>
+
+#define CFS_NGROUPS_PER_BLOCK   ((int)(CFS_PAGE_SIZE / sizeof(gid_t)))
+
+#define CFS_GROUP_AT(gi, i) \
+        ((gi)->blocks[(i) / CFS_NGROUPS_PER_BLOCK][(i) % CFS_NGROUPS_PER_BLOCK])
+
+enum {
+        CFS_IC_NOTHING     = 0,    /* convert nothing */
+        CFS_IC_ALL         = 1,    /* convert all items */
+        CFS_IC_MAPPED      = 2,    /* convert mapped uid/gid */
+        CFS_IC_UNMAPPED    = 3     /* convert unmapped uid/gid */
+};
+
+#define  CFS_IDMAP_NOTFOUND     (-1)
+
+#define CFS_IDMAP_HASHSIZE      32
+
+enum lustre_idmap_idx {
+        RMT_UIDMAP_IDX,
+        LCL_UIDMAP_IDX,
+        RMT_GIDMAP_IDX,
+        LCL_GIDMAP_IDX,
+        CFS_IDMAP_N_HASHES
+};
+
+struct lustre_idmap_table {
+        spinlock_t       lit_lock;
+        struct list_head lit_idmaps[CFS_IDMAP_N_HASHES][CFS_IDMAP_HASHSIZE];
+};
+
+extern void lustre_groups_from_list(struct group_info *ginfo, gid_t *glist);
+extern void lustre_groups_sort(struct group_info *group_info);
+extern int lustre_in_group_p(struct md_ucred *mu, gid_t grp);
+
+extern int lustre_idmap_add(struct lustre_idmap_table *t,
+                            uid_t ruid, uid_t luid,
+                            gid_t rgid, gid_t lgid);
+extern int lustre_idmap_del(struct lustre_idmap_table *t,
+                            uid_t ruid, uid_t luid,
+                            gid_t rgid, gid_t lgid);
+extern int lustre_idmap_lookup_uid(struct md_ucred *mu,
+                                   struct lustre_idmap_table *t,
+                                   int reverse, uid_t uid);
+extern int lustre_idmap_lookup_gid(struct md_ucred *mu,
+                                   struct lustre_idmap_table *t,
+                                   int reverse, gid_t gid);
+extern struct lustre_idmap_table *lustre_idmap_init(void);
+extern void lustre_idmap_fini(struct lustre_idmap_table *t);
+
+#endif
index 5dee54a..7a5c761 100644 (file)
@@ -66,6 +66,8 @@ struct obd_import {
 
         struct obd_device        *imp_obd;
         struct ptlrpc_sec        *imp_sec;
+        struct semaphore          imp_sec_mutex;
+        cfs_time_t                imp_sec_expire;
         cfs_waitq_t               imp_recovery_waitq;
 
         atomic_t                  imp_inflight;
index f025ead..598754b 100644 (file)
 # ifdef CONFIG_FS_POSIX_ACL
 #  ifdef HAVE_XATTR_ACL
 #   include <linux/xattr_acl.h>
-#  endif
+#  endif /*HAVE_XATTR_ACL */
 #  ifdef HAVE_LINUX_POSIX_ACL_XATTR_H
 #   include <linux/posix_acl_xattr.h>
-#  endif
-# endif
+#  endif /* HAVE_LINUX_POSIX_ACL_XATTR_H */
+# endif /* CONFIG_FS_POSIX_ACL */
 # ifndef HAVE_VFS_INTENT_PATCHES
 # include <linux/lustre_intent.h>
-# endif
-#endif
+# endif /* HAVE_VFS_INTENT_PATCHES */
+#endif /* __KERNEL__ */
 #include <lustre_handles.h>
 #include <libcfs/kp30.h>
 #include <lustre/lustre_idl.h>
index 861a077..06ed6b1 100644 (file)
@@ -40,24 +40,6 @@ struct com_thread_info {
         struct req_capsule cti_pill;
 };
 
-/* id map */
-#define MDT_IDMAP_HASHSIZE      (32)
-#define MDT_IDMAP_HASHFUNC(id)  ((id) & (MDT_IDMAP_HASHSIZE - 1))
-
-enum mdt_idmap_idx {
-        RMT_UIDMAP_IDX,
-        LCL_UIDMAP_IDX,
-        RMT_GIDMAP_IDX,
-        LCL_GIDMAP_IDX,
-        MDT_IDMAP_N_HASHES
-};
-
-struct mdt_idmap_table {
-        spinlock_t       mit_lock;
-        struct list_head mit_idmaps[MDT_IDMAP_N_HASHES]
-                                   [MDT_IDMAP_HASHSIZE];
-};
-
 enum {
         ESERIOUS = 0x0001000
 };
index 0635010..ca69a55 100644 (file)
@@ -337,9 +337,12 @@ struct ptlrpc_request {
         struct ptlrpc_cli_ctx   *rq_cli_ctx;     /* client's half ctx */
         struct ptlrpc_svc_ctx   *rq_svc_ctx;     /* server's half ctx */
         struct list_head         rq_ctx_chain;   /* link to waited ctx */
-        ptlrpc_sec_flavor_t      rq_sec_flavor;  /* client & server */
-                                 /* client security flags */
-        unsigned long            rq_ctx_init:1,      /* context initiation */
+
+        struct sptlrpc_flavor    rq_flvr;        /* client & server */
+        enum lustre_sec_part     rq_sp_from;
+
+        unsigned long            /* client/server security flags */
+                                 rq_ctx_init:1,      /* context initiation */
                                  rq_ctx_fini:1,      /* context destroy */
                                  rq_bulk_read:1,     /* request bulk read */
                                  rq_bulk_write:1,    /* request bulk write */
@@ -348,6 +351,9 @@ struct ptlrpc_request {
                                  rq_auth_remote:1,   /* authed as remote user */
                                  rq_auth_usr_root:1, /* authed as root */
                                  rq_auth_usr_mdt:1,  /* authed as mdt */
+                                 /* security tfm flags */
+                                 rq_pack_udesc:1,
+                                 rq_pack_bulk:1,
                                  /* doesn't expect reply FIXME */
                                  rq_no_reply:1;
 
index 8acf23e..afcc851 100644 (file)
@@ -60,9 +60,9 @@ int do_lcfg(char *cfgname, lnet_nid_t nid, int cmd,
 #define PARAM_MDC                  "mdc."
 #define PARAM_LLITE                "llite."
 #define PARAM_LOV                  "lov."
+#define PARAM_SRPC                 "srpc."
+#define PARAM_SRPC_FLVR            "srpc.flavor."
+#define PARAM_SRPC_UDESC           "srpc.udesc.cli2mdt"
 #define PARAM_SEC                  "security."
-#define PARAM_SEC_RPC              PARAM_SEC"rpc."
-#define PARAM_SEC_RPC_MDT          PARAM_SEC_RPC"mdt="
-#define PARAM_SEC_RPC_CLI          PARAM_SEC_RPC"cli="
 
 #endif /* _LUSTRE_PARAM_H */
index e9fe854..6455858 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
  * vim:expandtab:shiftwidth=8:tabstop=8:
  *
- * Copyright (C) 2004-2006 Cluster File Systems, Inc.
+ * Copyright (C) 2004-2007 Cluster File Systems, Inc.
  *
  *   This file is part of Lustre, http://www.lustre.org.
  *
@@ -32,6 +32,7 @@ struct ptlrpc_request;
 struct ptlrpc_reply_state;
 struct ptlrpc_bulk_desc;
 struct brw_page;
+struct seq_file;
 
 /*
  * forward declaration
@@ -51,7 +52,6 @@ enum sptlrpc_policy {
         SPTLRPC_POLICY_NULL             = 0,
         SPTLRPC_POLICY_PLAIN            = 1,
         SPTLRPC_POLICY_GSS              = 2,
-        SPTLRPC_POLICY_GSS_PIPEFS       = 3,
         SPTLRPC_POLICY_MAX,
 };
 
@@ -80,119 +80,169 @@ enum sptlrpc_service_type {
 };
 
 /*
- * flavor compose/extract
+ * rpc flavor compose/extract, represented as 16 bits
+ *
+ * 4b (reserved) | 4b (svc) | 4b (mech)  | 4b (policy)
  */
+#define RPC_FLVR_POLICY_OFFSET        (0)
+#define RPC_FLVR_MECH_OFFSET          (4)
+#define RPC_FLVR_SVC_OFFSET           (8)
 
-typedef __u32 ptlrpc_sec_flavor_t;
+#define MAKE_RPC_FLVR(policy, mech, svc)                                \
+        (((__u16)(policy) << RPC_FLVR_POLICY_OFFSET) |                  \
+         ((__u16)(mech) << RPC_FLVR_MECH_OFFSET) |                      \
+         ((__u16)(svc) << RPC_FLVR_SVC_OFFSET))
 
-/*
- *  8b (reserved)            | 8b (flags)
- *  4b (reserved) | 4b (svc) | 4b (mech)  | 4b (policy)
- */
-#define SEC_FLAVOR_POLICY_OFFSET        (0)
-#define SEC_FLAVOR_MECH_OFFSET          (4)
-#define SEC_FLAVOR_SVC_OFFSET           (8)
-#define SEC_FLAVOR_RESERVE1_OFFSET      (12)
-#define SEC_FLAVOR_FLAGS_OFFSET         (16)
-
-#define SEC_MAKE_RPC_FLAVOR(policy, mech, svc)                          \
-        (((__u32)(policy) << SEC_FLAVOR_POLICY_OFFSET) |                \
-         ((__u32)(mech) << SEC_FLAVOR_MECH_OFFSET) |                    \
-         ((__u32)(svc) << SEC_FLAVOR_SVC_OFFSET))
-
-#define SEC_MAKE_RPC_SUBFLAVOR(mech, svc)                               \
-        ((__u32)(mech) |                                                \
-         ((__u32)(svc) <<                                               \
-                (SEC_FLAVOR_SVC_OFFSET - SEC_FLAVOR_MECH_OFFSET)))
-
-#define SEC_FLAVOR_SUB(flavor)                                          \
-        ((((__u32)(flavor)) >> SEC_FLAVOR_MECH_OFFSET) & 0xFF)
-
-#define SEC_FLAVOR_POLICY(flavor)                                       \
-        ((((__u32)(flavor)) >> SEC_FLAVOR_POLICY_OFFSET) & 0xF)
-#define SEC_FLAVOR_MECH(flavor)                                         \
-        ((((__u32)(flavor)) >> SEC_FLAVOR_MECH_OFFSET) & 0xF)
-#define SEC_FLAVOR_SVC(flavor)                                          \
-        ((((__u32)(flavor)) >> SEC_FLAVOR_SVC_OFFSET) & 0xF)
-
-#define SEC_FLAVOR_RPC(f)                                               \
-        (((__u32) (f)) & ((1 << SEC_FLAVOR_RESERVE1_OFFSET) - 1))
+#define MAKE_RPC_SUBFLVR(mech, svc)                                     \
+        ((__u16)(mech) |                                                \
+         ((__u16)(svc) << (RPC_FLVR_SVC_OFFSET - RPC_FLVR_MECH_OFFSET)))
+
+#define RPC_FLVR_SUB(flavor)                                            \
+        ((((__u16)(flavor)) >> RPC_FLVR_MECH_OFFSET) & 0xFF)
+
+#define RPC_FLVR_POLICY(flavor)                                         \
+        ((((__u16)(flavor)) >> RPC_FLVR_POLICY_OFFSET) & 0xF)
+#define RPC_FLVR_MECH(flavor)                                           \
+        ((((__u16)(flavor)) >> RPC_FLVR_MECH_OFFSET) & 0xF)
+#define RPC_FLVR_SVC(flavor)                                            \
+        ((((__u16)(flavor)) >> RPC_FLVR_SVC_OFFSET) & 0xF)
 
 /*
  * gss subflavors
  */
-#define SPTLRPC_SUBFLVR_KRB5N                                   \
-        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_MECH_GSS_KRB5,           \
-                               SPTLRPC_SVC_NULL)
-#define SPTLRPC_SUBFLVR_KRB5A                                   \
-        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_MECH_GSS_KRB5,           \
-                               SPTLRPC_SVC_AUTH)
-#define SPTLRPC_SUBFLVR_KRB5I                                   \
-        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_MECH_GSS_KRB5,           \
-                               SPTLRPC_SVC_INTG)
-#define SPTLRPC_SUBFLVR_KRB5P                                   \
-        SEC_MAKE_RPC_SUBFLAVOR(SPTLRPC_MECH_GSS_KRB5,           \
-                               SPTLRPC_SVC_PRIV)
+#define SPTLRPC_SUBFLVR_KRB5N                                           \
+        MAKE_RPC_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_NULL)
+#define SPTLRPC_SUBFLVR_KRB5A                                           \
+        MAKE_RPC_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_AUTH)
+#define SPTLRPC_SUBFLVR_KRB5I                                           \
+        MAKE_RPC_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_INTG)
+#define SPTLRPC_SUBFLVR_KRB5P                                           \
+        MAKE_RPC_SUBFLVR(SPTLRPC_MECH_GSS_KRB5, SPTLRPC_SVC_PRIV)
 
 /*
  * "end user" flavors
  */
-#define SPTLRPC_FLVR_NULL                                       \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_NULL,                \
-                            SPTLRPC_MECH_NULL,                  \
-                            SPTLRPC_SVC_NULL)
-#define SPTLRPC_FLVR_PLAIN                                      \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_PLAIN,               \
-                            SPTLRPC_MECH_PLAIN,                 \
-                            SPTLRPC_SVC_NULL)
-#define SPTLRPC_FLVR_KRB5N                                      \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_MECH_GSS_KRB5,              \
-                            SPTLRPC_SVC_NULL)
-#define SPTLRPC_FLVR_KRB5A                                      \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_MECH_GSS_KRB5,              \
-                            SPTLRPC_SVC_AUTH)
-#define SPTLRPC_FLVR_KRB5I                                      \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_MECH_GSS_KRB5,              \
-                            SPTLRPC_SVC_INTG)
-#define SPTLRPC_FLVR_KRB5P                                      \
-        SEC_MAKE_RPC_FLAVOR(SPTLRPC_POLICY_GSS,                 \
-                            SPTLRPC_MECH_GSS_KRB5,              \
-                            SPTLRPC_SVC_PRIV)
-
-#define SPTLRPC_FLVR_INVALID            (-1)
+#define SPTLRPC_FLVR_NULL                               \
+        MAKE_RPC_FLVR(SPTLRPC_POLICY_NULL,              \
+                      SPTLRPC_MECH_NULL,                \
+                      SPTLRPC_SVC_NULL)
+#define SPTLRPC_FLVR_PLAIN                              \
+        MAKE_RPC_FLVR(SPTLRPC_POLICY_PLAIN,             \
+                      SPTLRPC_MECH_PLAIN,               \
+                      SPTLRPC_SVC_NULL)
+#define SPTLRPC_FLVR_KRB5N                              \
+        MAKE_RPC_FLVR(SPTLRPC_POLICY_GSS,               \
+                      SPTLRPC_MECH_GSS_KRB5,            \
+                      SPTLRPC_SVC_NULL)
+#define SPTLRPC_FLVR_KRB5A                              \
+        MAKE_RPC_FLVR(SPTLRPC_POLICY_GSS,               \
+                      SPTLRPC_MECH_GSS_KRB5,            \
+                      SPTLRPC_SVC_AUTH)
+#define SPTLRPC_FLVR_KRB5I                              \
+        MAKE_RPC_FLVR(SPTLRPC_POLICY_GSS,               \
+                      SPTLRPC_MECH_GSS_KRB5,            \
+                      SPTLRPC_SVC_INTG)
+#define SPTLRPC_FLVR_KRB5P                              \
+        MAKE_RPC_FLVR(SPTLRPC_POLICY_GSS,               \
+                      SPTLRPC_MECH_GSS_KRB5,            \
+                      SPTLRPC_SVC_PRIV)
+
+#define SPTLRPC_FLVR_INVALID            ((__u16) -1)
 
 #define SPTLRPC_FLVR_DEFAULT            SPTLRPC_FLVR_NULL
 
 /*
- * flavor flags (maximum 8 flags)
+ * 32 bits wire flavor (msg->lm_secflvr), lower 12 bits is the rpc flavor,
+ * higher 20 bits is not defined right now.
  */
-#define SEC_FLAVOR_FL_BULK              (1 << (0 + SEC_FLAVOR_FLAGS_OFFSET))
-#define SEC_FLAVOR_FL_USER              (1 << (1 + SEC_FLAVOR_FLAGS_OFFSET))
+#define WIRE_FLVR_RPC(wflvr)            (((__u16) (wflvr)) & 0x0FFF)
+
+static inline void rpc_flvr_set_svc(__u16 *flvr, __u16 svc)
+{
+        LASSERT(svc < SPTLRPC_SVC_MAX);
+        *flvr = MAKE_RPC_FLVR(RPC_FLVR_POLICY(*flvr),
+                              RPC_FLVR_MECH(*flvr),
+                              svc);
+}
+
 
-#define SEC_FLAVOR_HAS_BULK(flavor)             \
-        (((flavor) & SEC_FLAVOR_FL_BULK) != 0)
-#define SEC_FLAVOR_HAS_USER(flavor)             \
-        (((flavor) & SEC_FLAVOR_FL_USER) != 0)
+struct sptlrpc_flavor {
+        __u16   sf_rpc;         /* rpc flavor */
+        __u8    sf_bulk_priv;   /* bulk encrypt alg */
+        __u8    sf_bulk_csum;   /* bulk checksum alg */
+        __u32   sf_flags;       /* general flags */
+};
 
+enum lustre_sec_part {
+        LUSTRE_SP_CLI           = 0,
+        LUSTRE_SP_MDT,
+        LUSTRE_SP_OST,
+        LUSTRE_SP_MGS,
+        LUSTRE_SP_ANY           = 0xFF
+};
 
-struct sec_flavor_config {
-        __u32   sfc_rpc_flavor; /* main rpc flavor */
-        __u32   sfc_bulk_priv;  /* bulk encryption algorithm */
-        __u32   sfc_bulk_csum;  /* bulk checksum algorithm */
-        __u32   sfc_flags;      /* extra flags */
+struct sptlrpc_rule {
+        __u32                   sr_netid;   /* LNET network ID */
+        __u8                    sr_from;    /* sec_part */
+        __u8                    sr_to;      /* sec_part */
+        __u16                   sr_padding;
+        struct sptlrpc_flavor   sr_flvr;
 };
 
-enum lustre_part {
-        LUSTRE_CLI      = 0,
-        LUSTRE_MDT,
-        LUSTRE_OST,
-        LUSTRE_MGC,
-        LUSTRE_MGS,
+struct sptlrpc_rule_set {
+        int                     srs_nslot;
+        int                     srs_nrule;
+        struct sptlrpc_rule    *srs_rules;
+};
+
+#define SPTLRPC_CONF_LOG_MAX    (64)
+
+struct sptlrpc_conf_log {
+        __u32               scl_max;            /* maximum rules # */
+        __u32               scl_nrule;          /* rules # */
+        __u8                scl_part;           /* which part am i */
+        __u8                scl_pad0;
+        __u16               scl_pad1;
+        __u32               scl_pad2;
+        struct sptlrpc_rule scl_rules[SPTLRPC_CONF_LOG_MAX];
 };
 
+static inline void sptlrpc_rule_set_init(struct sptlrpc_rule_set *set)
+{
+        memset(set, 0, sizeof(*set));
+}
+
+void sptlrpc_rule_set_free(struct sptlrpc_rule_set *set);
+int  sptlrpc_rule_set_expand(struct sptlrpc_rule_set *set, int expand);
+int  sptlrpc_rule_set_merge(struct sptlrpc_rule_set *set,
+                            struct sptlrpc_rule *rule,
+                            int expand);
+int sptlrpc_rule_set_from_log(struct sptlrpc_rule_set *rset,
+                              struct sptlrpc_conf_log *log);
+void sptlrpc_rule_set_choose(struct sptlrpc_rule_set *rset,
+                             enum lustre_sec_part from,
+                             lnet_nid_t nid,
+                             struct sptlrpc_flavor *flavor);
+void sptlrpc_rule_set_dump(struct sptlrpc_rule_set *set);
+
+struct sptlrpc_conf_log *sptlrpc_conf_log_alloc(void);
+void sptlrpc_conf_log_free(struct sptlrpc_conf_log *log);
+int sptlrpc_conf_log_populate(struct sptlrpc_rule_set *gen,
+                              struct sptlrpc_rule_set *tgt,
+                              enum lustre_sec_part from,
+                              enum lustre_sec_part to,
+                              unsigned int fl_udesc,
+                              struct sptlrpc_conf_log *log);
+struct sptlrpc_conf_log *sptlrpc_conf_log_extract(struct lustre_cfg *lcfg);
+void sptlrpc_conf_log_cleanup(struct sptlrpc_conf_log *log);
+void sptlrpc_conf_log_dump(struct sptlrpc_conf_log *log);
+
+const char *sptlrpc_part2name(enum lustre_sec_part part);
+enum lustre_sec_part sptlrpc_target_sec_part(struct obd_device *obd);
+
+int sptlrpc_cliobd_process_config(struct obd_device *obd,
+                                  struct lustre_cfg *lcfg);
+
 /* The maximum length of security payload. 1024 is enough for Kerberos 5,
  * and should be enough for other future mechanisms but not sure.
  * Only used by pre-allocated request/reply pool.
@@ -275,11 +325,15 @@ struct ptlrpc_sec_cops {
          */
         struct ptlrpc_sec *     (*create_sec)  (struct obd_import *imp,
                                                 struct ptlrpc_svc_ctx *ctx,
-                                                __u32 flavor,
-                                                unsigned long flags);
+                                                struct sptlrpc_flavor *flavor);
         void                    (*destroy_sec) (struct ptlrpc_sec *sec);
 
         /*
+         * notify to-be-dead
+         */
+        void                    (*kill_sec)    (struct ptlrpc_sec *sec);
+
+        /*
          * context
          */
         struct ptlrpc_cli_ctx * (*lookup_ctx)  (struct ptlrpc_sec *sec,
@@ -324,7 +378,7 @@ struct ptlrpc_sec_cops {
          * misc
          */
         int                     (*display)     (struct ptlrpc_sec *sec,
-                                                char *buf, int buflen);
+                                                struct seq_file *seq);
 };
 
 struct ptlrpc_sec_sops {
@@ -350,24 +404,27 @@ struct ptlrpc_sec_sops {
 struct ptlrpc_sec_policy {
         struct module                  *sp_owner;
         char                           *sp_name;
-        __u32                           sp_policy; /* policy number */
+        __u16                           sp_policy; /* policy number */
         struct ptlrpc_sec_cops         *sp_cops;   /* client ops */
         struct ptlrpc_sec_sops         *sp_sops;   /* server ops */
 };
 
 #define PTLRPC_SEC_FL_REVERSE           0x0001 /* reverse sec */
 #define PTLRPC_SEC_FL_ROOTONLY          0x0002 /* treat everyone as root */
-#define PTLRPC_SEC_FL_PAG               0x0004 /* PAG mode */
+#define PTLRPC_SEC_FL_UDESC             0x0004 /* ship udesc */
 #define PTLRPC_SEC_FL_BULK              0x0008 /* intensive bulk i/o expected */
+#define PTLRPC_SEC_FL_PAG               0x0010 /* PAG mode */
 
 struct ptlrpc_sec {
         struct ptlrpc_sec_policy       *ps_policy;
         atomic_t                        ps_refcount;
-        __u32                           ps_flavor;      /* rpc flavor */
-        unsigned long                   ps_flags;       /* PTLRPC_SEC_FL_XX */
+        atomic_t                        ps_nctx;        /* statistic only */
+        int                             ps_id;          /* unique identifier */
+        struct sptlrpc_flavor           ps_flvr;        /* flavor */
+        enum lustre_sec_part            ps_part;
+        unsigned int                    ps_dying:1;
         struct obd_import              *ps_import;      /* owning import */
         spinlock_t                      ps_lock;        /* protect ccache */
-        atomic_t                        ps_busy;        /* busy count */
         /*
          * garbage collection
          */
@@ -378,12 +435,12 @@ struct ptlrpc_sec {
 
 static inline int sec_is_reverse(struct ptlrpc_sec *sec)
 {
-        return (sec->ps_flags & PTLRPC_SEC_FL_REVERSE);
+        return (sec->ps_flvr.sf_flags & PTLRPC_SEC_FL_REVERSE);
 }
 
 static inline int sec_is_rootonly(struct ptlrpc_sec *sec)
 {
-        return (sec->ps_flags & PTLRPC_SEC_FL_ROOTONLY);
+        return (sec->ps_flvr.sf_flags & PTLRPC_SEC_FL_ROOTONLY);
 }
 
 
@@ -429,16 +486,16 @@ enum bulk_encrypt_alg {
 
 struct ptlrpc_bulk_sec_desc {
         __u32           bsd_version;
-        __u32           bsd_pad;
-        __u32           bsd_csum_alg;   /* checksum algorithm */
-        __u32           bsd_priv_alg;   /* encrypt algorithm */
+        __u8            bsd_csum_alg;   /* checksum algorithm */
+        __u8            bsd_priv_alg;   /* encrypt algorithm */
+        __u16           bsd_pad;
         __u8            bsd_iv[16];     /* encrypt iv */
         __u8            bsd_csum[0];
 };
 
-const char * sptlrpc_bulk_csum_alg2name(__u32 csum_alg);
-const char * sptlrpc_bulk_priv_alg2name(__u32 priv_alg);
-__u32 sptlrpc_bulk_priv_alg2flags(__u32 priv_alg);
+const char * sptlrpc_bulk_csum_alg2name(__u8 csum_alg);
+const char * sptlrpc_bulk_priv_alg2name(__u8 priv_alg);
+__u32 sptlrpc_bulk_priv_alg2flags(__u8 priv_alg);
 
 /*
  * lprocfs
@@ -474,8 +531,9 @@ void _sptlrpc_enlarge_msg_inplace(struct lustre_msg *msg,
 int sptlrpc_register_policy(struct ptlrpc_sec_policy *policy);
 int sptlrpc_unregister_policy(struct ptlrpc_sec_policy *policy);
 
-__u32 sptlrpc_name2flavor(const char *name);
-char *sptlrpc_flavor2name(__u32 flavor);
+__u16 sptlrpc_name2rpcflavor(const char *name);
+const char *sptlrpc_rpcflavor2name(__u16 flavor);
+int sptlrpc_flavor2name(struct sptlrpc_flavor *sf, char *buf, int bufsize);
 
 static inline
 struct ptlrpc_sec_policy *sptlrpc_policy_get(struct ptlrpc_sec_policy *policy)
@@ -536,8 +594,15 @@ int cli_ctx_is_eternal(struct ptlrpc_cli_ctx *ctx)
 }
 
 /*
+ * sec get/put
+ */
+struct ptlrpc_sec *sptlrpc_sec_get(struct ptlrpc_sec *sec);
+void sptlrpc_sec_put(struct ptlrpc_sec *sec);
+
+/*
  * internal apis which only used by policy impelentation
  */
+int  sptlrpc_get_next_secid(void);
 void sptlrpc_sec_destroy(struct ptlrpc_sec *sec);
 
 /*
@@ -565,10 +630,14 @@ void sptlrpc_request_out_callback(struct ptlrpc_request *req);
 /*
  * exported higher interface of import & request
  */
-int sptlrpc_import_get_sec(struct obd_import *imp, struct ptlrpc_svc_ctx *svc_ctx,
-                           __u32 flavor, unsigned long flags);
-void sptlrpc_import_put_sec(struct obd_import *imp);
+int sptlrpc_import_sec_adapt(struct obd_import *imp,
+                             struct ptlrpc_svc_ctx *ctx,
+                             __u16 rpc_flavor);
+struct ptlrpc_sec *sptlrpc_import_sec_ref(struct obd_import *imp);
+void sptlrpc_import_sec_put(struct obd_import *imp);
+
 int  sptlrpc_import_check_ctx(struct obd_import *imp);
+void sptlrpc_import_inval_all_ctx(struct obd_import *imp);
 void sptlrpc_import_flush_root_ctx(struct obd_import *imp);
 void sptlrpc_import_flush_my_ctx(struct obd_import *imp);
 void sptlrpc_import_flush_all_ctx(struct obd_import *imp);
@@ -578,8 +647,7 @@ int  sptlrpc_req_refresh_ctx(struct ptlrpc_request *req, long timeout);
 int  sptlrpc_req_replace_dead_ctx(struct ptlrpc_request *req);
 void sptlrpc_req_set_flavor(struct ptlrpc_request *req, int opcode);
 
-int sptlrpc_parse_flavor(enum lustre_part from, enum lustre_part to,
-                         char *str, struct sec_flavor_config *conf);
+int sptlrpc_parse_rule(char *param, struct sptlrpc_rule *rule);
 
 /* gc */
 void sptlrpc_gc_add_sec(struct ptlrpc_sec *sec);
@@ -588,8 +656,7 @@ void sptlrpc_gc_add_ctx(struct ptlrpc_cli_ctx *ctx);
 
 /* misc */
 const char * sec2target_str(struct ptlrpc_sec *sec);
-int sptlrpc_lprocfs_rd(char *page, char **start, off_t off, int count,
-                       int *eof, void *data);
+int sptlrpc_lprocfs_cliobd_attach(struct obd_device *dev);
 
 /*
  * server side
@@ -600,8 +667,6 @@ enum secsvc_accept_res {
         SECSVC_DROP,
 };
 
-int sptlrpc_target_export_check(struct obd_export *exp,
-                                struct ptlrpc_request *req);
 int  sptlrpc_svc_unwrap_request(struct ptlrpc_request *req);
 int  sptlrpc_svc_alloc_rs(struct ptlrpc_request *req, int msglen);
 int  sptlrpc_svc_wrap_reply(struct ptlrpc_request *req);
@@ -610,6 +675,11 @@ void sptlrpc_svc_ctx_addref(struct ptlrpc_request *req);
 void sptlrpc_svc_ctx_decref(struct ptlrpc_request *req);
 void sptlrpc_svc_ctx_invalidate(struct ptlrpc_request *req);
 
+int  sptlrpc_target_export_check(struct obd_export *exp,
+                                 struct ptlrpc_request *req);
+void sptlrpc_target_update_exp_flavor(struct obd_device *obd,
+                                      struct sptlrpc_rule_set *rset);
+
 /*
  * reverse context
  */
@@ -647,7 +717,7 @@ int sptlrpc_pack_user_desc(struct lustre_msg *msg, int offset);
 int sptlrpc_unpack_user_desc(struct lustre_msg *msg, int offset);
 
 /* bulk helpers (internal use only by policies) */
-int bulk_sec_desc_size(__u32 csum_alg, int request, int read);
+int bulk_sec_desc_size(__u8 csum_alg, int request, int read);
 int bulk_sec_desc_unpack(struct lustre_msg *msg, int offset);
 
 int bulk_csum_cli_request(struct ptlrpc_bulk_desc *desc, int read,
index 0cba634..ecfdab8 100644 (file)
 
 struct upcall_cache_entry;
 
-struct mdt_setxid_perm {
+struct md_perm {
         lnet_nid_t      mp_nid;
         __u32           mp_perm;
 };
 
-struct mdt_identity {
+struct md_identity {
         struct upcall_cache_entry *mi_uc_entry;
         uid_t                      mi_uid;
         gid_t                      mi_gid;
         struct group_info         *mi_ginfo;
         int                        mi_nperms;
-        struct mdt_setxid_perm    *mi_perms;
-};
-
-struct rmtacl_upcall_data {
-        uid_t                      aud_uid;
-        gid_t                      aud_gid;
-        char                      *aud_cmd;
-};
-
-struct mdt_rmtacl {
-        uid_t                      ra_uid;
-        gid_t                      ra_gid;
-        __u32                      ra_handle;
-        char                      *ra_cmd;
-        char                      *ra_buf;
+        struct md_perm            *mi_perms;
 };
 
 struct upcall_cache_entry {
         struct list_head        ue_hash;
         __u64                   ue_key;
-//        __u64                   ue_primary;
-//        struct group_info      *ue_group_info;
         atomic_t                ue_refcount;
         int                     ue_flags;
         cfs_waitq_t             ue_waitq;
         cfs_time_t              ue_acquire_expire;
         cfs_time_t              ue_expire;
         union {
-                struct mdt_identity     identity;
-                struct mdt_rmtacl       acl;
+                struct md_identity     identity;
         } u;
 };
 
index 42fbe90..432cf0d 100644 (file)
@@ -47,20 +47,15 @@ struct md_device_operations;
 struct md_object;
 
 
-typedef enum {
+enum {
         UCRED_INVALID   = -1,
         UCRED_INIT      = 0,
         UCRED_OLD       = 1,
-        UCRED_NEW       = 2,
-} ucred_t;
-
-#define SQUASH_NONE     0x00
-#define SQUASH_UID      0x01
-#define SQUASH_GID      0x02
+        UCRED_NEW       = 2
+};
 
 struct md_ucred {
-        ucred_t                 mu_valid;
-        __u32                   mu_squash;
+        __u32               mu_valid;
         __u32                   mu_o_uid;
         __u32                   mu_o_gid;
         __u32                   mu_o_fsuid;
@@ -73,7 +68,7 @@ struct md_ucred {
         __u32                   mu_cap;
         __u32                   mu_umask;
        struct group_info      *mu_ginfo;
-       struct mdt_identity    *mu_identity;
+       struct md_identity *mu_identity;
 };
 
 #define MD_CAPAINFO_MAX 5
index 8d6e9f1..1515bab 100644 (file)
@@ -370,6 +370,10 @@ struct filter_obd {
         int                      fo_fmd_max_num; /* per exp filter_mod_data */
         int                      fo_fmd_max_age; /* jiffies to fmd expiry */
 
+        /* sptlrpc stuff */
+        rwlock_t                 fo_sptlrpc_lock;
+        struct sptlrpc_rule_set  fo_sptlrpc_rset;
+
         /* capability related */
         unsigned int             fo_fl_oss_capa;
         struct list_head         fo_capa_keys;
@@ -399,7 +403,8 @@ struct client_obd {
         int                      cl_max_mds_cookiesize;
 
         /* security configuration */
-        struct sec_flavor_config cl_sec_conf;
+        struct sptlrpc_rule_set  cl_sptlrpc_rset;
+        enum lustre_sec_part     cl_sec_part;
 
         //struct llog_canceld_ctxt *cl_llcd; /* it's included by obd_llog_ctxt */
         void                    *cl_llcd_offset;
@@ -492,15 +497,6 @@ struct mgs_obd {
         cfs_proc_dir_entry_t            *mgs_proc_live;
 };
 
-/* hah, upper limit 64 should be enough */
-#define N_NOSQUASH_NIDS 64
-struct rootsquash_info {
-        uid_t           rsi_uid;
-        gid_t           rsi_gid;
-        int             rsi_n_nosquash_nids;
-        lnet_nid_t      rsi_nosquash_nids[N_NOSQUASH_NIDS];
-};
-
 struct mds_obd {
         /* NB this field MUST be first */
         struct obd_device_target         mds_obt;
@@ -556,10 +552,6 @@ struct mds_obd {
                                          mds_fl_synced:1;
 
         struct upcall_cache             *mds_identity_cache;
-        struct upcall_cache             *mds_rmtacl_cache;
-
-        /* root squash */
-        struct rootsquash_info          *mds_rootsquash_info;
 
         /* for capability keys update */
         struct lustre_capa_key          *mds_capa_keys;
@@ -1070,7 +1062,8 @@ struct obd_ops {
         int (*o_connect)(const struct lu_env *env,
                          struct lustre_handle *conn, struct obd_device *src,
                          struct obd_uuid *cluuid, struct obd_connect_data *ocd);
-        int (*o_reconnect)(struct obd_export *exp, struct obd_device *src,
+        int (*o_reconnect)(const struct lu_env *env,
+                           struct obd_export *exp, struct obd_device *src,
                            struct obd_uuid *cluuid,
                            struct obd_connect_data *ocd);
         int (*o_disconnect)(struct obd_export *exp);
@@ -1293,7 +1286,7 @@ struct md_ops {
                          struct ptlrpc_request **);
         int (*m_getattr_name)(struct obd_export *, const struct lu_fid *,
                               struct obd_capa *, const char *, int, obd_valid,
-                              int, struct ptlrpc_request **);
+                              int, __u32, struct ptlrpc_request **);
         int (*m_intent_lock)(struct obd_export *, struct md_op_data *,
                              void *, int, struct lookup_intent *, int,
                              struct ptlrpc_request **,
@@ -1320,7 +1313,7 @@ struct md_ops {
 
         int (*m_setxattr)(struct obd_export *, const struct lu_fid *,
                           struct obd_capa *, obd_valid, const char *,
-                          const char *, int, int, int,
+                          const char *, int, int, int, __u32,
                           struct ptlrpc_request **);
 
         int (*m_getxattr)(struct obd_export *, const struct lu_fid *,
@@ -1355,7 +1348,8 @@ struct md_ops {
                             renew_capa_cb_t cb);
 
         int (*m_get_remote_perm)(struct obd_export *, const struct lu_fid *,
-                                 struct obd_capa *, struct ptlrpc_request **);
+                                 struct obd_capa *, __u32,
+                                 struct ptlrpc_request **);
 
         /*
          * NOTE: If adding ops, add another LPROCFS_MD_OP_INIT() line to
index 3f111f9..94cd618 100644 (file)
@@ -814,7 +814,8 @@ static inline int obd_connect(const struct lu_env *env,
         RETURN(rc);
 }
 
-static inline int obd_reconnect(struct obd_export *exp,
+static inline int obd_reconnect(const struct lu_env *env,
+                                struct obd_export *exp,
                                 struct obd_device *obd,
                                 struct obd_uuid *cluuid,
                                 struct obd_connect_data *d)
@@ -831,7 +832,7 @@ static inline int obd_reconnect(struct obd_export *exp,
         OBD_CHECK_DT_OP(obd, reconnect, 0);
         OBD_COUNTER_INCREMENT(obd, reconnect);
 
-        rc = OBP(obd, reconnect)(exp, obd, cluuid, d);
+        rc = OBP(obd, reconnect)(env, exp, obd, cluuid, d);
         /* check that only subset is granted */
         LASSERT(ergo(d != NULL,
                      (d->ocd_connect_flags & ocf) == d->ocd_connect_flags));
@@ -1751,7 +1752,7 @@ static inline int md_enqueue(struct obd_export *exp,
 static inline int md_getattr_name(struct obd_export *exp,
                                   const struct lu_fid *fid, struct obd_capa *oc,
                                   const char *name, int namelen,
-                                  obd_valid valid, int ea_size,
+                                  obd_valid valid, int ea_size, __u32 suppgid,
                                   struct ptlrpc_request **request)
 {
         int rc;
@@ -1759,7 +1760,7 @@ static inline int md_getattr_name(struct obd_export *exp,
         EXP_CHECK_MD_OP(exp, getattr_name);
         EXP_MD_COUNTER_INCREMENT(exp, getattr_name);
         rc = MDP(exp->exp_obd, getattr_name)(exp, fid, oc, name, namelen,
-                                             valid, ea_size, request);
+                                             valid, ea_size, suppgid, request);
         RETURN(rc);
 }
 
@@ -1892,7 +1893,7 @@ static inline int md_setxattr(struct obd_export *exp,
                               const struct lu_fid *fid, struct obd_capa *oc,
                               obd_valid valid, const char *name,
                               const char *input, int input_size,
-                              int output_size, int flags,
+                              int output_size, int flags, __u32 suppgid,
                               struct ptlrpc_request **request)
 {
         ENTRY;
@@ -1900,7 +1901,7 @@ static inline int md_setxattr(struct obd_export *exp,
         EXP_MD_COUNTER_INCREMENT(exp, setxattr);
         RETURN(MDP(exp->exp_obd, setxattr)(exp, fid, oc, valid, name, input,
                                            input_size, output_size, flags,
-                                           request));
+                                           suppgid, request));
 }
 
 static inline int md_getxattr(struct obd_export *exp,
@@ -1988,13 +1989,14 @@ static inline int md_init_ea_size(struct obd_export *exp, int easize,
 
 static inline int md_get_remote_perm(struct obd_export *exp,
                                      const struct lu_fid *fid,
-                                     struct obd_capa *oc,
+                                     struct obd_capa *oc, __u32 suppgid,
                                      struct ptlrpc_request **request)
 {
         ENTRY;
         EXP_CHECK_MD_OP(exp, get_remote_perm);
         EXP_MD_COUNTER_INCREMENT(exp, get_remote_perm);
-        RETURN(MDP(exp->exp_obd, get_remote_perm)(exp, fid, oc, request));
+        RETURN(MDP(exp->exp_obd, get_remote_perm)(exp, fid, oc, suppgid,
+                                                  request));
 }
 
 static inline int md_renew_capa(struct obd_export *exp, struct obd_capa *ocapa,
index 013ad43..77bc38f 100644 (file)
@@ -3424,7 +3424,8 @@ CONFIG_X86_MPPARSE=y
 #
 # Security options
 #
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
index 3d04f51..2c071b6 100644 (file)
@@ -3424,7 +3424,8 @@ CONFIG_X86_MPPARSE=y
 #
 # Security options
 #
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
index 7391827..ab3b905 100644 (file)
@@ -2997,7 +2997,8 @@ CONFIG_RCU_TORTURE_TEST=m
 #
 # Security options
 #
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
index d5e00e7..d9a018d 100644 (file)
@@ -2985,7 +2985,8 @@ CONFIG_RCU_TORTURE_TEST=m
 #
 # Security options
 #
-# CONFIG_KEYS is not set
+CONFIG_KEYS=y
+CONFIG_KEYS_DEBUG_PROC_KEYS=y
 CONFIG_SECURITY=y
 CONFIG_SECURITY_NETWORK=y
 # CONFIG_SECURITY_NETWORK_XFRM is not set
index 12ab289..197791e 100644 (file)
@@ -180,11 +180,10 @@ out:
 static void destroy_import(struct obd_import *imp)
 {
         /* drop security policy instance after all rpc finished/aborted
-         * to let all busy credentials be released.
-         */
+         * to let all busy contexts be released. */
         class_import_get(imp);
         class_destroy_import(imp);
-        sptlrpc_import_put_sec(imp);
+        sptlrpc_import_sec_put(imp);
         class_import_put(imp);
 }
 
@@ -247,10 +246,8 @@ int client_obd_setup(struct obd_device *obddev, struct lustre_cfg *lcfg)
 
         sema_init(&cli->cl_sem, 1);
         sema_init(&cli->cl_mgc_sem, 1);
-        cli->cl_sec_conf.sfc_rpc_flavor = SPTLRPC_FLVR_NULL;
-        cli->cl_sec_conf.sfc_bulk_csum = BULK_CSUM_ALG_NULL;
-        cli->cl_sec_conf.sfc_bulk_priv = BULK_PRIV_ALG_NULL;
-        cli->cl_sec_conf.sfc_flags = 0;
+        sptlrpc_rule_set_init(&cli->cl_sptlrpc_rset);
+        cli->cl_sec_part = LUSTRE_SP_ANY;
         cli->cl_conn_count = 0;
         memcpy(server_uuid.uuid, lustre_cfg_buf(lcfg, 2),
                min_t(unsigned int, LUSTRE_CFG_BUFLEN(lcfg, 2),
@@ -359,6 +356,7 @@ err:
 int client_obd_cleanup(struct obd_device *obddev)
 {
         ENTRY;
+        sptlrpc_rule_set_free(&obddev->u.cli.cl_sptlrpc_rset);
         ldlm_put_ref(obddev->obd_force);
         RETURN(0);
 }
@@ -400,11 +398,6 @@ int client_connect_import(const struct lu_env *env,
         if (rc != 0)
                 GOTO(out_ldlm, rc);
 
-        rc = sptlrpc_import_get_sec(imp, NULL, cli->cl_sec_conf.sfc_rpc_flavor,
-                                    cli->cl_sec_conf.sfc_flags);
-        if (rc)
-                GOTO(out_ldlm, rc);
-
         ocd = &imp->imp_connect_data;
         if (data) {
                 *ocd = *data;
@@ -810,7 +803,8 @@ dont_check_exports:
                                          &conn, target, &cluuid, data);
                 }
         } else {
-                rc = obd_reconnect(export, target, &cluuid, data);
+                rc = obd_reconnect(req->rq_svc_thread->t_env,
+                                   export, target, &cluuid, data);
         }
         if (rc)
                 GOTO(out, rc);
@@ -915,6 +909,20 @@ dont_check_exports:
                 /* destroyed import can be still referenced in ctxt */
                 obd_set_info_async(export, strlen(KEY_REVIMP_UPD), 
                                    KEY_REVIMP_UPD, 0, NULL, NULL);
+
+                /* in some recovery senarios, previous ctx init rpc handled
+                 * in sptlrpc_target_export_check() might be used to install
+                 * a reverse ctx in this reverse import, and later OBD_CONNECT
+                 * using the same gss ctx could reach here and following new
+                 * reverse import. note all reverse ctx in new/old import are
+                 * actually based on the same gss ctx. so we invalidate ctx
+                 * here before destroy import, otherwise flush old import will
+                 * lead to remote reverse ctx be destroied, thus the reverse
+                 * ctx of new import will lost its peer.
+                 * there might be a better way to deal with this???
+                 */
+                sptlrpc_import_inval_all_ctx(export->exp_imp_reverse);
+
                 destroy_import(export->exp_imp_reverse);
         }
 
@@ -938,8 +946,8 @@ dont_check_exports:
                 lustre_msg_add_op_flags(req->rq_repmsg, MSG_CONNECT_NEXT_VER);
         }
 
-        rc = sptlrpc_import_get_sec(revimp, req->rq_svc_ctx,
-                                    req->rq_sec_flavor, 0);
+        rc = sptlrpc_import_sec_adapt(revimp, req->rq_svc_ctx,
+                                      req->rq_flvr.sf_rpc);
         if (rc) {
                 CERROR("Failed to get sec for reverse import: %d\n", rc);
                 export->exp_imp_reverse = NULL;
index 32a8d69..9e2e644 100644 (file)
@@ -1412,6 +1412,9 @@ static void ldlm_handle_gl_callback(struct ptlrpc_request *req,
 
 static int ldlm_callback_reply(struct ptlrpc_request *req, int rc)
 {
+        if (req->rq_no_reply)
+                return 0;
+
         req->rq_status = rc;
         if (req->rq_reply_state == NULL) {
                 rc = lustre_pack_reply(req, 1, NULL, NULL);
index 97bba78..5cfb431 100644 (file)
@@ -1,7 +1,7 @@
 MODULES := lustre llite_lloop
 lustre-objs := dcache.o dir.o file.o llite_close.o llite_lib.o llite_nfs.o
 lustre-objs += llite_fid.o rw.o lproc_llite.o namei.o symlink.o llite_mmap.o
-lustre-objs += xattr.o remote_perm.o llite_capa.o
+lustre-objs += xattr.o remote_perm.o llite_rmtacl.o llite_capa.o
 lustre-objs += rw26.o super25.o
 
 llite_lloop-objs := lloop.o
index 2afec74..9f5f22a 100644 (file)
@@ -723,7 +723,7 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
                 oc = ll_mdscapa_get(inode);
                 rc = md_getattr_name(sbi->ll_md_exp, ll_inode2fid(inode), oc,
                                      filename, namelen, OBD_MD_FLID, 0,
-                                     &request);
+                                     ll_i2suppgid(inode), &request);
                 capa_put(oc);
                 if (rc < 0) {
                         CDEBUG(D_INFO, "md_getattr_name: %d\n", rc);
@@ -1119,22 +1119,22 @@ static int ll_dir_ioctl(struct inode *inode, struct file *file,
         }
         case LL_IOC_FLUSHCTX:
                 RETURN(ll_flush_ctx(inode));
-        case LL_IOC_GETFACL: {
-                struct rmtacl_ioctl_data ioc;
-
-                if (copy_from_user(&ioc, (void *)arg, sizeof(ioc)))
-                        RETURN(-EFAULT);
-
-                RETURN(ll_ioctl_getfacl(inode, &ioc));
-        }
-        case LL_IOC_SETFACL: {
-                struct rmtacl_ioctl_data ioc;
-
-                if (copy_from_user(&ioc, (void *)arg, sizeof(ioc)))
-                        RETURN(-EFAULT);
+#ifdef CONFIG_FS_POSIX_ACL
+        case LL_IOC_RMTACL: {
+            if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
+                inode == inode->i_sb->s_root->d_inode) {
+                struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+                int rc;
 
-                RETURN(ll_ioctl_setfacl(inode, &ioc));
+                LASSERT(fd != NULL);
+                rc = rct_add(&sbi->ll_rct, cfs_curproc_pid(), arg);
+                if (!rc)
+                        fd->fd_flags |= LL_FILE_RMTACL;
+                RETURN(rc);
+            } else
+                RETURN(0);
         }
+#endif
         default:
                 RETURN(obd_iocontrol(cmd, sbi->ll_dt_exp,0,NULL,(void *)arg));
         }
index 7a83bce..4ce948e 100644 (file)
@@ -286,9 +286,19 @@ int ll_file_release(struct inode *inode, struct file *file)
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n", inode->i_ino,
                inode->i_generation, inode);
 
-        /* don't do anything for / */
-        if (inode->i_sb->s_root == file->f_dentry)
-                RETURN(0);
+#ifdef CONFIG_FS_POSIX_ACL
+        if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
+            inode == inode->i_sb->s_root->d_inode) {
+                struct ll_file_data *fd = LUSTRE_FPRIVATE(file);
+
+                LASSERT(fd != NULL);
+                if (unlikely(fd->fd_flags & LL_FILE_RMTACL)) {
+                        fd->fd_flags &= ~LL_FILE_RMTACL;
+                        rct_del(&sbi->ll_rct, cfs_curproc_pid());
+                        et_search_free(&sbi->ll_et, cfs_curproc_pid());
+                }
+        }
+#endif
 
         ll_stats_ops_tally(sbi, LPROC_LL_RELEASE, 1);
         fd = LUSTRE_FPRIVATE(file);
@@ -469,10 +479,6 @@ int ll_file_open(struct inode *inode, struct file *file)
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p), flags %o\n", inode->i_ino,
                inode->i_generation, inode, file->f_flags);
 
-        /* don't do anything for / */
-        if (inode->i_sb->s_root == file->f_dentry)
-                RETURN(0);
-
 #ifdef HAVE_VFS_INTENT_PATCHES
         it = file->f_it;
 #else
@@ -1799,7 +1805,8 @@ int ll_lov_getstripe_ea_info(struct inode *inode, const char *filename,
         oc = ll_mdscapa_get(inode);
         rc = md_getattr_name(sbi->ll_md_exp, ll_inode2fid(inode),
                              oc, filename, strlen(filename) + 1,
-                             OBD_MD_FLEASIZE | OBD_MD_FLDIREA, lmmsize, &req);
+                             OBD_MD_FLEASIZE | OBD_MD_FLDIREA, lmmsize,
+                             ll_i2suppgid(inode), &req);
         capa_put(oc);
         if (rc < 0) {
                 CDEBUG(D_INFO, "md_getattr_name failed "
@@ -2302,22 +2309,6 @@ int ll_file_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
         */
         case LL_IOC_FLUSHCTX:
                 RETURN(ll_flush_ctx(inode));
-        case LL_IOC_GETFACL: {
-                struct rmtacl_ioctl_data ioc;
-
-                if (copy_from_user(&ioc, (void *)arg, sizeof(ioc)))
-                        RETURN(-EFAULT);
-
-                RETURN(ll_ioctl_getfacl(inode, &ioc));
-        }
-        case LL_IOC_SETFACL: {
-                struct rmtacl_ioctl_data ioc;
-
-                if (copy_from_user(&ioc, (void *)arg, sizeof(ioc)))
-                        RETURN(-EFAULT);
-
-                RETURN(ll_ioctl_setfacl(inode, &ioc));
-        }
         default: {
                 int err;
 
index 6273f68..64022e5 100644 (file)
 # include <linux/fs.h>
 #ifdef HAVE_XATTR_ACL
 # include <linux/xattr_acl.h>
-#endif
+#endif /* HAVE_XATTR_ACL */
 #ifdef HAVE_LINUX_POSIX_ACL_XATTR_H
 # include <linux/posix_acl_xattr.h>
-#endif
-#endif
+#endif /* HAVE_LINUX_POSIX_ACL_XATTR_H */
+#endif /* CONFIG_FS_POSIX_ACL */
 
 #include <lustre_debug.h>
 #include <lustre_ver.h>
 #include <lustre_disk.h>  /* for s2sbi */
+#include <lustre_eacl.h>
 
 #ifndef FMODE_EXEC
 #define FMODE_EXEC 0
@@ -233,6 +234,34 @@ enum stats_track_type {
 #define LL_SBI_LOCALFLOCK       0x200 /* Local flocks support by kernel */
 #define LL_SBI_LRU_RESIZE       0x400 /* lru resize support */
 
+#define RCE_HASHES      32
+
+struct rmtacl_ctl_entry {
+        struct list_head rce_list;
+        pid_t            rce_key; /* hash key */
+        int              rce_ops; /* acl operation type */
+};
+
+struct rmtacl_ctl_table {
+        spinlock_t       rct_lock;
+        struct list_head rct_entries[RCE_HASHES];
+};
+
+#define EE_HASHES       32
+
+struct eacl_entry {
+        struct list_head      ee_list;
+        pid_t                 ee_key; /* hash key */
+        struct lu_fid         ee_fid;
+        int                   ee_type; /* ACL type for ACCESS or DEFAULT */
+        ext_acl_xattr_header *ee_acl;
+};
+
+struct eacl_table {
+        spinlock_t       et_lock;
+        struct list_head et_entries[EE_HASHES];
+};
+
 struct ll_sb_info {
         struct list_head          ll_list;
         /* this protects pglist and ra_info.  It isn't safe to
@@ -285,6 +314,8 @@ struct ll_sb_info {
 
         dev_t                     ll_sdev_orig; /* save s_dev before assign for
                                                  * clustred nfs */
+        struct rmtacl_ctl_table   ll_rct;
+        struct eacl_table         ll_et;
 };
 
 #define LL_DEFAULT_MAX_RW_CHUNK         (32 * 1024 * 1024)
@@ -392,6 +423,7 @@ struct it_cb_data {
         obd_id hash;
 };
 
+__u32 ll_i2suppgid(struct inode *i);
 void ll_i2gids(__u32 *suppgids, struct inode *i1,struct inode *i2);
 
 #define LLAP_MAGIC 98764321
@@ -601,8 +633,6 @@ struct ll_async_page *llite_pglist_next_llap(struct ll_sb_info *sbi,
 int ll_obd_statfs(struct inode *inode, void *arg);
 int ll_get_max_mdsize(struct ll_sb_info *sbi, int *max_mdsize);
 int ll_process_config(struct lustre_cfg *lcfg);
-int ll_ioctl_getfacl(struct inode *inode, struct rmtacl_ioctl_data *ioc);
-int ll_ioctl_setfacl(struct inode *inode, struct rmtacl_ioctl_data *ioc);
 struct md_op_data *ll_prep_md_op_data(struct md_op_data *op_data,
                                       struct inode *i1, struct inode *i2,
                                       const char *name, int namelen,
@@ -768,6 +798,25 @@ void ll_truncate_free_capa(struct obd_capa *ocapa);
 void ll_clear_inode_capas(struct inode *inode);
 void ll_print_capa_stat(struct ll_sb_info *sbi);
 
+/* llite/llite_rmtacl.c */
+#ifdef CONFIG_FS_POSIX_ACL
+obd_valid rce_ops2valid(int ops);
+struct rmtacl_ctl_entry *rct_search(struct rmtacl_ctl_table *rct, pid_t key);
+int rct_add(struct rmtacl_ctl_table *rct, pid_t key, int ops);
+int rct_del(struct rmtacl_ctl_table *rct, pid_t key);
+void rct_init(struct rmtacl_ctl_table *rct);
+void rct_fini(struct rmtacl_ctl_table *rct);
+
+void ee_free(struct eacl_entry *ee);
+int ee_add(struct eacl_table *et, pid_t key, struct lu_fid *fid, int type,
+           ext_acl_xattr_header *header);
+struct eacl_entry *et_search_del(struct eacl_table *et, pid_t key,
+                                 struct lu_fid *fid, int type);
+void et_search_free(struct eacl_table *et, pid_t key);
+void et_init(struct eacl_table *et);
+void et_fini(struct eacl_table *et);
+#endif
+
 /* llite ioctl register support rountine */
 #ifdef __KERNEL__
 enum llioc_iter {
index ed8ae79..0f91ebc 100644 (file)
@@ -161,8 +161,7 @@ static int ll_init_ea_size(struct obd_export *md_exp, struct obd_export *dt_exp)
         RETURN(rc);
 }
 
-static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
-                                    uid_t nllu, gid_t nllg)
+static int client_common_fill_super(struct super_block *sb, char *md, char *dt)
 {
         struct inode *root = 0;
         struct ll_sb_info *sbi = ll_s2sbi(sb);
@@ -238,8 +237,6 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                 data->ocd_connect_flags &= ~OBD_CONNECT_RMT_CLIENT;
                 data->ocd_connect_flags |= OBD_CONNECT_LCL_CLIENT;
         }
-        data->ocd_nllu = nllu;
-        data->ocd_nllg = nllg;
 
         err = obd_connect(NULL, &md_conn, obd, &sbi->ll_sb_uuid, data);
         if (err == -EBUSY) {
@@ -487,6 +484,13 @@ static int client_common_fill_super(struct super_block *sb, char *md, char *dt,
                 GOTO(out_root, err);
         }
 
+#ifdef CONFIG_FS_POSIX_ACL
+        if (sbi->ll_flags & LL_SBI_RMT_CLIENT) {
+                rct_init(&sbi->ll_rct);
+                et_init(&sbi->ll_et);
+        }
+#endif
+
         checksum = sbi->ll_flags & LL_SBI_CHECKSUM;
         err = obd_set_info_async(sbi->ll_dt_exp, strlen("checksum"),"checksum",
                                  sizeof(checksum), &checksum, NULL);
@@ -675,6 +679,13 @@ void client_common_put_super(struct super_block *sb)
         struct ll_sb_info *sbi = ll_s2sbi(sb);
         ENTRY;
 
+#ifdef CONFIG_FS_POSIX_ACL
+        if (sbi->ll_flags & LL_SBI_RMT_CLIENT) {
+                et_fini(&sbi->ll_et);
+                rct_fini(&sbi->ll_rct);
+        }
+#endif
+
         obd_cancel_unused(sbi->ll_dt_exp, NULL, 0, NULL);
 
         ll_close_thread_shutdown(sbi->ll_lcq);
@@ -932,9 +943,7 @@ int ll_fill_super(struct super_block *sb)
         sprintf(md, "%s-%s", lprof->lp_md, ll_instance);
 
         /* connections, registrations, sb setup */
-        err = client_common_fill_super(sb, md, dt,
-                                       lsi->lsi_lmd->lmd_nllu,
-                                       lsi->lsi_lmd->lmd_nllg);
+        err = client_common_fill_super(sb, md, dt);
 
 out_free:
         if (md)
@@ -2208,100 +2217,3 @@ void ll_finish_md_op_data(struct md_op_data *op_data)
         capa_put(op_data->op_capa2);
         OBD_FREE_PTR(op_data);
 }
-
-int ll_ioctl_getfacl(struct inode *inode, struct rmtacl_ioctl_data *ioc)
-{
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
-        struct ptlrpc_request *req = NULL;
-        struct mdt_body *body;
-        char *cmd, *buf;
-        struct obd_capa *oc;
-        int rc, buflen;
-        ENTRY;
-
-        if (!(sbi->ll_flags & LL_SBI_RMT_CLIENT))
-                RETURN(-EBADE);
-
-        LASSERT(ioc->cmd && ioc->cmd_len && ioc->res && ioc->res_len);
-
-        OBD_ALLOC(cmd, ioc->cmd_len);
-        if (!cmd)
-                RETURN(-ENOMEM);
-        if (copy_from_user(cmd, ioc->cmd, ioc->cmd_len))
-                GOTO(out, rc = -EFAULT);
-
-        oc = ll_mdscapa_get(inode);
-        rc = md_getxattr(ll_i2sbi(inode)->ll_md_exp, ll_inode2fid(inode), oc,
-                         OBD_MD_FLXATTR, XATTR_NAME_LUSTRE_ACL, cmd,
-                         ioc->cmd_len, ioc->res_len, 0, &req);
-        capa_put(oc);
-        if (rc < 0) {
-                CERROR("mdc_getxattr %s [%s] failed: %d\n",
-                       XATTR_NAME_LUSTRE_ACL, cmd, rc);
-                GOTO(out, rc);
-        }
-
-        body = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*body));
-        LASSERT(body);
-
-        buflen = lustre_msg_buflen(req->rq_repmsg, REPLY_REC_OFF);
-        LASSERT(buflen <= ioc->res_len);
-        buf = lustre_msg_string(req->rq_repmsg, REPLY_REC_OFF + 1, ioc->res_len);
-        LASSERT(buf);
-        if (copy_to_user(ioc->res, buf, buflen))
-                GOTO(out, rc = -EFAULT);
-        EXIT;
-out:
-        if (req)
-                ptlrpc_req_finished(req);
-        OBD_FREE(cmd, ioc->cmd_len);
-        return rc;
-}
-
-int ll_ioctl_setfacl(struct inode *inode, struct rmtacl_ioctl_data *ioc)
-{
-        struct ll_sb_info *sbi = ll_i2sbi(inode);
-        struct ptlrpc_request *req = NULL;
-        char *cmd, *buf;
-        struct obd_capa *oc;
-        int buflen, rc;
-        ENTRY;
-
-        if (!(sbi->ll_flags & LL_SBI_RMT_CLIENT))
-                RETURN(-EBADE);
-
-        if (!(sbi->ll_flags & LL_SBI_ACL)) 
-                RETURN(-EOPNOTSUPP);
-
-        LASSERT(ioc->cmd && ioc->cmd_len && ioc->res && ioc->res_len);
-
-        OBD_ALLOC(cmd, ioc->cmd_len);
-        if (!cmd)
-                RETURN(-ENOMEM);
-        if (copy_from_user(cmd, ioc->cmd, ioc->cmd_len))
-                GOTO(out, rc = -EFAULT);
-
-        oc = ll_mdscapa_get(inode);
-        rc = md_setxattr(ll_i2sbi(inode)->ll_md_exp, ll_inode2fid(inode), oc,
-                         OBD_MD_FLXATTR, XATTR_NAME_LUSTRE_ACL, cmd,
-                         ioc->cmd_len, ioc->res_len, 0, &req);
-        capa_put(oc);
-        if (rc) {
-                CERROR("mdc_setxattr %s [%s] failed: %d\n",
-                       XATTR_NAME_LUSTRE_ACL, cmd, rc);
-                GOTO(out, rc);
-        }
-
-        buflen = lustre_msg_buflen(req->rq_repmsg, REPLY_REC_OFF);
-        LASSERT(buflen <= ioc->res_len);
-        buf = lustre_msg_string(req->rq_repmsg, REPLY_REC_OFF, ioc->res_len);
-        LASSERT(buf);
-        if (copy_to_user(ioc->res, buf, buflen))
-                GOTO(out, rc = -EFAULT);
-        EXIT;
-out:
-        if (req)
-                ptlrpc_req_finished(req);
-        OBD_FREE(cmd, ioc->cmd_len);
-        return rc;
-}
index 754e49d..afd0c9b 100644 (file)
@@ -213,7 +213,8 @@ static struct dentry *ll_get_parent(struct dentry *dchild)
                         dir->i_ino, PFID(ll_inode2fid(dir)));
 
         rc = md_getattr_name(sbi->ll_md_exp, ll_inode2fid(dir), NULL,
-                             dotdot, strlen(dotdot) + 1, 0, 0, &req);
+                             dotdot, strlen(dotdot) + 1, 0, 0,
+                             ll_i2suppgid(dir), &req);
         if (rc) {
                 CERROR("failure %d inode %lu get parent\n", rc, dir->i_ino);
                 RETURN(ERR_PTR(rc));
diff --git a/lustre/llite/llite_rmtacl.c b/lustre/llite/llite_rmtacl.c
new file mode 100644 (file)
index 0000000..924092d
--- /dev/null
@@ -0,0 +1,283 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *   lustre/llite/llite_rmtacl.c
+ *   Lustre Remote User Access Control List.
+ *   Author: Fan Yong <fanyong@clusterfs.com>
+ *
+ * Copyright (c) 2004-2007 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
+
+#ifdef CONFIG_FS_POSIX_ACL
+
+#include <lustre_lite.h>
+#include "llite_internal.h"
+
+static inline __u32 rce_hashfunc(uid_t id)
+{
+        return id & (RCE_HASHES - 1);
+}
+
+static inline __u32 ee_hashfunc(uid_t id)
+{
+        return id & (EE_HASHES - 1);
+}
+
+obd_valid rce_ops2valid(int ops)
+{
+        switch (ops) {
+        case RMT_LSETFACL:
+                return OBD_MD_FLRMTLSETFACL;
+        case RMT_LGETFACL:
+                return OBD_MD_FLRMTLGETFACL;
+        case RMT_RSETFACL:
+                return OBD_MD_FLRMTRSETFACL;
+        case RMT_RGETFACL:
+                return OBD_MD_FLRMTRGETFACL;
+        default:
+                return 0;
+        }
+}
+
+static struct rmtacl_ctl_entry *rce_alloc(pid_t key, int ops)
+{
+        struct rmtacl_ctl_entry *rce;
+
+        OBD_ALLOC_PTR(rce);
+        if (!rce)
+                return NULL;
+
+        CFS_INIT_LIST_HEAD(&rce->rce_list);
+        rce->rce_key = key;
+        rce->rce_ops = ops;
+
+        return rce;
+}
+
+static void rce_free(struct rmtacl_ctl_entry *rce)
+{
+        if (!list_empty(&rce->rce_list))
+                list_del(&rce->rce_list);
+
+        OBD_FREE_PTR(rce);
+}
+
+static struct rmtacl_ctl_entry *__rct_search(struct rmtacl_ctl_table *rct,
+                                           pid_t key)
+{
+        struct rmtacl_ctl_entry *rce;
+        struct list_head *head = &rct->rct_entries[rce_hashfunc(key)];
+
+        list_for_each_entry(rce, head, rce_list)
+                if (rce->rce_key == key)
+                        return rce;
+
+        return NULL;
+}
+
+struct rmtacl_ctl_entry *rct_search(struct rmtacl_ctl_table *rct, pid_t key)
+{
+        struct rmtacl_ctl_entry *rce;
+
+        spin_lock(&rct->rct_lock);
+        rce = __rct_search(rct, key);
+        spin_unlock(&rct->rct_lock);
+        return rce;
+}
+
+int rct_add(struct rmtacl_ctl_table *rct, pid_t key, int ops)
+{
+        struct rmtacl_ctl_entry *rce, *e;
+
+        rce = rce_alloc(key, ops);
+        if (rce == NULL)
+                return -ENOMEM;
+
+        spin_lock(&rct->rct_lock);
+        e = __rct_search(rct, key);
+        if (unlikely(e != NULL)) {
+                CWARN("Unexpected stale rmtacl_entry found: "
+                      "[key: %d] [ops: %d]\n", (int)key, ops);
+                rce_free(e);
+        }
+        list_add_tail(&rce->rce_list, &rct->rct_entries[rce_hashfunc(key)]);
+        spin_unlock(&rct->rct_lock);
+
+        return 0;
+}
+
+int rct_del(struct rmtacl_ctl_table *rct, pid_t key)
+{
+        struct rmtacl_ctl_entry *rce;
+
+        spin_lock(&rct->rct_lock);
+        rce = __rct_search(rct, key);
+        if (rce)
+                rce_free(rce);
+        spin_unlock(&rct->rct_lock);
+
+        return rce ? 0 : -ENOENT;
+}
+
+void rct_init(struct rmtacl_ctl_table *rct)
+{
+        int i;
+
+        spin_lock_init(&rct->rct_lock);
+        for (i = 0; i < RCE_HASHES; i++)
+                CFS_INIT_LIST_HEAD(&rct->rct_entries[i]);
+}
+
+void rct_fini(struct rmtacl_ctl_table *rct)
+{
+        struct rmtacl_ctl_entry *rce;
+        int i;
+
+        spin_lock(&rct->rct_lock);
+        for (i = 0; i < RCE_HASHES; i++)
+                while (!list_empty(&rct->rct_entries[i])) {
+                        rce = list_entry(rct->rct_entries[i].next,
+                                         struct rmtacl_ctl_entry, rce_list);
+                        rce_free(rce);
+                }
+        spin_unlock(&rct->rct_lock);
+}
+
+
+static struct eacl_entry *ee_alloc(pid_t key, struct lu_fid *fid, int type,
+                                   ext_acl_xattr_header *header)
+{
+        struct eacl_entry *ee;
+
+        OBD_ALLOC_PTR(ee);
+        if (!ee)
+                return NULL;
+
+        CFS_INIT_LIST_HEAD(&ee->ee_list);
+        ee->ee_key = key;
+        ee->ee_fid = *fid;
+        ee->ee_type = type;
+        ee->ee_acl = header;
+
+        return ee;
+}
+
+void ee_free(struct eacl_entry *ee)
+{
+        if (!list_empty(&ee->ee_list))
+                list_del(&ee->ee_list);
+
+        if (ee->ee_acl)
+                lustre_ext_acl_xattr_free(ee->ee_acl);
+
+        OBD_FREE_PTR(ee);
+}
+
+static struct eacl_entry *__et_search_del(struct eacl_table *et, pid_t key,
+                                        struct lu_fid *fid, int type)
+{
+        struct eacl_entry *ee;
+        struct list_head *head = &et->et_entries[ee_hashfunc(key)];
+
+        LASSERT(fid != NULL);
+        list_for_each_entry(ee, head, ee_list)
+                if (ee->ee_key == key) {
+                        if (lu_fid_eq(&ee->ee_fid, fid) &&
+                            ee->ee_type == type) {
+                                list_del_init(&ee->ee_list);
+                                return ee;
+                        }
+                }
+
+        return NULL;
+}
+
+struct eacl_entry *et_search_del(struct eacl_table *et, pid_t key,
+                                 struct lu_fid *fid, int type)
+{
+        struct eacl_entry *ee;
+
+        spin_lock(&et->et_lock);
+        ee = __et_search_del(et, key, fid, type);
+        spin_unlock(&et->et_lock);
+        return ee;
+}
+
+void et_search_free(struct eacl_table *et, pid_t key)
+{
+        struct eacl_entry *ee, *next;
+        struct list_head *head = &et->et_entries[ee_hashfunc(key)];
+
+        spin_lock(&et->et_lock);
+        list_for_each_entry_safe(ee, next, head, ee_list)
+                if (ee->ee_key == key)
+                        ee_free(ee);
+
+        spin_unlock(&et->et_lock);
+}
+
+int ee_add(struct eacl_table *et, pid_t key, struct lu_fid *fid, int type,
+           ext_acl_xattr_header *header)
+{
+        struct eacl_entry *ee, *e;
+
+        ee = ee_alloc(key, fid, type, header);
+        if (ee == NULL)
+                return -ENOMEM;
+
+        spin_lock(&et->et_lock);
+        e = __et_search_del(et, key, fid, type);
+        if (unlikely(e != NULL)) {
+                CWARN("Unexpected stale eacl_entry found: "
+                      "[key: %d] [fid: "DFID"] [type: %d]\n",
+                      (int)key, PFID(fid), type);
+                ee_free(e);
+        }
+        list_add_tail(&ee->ee_list, &et->et_entries[ee_hashfunc(key)]);
+        spin_unlock(&et->et_lock);
+
+        return 0;
+}
+
+void et_init(struct eacl_table *et)
+{
+        int i;
+
+        spin_lock_init(&et->et_lock);
+        for (i = 0; i < EE_HASHES; i++)
+                CFS_INIT_LIST_HEAD(&et->et_entries[i]);
+}
+
+void et_fini(struct eacl_table *et)
+{
+        struct eacl_entry *ee;
+        int i;
+
+        spin_lock(&et->et_lock);
+        for (i = 0; i < EE_HASHES; i++)
+                while (!list_empty(&et->et_entries[i])) {
+                        ee = list_entry(et->et_entries[i].next,
+                                        struct eacl_entry, ee_list);
+                        ee_free(ee);
+                }
+        spin_unlock(&et->et_lock);
+}
+
+#endif
index e6e204a..c4cc5ed 100644 (file)
@@ -214,31 +214,35 @@ int ll_md_blocking_ast(struct ldlm_lock *lock, struct ldlm_lock_desc *desc,
         RETURN(0);
 }
 
+__u32 ll_i2suppgid(struct inode *i)
+{
+        if (in_group_p(i->i_gid))
+                return (__u32)i->i_gid;
+        else
+                return (__u32)(-1);
+}
+
 /* Pack the required supplementary groups into the supplied groups array.
  * If we don't need to use the groups from the target inode(s) then we
  * instead pack one or more groups from the user's supplementary group
  * array in case it might be useful.  Not needed if doing an MDS-side upcall. */
 void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2)
 {
+#if 0
         int i;
+#endif
 
         LASSERT(i1 != NULL);
         LASSERT(suppgids != NULL);
 
-        if (in_group_p(i1->i_gid))
-                suppgids[0] = i1->i_gid;
-        else
-                suppgids[0] = -1;
+        suppgids[0] = ll_i2suppgid(i1);
 
-        if (i2) {
-                if (in_group_p(i2->i_gid))
-                        suppgids[1] = i2->i_gid;
+        if (i2)
+                suppgids[1] = ll_i2suppgid(i2);
                 else
                         suppgids[1] = -1;
-        } else {
-                suppgids[1] = -1;
-        }
 
+#if 0
         for (i = 0; i < current_ngroups; i++) {
                 if (suppgids[0] == -1) {
                         if (current_groups[i] != suppgids[1])
@@ -252,6 +256,7 @@ void ll_i2gids(__u32 *suppgids, struct inode *i1, struct inode *i2)
                 }
                 break;
         }
+#endif
 }
 
 static void ll_d_add(struct dentry *de, struct inode *inode)
index ac0aec0..e87239d 100644 (file)
@@ -263,7 +263,8 @@ check:
         }
 
         oc = ll_mdscapa_get(inode);
-        rc = md_get_remote_perm(sbi->ll_md_exp, ll_inode2fid(inode), oc, &req);
+        rc = md_get_remote_perm(sbi->ll_md_exp, ll_inode2fid(inode), oc,
+                                ll_i2suppgid(inode), &req);
         capa_put(oc);
         if (rc) {
                 up(&lli->lli_rmtperm_sem);
index c040923..db1bd85 100644 (file)
@@ -79,10 +79,9 @@ int get_xattr_type(const char *name)
 static
 int xattr_type_filter(struct ll_sb_info *sbi, int xattr_type)
 {
-        if (((xattr_type == XATTR_ACL_ACCESS_T) ||
-            (xattr_type == XATTR_ACL_DEFAULT_T)) &&
-            (!(sbi->ll_flags & LL_SBI_ACL) ||
-            (sbi->ll_flags & LL_SBI_RMT_CLIENT)))
+        if ((xattr_type == XATTR_ACL_ACCESS_T ||
+             xattr_type == XATTR_ACL_DEFAULT_T) &&
+           !(sbi->ll_flags & LL_SBI_ACL))
                 return -EOPNOTSUPP;
 
         if (xattr_type == XATTR_USER_T && !(sbi->ll_flags & LL_SBI_USER_XATTR))
@@ -104,6 +103,10 @@ int ll_setxattr_common(struct inode *inode, const char *name,
         struct ptlrpc_request *req;
         int xattr_type, rc;
         struct obd_capa *oc;
+        posix_acl_xattr_header *new_value = NULL;
+        struct rmtacl_ctl_entry *rce = NULL;
+        ext_acl_xattr_header *acl = NULL;
+        const char *pv = value;
         ENTRY;
 
         xattr_type = get_xattr_type(name);
@@ -116,10 +119,61 @@ int ll_setxattr_common(struct inode *inode, const char *name,
             (xattr_type == XATTR_LUSTRE_T && strcmp(name, "lustre.lov") == 0))
                 RETURN(0);
 
+#ifdef CONFIG_FS_POSIX_ACL
+        if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
+            (xattr_type == XATTR_ACL_ACCESS_T ||
+            xattr_type == XATTR_ACL_DEFAULT_T)) {
+                rce = rct_search(&sbi->ll_rct, cfs_curproc_pid());
+                if (rce == NULL ||
+                    (rce->rce_ops != RMT_LSETFACL &&
+                    rce->rce_ops != RMT_RSETFACL))
+                        RETURN(-EOPNOTSUPP);
+
+                if (rce->rce_ops == RMT_LSETFACL) {
+                        struct eacl_entry *ee;
+
+                        ee = et_search_del(&sbi->ll_et, cfs_curproc_pid(),
+                                           ll_inode2fid(inode), xattr_type);
+                        LASSERT(ee != NULL);
+                        if (valid & OBD_MD_FLXATTR) {
+                                acl = lustre_acl_xattr_merge2ext(
+                                                (posix_acl_xattr_header *)value,
+                                                size, ee->ee_acl);
+                                if (IS_ERR(acl)) {
+                                        ee_free(ee);
+                                        RETURN(PTR_ERR(acl));
+                                }
+                                size =  CFS_ACL_XATTR_SIZE(\
+                                                le32_to_cpu(acl->a_count), \
+                                                ext_acl_xattr);
+                                pv = (const char *)acl;
+                        }
+                        ee_free(ee);
+                } else if (rce->rce_ops == RMT_RSETFACL) {
+                        size = lustre_posix_acl_xattr_filter(
+                                                (posix_acl_xattr_header *)value,
+                                                size, &new_value);
+                        if (unlikely(size < 0))
+                                RETURN(size);
+
+                        pv = (const char *)new_value;
+                } else
+                        RETURN(-EOPNOTSUPP);
+
+                valid |= rce_ops2valid(rce->rce_ops);
+        }
+#endif
         oc = ll_mdscapa_get(inode);
-        rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, valid, name,
-                         value, size, 0, flags, &req);
+        rc = md_setxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
+                         valid, name, pv, size, 0, flags, ll_i2suppgid(inode),
+                         &req);
         capa_put(oc);
+#ifdef CONFIG_FS_POSIX_ACL
+        if (new_value != NULL)
+                lustre_posix_acl_xattr_free(new_value, size);
+        if (acl != NULL)
+                lustre_ext_acl_xattr_free(acl);
+#endif
         if (rc) {
                 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
                         LCONSOLE_INFO("Disabling user_xattr feature because "
@@ -200,6 +254,7 @@ int ll_getxattr_common(struct inode *inode, const char *name,
         int xattr_type, rc;
         void *xdata;
         struct obd_capa *oc;
+        struct rmtacl_ctl_entry *rce = NULL;
         ENTRY;
 
         CDEBUG(D_VFSTRACE, "VFS Op:inode=%lu/%u(%p)\n",
@@ -219,12 +274,27 @@ int ll_getxattr_common(struct inode *inode, const char *name,
         if (rc)
                 RETURN(rc);
 
+#ifdef CONFIG_FS_POSIX_ACL
+        if (sbi->ll_flags & LL_SBI_RMT_CLIENT &&
+            (xattr_type == XATTR_ACL_ACCESS_T ||
+            xattr_type == XATTR_ACL_DEFAULT_T)) {
+                rce = rct_search(&sbi->ll_rct, cfs_curproc_pid());
+                if (rce == NULL ||
+                    (rce->rce_ops != RMT_LSETFACL &&
+                    rce->rce_ops != RMT_LGETFACL &&
+                    rce->rce_ops != RMT_RSETFACL &&
+                    rce->rce_ops != RMT_RGETFACL))
+                        RETURN(-EOPNOTSUPP);
+        }
+#endif
+
         /* posix acl is under protection of LOOKUP lock. when calling to this,
          * we just have path resolution to the target inode, so we have great
          * chance that cached ACL is uptodate.
          */
 #ifdef CONFIG_FS_POSIX_ACL
-        if (xattr_type == XATTR_ACL_ACCESS_T) {
+        if (xattr_type == XATTR_ACL_ACCESS_T &&
+            !(sbi->ll_flags & LL_SBI_RMT_CLIENT)) {
                 struct ll_inode_info *lli = ll_i2info(inode);
                 struct posix_acl *acl;
 
@@ -243,8 +313,9 @@ int ll_getxattr_common(struct inode *inode, const char *name,
 
 do_getxattr:
         oc = ll_mdscapa_get(inode);
-        rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc, valid, name,
-                         NULL, 0, size, 0, &req);
+        rc = md_getxattr(sbi->ll_md_exp, ll_inode2fid(inode), oc,
+                         valid | (rce ? rce_ops2valid(rce->rce_ops) : 0),
+                         name, NULL, 0, size, 0, &req);
         capa_put(oc);
         if (rc) {
                 if (rc == -EOPNOTSUPP && xattr_type == XATTR_USER_T) {
@@ -285,12 +356,33 @@ do_getxattr:
                 GOTO(out, rc = -EFAULT);
         }
 
+#ifdef CONFIG_FS_POSIX_ACL
+        if (body->eadatasize >= 0 && rce && rce->rce_ops == RMT_LSETFACL) {
+                ext_acl_xattr_header *acl;
+
+                acl = lustre_posix_acl_xattr_2ext((posix_acl_xattr_header *)xdata,
+                                                  body->eadatasize);
+                if (IS_ERR(acl))
+                        GOTO(out, rc = PTR_ERR(acl));
+
+                rc = ee_add(&sbi->ll_et, cfs_curproc_pid(), ll_inode2fid(inode),
+                            xattr_type, acl);
+                if (unlikely(rc < 0)) {
+                        lustre_ext_acl_xattr_free(acl);
+                        GOTO(out, rc);
+                }
+        }
+
+        if (xattr_type == XATTR_ACL_ACCESS_T && !body->eadatasize)
+                GOTO(out, rc = -ENODATA);
+#endif
         LASSERT(buffer);
         memcpy(buffer, xdata, body->eadatasize);
         rc = body->eadatasize;
+        EXIT;
 out:
         ptlrpc_req_finished(req);
-        RETURN(rc);
+        return rc;
 }
 
 ssize_t ll_getxattr(struct dentry *dentry, const char *name,
index 9c6a4db..783f4b6 100644 (file)
@@ -1128,7 +1128,8 @@ static int lmv_getxattr(struct obd_export *exp, const struct lu_fid *fid,
 static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid,
                         struct obd_capa *oc, obd_valid valid, const char *name,
                         const char *input, int input_size, int output_size,
-                        int flags, struct ptlrpc_request **request)
+                        int flags, __u32 suppgid,
+                        struct ptlrpc_request **request)
 {
         struct obd_device *obd = exp->exp_obd;
         struct lmv_obd *lmv = &obd->u.lmv;
@@ -1145,7 +1146,8 @@ static int lmv_setxattr(struct obd_export *exp, const struct lu_fid *fid,
                 RETURN(PTR_ERR(tgt_exp));
 
         rc = md_setxattr(tgt_exp, fid, oc, valid, name,
-                         input, input_size, output_size, flags, request);
+                         input, input_size, output_size, flags, suppgid,
+                         request);
 
         RETURN(rc);
 }
@@ -1614,7 +1616,8 @@ lmv_enqueue(struct obd_export *exp, struct ldlm_enqueue_info *einfo,
 static int
 lmv_getattr_name(struct obd_export *exp, const struct lu_fid *fid,
                  struct obd_capa *oc, const char *filename, int namelen,
-                 obd_valid valid, int ea_size, struct ptlrpc_request **request)
+                 obd_valid valid, int ea_size, __u32 suppgid,
+                 struct ptlrpc_request **request)
 {
         struct obd_device *obd = exp->exp_obd;
         struct lmv_obd *lmv = &obd->u.lmv;
@@ -1654,7 +1657,7 @@ repeat:
                namelen, filename, PFID(fid), PFID(&rid));
 
         rc = md_getattr_name(tgt_exp, &rid, oc, filename, namelen, valid,
-                             ea_size, request);
+                             ea_size, suppgid, request);
         if (rc == 0) {
                 body = lustre_msg_buf((*request)->rq_repmsg,
                                       REQ_REC_OFF, sizeof(*body));
@@ -1676,7 +1679,7 @@ repeat:
 
                         rc = md_getattr_name(tgt_exp, &rid, NULL, NULL, 1,
                                              valid | OBD_MD_FLCROSSREF,
-                                             ea_size, &req);
+                                             ea_size, suppgid, &req);
                         ptlrpc_req_finished(*request);
                         *request = req;
                 }
@@ -2796,7 +2799,7 @@ int lmv_clear_open_replay_data(struct obd_export *exp,
 
 static int lmv_get_remote_perm(struct obd_export *exp,
                                const struct lu_fid *fid,
-                               struct obd_capa *oc,
+                               struct obd_capa *oc, __u32 suppgid,
                                struct ptlrpc_request **request)
 {
         struct obd_device *obd = exp->exp_obd;
@@ -2814,7 +2817,7 @@ static int lmv_get_remote_perm(struct obd_export *exp,
         if (IS_ERR(tgt_exp))
                 RETURN(PTR_ERR(tgt_exp));
 
-        rc = md_get_remote_perm(tgt_exp, fid, oc, request);
+        rc = md_get_remote_perm(tgt_exp, fid, oc, suppgid, request);
 
         RETURN(rc);
 }
index 8ed8c92..bea58ac 100644 (file)
@@ -79,7 +79,6 @@ static struct lprocfs_vars lprocfs_mdc_obd_vars[] = {
         { "mds_conn_uuid",   lprocfs_rd_conn_uuid,   0, 0 },
         { "max_rpcs_in_flight", mdc_rd_max_rpcs_in_flight,
                                 mdc_wr_max_rpcs_in_flight, 0 },
-        { "sptlrpc",         sptlrpc_lprocfs_rd, 0, 0 },
         { 0 }
 };
 
index 595dfd4..dda6f11 100644 (file)
@@ -37,7 +37,8 @@ static inline void lprocfs_mdc_init_vars(struct lprocfs_static_vars *lvars)
 #endif
 void mdc_pack_req_body(struct ptlrpc_request *req, int offset,
                        __u64 valid, const struct lu_fid *fid,
-                       struct obd_capa *oc, int ea_size, int flags);
+                       struct obd_capa *oc, int ea_size,
+                       __u32 suppgid, int flags);
 void mdc_pack_capa(struct ptlrpc_request *req, int offset, struct obd_capa *oc);
 void mdc_pack_rep_body(struct ptlrpc_request *);
 void mdc_is_subdir_pack(struct ptlrpc_request *req, int offset,
index 8f4cd9e..66e5ad3 100644 (file)
 #endif
 #endif
 
-static void mdc_pack_body(struct mdt_body *b)
+static void mdc_pack_body(struct mdt_body *b, __u32 suppgid)
 {
         LASSERT (b != NULL);
 
+        b->suppgid = suppgid;
+        b->uid = current->uid;
+        b->gid = current->gid;
         b->fsuid = current->fsuid;
         b->fsgid = current->fsgid;
         b->capability = current->cap_effective;
@@ -78,14 +81,15 @@ void mdc_is_subdir_pack(struct ptlrpc_request *req, int offset,
 
 void mdc_pack_req_body(struct ptlrpc_request *req, int offset,
                        __u64 valid, const struct lu_fid *fid,
-                       struct obd_capa *oc, int ea_size, int flags)
+                       struct obd_capa *oc, int ea_size, __u32 suppgid,
+                       int flags)
 {
         struct mdt_body *b = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*b));
 
         b->valid = valid;
         b->eadatasize = ea_size;
         b->flags = flags;
-        mdc_pack_body(b);
+        mdc_pack_body(b, suppgid);
         if (fid) {
                 b->fid1 = *fid;
                 mdc_pack_capa(req, offset + 1, oc);
@@ -100,9 +104,8 @@ void mdc_readdir_pack(struct ptlrpc_request *req, int offset, __u64 pgoff,
         b = lustre_msg_buf(req->rq_reqmsg, offset, sizeof(*b));
         b->fid1 = *fid;
         b->size = pgoff;                       /* !! */
-        b->suppgid = -1;
         b->nlink = size;                        /* !! */
-        mdc_pack_body(b);
+        mdc_pack_body(b, -1);
         mdc_pack_capa(req, offset + 1, oc);
 }
 
index e9334f9..b72e700 100644 (file)
@@ -97,7 +97,7 @@ static int send_getstatus(struct obd_import *imp, struct lu_fid *rootfid,
         req->rq_send_state = level;
         ptlrpc_req_set_repsize(req, 3, size);
 
-        mdc_pack_req_body(req, REQ_REC_OFF, 0, NULL, NULL, 0, 0);
+        mdc_pack_req_body(req, REQ_REC_OFF, 0, NULL, NULL, 0, -1, 0);
         lustre_msg_add_flags(req->rq_reqmsg, msg_flags);
         rc = ptlrpc_queue_wait(req);
 
@@ -244,7 +244,7 @@ int mdc_getattr(struct obd_export *exp, const struct lu_fid *fid,
         if (!req)
                 GOTO(out, rc = -ENOMEM);
 
-        mdc_pack_req_body(req, REQ_REC_OFF, valid, fid, oc, ea_size,
+        mdc_pack_req_body(req, REQ_REC_OFF, valid, fid, oc, ea_size, -1,
                           MDS_BFLAG_EXT_FLAGS/*request "new" flags(bug 9486)*/);
 
         if (valid & OBD_MD_FLRMTPERM)
@@ -267,7 +267,7 @@ int mdc_getattr(struct obd_export *exp, const struct lu_fid *fid,
 
 int mdc_getattr_name(struct obd_export *exp, const struct lu_fid *fid,
                      struct obd_capa *oc, const char *filename, int namelen,
-                     obd_valid valid, int ea_size,
+                     obd_valid valid, int ea_size, __u32 suppgid,
                      struct ptlrpc_request **request)
 {
         struct ptlrpc_request *req;
@@ -283,7 +283,7 @@ int mdc_getattr_name(struct obd_export *exp, const struct lu_fid *fid,
         if (!req)
                 GOTO(out, rc = -ENOMEM);
 
-        mdc_pack_req_body(req, REQ_REC_OFF, valid, fid, oc, ea_size,
+        mdc_pack_req_body(req, REQ_REC_OFF, valid, fid, oc, ea_size, suppgid,
                           MDS_BFLAG_EXT_FLAGS/*request "new" flags(bug 9486)*/);
 
         if (filename) {
@@ -342,12 +342,12 @@ int mdc_xattr_common(struct obd_export *exp, const struct lu_fid *fid,
                      struct obd_capa *oc,
                      int opcode, obd_valid valid, const char *xattr_name,
                      const char *input, int input_size, int output_size,
-                     int flags, struct ptlrpc_request **request)
+                     int flags, __u32 suppgid, struct ptlrpc_request **request)
 {
         struct ptlrpc_request *req;
         int size[5] = { sizeof(struct ptlrpc_body), sizeof(struct mdt_body) };
         int bufcnt = 3, offset = REQ_REC_OFF + 2;
-        int rc, xattr_namelen = 0, remote_acl = 0;
+        int rc, xattr_namelen = 0;
         void *tmp;
         ENTRY;
 
@@ -367,14 +367,13 @@ int mdc_xattr_common(struct obd_export *exp, const struct lu_fid *fid,
                 GOTO(out, rc = -ENOMEM);
 
         /* request data */
-        mdc_pack_req_body(req, REQ_REC_OFF, valid, fid, oc, output_size, flags);
+        mdc_pack_req_body(req, REQ_REC_OFF, valid, fid, oc, output_size,
+                          suppgid, flags);
 
 
         if (xattr_name) {
                 tmp = lustre_msg_buf(req->rq_reqmsg, offset++, xattr_namelen);
                 memcpy(tmp, xattr_name, xattr_namelen);
-                if (!strcmp(xattr_name, XATTR_NAME_LUSTRE_ACL))
-                        remote_acl = 1;
         }
         if (input_size) {
                 tmp = lustre_msg_buf(req->rq_reqmsg, offset++, input_size);
@@ -394,15 +393,12 @@ int mdc_xattr_common(struct obd_export *exp, const struct lu_fid *fid,
         ptlrpc_req_set_repsize(req, bufcnt, size);
 
         /* make rpc */
-        /* NB: set remote acl doesn't need hold rpc lock, because it just
-         * send command to MDS, and when it's executed on mountpoint on MDS,
-         * another mdc_xattr_common() will be invoked there. */
-        if (opcode == MDS_SETXATTR && !remote_acl)
+        if (opcode == MDS_SETXATTR)
                 mdc_get_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
 
         rc = ptlrpc_queue_wait(req);
 
-        if (opcode == MDS_SETXATTR && !remote_acl)
+        if (opcode == MDS_SETXATTR)
                 mdc_put_rpc_lock(exp->exp_obd->u.cli.cl_rpc_lock, NULL);
 
         if (rc != 0)
@@ -428,10 +424,11 @@ err_out:
 int mdc_setxattr(struct obd_export *exp, const struct lu_fid *fid,
                  struct obd_capa *oc, obd_valid valid, const char *xattr_name,
                  const char *input, int input_size, int output_size, int flags,
-                 struct ptlrpc_request **request)
+                 __u32 suppgid, struct ptlrpc_request **request)
 {
         return mdc_xattr_common(exp, fid, oc, MDS_SETXATTR, valid, xattr_name,
-                                input, input_size, output_size, flags, request);
+                                input, input_size, output_size, flags, suppgid,
+                                request);
 }
 
 int mdc_getxattr(struct obd_export *exp, const struct lu_fid *fid,
@@ -440,7 +437,8 @@ int mdc_getxattr(struct obd_export *exp, const struct lu_fid *fid,
                  struct ptlrpc_request **request)
 {
         return mdc_xattr_common(exp, fid, oc, MDS_GETXATTR, valid, xattr_name,
-                                input, input_size, output_size, flags, request);
+                                input, input_size, output_size, flags, -1,
+                                request);
 }
 
 #ifdef CONFIG_FS_POSIX_ACL
@@ -1367,7 +1365,7 @@ int mdc_sync(struct obd_export *exp, const struct lu_fid *fid,
         if (!req)
                 RETURN(rc = -ENOMEM);
 
-        mdc_pack_req_body(req, REQ_REC_OFF, 0, fid, oc, 0, 0);
+        mdc_pack_req_body(req, REQ_REC_OFF, 0, fid, oc, 0, -1, 0);
 
         ptlrpc_req_set_repsize(req, 2, size);
 
@@ -1527,6 +1525,7 @@ static int mdc_setup(struct obd_device *obd, struct lustre_cfg *cfg)
                 GOTO(err_close_lock, rc);
         lprocfs_mdc_init_vars(&lvars);
         lprocfs_obd_setup(obd, lvars.obd_vars);
+        sptlrpc_lprocfs_cliobd_attach(obd);
         ptlrpc_lprocfs_register_obd(obd);
 
         rc = obd_llog_init(obd, NULL, obd, 0, NULL, NULL);
@@ -1662,14 +1661,23 @@ static int mdc_process_config(struct obd_device *obd, obd_count len, void *buf)
         int rc = 0;
 
         lprocfs_mdc_init_vars(&lvars);
-        
-        rc = class_process_proc_param(PARAM_MDC, lvars.obd_vars, lcfg, obd);
+
+        switch (lcfg->lcfg_command) {
+        case LCFG_SPTLRPC_CONF:
+                rc = sptlrpc_cliobd_process_config(obd, lcfg);
+                break;
+        default:
+                rc = class_process_proc_param(PARAM_MDC, lvars.obd_vars,
+                                              lcfg, obd);
+                break;
+        }
         return(rc);
 }
 
 /* get remote permission for current user on fid */
 int mdc_get_remote_perm(struct obd_export *exp, const struct lu_fid *fid,
-                        struct obd_capa *oc, struct ptlrpc_request **request)
+                        struct obd_capa *oc, __u32 suppgid,
+                        struct ptlrpc_request **request)
 {
         struct ptlrpc_request *req;
         struct mdt_body *body;
@@ -1686,7 +1694,8 @@ int mdc_get_remote_perm(struct obd_export *exp, const struct lu_fid *fid,
         if (!req)
                 RETURN(-ENOMEM);
 
-        mdc_pack_req_body(req, REQ_REC_OFF, OBD_MD_FLRMTPERM, fid, oc, 0, 0);
+        mdc_pack_req_body(req, REQ_REC_OFF, OBD_MD_FLRMTPERM, fid, oc, 0,
+                          suppgid, 0);
 
         size[REPLY_REC_OFF + 1] = sizeof(*perm);
         ptlrpc_req_set_repsize(req, 5, size);
@@ -1753,7 +1762,7 @@ static int mdc_renew_capa(struct obd_export *exp, struct obd_capa *oc,
                 RETURN(-ENOMEM);
 
         mdc_pack_req_body(req, REQ_REC_OFF, OBD_MD_FLOSSCAPA,
-                          &oc->c_capa.lc_fid, oc, 0, 0);
+                          &oc->c_capa.lc_fid, oc, 0, -1, 0);
 
         ptlrpc_req_set_repsize(req, 5, size);
         req->rq_async_args.pointer_arg[0] = oc;
index 82efb15..a887733 100644 (file)
@@ -30,6 +30,7 @@
 #include <asm/semaphore.h>
 
 #include <linux/lustre_acl.h>
+#include <lustre_eacl.h>
 #include <obd.h>
 #include <md_object.h>
 #include <dt_object.h>
@@ -301,7 +302,6 @@ static inline int mdd_capable(struct md_ucred *uc, int cap)
         return 0;
 }
 
-int mdd_in_group_p(struct md_ucred *uc, gid_t grp);
 int mdd_acl_def_get(const struct lu_env *env, struct mdd_object *mdd_obj,
                     struct md_attr *ma);
 int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode,
index c10d4bc..758a1fc 100644 (file)
@@ -664,7 +664,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj,
                                       (tmp_la->la_mode & ~S_IALLUGO);
 
                 /* Also check the setgid bit! */
-                if (!mdd_in_group_p(uc, (la->la_valid & LA_GID) ? la->la_gid :
+                if (!lustre_in_group_p(uc, (la->la_valid & LA_GID) ? la->la_gid :
                                 tmp_la->la_gid) && !mdd_capable(uc, CAP_FSETID))
                         la->la_mode &= ~S_ISGID;
         } else {
@@ -704,7 +704,7 @@ static int mdd_fix_attr(const struct lu_env *env, struct mdd_object *obj,
                         la->la_gid = tmp_la->la_gid;
                 if (((uc->mu_fsuid != tmp_la->la_uid) ||
                     ((la->la_gid != tmp_la->la_gid) &&
-                    !mdd_in_group_p(uc, la->la_gid))) &&
+                    !lustre_in_group_p(uc, la->la_gid))) &&
                     !mdd_capable(uc, CAP_CHOWN))
                         RETURN(-EPERM);
 
index a6357f0..1dad3eb 100644 (file)
 #include <lustre_mds.h>
 #include <lustre/lustre_idl.h>
 
-#ifdef CONFIG_FS_POSIX_ACL
-# include <linux/posix_acl_xattr.h>
-# include <linux/posix_acl.h>
-#endif
-
 #include "mdd_internal.h"
 
-#define mdd_get_group_info(group_info) do {             \
-        atomic_inc(&(group_info)->usage);               \
-} while (0)
-
-#define mdd_put_group_info(group_info) do {             \
-        if (atomic_dec_and_test(&(group_info)->usage))  \
-                groups_free(group_info);                \
-} while (0)
-
-#define MDD_NGROUPS_PER_BLOCK       ((int)(CFS_PAGE_SIZE / sizeof(gid_t)))
-
-#define MDD_GROUP_AT(gi, i) \
-    ((gi)->blocks[(i) / MDD_NGROUPS_PER_BLOCK][(i) % MDD_NGROUPS_PER_BLOCK])
-
-/*
- * groups_search() is copied from linux kernel!
- * A simple bsearch.
- */
-static int mdd_groups_search(struct group_info *group_info, gid_t grp)
-{
-        int left, right;
-
-        if (!group_info)
-                return 0;
-
-        left = 0;
-        right = group_info->ngroups;
-        while (left < right) {
-                int mid = (left + right) / 2;
-                int cmp = grp - MDD_GROUP_AT(group_info, mid);
-
-                if (cmp > 0)
-                        left = mid + 1;
-                else if (cmp < 0)
-                        right = mid;
-                else
-                        return 1;
-        }
-        return 0;
-}
-
-int mdd_in_group_p(struct md_ucred *uc, gid_t grp)
-{
-        int rc = 1;
-
-        if (grp != uc->mu_fsgid) {
-                struct group_info *group_info = NULL;
-
-                if (uc->mu_ginfo || !uc->mu_identity ||
-                    uc->mu_valid == UCRED_OLD)
-                        if (grp == uc->mu_suppgids[0] ||
-                            grp == uc->mu_suppgids[1])
-                                return 1;
-
-                if (uc->mu_ginfo)
-                        group_info = uc->mu_ginfo;
-                else if (uc->mu_identity)
-                        group_info = uc->mu_identity->mi_ginfo;
-
-                if (!group_info)
-                        return 0;
-
-                mdd_get_group_info(group_info);
-                rc = mdd_groups_search(group_info, grp);
-                mdd_put_group_info(group_info);
-        }
-        return rc;
-}
-
 #ifdef CONFIG_FS_POSIX_ACL
-static inline void mdd_acl_le_to_cpu(posix_acl_xattr_entry *p)
-{
-        p->e_tag = le16_to_cpu(p->e_tag);
-        p->e_perm = le16_to_cpu(p->e_perm);
-        p->e_id = le32_to_cpu(p->e_id);
-}
-
-static inline void mdd_acl_cpu_to_le(posix_acl_xattr_entry *p)
-{
-        p->e_tag = cpu_to_le16(p->e_tag);
-        p->e_perm = cpu_to_le16(p->e_perm);
-        p->e_id = cpu_to_le32(p->e_id);
-}
-
-/*
- * Check permission based on POSIX ACL.
- */
-static int mdd_posix_acl_permission(struct md_ucred *uc, struct lu_attr *la,
-                                    int want, posix_acl_xattr_entry *entry,
-                                    int count)
-{
-        posix_acl_xattr_entry *pa, *pe, *mask_obj;
-        int found = 0;
-        ENTRY;
-
-        if (count <= 0)
-                RETURN(-EACCES);
-
-        for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
-                mdd_acl_le_to_cpu(pa);
-                switch(pa->e_tag) {
-                        case ACL_USER_OBJ:
-                                /* (May have been checked already) */
-                                if (la->la_uid == uc->mu_fsuid)
-                                        goto check_perm;
-                                break;
-                        case ACL_USER:
-                                if (pa->e_id == uc->mu_fsuid)
-                                        goto mask;
-                                break;
-                        case ACL_GROUP_OBJ:
-                                if (mdd_in_group_p(uc, la->la_gid)) {
-                                        found = 1;
-                                        if ((pa->e_perm & want) == want)
-                                                goto mask;
-                                }
-                                break;
-                        case ACL_GROUP:
-                                if (mdd_in_group_p(uc, pa->e_id)) {
-                                        found = 1;
-                                        if ((pa->e_perm & want) == want)
-                                                goto mask;
-                                }
-                                break;
-                        case ACL_MASK:
-                                break;
-                        case ACL_OTHER:
-                                if (found)
-                                        RETURN(-EACCES);
-                                else
-                                        goto check_perm;
-                        default:
-                                RETURN(-EIO);
-                }
-        }
-        RETURN(-EIO);
-
-mask:
-        for (mask_obj = pa + 1; mask_obj <= pe; mask_obj++) {
-                mdd_acl_le_to_cpu(mask_obj);
-                if (mask_obj->e_tag == ACL_MASK) {
-                        if ((pa->e_perm & mask_obj->e_perm & want) == want)
-                                RETURN(0);
-
-                        RETURN(-EACCES);
-                }
-        }
-
-check_perm:
-        if ((pa->e_perm & want) == want)
-                RETURN(0);
-
-        RETURN(-EACCES);
-}
 
 /*
  * Get default acl EA only.
@@ -232,54 +74,6 @@ int mdd_acl_def_get(const struct lu_env *env, struct mdd_object *mdd_obj,
 }
 
 /*
- * Modify the ACL for the chmod.
- */
-static int mdd_posix_acl_chmod_masq(posix_acl_xattr_entry *entry,
-                                    __u32 mode, int count)
-{
-       posix_acl_xattr_entry *group_obj = NULL, *mask_obj = NULL, *pa, *pe;
-
-        for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
-                mdd_acl_le_to_cpu(pa);
-               switch(pa->e_tag) {
-                       case ACL_USER_OBJ:
-                               pa->e_perm = (mode & S_IRWXU) >> 6;
-                               break;
-
-                       case ACL_USER:
-                       case ACL_GROUP:
-                               break;
-
-                       case ACL_GROUP_OBJ:
-                               group_obj = pa;
-                               break;
-
-                       case ACL_MASK:
-                               mask_obj = pa;
-                               break;
-
-                       case ACL_OTHER:
-                               pa->e_perm = (mode & S_IRWXO);
-                               break;
-
-                       default:
-                               return -EIO;
-               }
-                mdd_acl_cpu_to_le(pa);
-       }
-
-       if (mask_obj) {
-               mask_obj->e_perm = cpu_to_le16((mode & S_IRWXG) >> 3);
-       } else {
-               if (!group_obj)
-                       return -EIO;
-               group_obj->e_perm = cpu_to_le16((mode & S_IRWXG) >> 3);
-       }
-
-       return 0;
-}
-
-/*
  * Hold write_lock for o.
  */
 int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode, 
@@ -310,7 +104,7 @@ int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode,
         if (entry_count <= 0)
                 RETURN(0);
        
-        rc = mdd_posix_acl_chmod_masq(entry, mode, entry_count);
+        rc = lustre_posix_acl_chmod_masq(entry, mode, entry_count);
         if (rc)
                 RETURN(rc);
 
@@ -320,67 +114,6 @@ int mdd_acl_chmod(const struct lu_env *env, struct mdd_object *o, __u32 mode,
 }
 
 /*
- * Modify acl when creating a new obj.
- */
-static int mdd_posix_acl_create_masq(posix_acl_xattr_entry *entry,
-                                     __u32 *mode_p, int count)
-{
-        posix_acl_xattr_entry *group_obj = NULL, *mask_obj = NULL, *pa, *pe;
-       __u32 mode = *mode_p;
-       int not_equiv = 0;
-
-        for (pa = &entry[0], pe = &entry[count - 1]; pa <= pe; pa++) {
-                mdd_acl_le_to_cpu(pa);
-                switch(pa->e_tag) {
-                        case ACL_USER_OBJ:
-                               pa->e_perm &= (mode >> 6) | ~S_IRWXO;
-                               mode &= (pa->e_perm << 6) | ~S_IRWXU;
-                               break;
-
-                       case ACL_USER:
-                       case ACL_GROUP:
-                               not_equiv = 1;
-                               break;
-
-                        case ACL_GROUP_OBJ:
-                               group_obj = pa;
-                                break;
-
-                        case ACL_OTHER:
-                               pa->e_perm &= mode | ~S_IRWXO;
-                               mode &= pa->e_perm | ~S_IRWXO;
-                                break;
-
-                        case ACL_MASK:
-                               mask_obj = pa;
-                               not_equiv = 1;
-                                break;
-
-                       default:
-                               return -EIO;
-                }
-                mdd_acl_cpu_to_le(pa);
-        }
-
-       if (mask_obj) {
-               mask_obj->e_perm = le16_to_cpu(mask_obj->e_perm) &
-                                   ((mode >> 3) | ~S_IRWXO);
-               mode &= (mask_obj->e_perm << 3) | ~S_IRWXG;
-                mask_obj->e_perm = cpu_to_le16(mask_obj->e_perm);
-       } else {
-               if (!group_obj)
-                       return -EIO;
-               group_obj->e_perm = le16_to_cpu(group_obj->e_perm) &
-                                    ((mode >> 3) | ~S_IRWXO);
-               mode &= (group_obj->e_perm << 3) | ~S_IRWXG;
-                group_obj->e_perm = cpu_to_le16(group_obj->e_perm);
-       }
-
-       *mode_p = (*mode_p & ~S_IRWXUGO) | mode;
-        return not_equiv;
-}
-
-/*
  * Hold write_lock for obj.
  */
 int __mdd_acl_init(const struct lu_env *env, struct mdd_object *obj,
@@ -407,7 +140,7 @@ int __mdd_acl_init(const struct lu_env *env, struct mdd_object *obj,
                         RETURN(rc);
        }
 
-        rc = mdd_posix_acl_create_masq(entry, mode, entry_count);
+        rc = lustre_posix_acl_create_masq(entry, mode, entry_count);
         if (rc <= 0)
                 RETURN(rc);
 
@@ -472,7 +205,7 @@ static int mdd_check_acl(const struct lu_env *env, struct mdd_object *obj,
         entry_count = (buf->lb_len - sizeof(head->a_version)) /
                       sizeof(posix_acl_xattr_entry);
 
-        rc = mdd_posix_acl_permission(uc, la, mask, entry, entry_count);
+        rc = lustre_posix_acl_permission(uc, la, mask, entry, entry_count);
         RETURN(rc);
 #else
         ENTRY;
@@ -528,7 +261,7 @@ int __mdd_permission_internal(const struct lu_env *env, struct mdd_object *obj,
                                  (rc != -ENODATA))
                                 RETURN(rc);
                 }
-                if (mdd_in_group_p(uc, la->la_gid))
+                if (lustre_in_group_p(uc, la->la_gid))
                         mode >>= 3;
         }
 
@@ -554,11 +287,13 @@ int mdd_permission(const struct lu_env *env,
                    struct md_attr *ma, int mask)
 {
         struct mdd_object *mdd_pobj, *mdd_cobj;
+        struct md_ucred *uc = NULL;
         struct lu_attr *la = NULL;
         int check_create, check_link;
         int check_unlink;
         int check_rename_src, check_rename_tar;
         int check_vtx_part, check_vtx_full;
+        int check_rgetfacl;
         int rc = 0;
         ENTRY;
 
@@ -584,11 +319,13 @@ int mdd_permission(const struct lu_env *env,
         check_rename_tar = mask & MAY_RENAME_TAR;
         check_vtx_part = mask & MAY_VTX_PART;
         check_vtx_full = mask & MAY_VTX_FULL;
+        check_rgetfacl = mask & MAY_RGETFACL;
 
         mask &= ~(MAY_CREATE | MAY_LINK |
                 MAY_UNLINK |
                 MAY_RENAME_SRC | MAY_RENAME_TAR |
-                MAY_VTX_PART | MAY_VTX_FULL);
+                MAY_VTX_PART | MAY_VTX_FULL |
+                MAY_RGETFACL);
 
         rc = mdd_permission_internal_locked(env, mdd_cobj, NULL, mask);
 
@@ -609,8 +346,7 @@ int mdd_permission(const struct lu_env *env,
         }
 
         if (!rc && (check_vtx_part || check_vtx_full)) {
-                struct md_ucred *uc = md_ucred(env);
-
+                uc = md_ucred(env);
                 LASSERT(ma);
                 if (likely(!la)) {
                         la = &mdd_env_info(env)->mti_la;
@@ -630,6 +366,21 @@ int mdd_permission(const struct lu_env *env,
                 }
         }
 
+        if (unlikely(!rc && check_rgetfacl)) {
+                if (likely(!uc))
+                        uc = md_ucred(env);
+
+                if (likely(!la)) {
+                        la = &mdd_env_info(env)->mti_la;
+                        rc = mdd_la_get(env, mdd_cobj, la, BYPASS_CAPA);
+                        if (rc)
+                                RETURN(rc);
+                }
+
+                if (la->la_uid != uc->mu_fsuid && !mdd_capable(uc, CAP_FOWNER))
+                        rc = -EPERM;
+        }
+
         RETURN(rc);
 }
 
index 4e16577..d5f60de 100644 (file)
@@ -289,7 +289,8 @@ static int mds_connect_internal(struct obd_export *exp,
         return 0;
 }
 
-static int mds_reconnect(struct obd_export *exp, struct obd_device *obd,
+static int mds_reconnect(const struct lu_env *env,
+                         struct obd_export *exp, struct obd_device *obd,
                          struct obd_uuid *cluuid,
                          struct obd_connect_data *data)
 {
@@ -340,6 +341,8 @@ static int mds_connect(const struct lu_env *env,
         LASSERT(exp);
         med = &exp->exp_mds_data;
 
+        exp->exp_flvr.sf_rpc = SPTLRPC_FLVR_NULL;
+
         rc = mds_connect_internal(exp, data);
         if (rc)
                 GOTO(out, rc);
index cc854bb..e06fd34 100644 (file)
@@ -1,5 +1,5 @@
 MODULES := mdt
 mdt-objs := mdt_handler.o mdt_lib.o mdt_reint.o mdt_xattr.o mdt_recovery.o
-mdt-objs += mdt_open.o mdt_idmap.o mdt_identity.o mdt_rmtacl.o mdt_capa.o mdt_lproc.o
+mdt-objs += mdt_open.o mdt_idmap.o mdt_identity.o mdt_capa.o mdt_lproc.o
 
 @INCLUDE_RULES@
index 206b5bd..001583f 100644 (file)
@@ -1347,10 +1347,6 @@ static int mdt_readpage(struct mdt_thread_info *info)
         if (reqbody == NULL || repbody == NULL)
                 RETURN(err_serious(-EFAULT));
 
-        rc = mdt_check_ucred(info);
-        if (rc)
-                RETURN(err_serious(rc));
-
         /*
          * prepare @rdpg before calling lower layers and transfer itself. Here
          * reqbody->size contains offset of where to start to read and
@@ -3676,9 +3672,6 @@ static void mdt_fini(const struct lu_env *env, struct mdt_device *m)
 
         mdt_fs_cleanup(env, m);
 
-        upcall_cache_cleanup(m->mdt_rmtacl_cache);
-        m->mdt_rmtacl_cache = NULL;
-
         upcall_cache_cleanup(m->mdt_identity_cache);
         m->mdt_identity_cache = NULL;
 
@@ -3694,10 +3687,7 @@ static void mdt_fini(const struct lu_env *env, struct mdt_device *m)
         ptlrpc_lprocfs_unregister_obd(d->ld_obd);
         lprocfs_obd_cleanup(d->ld_obd);
 
-        if (m->mdt_rootsquash_info) {
-                OBD_FREE_PTR(m->mdt_rootsquash_info);
-                m->mdt_rootsquash_info = NULL;
-        }
+        sptlrpc_rule_set_free(&m->mdt_sptlrpc_rset);
 
         next->md_ops->mdo_init_capa_ctxt(env, next, 0, 0, 0, NULL);
         del_timer(&m->mdt_ck_timer);
@@ -3781,6 +3771,7 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m,
         struct lustre_mount_info  *lmi;
         struct lustre_sb_info     *lsi;
         struct lu_site            *s;
+        const char                *identity_upcall = "NONE";
         int                        rc;
         ENTRY;
 
@@ -3807,6 +3798,9 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m,
                 server_put_mount_2(dev, lmi->lmi_mnt);
         }
 
+        m->mdt_sptlrpc_lock = RW_LOCK_UNLOCKED;
+        sptlrpc_rule_set_init(&m->mdt_sptlrpc_rset);
+
         spin_lock_init(&m->mdt_ioepoch_lock);
         m->mdt_opts.mo_compat_resname = 0;
         m->mdt_capa_timeout = CAPA_TIMEOUT;
@@ -3892,8 +3886,12 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m,
         /* set obd_namespace for compatibility with old code */
         obd->obd_namespace = m->mdt_namespace;
 
-        m->mdt_identity_cache = upcall_cache_init(obd->obd_name,
-                                                  "NONE",
+        /* XXX: to support suppgid for ACL, we enable identity_upcall
+         * by default, otherwise, maybe got unexpected -EACCESS. */
+        if (m->mdt_opts.mo_acl)
+                identity_upcall = MDT_IDENTITY_UPCALL_PATH;
+
+        m->mdt_identity_cache = upcall_cache_init(obd->obd_name, identity_upcall,
                                                   &mdt_identity_upcall_cache_ops);
         if (IS_ERR(m->mdt_identity_cache)) {
                 rc = PTR_ERR(m->mdt_identity_cache);
@@ -3901,15 +3899,6 @@ static int mdt_init0(const struct lu_env *env, struct mdt_device *m,
                 GOTO(err_free_ns, rc);
         }
 
-        m->mdt_rmtacl_cache = upcall_cache_init(obd->obd_name,
-                                                MDT_RMTACL_UPCALL_PATH,
-                                                &mdt_rmtacl_upcall_cache_ops);
-        if (IS_ERR(m->mdt_rmtacl_cache)) {
-                rc = PTR_ERR(m->mdt_rmtacl_cache);
-                m->mdt_rmtacl_cache = NULL;
-                GOTO(err_free_ns, rc);
-        }
-
         m->mdt_ck_timer.function = mdt_ck_timer_callback;
         m->mdt_ck_timer.data = (unsigned long)m;
         init_timer(&m->mdt_ck_timer);
@@ -3953,8 +3942,6 @@ err_capa:
         del_timer(&m->mdt_ck_timer);
         mdt_ck_thread_stop(m);
 err_free_ns:
-        upcall_cache_cleanup(m->mdt_rmtacl_cache);
-        m->mdt_rmtacl_cache = NULL;
         upcall_cache_cleanup(m->mdt_identity_cache);
         m->mdt_identity_cache = NULL;
         ldlm_namespace_free(m->mdt_namespace, 0);
@@ -3988,6 +3975,34 @@ static int mdt_process_config(const struct lu_env *env,
         ENTRY;
 
         switch (cfg->lcfg_command) {
+        case LCFG_SPTLRPC_CONF: {
+                struct sptlrpc_conf_log *log;
+                struct sptlrpc_rule_set  tmp_rset;
+
+                log = sptlrpc_conf_log_extract(cfg);
+                if (IS_ERR(log)) {
+                        rc = PTR_ERR(log);
+                        break;
+                }
+
+                sptlrpc_rule_set_init(&tmp_rset);
+
+                rc = sptlrpc_rule_set_from_log(&tmp_rset, log);
+                if (rc) {
+                        CERROR("mdt %p: failed get sptlrpc rules: %d\n", m, rc);
+                        break;
+                }
+
+                write_lock(&m->mdt_sptlrpc_lock);
+                sptlrpc_rule_set_free(&m->mdt_sptlrpc_rset);
+                m->mdt_sptlrpc_rset = tmp_rset;
+                write_unlock(&m->mdt_sptlrpc_lock);
+
+                sptlrpc_target_update_exp_flavor(
+                                md2lu_dev(&m->mdt_md_dev)->ld_obd, &tmp_rset);
+
+                break;
+        }
         case LCFG_PARAM: {
                 struct lprocfs_static_vars lvars;
                 struct obd_device *obd = d->ld_obd;
@@ -4173,9 +4188,11 @@ static int mdt_obd_connect(const struct lu_env *env,
                            struct obd_uuid *cluuid,
                            struct obd_connect_data *data)
 {
+        struct mdt_thread_info *info;
         struct mdt_client_data *mcd;
         struct obd_export      *exp;
         struct mdt_device      *mdt;
+        struct ptlrpc_request  *req;
         int                     rc;
         ENTRY;
 
@@ -4183,6 +4200,8 @@ static int mdt_obd_connect(const struct lu_env *env,
         if (!conn || !obd || !cluuid)
                 RETURN(-EINVAL);
 
+        info = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
+        req = info->mti_pill.rc_req;
         mdt = mdt_dev(obd->obd_lu_dev);
 
         rc = class_connect(conn, obd, cluuid);
@@ -4192,6 +4211,26 @@ static int mdt_obd_connect(const struct lu_env *env,
         exp = class_conn2export(conn);
         LASSERT(exp != NULL);
 
+        CDEBUG(D_SEC, "from %s\n", sptlrpc_part2name(req->rq_sp_from));
+
+        spin_lock(&exp->exp_lock);
+        exp->exp_sp_peer = req->rq_sp_from;
+
+        read_lock(&mdt->mdt_sptlrpc_lock);
+        sptlrpc_rule_set_choose(&mdt->mdt_sptlrpc_rset, exp->exp_sp_peer,
+                                req->rq_peer.nid, &exp->exp_flvr);
+        read_unlock(&mdt->mdt_sptlrpc_lock);
+
+        if (exp->exp_flvr.sf_rpc != req->rq_flvr.sf_rpc) {
+                CERROR("invalid rpc flavor %x, expect %x, from %s\n",
+                       req->rq_flvr.sf_rpc, exp->exp_flvr.sf_rpc,
+                       libcfs_nid2str(req->rq_peer.nid));
+                exp->exp_flvr.sf_rpc = SPTLRPC_FLVR_INVALID;
+                spin_unlock(&exp->exp_lock);
+                RETURN(-EACCES);
+        }
+        spin_unlock(&exp->exp_lock);
+
         rc = mdt_connect_internal(exp, mdt, data);
         if (rc == 0) {
                 OBD_ALLOC_PTR(mcd);
@@ -4220,16 +4259,47 @@ static int mdt_obd_connect(const struct lu_env *env,
         RETURN(rc);
 }
 
-static int mdt_obd_reconnect(struct obd_export *exp, struct obd_device *obd,
+static int mdt_obd_reconnect(const struct lu_env *env,
+                             struct obd_export *exp, struct obd_device *obd,
                              struct obd_uuid *cluuid,
                              struct obd_connect_data *data)
 {
-        int rc;
+        struct mdt_thread_info *info;
+        struct mdt_device      *mdt;
+        struct ptlrpc_request  *req;
+        int                     rc;
         ENTRY;
 
         if (exp == NULL || obd == NULL || cluuid == NULL)
                 RETURN(-EINVAL);
 
+        info = lu_context_key_get(&env->le_ctx, &mdt_thread_key);
+        req = info->mti_pill.rc_req;
+        mdt = mdt_dev(obd->obd_lu_dev);
+
+        CDEBUG(D_SEC, "from %s\n", sptlrpc_part2name(req->rq_sp_from));
+
+        spin_lock(&exp->exp_lock);
+        if (exp->exp_flvr.sf_rpc == SPTLRPC_FLVR_INVALID) {
+                exp->exp_sp_peer = req->rq_sp_from;
+
+                read_lock(&mdt->mdt_sptlrpc_lock);
+                sptlrpc_rule_set_choose(&mdt->mdt_sptlrpc_rset,
+                                        exp->exp_sp_peer,
+                                        req->rq_peer.nid, &exp->exp_flvr);
+                read_unlock(&mdt->mdt_sptlrpc_lock);
+
+                if (exp->exp_flvr.sf_rpc != req->rq_flvr.sf_rpc) {
+                        CERROR("invalid rpc flavor %x, expect %x, from %s\n",
+                               req->rq_flvr.sf_rpc, exp->exp_flvr.sf_rpc,
+                               libcfs_nid2str(req->rq_peer.nid));
+                        exp->exp_flvr.sf_rpc = SPTLRPC_FLVR_INVALID;
+                        spin_unlock(&exp->exp_lock);
+                        RETURN(-EACCES);
+                }
+        }
+        spin_unlock(&exp->exp_lock);
+
         rc = mdt_connect_internal(exp, mdt_dev(obd->obd_lu_dev), data);
 
         RETURN(rc);
@@ -4276,6 +4346,8 @@ static int mdt_init_export(struct obd_export *exp)
 
         INIT_LIST_HEAD(&med->med_open_head);
         spin_lock_init(&med->med_open_lock);
+        sema_init(&med->med_idmap_sem, 1);
+        med->med_idmap = NULL;
         spin_lock(&exp->exp_lock);
         exp->exp_connecting = 1;
         spin_unlock(&exp->exp_lock);
@@ -4775,6 +4847,11 @@ static struct mdt_opc_slice mdt_xmds_handlers[] = {
                 .mos_hs        = mdt_obd_ops
         },
         {
+                .mos_opc_start = SEC_CTX_INIT,
+                .mos_opc_end   = SEC_LAST_OPC,
+                .mos_hs        = mdt_sec_ctx_ops
+        },
+        {
                 .mos_hs        = NULL
         }
 };
index f196570..12ed4a8 100644 (file)
@@ -67,15 +67,18 @@ static void mdt_identity_entry_init(struct upcall_cache_entry *entry,
 static void mdt_identity_entry_free(struct upcall_cache *cache,
                                     struct upcall_cache_entry *entry)
 {
-        struct mdt_identity *identity = &entry->u.identity;
+        struct md_identity *identity = &entry->u.identity;
 
-        if (identity->mi_ginfo)
+        if (identity->mi_ginfo) {
                 groups_free(identity->mi_ginfo);
+                identity->mi_ginfo = NULL;
+        }
 
         if (identity->mi_nperms) {
                 LASSERT(identity->mi_perms);
                 OBD_FREE(identity->mi_perms,
-                         identity->mi_nperms * sizeof(struct mdt_setxid_perm));
+                         identity->mi_nperms * sizeof(struct md_perm));
+                identity->mi_nperms = 0;
         }
 }
 
@@ -120,10 +123,10 @@ static int mdt_identity_parse_downcall(struct upcall_cache *cache,
                                        struct upcall_cache_entry *entry,
                                        void *args)
 {
-        struct mdt_identity *identity = &entry->u.identity;
+        struct md_identity *identity = &entry->u.identity;
         struct identity_downcall_data *data = args;
         struct group_info *ginfo;
-        struct mdt_setxid_perm *perms = NULL;
+        struct md_perm *perms = NULL;
         int size, i;
         ENTRY;
 
@@ -137,9 +140,8 @@ static int mdt_identity_parse_downcall(struct upcall_cache *cache,
                 RETURN(-ENOMEM);
         }
 
-        groups_from_list(ginfo, data->idd_groups);
-        groups_sort(ginfo);
-        identity->mi_ginfo = ginfo;
+        lustre_groups_from_list(ginfo, data->idd_groups);
+        lustre_groups_sort(ginfo);
 
         if (data->idd_nperms) {
                 size = data->idd_nperms * sizeof(*perms);
@@ -147,9 +149,10 @@ static int mdt_identity_parse_downcall(struct upcall_cache *cache,
                 if (!perms) {
                         CERROR("failed to alloc %d permissions\n",
                                data->idd_nperms);
-                        put_group_info(ginfo);
+                        groups_free(ginfo);
                         RETURN(-ENOMEM);
                 }
+
                 for (i = 0; i < data->idd_nperms; i++) {
                         perms[i].mp_nid = data->idd_perms[i].pdd_nid;
                         perms[i].mp_perm = data->idd_perms[i].pdd_perm;
@@ -169,7 +172,7 @@ static int mdt_identity_parse_downcall(struct upcall_cache *cache,
         RETURN(0);
 }
 
-struct mdt_identity *mdt_identity_get(struct upcall_cache *cache, __u32 uid)
+struct md_identity *mdt_identity_get(struct upcall_cache *cache, __u32 uid)
 {
         struct upcall_cache_entry *entry;
 
@@ -185,7 +188,7 @@ struct mdt_identity *mdt_identity_get(struct upcall_cache *cache, __u32 uid)
         return &entry->u.identity;
 }
 
-void mdt_identity_put(struct upcall_cache *cache, struct mdt_identity *identity)
+void mdt_identity_put(struct upcall_cache *cache, struct md_identity *identity)
 {
         if (!cache)
                 return;
@@ -213,12 +216,18 @@ void mdt_flush_identity(struct upcall_cache *cache, int uid)
  * If there is LNET_NID_ANY in perm[i].mp_nid,
  * it must be perm[0].mp_nid, and act as default perm.
  */
-__u32 mdt_identity_get_setxid_perm(struct mdt_identity *identity,
+__u32 mdt_identity_get_perm(struct md_identity *identity,
                                    __u32 is_rmtclient, lnet_nid_t nid)
 {
-        struct mdt_setxid_perm *perm = identity->mi_perms;
+        struct md_perm *perm;
         int i;
 
+        if (!identity) {
+                LASSERT(is_rmtclient == 0);
+                return CFS_SETGRP_PERM;
+        }
+
+        perm = identity->mi_perms;
         /* check exactly matched nid first */
         for (i = identity->mi_nperms - 1; i > 0; i--) {
                 if (perm[i].mp_nid != nid)
@@ -232,7 +241,7 @@ __u32 mdt_identity_get_setxid_perm(struct mdt_identity *identity,
                 return perm[0].mp_perm;
 
         /* return default last */
-        return is_rmtclient ? 0 : LUSTRE_SETGRP_PERM;
+        return is_rmtclient ? 0 : CFS_SETGRP_PERM;
 }
 
 int mdt_pack_remote_perm(struct mdt_thread_info *info, struct mdt_object *o,
index 567c884..d7d602c 100644 (file)
@@ -27,9 +27,7 @@
 #endif
 #define DEBUG_SUBSYSTEM S_MDS
 
-#ifndef AUTOCONF_INCLUDED
 #include <linux/config.h>
-#endif
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/mm.h>
 
 #include "mdt_internal.h"
 
-enum {
-        MDT_IDMAP_NOTFOUND      = -1,
-};
-
-struct mdt_idmap_entry {
-        struct list_head mie_rmt_hash; /* hashed as mie_rmt_id; */
-        struct list_head mie_lcl_hash; /* hashed as mie_lcl_id; */
-        int              mie_refcount;
-        uid_t            mie_rmt_id;   /* remote uid/gid */
-        uid_t            mie_lcl_id;   /* local uid/gid */
-};
-
-/* uid/gid mapping */
-static struct mdt_idmap_table *mdt_idmap_alloc(void)
-{
-        struct mdt_idmap_table *tbl;
-        int i, j;
-
-        OBD_ALLOC_PTR(tbl);
-        if (!tbl)
-                return NULL;
-
-        spin_lock_init(&tbl->mit_lock);
-        for (i = 0; i < ARRAY_SIZE(tbl->mit_idmaps); i++)
-                for (j = 0; j < ARRAY_SIZE(tbl->mit_idmaps[i]); j++)
-                        INIT_LIST_HEAD(&tbl->mit_idmaps[i][j]);
-
-        return tbl;
-}
-
-static struct mdt_idmap_entry *idmap_entry_alloc(__u32 mie_rmt_id,
-                                                 __u32 mie_lcl_id)
-{
-        struct mdt_idmap_entry *e;
-
-        OBD_ALLOC_PTR(e);
-        if (!e)
-                return NULL;
-
-        INIT_LIST_HEAD(&e->mie_rmt_hash);
-        INIT_LIST_HEAD(&e->mie_lcl_hash);
-        e->mie_refcount = 1;
-        e->mie_rmt_id = mie_rmt_id;
-        e->mie_lcl_id = mie_lcl_id;
-
-        return e;
-}
-
-static void idmap_entry_free(struct mdt_idmap_entry *e)
-{
-        if (!list_empty(&e->mie_rmt_hash))
-                list_del(&e->mie_rmt_hash);
-        if (!list_empty(&e->mie_lcl_hash))
-                list_del(&e->mie_lcl_hash);
-        OBD_FREE_PTR(e);
-}
-
 int mdt_init_idmap(struct mdt_thread_info *info)
 {
         struct ptlrpc_request *req = mdt_info_req(info);
@@ -135,7 +76,6 @@ int mdt_init_idmap(struct mdt_thread_info *info)
         if (!req->rq_auth_gss || req->rq_auth_usr_mdt) {
                 med->med_rmtclient = 0;
                 reply->ocd_connect_flags &= ~OBD_CONNECT_RMT_CLIENT;
-                //reply->ocd_connect_flags |= OBD_CONNECT_LCL_CLIENT;
                 RETURN(0);
         }
 
@@ -153,22 +93,31 @@ int mdt_init_idmap(struct mdt_thread_info *info)
         }
 
         if (med->med_rmtclient) {
-                med->med_nllu = data->ocd_nllu;
-                med->med_nllg = data->ocd_nllg;
+                down(&med->med_idmap_sem);
                 if (!med->med_idmap)
-                        med->med_idmap = mdt_idmap_alloc();
-                if (!med->med_idmap) {
-                        CERROR("client %s -> target %s failed to alloc idmap!\n"
-                               , client, obd->obd_name);
+                        med->med_idmap = lustre_idmap_init();
+                up(&med->med_idmap_sem);
+
+                if (IS_ERR(med->med_idmap)) {
+                        long err = PTR_ERR(med->med_idmap);
+
+                        med->med_idmap = NULL;
+                        CERROR("client %s -> target %s "
+                               "failed to init idmap [%ld]!\n",
+                               client, obd->obd_name, err);
+                        RETURN(err);
+                } else if (!med->med_idmap) {
+                        CERROR("client %s -> target %s "
+                               "failed to init(2) idmap!\n",
+                               client, obd->obd_name);
                         RETURN(-ENOMEM);
                 }
 
                 reply->ocd_connect_flags &= ~OBD_CONNECT_LCL_CLIENT;
-                //reply->ocd_connect_flags |= OBD_CONNECT_RMT_CLIENT;
                 CDEBUG(D_SEC, "client %s -> target %s is remote.\n",
                        client, obd->obd_name);
 
-                /* NB, MDT_CONNECT establish root idmap too! */
+                /* NB, MDS_CONNECT establish root idmap too! */
                 rc = mdt_handle_idmap(info);
         } else {
                 if (req->rq_auth_uid == INVALID_UID) {
@@ -177,47 +126,21 @@ int mdt_init_idmap(struct mdt_thread_info *info)
                         RETURN(-EACCES);
                 }
                 reply->ocd_connect_flags &= ~OBD_CONNECT_RMT_CLIENT;
-                //reply->ocd_connect_flags |= OBD_CONNECT_LCL_CLIENT;
         }
 
         RETURN(rc);
 }
 
-static void idmap_clear_mie_rmt_hash(struct list_head *list)
-{
-        struct mdt_idmap_entry *e;
-        int i;
-
-        for (i = 0; i < MDT_IDMAP_HASHSIZE; i++) {
-                while (!list_empty(&list[i])) {
-                        e = list_entry(list[i].next, struct mdt_idmap_entry,
-                                       mie_rmt_hash);
-                        idmap_entry_free(e);
-                }
-        }
-}
-
 void mdt_cleanup_idmap(struct mdt_export_data *med)
 {
-        struct mdt_idmap_table *tbl = med->med_idmap;
-        int i;
-
         LASSERT(med->med_rmtclient);
-        LASSERT(tbl);
-
-        spin_lock(&tbl->mit_lock);
-        idmap_clear_mie_rmt_hash(tbl->mit_idmaps[RMT_UIDMAP_IDX]);
-        idmap_clear_mie_rmt_hash(tbl->mit_idmaps[RMT_GIDMAP_IDX]);
-
-        /* paranoid checking */
-        for (i = 0; i < MDT_IDMAP_HASHSIZE; i++) {
-                LASSERT(list_empty(&tbl->mit_idmaps[LCL_UIDMAP_IDX][i]));
-                LASSERT(list_empty(&tbl->mit_idmaps[LCL_GIDMAP_IDX][i]));
-        }
-        spin_unlock(&tbl->mit_lock);
 
-        OBD_FREE_PTR(tbl);
+        down(&med->med_idmap_sem);
+        if (med->med_idmap != NULL) {
+                lustre_idmap_fini(med->med_idmap);
         med->med_idmap = NULL;
+        }
+        up(&med->med_idmap_sem);
 }
 
 static inline void mdt_revoke_export_locks(struct obd_export *exp)
@@ -229,217 +152,15 @@ static inline void mdt_revoke_export_locks(struct obd_export *exp)
         ldlm_revoke_export_locks(exp);
 }
 
-static
-struct mdt_idmap_entry *idmap_lookup_entry(struct list_head *mie_rmt_hash,
-                                           uid_t mie_rmt_id, uid_t mie_lcl_id)
-{
-        struct list_head *rmt_head =
-                         &mie_rmt_hash[MDT_IDMAP_HASHFUNC(mie_rmt_id)];
-        struct mdt_idmap_entry *e;
-
-        list_for_each_entry(e, rmt_head, mie_rmt_hash) {
-                if ((e->mie_rmt_id == mie_rmt_id) &&
-                    (e->mie_lcl_id == mie_lcl_id))
-                        return e;
-        }
-        return NULL;
-}
-
-/*
- * return value
- * NULL: not found entry
- * ERR_PTR(-EACCES): found multi->single mapped entry
- * others: found normal entry
- */
-static
-struct mdt_idmap_entry *idmap_search_entry(struct list_head *mie_rmt_hash,
-                                           uid_t mie_rmt_id,
-                                           struct list_head *mie_lcl_hash,
-                                           uid_t mie_lcl_id,
-                                           const char *warn_msg)
-{
-        struct list_head *rmt_head =
-                         &mie_rmt_hash[MDT_IDMAP_HASHFUNC(mie_rmt_id)];
-        struct list_head *lcl_head =
-                         &mie_lcl_hash[MDT_IDMAP_HASHFUNC(mie_lcl_id)];
-        struct mdt_idmap_entry *e;
-
-        list_for_each_entry(e, rmt_head, mie_rmt_hash) {
-                if (e->mie_rmt_id == mie_rmt_id) {
-                        if (e->mie_lcl_id == mie_lcl_id) {
-                                e->mie_refcount++;
-                                return e;
-                        } else {
-                                CERROR("%s: rmt id %u already be mapped to %u"
-                                       " (new %u)\n", warn_msg, e->mie_rmt_id,
-                                       e->mie_lcl_id, mie_lcl_id);
-                                return ERR_PTR(-EACCES);
-                        }
-                }
-        }
-
-        list_for_each_entry(e, lcl_head, mie_lcl_hash) {
-                if (e->mie_lcl_id == mie_lcl_id) {
-                        if (e->mie_rmt_id == mie_rmt_id) {
-                                e->mie_refcount++;
-                                return e;
-                        } else {
-                                CERROR("%s: lcl id %u already be mapped from %u"
-                                       " (new %u)\n", warn_msg, e->mie_lcl_id,
-                                       e->mie_rmt_id, mie_rmt_id);
-                                return ERR_PTR(-EACCES);
-                        }
-                }
-        }
-
-        return NULL;
-}
-
-static
-struct mdt_idmap_entry *idmap_insert_entry(struct list_head *mie_rmt_hash,
-                                           struct list_head *mie_lcl_hash,
-                                           struct mdt_idmap_entry *new,
-                                           const char *warn_msg)
-{
-        struct list_head *rmt_head =
-                         &mie_rmt_hash[MDT_IDMAP_HASHFUNC(new->mie_rmt_id)];
-        struct list_head *lcl_head =
-                         &mie_lcl_hash[MDT_IDMAP_HASHFUNC(new->mie_lcl_id)];
-        struct mdt_idmap_entry *e;
-
-        e = idmap_search_entry(mie_rmt_hash, new->mie_rmt_id,
-                               mie_lcl_hash, new->mie_lcl_id,
-                               warn_msg);
-        if (e == NULL) {
-                list_add_tail(&new->mie_rmt_hash, rmt_head);
-                list_add_tail(&new->mie_lcl_hash, lcl_head);
-        }
-        return e;
-}
-
-static int idmap_remove_entry(struct list_head *mie_rmt_hash,
-                              struct list_head *mie_lcl_hash,
-                              __u32 mie_rmt_id, __u32 mie_lcl_id)
-{
-        struct mdt_idmap_entry *e;
-        int rc = -ENOENT;
-
-        e = idmap_lookup_entry(mie_rmt_hash, mie_rmt_id, mie_lcl_id);
-        if (e != NULL) {
-                        e->mie_refcount--;
-                        if ((rc = e->mie_refcount) <= 0)
-                                idmap_entry_free(e);
-        }
-        return rc;
-}
-
-static int mdt_idmap_add(struct mdt_idmap_table *tbl,
-                         uid_t ruid, uid_t luid,
-                         gid_t rgid, gid_t lgid)
-{
-        struct mdt_idmap_entry *ue0, *ue1, *ge0, *ge1;
-        ENTRY;
-
-        LASSERT(tbl);
-
-        spin_lock(&tbl->mit_lock);
-        ue0 = idmap_search_entry(tbl->mit_idmaps[RMT_UIDMAP_IDX], ruid,
-                                 tbl->mit_idmaps[LCL_UIDMAP_IDX], luid,
-                                 "UID mapping");
-        spin_unlock(&tbl->mit_lock);
-        if (!ue0) {
-                ue0 = idmap_entry_alloc(ruid, luid);
-                if (!ue0)
-                        RETURN(-ENOMEM);
-
-                spin_lock(&tbl->mit_lock);
-                ue1 = idmap_insert_entry(tbl->mit_idmaps[RMT_UIDMAP_IDX],
-                                         tbl->mit_idmaps[LCL_UIDMAP_IDX],
-                                         ue0, "UID mapping");
-                if (ue1 != NULL) {
-                        idmap_entry_free(ue0);
-                        ue0 = ue1;
-                }
-                spin_unlock(&tbl->mit_lock);
-
-                if (IS_ERR(ue1))
-                        RETURN(PTR_ERR(ue1));
-        } else if (IS_ERR(ue0)) {
-                RETURN(PTR_ERR(ue0));
-        }
-
-        spin_lock(&tbl->mit_lock);
-        ge0 = idmap_search_entry(tbl->mit_idmaps[RMT_GIDMAP_IDX], rgid,
-                                 tbl->mit_idmaps[LCL_GIDMAP_IDX], lgid,
-                                 "GID mapping");
-        spin_unlock(&tbl->mit_lock);
-        if (!ge0) {
-                ge0 = idmap_entry_alloc(rgid, lgid);
-                spin_lock(&tbl->mit_lock);
-                if (!ge0) {
-                        ue0->mie_refcount--;
-                        if (ue0->mie_refcount <= 0)
-                                idmap_entry_free(ue0);
-                        spin_unlock(&tbl->mit_lock);
-                        RETURN(-ENOMEM);
-                }
-
-                ge1 = idmap_insert_entry(tbl->mit_idmaps[RMT_GIDMAP_IDX],
-                                         tbl->mit_idmaps[LCL_GIDMAP_IDX],
-                                         ge0, "GID mapping");
-                if (ge1 != NULL) {
-                        ue0->mie_refcount--;
-                        if (ue0->mie_refcount <= 0)
-                                idmap_entry_free(ue0);
-                        idmap_entry_free(ge0);
-                }
-                spin_unlock(&tbl->mit_lock);
-
-                if (IS_ERR(ge1))
-                        RETURN(PTR_ERR(ge1));
-        } else if (IS_ERR(ge0)) {
-                spin_lock(&tbl->mit_lock);
-                ue0->mie_refcount--;
-                if (ue0->mie_refcount <= 0)
-                        idmap_entry_free(ue0);
-                spin_unlock(&tbl->mit_lock);
-                RETURN(PTR_ERR(ge0));
-        }
-
-        RETURN(0);
-}
-
-static int mdt_idmap_del(struct mdt_idmap_table *tbl,
-                         uid_t ruid, uid_t luid,
-                         gid_t rgid, gid_t lgid)
-{
-        ENTRY;
-
-        if (!tbl)
-                RETURN(0);
-
-        spin_lock(&tbl->mit_lock);
-        idmap_remove_entry(tbl->mit_idmaps[RMT_UIDMAP_IDX],
-                           tbl->mit_idmaps[LCL_UIDMAP_IDX],
-                           ruid, luid);
-        idmap_remove_entry(tbl->mit_idmaps[RMT_GIDMAP_IDX],
-                           tbl->mit_idmaps[LCL_GIDMAP_IDX],
-                           rgid, lgid);
-        spin_unlock(&tbl->mit_lock);
-
-        RETURN(0);
-}
-
 int mdt_handle_idmap(struct mdt_thread_info *info)
 {
         struct ptlrpc_request *req = mdt_info_req(info);
         struct mdt_device *mdt = info->mti_mdt;
         struct mdt_export_data *med;
         struct ptlrpc_user_desc *pud = req->rq_user_desc;
-        struct mdt_identity *identity;
+        struct md_identity *identity;
         __u32 opc;
         int rc = 0;
-
         ENTRY;
 
         if (!req->rq_export)
@@ -455,9 +176,13 @@ int mdt_handle_idmap(struct mdt_thread_info *info)
             (opc != SEC_CTX_FINI) && (opc != MDS_CONNECT))
                 RETURN(0);
 
-        LASSERT(pud);
         LASSERT(med->med_idmap);
 
+        if (unlikely(!pud)) {
+                CERROR("remote client must run with rq_user_desc present\n");
+                RETURN(-EACCES);
+       }
+
         if (req->rq_auth_mapped_uid == INVALID_UID) {
                 CERROR("invalid authorized mapped uid, please check "
                        "/etc/lustre/idmap.conf!\n");
@@ -481,12 +206,12 @@ int mdt_handle_idmap(struct mdt_thread_info *info)
         case SEC_CTX_INIT:
         case SEC_CTX_INIT_CONT:
         case MDS_CONNECT:
-                rc = mdt_idmap_add(med->med_idmap,
+                        rc = lustre_idmap_add(med->med_idmap,
                                    pud->pud_uid, identity->mi_uid,
                                    pud->pud_gid, identity->mi_gid);
                 break;
         case SEC_CTX_FINI:
-                rc = mdt_idmap_del(med->med_idmap,
+                        rc = lustre_idmap_del(med->med_idmap,
                                    pud->pud_uid, identity->mi_uid,
                                    pud->pud_gid, identity->mi_gid);
                 break;
@@ -504,67 +229,15 @@ int mdt_handle_idmap(struct mdt_thread_info *info)
                 mdt_revoke_export_locks(req->rq_export);
                 break;
         }
-        RETURN(0);
-}
-
-static __u32 idmap_lookup_id(struct list_head *hash, int reverse, __u32 id)
-{
-        struct list_head *head = &hash[MDT_IDMAP_HASHFUNC(id)];
-        struct mdt_idmap_entry *e;
-
-        if (!reverse) {
-                list_for_each_entry(e, head, mie_rmt_hash) {
-                        if (e->mie_rmt_id == id)
-                                return e->mie_lcl_id;
-                }
-        } else {
-                list_for_each_entry(e, head, mie_lcl_hash) {
-                        if (e->mie_lcl_id == id)
-                                return e->mie_rmt_id;
-                }
-        }
-        return MDT_IDMAP_NOTFOUND;
-}
-
-static int mdt_idmap_lookup_uid(struct mdt_idmap_table *tbl, int reverse,
-                                uid_t uid)
-{
-        struct list_head *hash;
-
-        if (!tbl)
-                return MDT_IDMAP_NOTFOUND;
-
-        hash = tbl->mit_idmaps[reverse ? LCL_UIDMAP_IDX : RMT_UIDMAP_IDX];
-
-        spin_lock(&tbl->mit_lock);
-        uid = idmap_lookup_id(hash, reverse, uid);
-        spin_unlock(&tbl->mit_lock);
-
-        return uid;
-}
-
-static int mdt_idmap_lookup_gid(struct mdt_idmap_table *tbl, int reverse,
-                                gid_t gid)
-{
-        struct list_head *hash;
-
-        if (!tbl)
-                return MDT_IDMAP_NOTFOUND;
-
-        hash = tbl->mit_idmaps[reverse ? LCL_GIDMAP_IDX : RMT_GIDMAP_IDX];
-
-        spin_lock(&tbl->mit_lock);
-        gid = idmap_lookup_id(hash, reverse, gid);
-        spin_unlock(&tbl->mit_lock);
 
-        return gid;
+        RETURN(0);
 }
 
 int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
                               struct ptlrpc_user_desc *pud)
 {
         struct mdt_export_data *med = mdt_req2med(req);
-        struct mdt_idmap_table *idmap = med->med_idmap;
+        struct lustre_idmap_table *idmap = med->med_idmap;
         uid_t uid, fsuid;
         gid_t gid, fsgid;
 
@@ -572,8 +245,8 @@ int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
         if (!med->med_rmtclient)
                 return 0;
 
-        uid = mdt_idmap_lookup_uid(idmap, 0, pud->pud_uid);
-        if (uid == MDT_IDMAP_NOTFOUND) {
+        uid = lustre_idmap_lookup_uid(NULL, idmap, 0, pud->pud_uid);
+        if (uid == CFS_IDMAP_NOTFOUND) {
                 CERROR("no mapping for uid %u\n", pud->pud_uid);
                 return -EACCES;
         }
@@ -581,15 +254,15 @@ int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
         if (pud->pud_uid == pud->pud_fsuid) {
                 fsuid = uid;
         } else {
-                fsuid = mdt_idmap_lookup_uid(idmap, 0, pud->pud_fsuid);
-                if (fsuid == MDT_IDMAP_NOTFOUND) {
+                fsuid = lustre_idmap_lookup_uid(NULL, idmap, 0, pud->pud_fsuid);
+                if (fsuid == CFS_IDMAP_NOTFOUND) {
                         CERROR("no mapping for fsuid %u\n", pud->pud_fsuid);
                         return -EACCES;
                 }
         }
 
-        gid = mdt_idmap_lookup_gid(idmap, 0, pud->pud_gid);
-        if (gid == MDT_IDMAP_NOTFOUND) {
+        gid = lustre_idmap_lookup_gid(NULL, idmap, 0, pud->pud_gid);
+        if (gid == CFS_IDMAP_NOTFOUND) {
                 CERROR("no mapping for gid %u\n", pud->pud_gid);
                 return -EACCES;
         }
@@ -597,8 +270,8 @@ int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
         if (pud->pud_gid == pud->pud_fsgid) {
                 fsgid = gid;
         } else {
-                fsgid = mdt_idmap_lookup_gid(idmap, 0, pud->pud_fsgid);
-                if (fsgid == MDT_IDMAP_NOTFOUND) {
+                fsgid = lustre_idmap_lookup_gid(NULL, idmap, 0, pud->pud_fsgid);
+                if (fsgid == CFS_IDMAP_NOTFOUND) {
                         CERROR("no mapping for fsgid %u\n", pud->pud_fsgid);
                         return -EACCES;
                 }
@@ -613,37 +286,23 @@ int ptlrpc_user_desc_do_idmap(struct ptlrpc_request *req,
 }
 
 /*
- * Reverse map
- * Do not ignore rootsquash.
+ * Reverse mapping
  */
 void mdt_body_reverse_idmap(struct mdt_thread_info *info, struct mdt_body *body)
 {
         struct ptlrpc_request   *req = mdt_info_req(info);
         struct md_ucred         *uc = mdt_ucred(info);
         struct mdt_export_data  *med = mdt_req2med(req);
-        struct mdt_idmap_table  *idmap = med->med_idmap;
-        uid_t uid;
-        gid_t gid;
+        struct lustre_idmap_table *idmap = med->med_idmap;
 
         if (!med->med_rmtclient)
                 return;
 
         if (body->valid & OBD_MD_FLUID) {
-                if (((uc->mu_valid == UCRED_OLD) ||
-                    (uc->mu_valid == UCRED_NEW)) &&
-                    !(uc->mu_squash & SQUASH_UID)) {
-                        if (body->uid == uc->mu_uid)
-                                uid = uc->mu_o_uid;
-                        else if (body->uid == uc->mu_fsuid)
-                                uid = uc->mu_o_fsuid;
-                        else
-                                uid = mdt_idmap_lookup_uid(idmap, 1, body->uid);
-                } else {
-                        uid = mdt_idmap_lookup_uid(idmap, 1, body->uid);
-                }
+                uid_t uid = lustre_idmap_lookup_uid(uc, idmap, 1, body->uid);
 
-                if (uid == MDT_IDMAP_NOTFOUND) {
-                        uid = med->med_nllu;
+                if (uid == CFS_IDMAP_NOTFOUND) {
+                        uid = NOBODY_UID;
                         if (body->valid & OBD_MD_FLMODE)
                                 body->mode = (body->mode & ~S_IRWXU) |
                                              ((body->mode & S_IRWXO) << 6);
@@ -653,21 +312,10 @@ void mdt_body_reverse_idmap(struct mdt_thread_info *info, struct mdt_body *body)
         }
 
         if (body->valid & OBD_MD_FLGID) {
-                if (((uc->mu_valid == UCRED_OLD) ||
-                    (uc->mu_valid == UCRED_NEW)) &&
-                    !(uc->mu_squash & SQUASH_GID)) {
-                        if (body->gid == uc->mu_gid)
-                                gid = uc->mu_o_gid;
-                        else if (body->gid == uc->mu_fsgid)
-                                gid = uc->mu_o_fsgid;
-                        else
-                                gid = mdt_idmap_lookup_gid(idmap, 1, body->gid);
-                } else {
-                        gid = mdt_idmap_lookup_gid(idmap, 1, body->gid);
-                }
+                gid_t gid = lustre_idmap_lookup_gid(uc, idmap, 1, body->gid);
 
-                if (gid == MDT_IDMAP_NOTFOUND) {
-                        gid = med->med_nllg;
+                if (gid == CFS_IDMAP_NOTFOUND) {
+                        gid = NOBODY_GID;
                         if (body->valid & OBD_MD_FLMODE)
                                 body->mode = (body->mode & ~S_IRWXG) |
                                              ((body->mode & S_IRWXO) << 3);
@@ -677,124 +325,50 @@ void mdt_body_reverse_idmap(struct mdt_thread_info *info, struct mdt_body *body)
         }
 }
 
-/* NB: return error if no mapping, so this will look strange:
- * if client hasn't kinit the to map xid for the mapped xid, client
- * will always get -EPERM, and the same for rootsquash case. */
-int mdt_remote_perm_reverse_idmap(struct ptlrpc_request *req,
-                                  struct mdt_remote_perm *perm)
-{
-        struct mdt_export_data *med = mdt_req2med(req);
-        uid_t uid, fsuid;
-        gid_t gid, fsgid;
-
-        LASSERT(med->med_rmtclient);
-
-        uid = mdt_idmap_lookup_uid(med->med_idmap, 1, perm->rp_uid);
-        if (uid == MDT_IDMAP_NOTFOUND) {
-                CERROR("no mapping for uid %u\n", perm->rp_uid);
-                return -EPERM;
-        }
-
-        gid = mdt_idmap_lookup_gid(med->med_idmap, 1, perm->rp_gid);
-        if (gid == MDT_IDMAP_NOTFOUND) {
-                CERROR("no mapping for gid %u\n", perm->rp_gid);
-                return -EPERM;
-        }
-
-        if (perm->rp_uid != perm->rp_fsuid) {
-                fsuid = mdt_idmap_lookup_uid(med->med_idmap, 1, perm->rp_fsuid);
-                if (fsuid == MDT_IDMAP_NOTFOUND) {
-                        CERROR("no mapping for fsuid %u\n", perm->rp_fsuid);
-                        return -EPERM;
-                }
-        } else {
-                fsuid = uid;
-        }
-
-        if (perm->rp_gid != perm->rp_fsgid) {
-                fsgid = mdt_idmap_lookup_gid(med->med_idmap, 1, perm->rp_fsgid);
-                if (fsgid == MDT_IDMAP_NOTFOUND) {
-                        CERROR("no mapping for fsgid %u\n", perm->rp_fsgid);
-                        return -EPERM;
-                }
-        } else {
-                fsgid = gid;
-        }
-
-        perm->rp_uid = uid;
-        perm->rp_gid = gid;
-        perm->rp_fsuid = fsuid;
-        perm->rp_fsgid = fsgid;
-        return 0;
-}
-
-/* Process remote client and rootsquash */
+/* Do not ignore root_squash for non-setattr case. */
 int mdt_fix_attr_ucred(struct mdt_thread_info *info, __u32 op)
 {
         struct ptlrpc_request   *req = mdt_info_req(info);
         struct md_ucred         *uc = mdt_ucred(info);
         struct lu_attr          *attr = &info->mti_attr.ma_attr;
         struct mdt_export_data  *med = mdt_req2med(req);
-        struct mdt_idmap_table  *idmap = med->med_idmap;
-
-        ENTRY;
+        struct lustre_idmap_table *idmap = med->med_idmap;
 
         if ((uc->mu_valid != UCRED_OLD) && (uc->mu_valid != UCRED_NEW))
-                RETURN(-EINVAL);
-
-        if (!med->med_rmtclient && (uc->mu_squash == SQUASH_NONE))
-                RETURN(0);
+                return -EINVAL;
 
         if (op != REINT_SETATTR) {
                 if ((attr->la_valid & LA_UID) && (attr->la_uid != -1))
                         attr->la_uid = uc->mu_fsuid;
-                if (op != REINT_CREATE) {
+                /* for S_ISGID, inherit gid from his parent, such work will be
+                 * done in cmm/mdd layer, here set all cases as uc->mu_fsgid. */
                         if ((attr->la_valid & LA_GID) && (attr->la_gid != -1))
                                 attr->la_gid = uc->mu_fsgid;
-                } else {
-                        /* for S_ISGID, inherit gid from his parent */
-                        if (!(attr->la_mode & S_ISGID) && (attr->la_gid != -1))
-                                attr->la_gid = uc->mu_fsgid;
-                }
         } else if (med->med_rmtclient) {
                 /* NB: -1 case will be handled by mdt_fix_attr() later. */
                 if ((attr->la_valid & LA_UID) && (attr->la_uid != -1)) {
-                        uid_t uid;
-
-                        if (attr->la_uid == uc->mu_o_uid)
-                                uid = uc->mu_uid;
-                        else if (attr->la_uid == uc->mu_o_fsuid)
-                                uid = uc->mu_fsuid;
-                        else
-                                uid = mdt_idmap_lookup_uid(idmap, 0,
+                        uid_t uid = lustre_idmap_lookup_uid(uc, idmap, 0,
                                                            attr->la_uid);
 
-                        if (uid == MDT_IDMAP_NOTFOUND) {
+                        if (uid == CFS_IDMAP_NOTFOUND) {
                                 CWARN("Deny chown to uid %u\n", attr->la_uid);
-                                RETURN(-EPERM);
+                                return -EPERM;
                         }
 
                         attr->la_uid = uid;
                 }
                 if ((attr->la_valid & LA_GID) && (attr->la_gid != -1)) {
-                        gid_t gid;
-
-                        if (attr->la_gid == uc->mu_o_gid)
-                                gid = uc->mu_gid;
-                        else if (attr->la_gid == uc->mu_o_fsgid)
-                                gid = uc->mu_fsgid;
-                        else
-                                gid = mdt_idmap_lookup_gid(idmap, 0,
+                        gid_t gid = lustre_idmap_lookup_gid(uc, idmap, 0,
                                                            attr->la_gid);
 
-                        if (gid == MDT_IDMAP_NOTFOUND) {
+                        if (gid == CFS_IDMAP_NOTFOUND) {
                                 CWARN("Deny chown to gid %u\n", attr->la_gid);
-                                RETURN(-EPERM);
+                                return -EPERM;
                         }
 
                         attr->la_gid = gid;
                 }
         }
 
-        RETURN(0);
+        return 0;
 }
index 4ff1b1e..1745876 100644 (file)
@@ -55,6 +55,8 @@
 #include <lustre_disk.h>
 #include <lustre_sec.h>
 #include <lvfs.h>
+#include <lustre_idmap.h>
+#include <lustre_eacl.h>
 
 
 /* Data stored per client in the last_rcvd file.  In le32 order. */
@@ -177,10 +179,10 @@ struct mdt_device {
         unsigned long              mdt_client_bitmap[(LR_MAX_CLIENTS >> 3) / sizeof(long)];
 
         struct upcall_cache        *mdt_identity_cache;
-        struct upcall_cache        *mdt_rmtacl_cache;
 
-        /* root squash */
-        struct rootsquash_info     *mdt_rootsquash_info;
+        /* sptlrpc rules */
+        rwlock_t                   mdt_sptlrpc_lock;
+        struct sptlrpc_rule_set    mdt_sptlrpc_rset;
 
         /* capability keys */
         unsigned long              mdt_capa_timeout;
@@ -599,17 +601,10 @@ const struct lu_buf *mdt_buf_const(const struct lu_env *env,
 void mdt_dump_lmm(int level, const struct lov_mds_md *lmm);
 
 int mdt_check_ucred(struct mdt_thread_info *);
-
 int mdt_init_ucred(struct mdt_thread_info *, struct mdt_body *);
-
 int mdt_init_ucred_reint(struct mdt_thread_info *);
-
 void mdt_exit_ucred(struct mdt_thread_info *);
 
-int groups_from_list(struct group_info *, gid_t *);
-
-void groups_sort(struct group_info *);
-
 /* mdt_idmap.c */
 int mdt_init_idmap(struct mdt_thread_info *);
 
@@ -639,23 +634,16 @@ static inline struct mdt_device *mdt_dev(struct lu_device *d)
 
 extern struct upcall_cache_ops mdt_identity_upcall_cache_ops;
 
-struct mdt_identity *mdt_identity_get(struct upcall_cache *, __u32);
+struct md_identity *mdt_identity_get(struct upcall_cache *, __u32);
 
-void mdt_identity_put(struct upcall_cache *, struct mdt_identity *);
+void mdt_identity_put(struct upcall_cache *, struct md_identity *);
 
 void mdt_flush_identity(struct upcall_cache *, int);
 
-__u32 mdt_identity_get_setxid_perm(struct mdt_identity *, __u32, lnet_nid_t);
+__u32 mdt_identity_get_perm(struct md_identity *, __u32, lnet_nid_t);
 
 int mdt_pack_remote_perm(struct mdt_thread_info *, struct mdt_object *, void *);
 
-/* mdt/mdt_rmtacl.c */
-#define MDT_RMTACL_UPCALL_PATH          "/usr/sbin/l_facl"
-
-extern struct upcall_cache_ops mdt_rmtacl_upcall_cache_ops;
-
-int mdt_rmtacl_upcall(struct mdt_thread_info *, char *, struct lu_buf *);
-
 extern struct lu_context_key       mdt_thread_key;
 /* debug issues helper starts here*/
 static inline void mdt_fail_write(const struct lu_env *env,
index 28500c9..37cb8f0 100644 (file)
@@ -11,6 +11,7 @@
  *   Author: Mike Shaver <shaver@clusterfs.com>
  *   Author: Nikita Danilov <nikita@clusterfs.com>
  *   Author: Huang Hua <huanghua@clusterfs.com>
+ *   Author: Fan Yong <fanyong@clusterfs.com>
  *
  *
  *   This file is part of the Lustre file system, http://www.lustre.org
@@ -47,55 +48,6 @@ typedef enum ucred_init_type {
         REC_INIT        = 2
 } ucred_init_type_t;
 
-int groups_from_list(struct group_info *ginfo, gid_t *glist)
-{
-        int i;
-        int count = ginfo->ngroups;
-
-        /* fill group_info from gid array */
-        for (i = 0; i < ginfo->nblocks; i++) {
-                int cp_count = min(NGROUPS_PER_BLOCK, count);
-                int off = i * NGROUPS_PER_BLOCK;
-                int len = cp_count * sizeof(*glist);
-
-                if (memcpy(ginfo->blocks[i], glist + off, len))
-                        return -EFAULT;
-
-                count -= cp_count;
-        }
-        return 0;
-}
-
-/* groups_sort() is copied from linux kernel! */
-/* a simple shell-metzner sort */
-void groups_sort(struct group_info *group_info)
-{
-        int base, max, stride;
-        int gidsetsize = group_info->ngroups;
-
-        for (stride = 1; stride < gidsetsize; stride = 3 * stride + 1)
-                ; /* nothing */
-        stride /= 3;
-
-        while (stride) {
-                max = gidsetsize - stride;
-                for (base = 0; base < max; base++) {
-                        int left = base;
-                        int right = left + stride;
-                        gid_t tmp = GROUP_AT(group_info, right);
-
-                        while (left >= 0 && GROUP_AT(group_info, left) > tmp) {
-                                GROUP_AT(group_info, right) =
-                                    GROUP_AT(group_info, left);
-                                right = left;
-                                left -= stride;
-                        }
-                        GROUP_AT(group_info, right) = tmp;
-                }
-                stride /= 3;
-        }
-}
-
 void mdt_exit_ucred(struct mdt_thread_info *info)
 {
         struct md_ucred   *uc  = mdt_ucred(info);
@@ -116,168 +68,13 @@ void mdt_exit_ucred(struct mdt_thread_info *info)
         }
 }
 
-static int old_init_ucred(struct mdt_thread_info *info,
-                          struct mdt_body *body)
+/* XXX: root_squash will be redesigned in Lustre 1.7.
+ * Do not root_squash for inter-MDS operations */
+static int mdt_root_squash(struct mdt_thread_info *info)
 {
-        struct md_ucred     *uc  = mdt_ucred(info);
-        struct mdt_device   *mdt = info->mti_mdt;
-        struct mdt_identity *identity = NULL;
-
-        ENTRY;
-
-        uc->mu_valid = UCRED_INVALID;
-
-        if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
-                /* get identity info of this user */
-                identity = mdt_identity_get(mdt->mdt_identity_cache,
-                                            body->fsuid);
-                if (!identity) {
-                        CERROR("Deny access without identity: uid %d\n",
-                               body->fsuid);
-                        RETURN(-EACCES);
-                }
-        }
-
-        uc->mu_valid = UCRED_OLD;
-        uc->mu_squash = SQUASH_NONE;
-        uc->mu_o_uid = uc->mu_uid = body->uid;
-        uc->mu_o_gid = uc->mu_gid = body->gid;
-        uc->mu_o_fsuid = uc->mu_fsuid = body->fsuid;
-        uc->mu_o_fsgid = uc->mu_fsgid = body->fsgid;
-        uc->mu_suppgids[0] = body->suppgid;
-        uc->mu_suppgids[1] = -1;
-        if (uc->mu_fsuid)
-                uc->mu_cap = body->capability & ~CAP_FS_MASK;
-        else
-                uc->mu_cap = body->capability;
-        uc->mu_ginfo = NULL;
-        uc->mu_identity = identity;
-
-        RETURN(0);
-}
-
-static int old_init_ucred_reint(struct mdt_thread_info *info)
-{
-        struct md_ucred     *uc  = mdt_ucred(info);
-        struct mdt_device   *mdt = info->mti_mdt;
-        struct mdt_identity *identity = NULL;
-
-        ENTRY;
-
-        uc->mu_valid = UCRED_INVALID;
-
-        if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
-                /* get identity info of this user */
-                identity = mdt_identity_get(mdt->mdt_identity_cache,
-                                            uc->mu_fsuid);
-                if (!identity) {
-                        CERROR("Deny access without identity: uid %d\n",
-                               uc->mu_fsuid);
-                        RETURN(-EACCES);
-                }
-        }
-
-        uc->mu_valid = UCRED_OLD;
-        uc->mu_squash = SQUASH_NONE;
-        uc->mu_o_uid = uc->mu_o_fsuid = uc->mu_uid = uc->mu_fsuid;
-        uc->mu_o_gid = uc->mu_o_fsgid = uc->mu_gid = uc->mu_fsgid;
-        if (uc->mu_fsuid)
-                uc->mu_cap &= ~CAP_FS_MASK;
-        uc->mu_ginfo = NULL;
-        uc->mu_identity = identity;
-
-        RETURN(0);
-}
-
-static int nid_nosquash(struct mdt_device *mdt, lnet_nid_t nid)
-{
-        struct rootsquash_info *rsi = mdt->mdt_rootsquash_info;
-        int i;
-
-        for (i = 0; i < rsi->rsi_n_nosquash_nids; i++)
-                if ((rsi->rsi_nosquash_nids[i] == nid) ||
-                    (rsi->rsi_nosquash_nids[i] == LNET_NID_ANY))
-                        return 1;
-
         return 0;
 }
 
-static int mdt_squash_root(struct mdt_device *mdt, struct md_ucred *ucred,
-                           struct ptlrpc_user_desc *pud, lnet_nid_t peernid)
-{
-        struct rootsquash_info *rsi = mdt->mdt_rootsquash_info;
-
-        if (!rsi || (!rsi->rsi_uid && !rsi->rsi_gid) ||
-            nid_nosquash(mdt, peernid))
-                return 0;
-
-        CDEBUG(D_SEC, "squash req from "LPX64":"
-               "(%u:%u-%u:%u/%x)=>(%u:%u-%u:%u/%x)\n", peernid,
-               pud->pud_uid, pud->pud_gid,
-               pud->pud_fsuid, pud->pud_fsgid, pud->pud_cap,
-               pud->pud_uid ? pud->pud_uid : rsi->rsi_uid,
-               pud->pud_uid ? pud->pud_gid : rsi->rsi_gid,
-               pud->pud_fsuid ? pud->pud_fsuid : rsi->rsi_uid,
-               pud->pud_fsuid ? pud->pud_fsgid : rsi->rsi_gid,
-               pud->pud_cap & ~CAP_FS_MASK);
-
-        if (rsi->rsi_uid) {
-                if (!pud->pud_uid) {
-                        ucred->mu_uid = rsi->rsi_uid;
-                        ucred->mu_squash |= SQUASH_UID;
-                } else {
-                        ucred->mu_uid = pud->pud_uid;
-                }
-
-                if (!pud->pud_fsuid) {
-                        ucred->mu_fsuid = rsi->rsi_uid;
-                        ucred->mu_squash |= SQUASH_UID;
-                } else {
-                        ucred->mu_fsuid = pud->pud_fsuid;
-                }
-        } else {
-                ucred->mu_uid   = pud->pud_uid;
-                ucred->mu_fsuid = pud->pud_fsuid;
-        }
-
-        if (rsi->rsi_gid) {
-                int i;
-
-                if (!pud->pud_gid) {
-                        ucred->mu_gid = rsi->rsi_gid;
-                        ucred->mu_squash |= SQUASH_GID;
-                } else {
-                        ucred->mu_gid = pud->pud_gid;
-                }
-
-                if (!pud->pud_fsgid) {
-                        ucred->mu_fsgid = rsi->rsi_gid;
-                        ucred->mu_squash |= SQUASH_GID;
-                } else {
-                        ucred->mu_fsgid = pud->pud_fsgid;
-                }
-
-                for (i = 0; i < 2; i++) {
-                        if (!ucred->mu_suppgids[i]) {
-                                ucred->mu_suppgids[i] = rsi->rsi_gid;
-                                ucred->mu_squash |= SQUASH_GID;
-                        }
-                }
-
-                for (i = 0; i < pud->pud_ngroups; i++) {
-                        if (!pud->pud_groups[i]) {
-                                pud->pud_groups[i] = rsi->rsi_gid;
-                                ucred->mu_squash |= SQUASH_GID;
-                        }
-                }
-        } else {
-                ucred->mu_gid   = pud->pud_gid;
-                ucred->mu_fsgid = pud->pud_fsgid;
-        }
-
-        return 1;
-}
-
 static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                           void *buf)
 {
@@ -286,9 +83,8 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
         struct mdt_device       *mdt = info->mti_mdt;
         struct ptlrpc_user_desc *pud = req->rq_user_desc;
         struct md_ucred         *ucred = mdt_ucred(info);
-        struct mdt_identity     *identity = NULL;
         lnet_nid_t              peernid = req->rq_peer.nid;
-        __u32                   setxid_perm = 0;
+        __u32                    perm = 0;
         int                     setuid;
         int                     setgid;
         int                     rc = 0;
@@ -324,10 +120,12 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                         RETURN(-EACCES);
 
                 if (req->rq_auth_mapped_uid != pud->pud_uid) {
-                        CERROR("remote client "LPU64": auth uid %u "
+                        CERROR("remote client "LPU64": auth/mapped uid %u/%u "
                                "while client claim %u:%u/%u:%u\n",
-                               peernid, req->rq_auth_uid, pud->pud_uid,
-                               pud->pud_gid, pud->pud_fsuid, pud->pud_fsgid);
+                               peernid, req->rq_auth_uid,
+                               req->rq_auth_mapped_uid,
+                               pud->pud_uid, pud->pud_gid,
+                               pud->pud_fsuid, pud->pud_fsgid);
                         RETURN(-EACCES);
                 }
         } else {
@@ -346,87 +144,100 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type,
                                "enabled!\n");
                         RETURN(-EACCES);
                 } else {
-                        setxid_perm |= LUSTRE_SETGRP_PERM;
-                        goto check_squash;
+                        ucred->mu_identity = NULL;
+                        perm = CFS_SETUID_PERM | CFS_SETGID_PERM |
+                               CFS_SETGRP_PERM;
                 }
-        }
-
-        identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid);
-        if (!identity) {
-                CERROR("Deny access without identity: uid %d\n", pud->pud_uid);
+        } else {
+                ucred->mu_identity = mdt_identity_get(mdt->mdt_identity_cache,
+                                                      pud->pud_uid);
+                if (!ucred->mu_identity) {
+                        CERROR("Deny access without identity: uid %d\n",
+                               pud->pud_uid);
                 RETURN(-EACCES);
-        }
-
-        setxid_perm = mdt_identity_get_setxid_perm(identity,
+                } else {
+                        perm = mdt_identity_get_perm(ucred->mu_identity,
                                                    med->med_rmtclient,
                                                    peernid);
+                }
+        }
 
         /* find out the setuid/setgid attempt */
         setuid = (pud->pud_uid != pud->pud_fsuid);
-        setgid = (pud->pud_gid != pud->pud_fsgid ||
-                  pud->pud_gid != identity->mi_gid);
+        setgid = ((pud->pud_gid != pud->pud_fsgid) ||
+                  (ucred->mu_identity &&
+                  (pud->pud_gid != ucred->mu_identity->mi_gid)));
 
         /* check permission of setuid */
-        if (setuid && !(setxid_perm & LUSTRE_SETUID_PERM)) {
+        if (setuid && !(perm & CFS_SETUID_PERM)) {
                 CWARN("mdt blocked setuid attempt (%u -> %u) from "
                       LPX64"\n", pud->pud_uid, pud->pud_fsuid, peernid);
                 GOTO(out, rc = -EACCES);
         }
 
         /* check permission of setgid */
-        if (setgid && !(setxid_perm & LUSTRE_SETGID_PERM)) {
+        if (setgid && !(perm & CFS_SETGID_PERM)) {
                 CWARN("mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
                       "from "LPX64"\n", pud->pud_uid, pud->pud_gid,
-                      pud->pud_fsuid, pud->pud_fsgid, identity->mi_gid,
-                      peernid);
+                      pud->pud_fsuid, pud->pud_fsgid,
+                      ucred->mu_identity->mi_gid, peernid);
                 GOTO(out, rc = -EACCES);
         }
 
-check_squash:
-        /* FIXME: The exact behavior of root_squash is not defined. */
-        ucred->mu_squash = SQUASH_NONE;
-        if (mdt_squash_root(mdt, ucred, pud, peernid) == 0) {
-                ucred->mu_uid   = pud->pud_uid;
-                ucred->mu_gid   = pud->pud_gid;
-                ucred->mu_fsuid = pud->pud_fsuid;
-                ucred->mu_fsgid = pud->pud_fsgid;
-        }
-
-        /* remove fs privilege for non-root user */
-        if (ucred->mu_fsuid)
-                ucred->mu_cap = pud->pud_cap & ~CAP_FS_MASK;
-        else
-                ucred->mu_cap = pud->pud_cap;
-
         /*
          * NB: remote client not allowed to setgroups anyway.
          */
-        if (!med->med_rmtclient && pud->pud_ngroups &&
-            (setxid_perm & LUSTRE_SETGRP_PERM)) {
-                struct group_info *ginfo;
-
+        if (!med->med_rmtclient && perm & CFS_SETGRP_PERM) {
+                if (pud->pud_ngroups) {
                 /* setgroups for local client */
-                ginfo = groups_alloc(pud->pud_ngroups);
-                if (!ginfo) {
+                        ucred->mu_ginfo = groups_alloc(pud->pud_ngroups);
+                        if (!ucred->mu_ginfo) {
                         CERROR("failed to alloc %d groups\n",
                                pud->pud_ngroups);
                         GOTO(out, rc = -ENOMEM);
                 }
-                groups_from_list(ginfo, pud->pud_groups);
-                groups_sort(ginfo);
-                ucred->mu_ginfo = ginfo;
+
+                        lustre_groups_from_list(ucred->mu_ginfo,
+                                                pud->pud_groups);
+                        lustre_groups_sort(ucred->mu_ginfo);
         } else {
                 ucred->mu_ginfo = NULL;
         }
+        } else {
+                ucred->mu_suppgids[0] = -1;
+                ucred->mu_suppgids[1] = -1;
+                ucred->mu_ginfo = NULL;
+        }
 
-        ucred->mu_identity = identity;
+        ucred->mu_uid   = pud->pud_uid;
+        ucred->mu_gid   = pud->pud_gid;
+        ucred->mu_fsuid = pud->pud_fsuid;
+        ucred->mu_fsgid = pud->pud_fsgid;
+
+        /* XXX: need to process root_squash here. */
+        mdt_root_squash(info);
+
+        /* remove fs privilege for non-root user */
+        if (ucred->mu_fsuid)
+                ucred->mu_cap = pud->pud_cap & ~CAP_FS_MASK;
+        else
+                ucred->mu_cap = pud->pud_cap;
         ucred->mu_valid = UCRED_NEW;
 
         EXIT;
 
 out:
-        if (rc && identity)
-                mdt_identity_put(mdt->mdt_identity_cache, identity);
+        if (rc) {
+                if (ucred->mu_ginfo) {
+                        groups_free(ucred->mu_ginfo);
+                        ucred->mu_ginfo = NULL;
+                }
+                if (ucred->mu_identity) {
+                        mdt_identity_put(mdt->mdt_identity_cache,
+                                         ucred->mu_identity);
+                        ucred->mu_identity = NULL;
+                }
+        }
 
         return rc;
 }
@@ -438,20 +249,23 @@ int mdt_check_ucred(struct mdt_thread_info *info)
         struct mdt_device       *mdt = info->mti_mdt;
         struct ptlrpc_user_desc *pud = req->rq_user_desc;
         struct md_ucred         *ucred = mdt_ucred(info);
-        struct mdt_identity     *identity;
+        struct md_identity      *identity = NULL;
         lnet_nid_t              peernid = req->rq_peer.nid;
+        __u32                    perm = 0;
+        int                      setuid;
+        int                      setgid;
+        int                      rc = 0;
 
         ENTRY;
 
         if ((ucred->mu_valid == UCRED_OLD) || (ucred->mu_valid == UCRED_NEW))
                 RETURN(0);
 
-        if (!req->rq_user_desc)
+        if (!req->rq_auth_gss || req->rq_auth_usr_mdt || !req->rq_user_desc)
                 RETURN(0);
 
         /* sanity check: if we use strong authentication, we expect the
          * uid which client claimed is true */
-        if (req->rq_auth_gss) {
                 if (med->med_rmtclient) {
                         if (req->rq_auth_mapped_uid == INVALID_UID) {
                                 CWARN("remote user not mapped, deny access!\n");
@@ -462,11 +276,12 @@ int mdt_check_ucred(struct mdt_thread_info *info)
                                 RETURN(-EACCES);
 
                         if (req->rq_auth_mapped_uid != pud->pud_uid) {
-                                CERROR("remote client "LPU64": auth uid %u "
+                        CERROR("remote client "LPU64": auth/mapped uid %u/%u "
                                        "while client claim %u:%u/%u:%u\n",
-                                       peernid, req->rq_auth_uid, pud->pud_uid,
-                                       pud->pud_gid, pud->pud_fsuid,
-                                       pud->pud_fsgid);
+                               peernid, req->rq_auth_uid,
+                               req->rq_auth_mapped_uid,
+                               pud->pud_uid, pud->pud_gid,
+                               pud->pud_fsuid, pud->pud_fsgid);
                                 RETURN(-EACCES);
                         }
                 } else {
@@ -479,25 +294,122 @@ int mdt_check_ucred(struct mdt_thread_info *info)
                                 RETURN(-EACCES);
                         }
                 }
-        }
 
         if (is_identity_get_disabled(mdt->mdt_identity_cache)) {
                 if (med->med_rmtclient) {
-                        CERROR("remote client must run with "
-                               "identity_get enabled!\n");
+                        CERROR("remote client must run with identity_get "
+                               "enabled!\n");
                         RETURN(-EACCES);
                 }
-        } else {
+                RETURN(0);
+        }
+
+        identity = mdt_identity_get(mdt->mdt_identity_cache, pud->pud_uid);
+        if (!identity) {
+                CERROR("Deny access without identity: uid %d\n", pud->pud_uid);
+                RETURN(-EACCES);
+        }
+
+        perm = mdt_identity_get_perm(identity, med->med_rmtclient, peernid);
+        /* find out the setuid/setgid attempt */
+        setuid = (pud->pud_uid != pud->pud_fsuid);
+        setgid = (pud->pud_gid != pud->pud_fsgid ||
+                  pud->pud_gid != identity->mi_gid);
+
+        /* check permission of setuid */
+        if (setuid && !(perm & CFS_SETUID_PERM)) {
+                CWARN("mdt blocked setuid attempt (%u -> %u) from "
+                      LPX64"\n", pud->pud_uid, pud->pud_fsuid, peernid);
+                GOTO(out, rc = -EACCES);
+        }
+
+        /* check permission of setgid */
+        if (setgid && !(perm & CFS_SETGID_PERM)) {
+                CWARN("mdt blocked setgid attempt (%u:%u/%u:%u -> %u) "
+                      "from "LPX64"\n", pud->pud_uid, pud->pud_gid,
+                      pud->pud_fsuid, pud->pud_fsgid, identity->mi_gid,
+                      peernid);
+                GOTO(out, rc = -EACCES);
+        }
+
+        EXIT;
+
+out:
+        mdt_identity_put(mdt->mdt_identity_cache, identity);
+        return rc;
+}
+
+static int old_init_ucred(struct mdt_thread_info *info,
+                          struct mdt_body *body)
+{
+        struct md_ucred *uc = mdt_ucred(info);
+        struct mdt_device  *mdt = info->mti_mdt;
+        struct md_identity *identity = NULL;
+
+        ENTRY;
+
+        uc->mu_valid = UCRED_INVALID;
+        uc->mu_o_uid = uc->mu_uid = body->uid;
+        uc->mu_o_gid = uc->mu_gid = body->gid;
+        uc->mu_o_fsuid = uc->mu_fsuid = body->fsuid;
+        uc->mu_o_fsgid = uc->mu_fsgid = body->fsgid;
+        uc->mu_suppgids[0] = body->suppgid;
+        uc->mu_suppgids[1] = -1;
+        uc->mu_ginfo = NULL;
+        if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
                 identity = mdt_identity_get(mdt->mdt_identity_cache,
-                                            pud->pud_uid);
+                                            uc->mu_fsuid);
                 if (!identity) {
                         CERROR("Deny access without identity: uid %d\n",
-                               pud->pud_uid);
+                               uc->mu_fsuid);
                         RETURN(-EACCES);
                 }
+        }
+        uc->mu_identity = identity;
+
+        /* XXX: need to process root_squash here. */
+        mdt_root_squash(info);
+
+        /* remove fs privilege for non-root user */
+        if (uc->mu_fsuid)
+                uc->mu_cap = body->capability & ~CAP_FS_MASK;
+        else
+                uc->mu_cap = body->capability;
+        uc->mu_valid = UCRED_OLD;
+
+        RETURN(0);
+}
+
+static int old_init_ucred_reint(struct mdt_thread_info *info)
+{
+        struct md_ucred *uc = mdt_ucred(info);
+        struct mdt_device  *mdt = info->mti_mdt;
+        struct md_identity *identity = NULL;
+
+        ENTRY;
 
-                mdt_identity_put(mdt->mdt_identity_cache, identity);
+        uc->mu_valid = UCRED_INVALID;
+        uc->mu_o_uid = uc->mu_o_fsuid = uc->mu_uid = uc->mu_fsuid;
+        uc->mu_o_gid = uc->mu_o_fsgid = uc->mu_gid = uc->mu_fsgid;
+        uc->mu_ginfo = NULL;
+        if (!is_identity_get_disabled(mdt->mdt_identity_cache)) {
+                identity = mdt_identity_get(mdt->mdt_identity_cache,
+                                            uc->mu_fsuid);
+                if (!identity) {
+                        CERROR("Deny access without identity: uid %d\n",
+                               uc->mu_fsuid);
+                        RETURN(-EACCES);
+        }
         }
+        uc->mu_identity = identity;
+
+        /* XXX: need to process root_squash here. */
+        mdt_root_squash(info);
+
+        /* remove fs privilege for non-root user */
+        if (uc->mu_fsuid)
+                uc->mu_cap &= ~CAP_FS_MASK;
+        uc->mu_valid = UCRED_OLD;
 
         RETURN(0);
 }
index e7565dd..3b2db54 100644 (file)
@@ -227,9 +227,9 @@ static int lprocfs_wr_identity_info(struct file *file, const char *buffer,
                 GOTO(out, rc = -EINVAL);
         }
 
-        if (sparam.idd_nperms > N_SETXID_PERMS_MAX) {
+        if (sparam.idd_nperms > N_PERMS_MAX) {
                 CERROR("%s: perm count %d more than maximum %d\n",
-                       obd->obd_name, sparam.idd_nperms, N_SETXID_PERMS_MAX);
+                       obd->obd_name, sparam.idd_nperms, N_PERMS_MAX);
                 GOTO(out, rc = -EINVAL);
         }
 
@@ -268,301 +268,6 @@ out:
         return rc ?: count;
 }
 
-static int lprocfs_rd_rmtacl_expire(char *page, char **start, off_t off,
-                                    int count, int *eof, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-
-        *eof = 1;
-        return snprintf(page, count, "%lu\n",
-                        mdt->mdt_rmtacl_cache->uc_entry_expire / HZ);
-}
-
-static int lprocfs_wr_rmtacl_expire(struct file *file, const char *buffer,
-                                    unsigned long count, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        int rc, val;
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        mdt->mdt_rmtacl_cache->uc_entry_expire = val * HZ;
-        return count;
-}
-
-static int lprocfs_rd_rmtacl_acquire_expire(char *page, char **start,
-                                            off_t off, int count, int *eof,
-                                            void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-
-        *eof = 1;
-        return snprintf(page, count, "%lu\n",
-                        mdt->mdt_rmtacl_cache->uc_acquire_expire / HZ);
-}
-
-static int lprocfs_wr_rmtacl_acquire_expire(struct file *file,
-                                            const char *buffer,
-                                            unsigned long count,
-                                            void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        int rc, val;
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        mdt->mdt_rmtacl_cache->uc_acquire_expire = val * HZ;
-        return count;
-}
-
-static int lprocfs_rd_rmtacl_upcall(char *page, char **start, off_t off,
-                                      int count, int *eof, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-
-        *eof = 1;
-        return snprintf(page, count, "%s\n",
-                        mdt->mdt_rmtacl_cache->uc_upcall);
-}
-
-static int lprocfs_wr_rmtacl_upcall(struct file *file, const char *buffer,
-                                      unsigned long count, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        struct upcall_cache *hash = mdt->mdt_rmtacl_cache;
-        char kernbuf[UC_CACHE_UPCALL_MAXPATH] = { '\0' };
-
-        if (count >= UC_CACHE_UPCALL_MAXPATH) {
-                CERROR("%s: remote ACL upcall too long\n", obd->obd_name);
-                return -EINVAL;
-        }
-
-        if (copy_from_user(kernbuf, buffer,
-                           min(count, UC_CACHE_UPCALL_MAXPATH - 1)))
-                return -EFAULT;
-
-        /* Remove any extraneous bits from the upcall (e.g. linefeeds) */
-        sscanf(kernbuf, "%s", hash->uc_upcall);
-
-        if (strcmp(hash->uc_name, obd->obd_name) != 0)
-                CWARN("%s: write to upcall name %s\n",
-                      obd->obd_name, hash->uc_upcall);
-        CWARN("%s: remote ACL upcall set to %s\n", obd->obd_name, hash->uc_upcall);
-
-        return count;
-}
-
-static int lprocfs_wr_rmtacl_info(struct file *file, const char *buffer,
-                                  unsigned long count, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        struct rmtacl_downcall_data sparam, *param = &sparam;
-        int size = 0, rc = 0;
-
-        if (count < sizeof(*param)) {
-                CERROR("%s: invalid data size %lu\n", obd->obd_name, count);
-                return count;
-        }
-
-        if (copy_from_user(&sparam, buffer, sizeof(sparam))) {
-                CERROR("%s: bad remote acl data\n", obd->obd_name);
-                GOTO(out, rc = -EFAULT);
-        }
-
-        if (sparam.add_magic != RMTACL_DOWNCALL_MAGIC) {
-                CERROR("%s: MDT remote acl downcall bad params\n", obd->obd_name);
-                GOTO(out, rc = -EINVAL);
-        }
-
-        if (sparam.add_buflen) {
-                size = offsetof(struct rmtacl_downcall_data,
-                                add_buf[sparam.add_buflen]);
-                OBD_ALLOC(param, size);
-                if (!param) {
-                        CERROR("%s: fail to alloc %d bytes for ino "LPU64"\n",
-                               obd->obd_name, size, sparam.add_key);
-                        param = &sparam;
-                        param->add_buflen = 0;
-                } else if (copy_from_user(param, buffer, size)) {
-                        CERROR("%s: ino "LPU64" bad remote acl data\n",
-                               obd->obd_name, sparam.add_key);
-                        OBD_FREE(param, size);
-                        param = &sparam;
-                        param->add_buflen = 0;
-                }
-        }
-
-        rc = upcall_cache_downcall(mdt->mdt_rmtacl_cache, 0, param->add_key,
-                                   param);
-
-out:
-        if (param && (param != &sparam))
-                OBD_FREE(param, size);
-
-        return rc ?: count;
-}
-
-static int lprocfs_rd_rootsquash_uid(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        struct rootsquash_info *rsi = mdt->mdt_rootsquash_info;
-
-        *eof = 1;
-        return snprintf(page, count, "%u\n",
-                        rsi ? rsi->rsi_uid : 0);
-}
-
-static int lprocfs_wr_rootsquash_uid(struct file *file, const char *buffer,
-                                     unsigned long count, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        int val, rc;
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (!mdt->mdt_rootsquash_info)
-                OBD_ALLOC_PTR(mdt->mdt_rootsquash_info);
-        if (!mdt->mdt_rootsquash_info)
-                return -ENOMEM;
-
-        mdt->mdt_rootsquash_info->rsi_uid = val;
-        return count;
-}
-
-static int lprocfs_rd_rootsquash_gid(char *page, char **start, off_t off,
-                                 int count, int *eof, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        struct rootsquash_info *rsi = mdt->mdt_rootsquash_info;
-
-        *eof = 1;
-        return snprintf(page, count, "%u\n",
-                        rsi ? rsi->rsi_gid : 0);
-}
-
-static int lprocfs_wr_rootsquash_gid(struct file *file, const char *buffer,
-                                     unsigned long count, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        int val, rc;
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (!mdt->mdt_rootsquash_info)
-                OBD_ALLOC_PTR(mdt->mdt_rootsquash_info);
-        if (!mdt->mdt_rootsquash_info)
-                return -ENOMEM;
-
-        mdt->mdt_rootsquash_info->rsi_gid = val;
-        return count;
-}
-
-static int lprocfs_rd_nosquash_nids(char *page, char **start, off_t off,
-                                       int count, int *eof, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        struct rootsquash_info *rsi = mdt->mdt_rootsquash_info;
-        int i, ret;
-
-        ret = snprintf(page, count, "rootsquash skip list:\n");
-        for (i = 0; rsi && (i < rsi->rsi_n_nosquash_nids); i++) {
-                ret += snprintf(page + ret, count - ret, "%s\n",
-                                libcfs_nid2str(rsi->rsi_nosquash_nids[i]));
-        }
-
-        *eof = 1;
-        return ret;
-}
-
-static inline void remove_newline(char *str)
-{
-        int len = strlen(str);
-
-        if (str[len - 1] == '\n')
-                str[len - 1] = '\0';
-}
-
-/* XXX: This macro is copied from lnet/libcfs/nidstring.c */
-#define LNET_NIDSTR_SIZE   32      /* size of each one (see below for usage) */
-
-static void do_process_nosquash_nids(struct mdt_device *m, char *buf)
-{
-        struct rootsquash_info *rsi = m->mdt_rootsquash_info;
-        char str[LNET_NIDSTR_SIZE], *end;
-        lnet_nid_t nid;
-
-        LASSERT(rsi);
-        rsi->rsi_n_nosquash_nids = 0;
-        while (rsi->rsi_n_nosquash_nids < N_NOSQUASH_NIDS) {
-                end = strchr(buf, ',');
-                memset(str, 0, sizeof(str));
-                if (end)
-                        strncpy(str, buf, min_t(int, sizeof(str), end - buf));
-                else
-                        strncpy(str, buf, min_t(int, sizeof(str), strlen(buf)));
-
-                if (!strcmp(str, "*")) {
-                        nid = LNET_NID_ANY;
-                } else {
-                        nid = libcfs_str2nid(str);
-                        if (nid == LNET_NID_ANY)
-                                goto ignore;
-                }
-                rsi->rsi_nosquash_nids[rsi->rsi_n_nosquash_nids++] = nid;
-ignore:
-                if (!end || (*(end + 1) == 0))
-                        return;
-                buf = end + 1;
-        }
-}
-
-static int lprocfs_wr_nosquash_nids(struct file *file, const char *buffer,
-                                       unsigned long count, void *data)
-{
-        struct obd_device *obd = data;
-        struct mdt_device *mdt = mdt_dev(obd->obd_lu_dev);
-        char skips[LNET_NIDSTR_SIZE * N_NOSQUASH_NIDS] = "";
-        unsigned long size = sizeof(skips);
-
-        if (count > size) {
-                CERROR("parameter exceeds max limit %lu\n", size);
-                return -EINVAL;
-        }
-
-        if (copy_from_user(skips, buffer, min(size, count)))
-                return -EFAULT;
-
-        if (!mdt->mdt_rootsquash_info)
-                OBD_ALLOC_PTR(mdt->mdt_rootsquash_info);
-        if (!mdt->mdt_rootsquash_info)
-                return -ENOMEM;
-
-        remove_newline(skips);
-        do_process_nosquash_nids(mdt, skips);
-        return count;
-}
-
 /* for debug only */
 static int lprocfs_rd_capa(char *page, char **start, off_t off,
                            int count, int *eof, void *data)
@@ -728,19 +433,6 @@ static struct lprocfs_vars lprocfs_mdt_obd_vars[] = {
                                         lprocfs_wr_identity_upcall,         0 },
         { "identity_flush",             0, lprocfs_wr_identity_flush,       0 },
         { "identity_info",              0, lprocfs_wr_identity_info,        0 },
-        { "rmtacl_expire",              lprocfs_rd_rmtacl_expire,
-                                        lprocfs_wr_rmtacl_expire,           0 },
-        { "rmtacl_acquire_expire",      lprocfs_rd_rmtacl_acquire_expire,
-                                        lprocfs_wr_rmtacl_acquire_expire,   0 },
-        { "rmtacl_upcall",              lprocfs_rd_rmtacl_upcall,
-                                        lprocfs_wr_rmtacl_upcall,           0 },
-        { "rmtacl_info",                0, lprocfs_wr_rmtacl_info,          0 },
-        { "rootsquash_uid",             lprocfs_rd_rootsquash_uid,
-                                        lprocfs_wr_rootsquash_uid,          0 },
-        { "rootsquash_gid",             lprocfs_rd_rootsquash_gid,
-                                        lprocfs_wr_rootsquash_gid,          0 },
-        { "nosquash_nids",              lprocfs_rd_nosquash_nids,
-                                        lprocfs_wr_nosquash_nids,           0 },
         { "capa",                       lprocfs_rd_capa,
                                         lprocfs_wr_capa,                    0 },
         { "capa_timeout",               lprocfs_rd_capa_timeout,
diff --git a/lustre/mdt/mdt_rmtacl.c b/lustre/mdt/mdt_rmtacl.c
deleted file mode 100644 (file)
index 13fa70a..0000000
+++ /dev/null
@@ -1,260 +0,0 @@
-/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
- * vim:expandtab:shiftwidth=8:tabstop=8:
- *
- * Copyright (C) 2004-2006 Cluster File Systems, Inc.
- *   Author: Lai Siyao <lsy@clusterfs.com>
- *   Author: Fan Yong <fanyong@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.
- */
-
-#ifndef EXPORT_SYMTAB
-#define EXPORT_SYMTAB
-#endif
-#define DEBUG_SUBSYSTEM S_MDS
-
-#ifndef AUTOCONF_INCLUDED
-#include <linux/config.h>
-#endif
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/kmod.h>
-#include <linux/string.h>
-#include <linux/stat.h>
-#include <linux/errno.h>
-#include <linux/version.h>
-#include <linux/unistd.h>
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <linux/fs.h>
-#include <linux/stat.h>
-#include <asm/uaccess.h>
-#include <linux/slab.h>
-#include <asm/segment.h>
-
-#include <libcfs/kp30.h>
-#include <obd.h>
-#include <obd_class.h>
-#include <obd_support.h>
-#include <lustre_net.h>
-#include <lustre_import.h>
-#include <lustre_dlm.h>
-#include <lustre_lib.h>
-#include <lustre_ucache.h>
-
-#include "mdt_internal.h"
-
-#define MAX_CMD_LEN     256
-
-static __u64 rmtacl_key = 0;
-static spinlock_t rmtacl_key_lock = SPIN_LOCK_UNLOCKED;
-
-/* 
- * For remote acl operation, do NOT cache!
- * Use different key for each remote acl operation.
- */
-static __u64 mdt_rmtacl_getkey(void)
-{
-        __u64 key;
-
-        spin_lock(&rmtacl_key_lock);
-        key = ++rmtacl_key;
-        spin_unlock(&rmtacl_key_lock);
-
-        return key;
-}
-
-static void mdt_rmtacl_entry_init(struct upcall_cache_entry *entry, void *args)
-{
-        struct rmtacl_upcall_data *data = args;
-        struct mdt_rmtacl *acl = &entry->u.acl;
-        char *cmd;
-
-        acl->ra_uid = data->aud_uid;
-        acl->ra_gid = data->aud_gid;
-        /* we use address of this cache entry as handle */
-        acl->ra_handle = (__u32)entry;
-        OBD_ALLOC(cmd, strlen(data->aud_cmd) + 1);
-        if (!cmd)
-                return; /* upcall will fail later! */
-
-        strcpy(cmd, data->aud_cmd);
-        acl->ra_cmd = cmd;
-}
-
-static void mdt_rmtacl_entry_free(struct upcall_cache *cache,
-                                  struct upcall_cache_entry *entry)
-{
-        struct mdt_rmtacl *acl = &entry->u.acl;
-        int len;
-
-        if (acl->ra_cmd) {
-                len = strlen(acl->ra_cmd) + 1;
-                OBD_FREE(acl->ra_cmd, len);
-        }
-
-        if (acl->ra_buf) {
-                len = strlen(acl->ra_buf) + 1;
-                OBD_FREE(acl->ra_buf, len);
-        }
-}
-
-static int mdt_rmtacl_upcall_compare(struct upcall_cache *cache,
-                                     struct upcall_cache_entry *entry,
-                                     __u64 key, void *args)
-{
-        struct rmtacl_upcall_data *data = args;
-
-        LASSERT(entry && data);
-        LASSERT(entry->u.acl.ra_cmd && data->aud_cmd);
-        return strncmp(entry->u.acl.ra_cmd, data->aud_cmd, MAX_CMD_LEN);
-}
-
-static int mdt_rmtacl_downcall_compare(struct upcall_cache *cache,
-                                       struct upcall_cache_entry *entry,
-                                       __u64 key, void *args)
-{
-        struct rmtacl_downcall_data *data = args;
-
-        return entry->u.acl.ra_handle - data->add_handle;
-}
-
-static int mdt_rmtacl_do_upcall(struct upcall_cache *cache,
-                                struct upcall_cache_entry *entry)
-{
-        struct mdt_rmtacl *acl = &entry->u.acl;
-        char uidstr[8] = "";
-        char gidstr[8] = "";
-        char handle[20] = "";
-        char keystr[20] = "";
-        char *argv[] = {
-                  [0] = cache->uc_upcall,
-                  [1] = uidstr,
-                  [2] = gidstr,
-                  [3] = cache->uc_name,
-                  [4] = keystr,
-                  [5] = handle,
-                  [6] = acl->ra_cmd,
-                  [7] = NULL
-        };
-        char *envp[] = {
-                  [0] = "HOME=/",
-                  [1] = "PATH=/bin:/usr/bin:/sbin:/usr/sbin",
-                  [2] = NULL
-        };
-        int rc;
-        ENTRY;
-
-        if (!acl->ra_cmd)
-                RETURN(-ENOMEM);
-
-        snprintf(uidstr, sizeof(uidstr), "%u", acl->ra_uid);
-        snprintf(gidstr, sizeof(gidstr), "%u", acl->ra_gid);
-        snprintf(keystr, sizeof(keystr), LPU64, entry->ue_key);
-        snprintf(handle, sizeof(handle), "%u", acl->ra_handle);
-
-        LASSERTF(strcmp(cache->uc_upcall, "NONE"), "no upcall set!");
-
-        CDEBUG(D_INFO, "%s: remote acl upcall %s %s %s %s %s %s %s\n",
-               cache->uc_name, argv[0], argv[1], argv[2], argv[3], argv[4],
-               argv[5], argv[6]);
-
-        rc = USERMODEHELPER(argv[0], argv, envp);
-        if (rc < 0) {
-                CERROR("%s: error invoking upcall %s %s %s %s %s %s %s: rc %d; "
-                       "check /proc/fs/lustre/mdt/%s/rmtacl_upcall\n",
-                       cache->uc_name, argv[0], argv[1], argv[2], argv[3],
-                       argv[4], argv[5], argv[6], rc, cache->uc_name);
-        } else {
-                CDEBUG(D_HA, "%s: invoked upcall %s %s %s %s %s %s %s\n",
-                       cache->uc_name, argv[0], argv[1], argv[2], argv[3],
-                       argv[4], argv[5], argv[6]);
-                rc = 0;
-        }
-        RETURN(rc);
-}
-
-static int mdt_rmtacl_parse_downcall(struct upcall_cache *cache,
-                                     struct upcall_cache_entry *entry,
-                                     void *args)
-{
-        struct mdt_rmtacl *acl = &entry->u.acl;
-        struct rmtacl_downcall_data *data;
-        char *buf;
-        int len;
-        ENTRY;
-
-        data = (struct rmtacl_downcall_data *)args;
-        LASSERT(data);
-
-        len = strlen(data->add_buf) + 1;
-        OBD_ALLOC(buf, len);
-        if (!buf)
-                RETURN(-ENOMEM);
-
-        memcpy(buf, data->add_buf, len);
-        acl->ra_buf = buf;
-
-        CDEBUG(D_OTHER, "parse mdt acl@%p: %s %s\n",
-               acl, acl->ra_cmd, acl->ra_buf);
-
-        RETURN(0);
-}
-
-struct upcall_cache_ops mdt_rmtacl_upcall_cache_ops = {
-        .init_entry       = mdt_rmtacl_entry_init,
-        .free_entry       = mdt_rmtacl_entry_free,
-        .upcall_compare   = mdt_rmtacl_upcall_compare,
-        .downcall_compare = mdt_rmtacl_downcall_compare,
-        .do_upcall        = mdt_rmtacl_do_upcall,
-        .parse_downcall   = mdt_rmtacl_parse_downcall,
-};
-
-int mdt_rmtacl_upcall(struct mdt_thread_info *info, char *cmd,
-                      struct lu_buf *buf)
-{
-        struct mdt_device              *mdt = info->mti_mdt;
-        struct md_ucred                *uc  = mdt_ucred(info);
-        struct rmtacl_upcall_data       data;
-        struct upcall_cache_entry      *entry;
-        __u64                           key;
-        int                             rc  = 0;
-        ENTRY;
-
-        data.aud_uid = uc->mu_fsuid;
-        data.aud_gid = uc->mu_fsgid;
-        data.aud_cmd = cmd;
-
-        key = mdt_rmtacl_getkey();
-
-        entry = upcall_cache_get_entry(mdt->mdt_rmtacl_cache, key, &data);
-        if (IS_ERR(entry))
-                GOTO(out, rc = PTR_ERR(entry));
-
-        if (buf->lb_len <= strlen(entry->u.acl.ra_buf))
-                GOTO(out, rc = -EFAULT);
-
-        memcpy(buf->lb_buf, entry->u.acl.ra_buf, strlen(entry->u.acl.ra_buf));
-        /* remote acl operation expire at once! */
-        UC_CACHE_SET_EXPIRED(entry);
-        upcall_cache_put_entry(mdt->mdt_rmtacl_cache, entry);
-
-out:
-        if (rc)
-                sprintf(buf->lb_buf, "server processing error: %d\n", rc);
-        RETURN(0);
-}
index 2d80821..b9682a6 100644 (file)
@@ -68,9 +68,6 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info)
                     !strncmp(xattr_name, user_string, sizeof(user_string) - 1))
                         RETURN(-EOPNOTSUPP);
                 
-                if (!strcmp(xattr_name, XATTR_NAME_LUSTRE_ACL))
-                        size = RMTACL_SIZE_MAX;
-                else
                         size = mo_xattr_get(info->mti_env,
                                             mdt_object_child(info->mti_object),
                                             &LU_BUF_NULL, xattr_name);
@@ -108,32 +105,11 @@ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info)
         RETURN(size);
 }
 
-static int do_remote_getfacl(struct mdt_thread_info *info, struct lu_buf *buf)
-{
-        struct ptlrpc_request *req = mdt_info_req(info);
-        char *cmd;
-        int rc;
-        ENTRY;
-
-        if (!buf->lb_buf || (buf->lb_len != RMTACL_SIZE_MAX))
-                RETURN(-EINVAL);
-
-        cmd = req_capsule_client_get(&info->mti_pill, &RMF_EADATA);
-        if (!cmd) {
-                CERROR("missing getfacl command!\n");
-                RETURN(-EFAULT);
-        }
-
-        rc = mdt_rmtacl_upcall(info, cmd, buf);
-        if (rc)
-                CERROR("remote acl upcall failed: %d\n", rc);
-
-        lustre_shrink_reply(req, REPLY_REC_OFF + 1, strlen(buf->lb_buf) + 1, 0);
-        RETURN(rc ?: strlen(buf->lb_buf) + 1);
-}
-
 int mdt_getxattr(struct mdt_thread_info *info)
 {
+        struct ptlrpc_request  *req = mdt_info_req(info);
+        struct mdt_export_data *med = mdt_req2med(req);
+        struct md_ucred        *uc  = mdt_ucred(info);
         struct  mdt_body       *reqbody;
         struct  mdt_body       *repbody = NULL;
         struct  md_object      *next;
@@ -154,6 +130,23 @@ int mdt_getxattr(struct mdt_thread_info *info)
         if (rc)
                 RETURN(err_serious(rc));
 
+        next = mdt_object_child(info->mti_object);
+
+        if (info->mti_body->valid & OBD_MD_FLRMTRGETFACL) {
+                __u32 perm = mdt_identity_get_perm(uc->mu_identity,
+                                                   med->med_rmtclient,
+                                                   req->rq_peer.nid);
+
+                LASSERT(med->med_rmtclient);
+                if (!(perm & CFS_RMTACL_PERM))
+                        GOTO(out, rc = err_serious(-EPERM));
+
+                rc = mo_permission(info->mti_env, NULL, next, NULL,
+                                   MAY_RGETFACL);
+                if (rc)
+                        GOTO(out, rc = err_serious(rc));
+        }
+
         easize = mdt_getxattr_pack_reply(info);
         if (easize < 0)
                 GOTO(out, rc = err_serious(easize));
@@ -168,20 +161,36 @@ int mdt_getxattr(struct mdt_thread_info *info)
         buf = &info->mti_buf;
         buf->lb_buf = req_capsule_server_get(&info->mti_pill, &RMF_EADATA);
         buf->lb_len = easize;
-        next = mdt_object_child(info->mti_object);
 
         if (info->mti_body->valid & OBD_MD_FLXATTR) {
+                int flags = CFS_IC_NOTHING;
                 char *xattr_name = req_capsule_client_get(&info->mti_pill,
                                                           &RMF_NAME);
                 CDEBUG(D_INODE, "getxattr %s\n", xattr_name);
 
-                if (!strcmp(xattr_name, XATTR_NAME_LUSTRE_ACL))
-                        rc = do_remote_getfacl(info, buf);
-                else
                         rc = mo_xattr_get(info->mti_env, next, buf, xattr_name);
-
-                if (rc < 0)
+                if (rc < 0) {
                         CERROR("getxattr failed: %d\n", rc);
+                        GOTO(out, rc);
+                }
+
+                if (info->mti_body->valid &
+                    (OBD_MD_FLRMTLSETFACL | OBD_MD_FLRMTLGETFACL))
+                        flags = CFS_IC_ALL;
+                else if (info->mti_body->valid & OBD_MD_FLRMTRGETFACL)
+                        flags = CFS_IC_MAPPED;
+
+                if (rc > 0 && flags != CFS_IC_NOTHING) {
+                        int rc1;
+
+                        LASSERT(med->med_rmtclient);
+                        rc1 = lustre_posix_acl_xattr_id2client(uc,
+                                        med->med_idmap,
+                                        (posix_acl_xattr_header *)(buf->lb_buf),
+                                        rc, flags);
+                        if (unlikely(rc1 < 0))
+                                rc = rc1;
+                }
         } else if (info->mti_body->valid & OBD_MD_FLXATTRLS) {
                 CDEBUG(D_INODE, "listxattr\n");
 
@@ -201,60 +210,58 @@ out:
         return rc;
 }
 
-/* return EADATA length to the caller. negative value means error */
-static int mdt_setxattr_pack_reply(struct mdt_thread_info * info)
-{
-        struct req_capsule     *pill = &info->mti_pill ;
-        __u64                   valid = info->mti_body->valid;
-        int                     rc = 0, rc1;
-
-        if ((valid & OBD_MD_FLXATTR) == OBD_MD_FLXATTR) {
-                char *xattr_name;
-
-                xattr_name = req_capsule_client_get(pill, &RMF_NAME);
-                if (!xattr_name)
-                        return -EFAULT;
-
-                if (!strcmp(xattr_name, XATTR_NAME_LUSTRE_ACL))
-                        rc = RMTACL_SIZE_MAX;
-        }
-
-        req_capsule_set_size(pill, &RMF_EADATA, RCL_SERVER, rc);
-
-        rc1 = req_capsule_pack(pill);
-
-        return rc = rc1 ? rc1 : rc;
-}
-
-static int do_remote_setfacl(struct mdt_thread_info *info)
+static int mdt_rmtlsetfacl(struct mdt_thread_info *info, char *xattr_name,
+                           ext_acl_xattr_header *header,
+                           posix_acl_xattr_header **out)
 {
         struct ptlrpc_request *req = mdt_info_req(info);
+        struct mdt_export_data *med = mdt_req2med(req);
+        struct md_ucred *uc = mdt_ucred(info);
+        struct md_object *next = mdt_object_child(info->mti_object);
         struct lu_buf         *buf = &info->mti_buf;
-        char *cmd;
         int rc;
         ENTRY;
 
-        cmd = req_capsule_client_get(&info->mti_pill, &RMF_EADATA);
-        if (!cmd) {
-                CERROR("missing setfacl command!\n");
-                RETURN(-EFAULT);
+        rc = lustre_ext_acl_xattr_id2server(uc, med->med_idmap, header);
+        if (rc)
+                RETURN(rc);
+        rc = mo_xattr_get(info->mti_env, next, &LU_BUF_NULL, xattr_name);
+        if (rc == -ENODATA)
+                rc = 0;
+        else if (rc < 0)
+                RETURN(rc);
+
+        buf->lb_len = rc;
+        if (buf->lb_len > 0) {
+                OBD_ALLOC(buf->lb_buf, buf->lb_len);
+                if (unlikely(buf->lb_buf == NULL))
+                        RETURN(-ENOMEM);
+
+                rc = mo_xattr_get(info->mti_env, next, buf, xattr_name);
+                if (rc < 0) {
+                        CERROR("getxattr failed: %d\n", rc);
+                        GOTO(_out, rc);
         }
+        } else
+                buf->lb_buf = NULL;
 
-        buf->lb_buf = req_capsule_server_get(&info->mti_pill, &RMF_EADATA);
-        LASSERT(buf->lb_buf);
-        buf->lb_len = RMTACL_SIZE_MAX;
+        rc = lustre_acl_xattr_merge2posix((posix_acl_xattr_header *)(buf->lb_buf),
+                                          buf->lb_len, header, out);
+        EXIT;
 
-        rc = mdt_rmtacl_upcall(info, cmd, buf);
-        if (rc)
-                CERROR("remote acl upcall failed: %d\n", rc);
+_out:
+        if (rc <= 0 && buf->lb_buf != NULL)
+                OBD_FREE(buf->lb_buf, buf->lb_len);
 
-        lustre_shrink_reply(req, REPLY_REC_OFF, strlen(buf->lb_buf) + 1, 0);
-        RETURN(rc);
+        return rc;
 }
 
 int mdt_setxattr(struct mdt_thread_info *info)
 {
         struct ptlrpc_request   *req = mdt_info_req(info);
+        struct mdt_export_data  *med = mdt_req2med(req);
+        struct md_ucred         *uc  = mdt_ucred(info);
         struct mdt_body         *reqbody;
         const char               user_string[] = "user.";
         const char               trust_string[] = "trusted.";
@@ -267,9 +274,10 @@ int mdt_setxattr(struct mdt_thread_info *info)
         struct lu_buf           *buf  = &info->mti_buf;
         __u64                    valid  = body->valid;
         char                    *xattr_name;
-        int                      xattr_len;
+        int                      xattr_len = 0;
         __u64                    lockpart;
         int                      rc;
+        posix_acl_xattr_header  *new_xattr = NULL;
         ENTRY;
 
         CDEBUG(D_INODE, "setxattr "DFID"\n", PFID(&body->fid1));
@@ -285,7 +293,17 @@ int mdt_setxattr(struct mdt_thread_info *info)
         if (rc)
                 RETURN(err_serious(rc));
 
-        rc = mdt_setxattr_pack_reply(info);
+        if (valid & OBD_MD_FLRMTRSETFACL) {
+                __u32 perm = mdt_identity_get_perm(uc->mu_identity,
+                                                   med->med_rmtclient,
+                                                   req->rq_peer.nid);
+
+                LASSERT(med->med_rmtclient);
+                if (!(perm & CFS_RMTACL_PERM))
+                        GOTO(out, rc = err_serious(-EPERM));
+        }
+
+        rc = req_capsule_pack(pill);
         if (rc < 0)
                 GOTO(out, rc = err_serious(rc));
 
@@ -297,12 +315,6 @@ int mdt_setxattr(struct mdt_thread_info *info)
         CDEBUG(D_INODE, "%s xattr %s\n",
                   body->valid & OBD_MD_FLXATTR ? "set" : "remove", xattr_name);
 
-        if (((valid & OBD_MD_FLXATTR) == OBD_MD_FLXATTR) &&
-            (!strcmp(xattr_name, XATTR_NAME_LUSTRE_ACL))) {
-                rc = do_remote_setfacl(info);
-                GOTO(out, rc);
-        }
-
         if (strncmp(xattr_name, trust_string, sizeof(trust_string) - 1) == 0) {
                 if (strcmp(xattr_name + 8, XATTR_NAME_LOV) == 0)
                         GOTO(out, rc = -EACCES);
@@ -335,6 +347,17 @@ int mdt_setxattr(struct mdt_thread_info *info)
                         int flags = 0;
                         xattr = req_capsule_client_get(pill, &RMF_EADATA);
 
+                        if (valid & OBD_MD_FLRMTLSETFACL) {
+                                LASSERT(med->med_rmtclient);
+                                xattr_len = mdt_rmtlsetfacl(info, xattr_name,
+                                                (ext_acl_xattr_header *)xattr,
+                                                &new_xattr);
+                                if (xattr_len < 0)
+                                        GOTO(out_unlock, rc = xattr_len);
+
+                                xattr = (char *)new_xattr;
+                        }
+
                         if (body->flags & XATTR_REPLACE)
                                 flags |= LU_XATTR_REPLACE;
 
@@ -356,6 +379,8 @@ int mdt_setxattr(struct mdt_thread_info *info)
         }
         EXIT;
 out_unlock:
+        if (unlikely(new_xattr != NULL))
+                lustre_posix_acl_xattr_free(new_xattr, xattr_len);
         mdt_object_unlock(info, obj, lh, rc);
 out:
         mdt_exit_ucred(info);
index 01d85bd..65c8610 100644 (file)
@@ -317,7 +317,7 @@ static int mgc_requeue_add(struct config_llog_data *cld, int later)
         CDEBUG(D_INFO, "log %s: requeue (l=%d r=%d sp=%d st=%x)\n", 
                cld->cld_logname, later, atomic_read(&cld->cld_refcount),
                cld->cld_stopping, rq_state);
-        
+
         /* Hold lock for rq_state */
         spin_lock(&config_list_lock);
         cld->cld_lostlock = 1;
index 598ad31..e3d71ad 100644 (file)
@@ -29,6 +29,7 @@
 #include <obd.h>
 #include <obd_class.h>
 #include <lprocfs_status.h>
+#include <lustre_param.h>
 #include "mgs_internal.h"
 
 #ifdef LPROCFS
@@ -88,9 +89,40 @@ int lproc_mgs_setup(struct obd_device *obd)
         return rc;
 }
 
+static void seq_show_srpc_rule(struct seq_file *seq, const char *tgtname,
+                               struct sptlrpc_rule_set *rset)
+{
+        struct sptlrpc_rule    *r;
+        char                    dirbuf[10];
+        char                    flvrbuf[40];
+        char                   *net;
+        int                     i;
+
+        for (i = 0; i < rset->srs_nrule; i++) {
+                r = &rset->srs_rules[i];
+
+                if (r->sr_netid == LNET_NIDNET(LNET_NID_ANY))
+                        net = "default";
+                else
+                        net = libcfs_net2str(r->sr_netid);
+
+                if (r->sr_from == LUSTRE_SP_ANY && r->sr_to == LUSTRE_SP_ANY)
+                        dirbuf[0] = '\0';
+                else
+                        snprintf(dirbuf, sizeof(dirbuf), ".%s2%s",
+                                 sptlrpc_part2name(r->sr_from),
+                                 sptlrpc_part2name(r->sr_to));
+
+                sptlrpc_flavor2name(&r->sr_flvr, flvrbuf, sizeof(flvrbuf));
+                seq_printf(seq, "%s.srpc.flavor.%s%s=%s\n", tgtname,
+                           net, dirbuf, flvrbuf);
+        }
+}
+
 static int mgs_live_seq_show(struct seq_file *seq, void *v) 
 {
-        struct fs_db *fsdb = seq->private;
+        struct fs_db             *fsdb = seq->private;
+        struct mgs_tgt_srpc_conf *srpc_tgt;
         int i;
         
         down(&fsdb->fsdb_sem);
@@ -105,6 +137,18 @@ static int mgs_live_seq_show(struct seq_file *seq, void *v)
                  if (test_bit(i, fsdb->fsdb_ost_index_map)) 
                          seq_printf(seq, "%s-OST%04x\n", fsdb->fsdb_name, i);
 
+        seq_printf(seq, "\nSecure RPC Config Rules:\n");
+#if 0
+        seq_printf(seq, "%s.%s=%s\n", fsdb->fsdb_name,
+                   PARAM_SRPC_UDESC, fsdb->fsdb_srpc_fl_udesc ? "yes" : "no");
+#endif
+        for (srpc_tgt = fsdb->fsdb_srpc_tgt; srpc_tgt;
+             srpc_tgt = srpc_tgt->mtsc_next) {
+                seq_show_srpc_rule(seq, srpc_tgt->mtsc_tgt,
+                                   &srpc_tgt->mtsc_rset);
+        }
+        seq_show_srpc_rule(seq, fsdb->fsdb_name, &fsdb->fsdb_srpc_gen);
+
         up(&fsdb->fsdb_sem);
         return 0;
 }
index 786ea2a..1efe1ab 100644 (file)
@@ -65,6 +65,8 @@ static int mgs_connect(const struct lu_env *env,
         exp = class_conn2export(conn);
         LASSERT(exp);
 
+        exp->exp_flvr.sf_rpc = SPTLRPC_FLVR_NULL;
+
         if (data != NULL) {
                 data->ocd_connect_flags &= MGS_CONNECT_SUPPORTED;
                 exp->exp_connect_flags = data->ocd_connect_flags;
index 69acba9..5f0361f 100644 (file)
@@ -23,6 +23,12 @@ int class_dentry_readdir(struct obd_device *obd, struct dentry *dir,
                          struct vfsmount *inmnt, 
                          struct list_head *dentry_list);
  
+struct mgs_tgt_srpc_conf {
+        struct mgs_tgt_srpc_conf  *mtsc_next;
+        char                      *mtsc_tgt;
+        struct sptlrpc_rule_set    mtsc_rset;
+};
+
 #define INDEX_MAP_SIZE  8192     /* covers indicies to FFFF */
 #define FSDB_LOG_EMPTY  0x0001  /* missing client log */
 #define FSDB_OLDLOG14   0x0002  /* log starts in old (1.4) style */
@@ -43,6 +49,11 @@ struct fs_db {
         /* end COMPAT_146 */
         __u32             fsdb_flags;
         __u32             fsdb_gen;
+
+        /* in-memory copy of the srpc rules, guarded by fsdb_sem */
+        struct sptlrpc_rule_set   fsdb_srpc_gen;
+        struct mgs_tgt_srpc_conf *fsdb_srpc_tgt;
+        unsigned int              fsdb_srpc_fl_udesc:1;
 };
 
 int mgs_init_fsdb_list(struct obd_device *obd);
index 7f5eb86..e942879 100644 (file)
 #include <lustre_sec.h>
 #include "mgs_internal.h"
 
+static int mgs_get_fsdb_srpc_from_llog(struct obd_device *obd,
+                                       struct fs_db *fsdb);
+static int mgs_get_srpc_conf_log(struct fs_db *fsdb, const char *tgt,
+                                 enum lustre_sec_part from,
+                                 enum lustre_sec_part to,
+                                 struct sptlrpc_conf_log *log);
+
 /********************** Class functions ********************/
 
 /* Caller must list_del and OBD_FREE each dentry from the list */
@@ -260,6 +267,26 @@ out_pop:
         RETURN(rc);
 }
 
+static void mgs_free_fsdb_srpc(struct fs_db *fsdb)
+{
+        struct mgs_tgt_srpc_conf *tgtconf;
+
+        /* free target-specific rules */
+        while (fsdb->fsdb_srpc_tgt) {
+                tgtconf = fsdb->fsdb_srpc_tgt;
+                fsdb->fsdb_srpc_tgt = tgtconf->mtsc_next;
+
+                LASSERT(tgtconf->mtsc_tgt);
+
+                sptlrpc_rule_set_free(&tgtconf->mtsc_rset);
+                OBD_FREE(tgtconf->mtsc_tgt, strlen(tgtconf->mtsc_tgt) + 1);
+                OBD_FREE_PTR(tgtconf);
+        }
+
+        /* free general rules */
+        sptlrpc_rule_set_free(&fsdb->fsdb_srpc_gen);
+}
+
 static struct fs_db *mgs_find_fsdb(struct obd_device *obd, char *fsname)
 {
         struct mgs_obd *mgs = &obd->u.mgs;
@@ -309,6 +336,7 @@ static struct fs_db *mgs_new_fsdb(struct obd_device *obd, char *fsname)
         if (rc) 
                 GOTO(err, rc);
 
+        fsdb->fsdb_srpc_fl_udesc = 1;
         sema_init(&fsdb->fsdb_sem, 1);
         list_add(&fsdb->fsdb_list, &mgs->mgs_fs_db_list);
         lproc_mgs_add_live(obd, fsdb);
@@ -340,6 +368,7 @@ static void mgs_free_fsdb(struct obd_device *obd, struct fs_db *fsdb)
         name_destroy(&fsdb->fsdb_mdtlov); 
         name_destroy(&fsdb->fsdb_mdtlmv); 
         name_destroy(&fsdb->fsdb_mdc); 
+        mgs_free_fsdb_srpc(fsdb);
         OBD_FREE_PTR(fsdb);
 }
 
@@ -393,6 +422,14 @@ static int mgs_find_or_make_fsdb(struct obd_device *obd, char *name,
                 return rc;
         }
 
+        /* populate srpc rules from params llog */
+        rc = mgs_get_fsdb_srpc_from_llog(obd, fsdb);
+        if (rc) {
+                CERROR("Can't get db from params log %d\n", rc);
+                mgs_free_fsdb(obd, fsdb);
+                return rc;
+        }
+
         *dbh = fsdb;
 
         return 0;
@@ -712,17 +749,18 @@ static inline int record_setup(struct obd_device *obd, struct llog_handle *llh,
         return record_base(obd,llh,devname,0,LCFG_SETUP,s1,s2,s3,s4);
 }
 
-static inline int record_sec_flavor(struct obd_device *obd,
-                                    struct llog_handle *llh, char *devname,
-                                    struct sec_flavor_config *conf)
+static inline int record_sptlrpc_conf(struct obd_device *obd,
+                                      struct llog_handle *llh,
+                                      char *devname,
+                                      struct sp