struct lustre_capa_key k_key;
};
-enum {
- LC_ID_NONE = 0,
- LC_ID_PLAIN = 1,
- LC_ID_CONVERT = 2
+enum lc_auth_id {
+ LC_ID_NONE = 0,
+ LC_ID_PLAIN = 1,
+ LC_ID_CONVERT = 2
};
#define BYPASS_CAPA (struct lustre_capa *)ERR_PTR(-ENOENT)
+enum {
+ LU_CAPAINFO_MAX = 5
+};
+
+/** there are at most 5 FIDs in one operation, see rename,
+ * NOTE the last one is a temporary one used for is_subdir() */
+struct lu_capainfo {
+ enum lc_auth_id lci_auth;
+ __u32 lci_padding;
+ struct lu_fid lci_fid[LU_CAPAINFO_MAX];
+ struct lustre_capa *lci_capa[LU_CAPAINFO_MAX];
+};
+
+int lu_capainfo_init(void);
+void lu_capainfo_fini(void);
+struct lu_capainfo *lu_capainfo_get(const struct lu_env *env);
+
/** @} capa */
#endif /* __LINUX_CAPA_H_ */
struct md_object;
struct obd_export;
-enum {
- MD_CAPAINFO_MAX = 5
-};
-
-/** there are at most 5 fids in one operation, see rename, NOTE the last one
- * is a temporary one used for is_subdir() */
-struct md_capainfo {
- __u32 mc_auth;
- __u32 mc_padding;
- struct lu_fid mc_fid[MD_CAPAINFO_MAX];
- struct lustre_capa *mc_capa[MD_CAPAINFO_MAX];
-};
-
struct md_quota {
struct obd_export *mq_exp;
};
-/**
- * Implemented in mdd/mdd_handler.c.
- *
- * XXX should be moved into separate .h/.c together with all md security
- * related definitions.
- */
-struct md_capainfo *md_capainfo(const struct lu_env *env);
struct md_quota *md_quota(const struct lu_env *env);
/** metadata attributes */
.o_health_check = mdd_obd_health_check
};
-/*
- * context key constructor/destructor:
- * mdd_capainfo_key_init, mdd_capainfo_key_fini
- */
-LU_KEY_INIT_FINI(mdd_capainfo, struct md_capainfo);
-
-struct lu_context_key mdd_capainfo_key = {
- .lct_tags = LCT_SESSION,
- .lct_init = mdd_capainfo_key_init,
- .lct_fini = mdd_capainfo_key_fini
-};
-
-struct md_capainfo *md_capainfo(const struct lu_env *env)
-{
- /* NB, in mdt_init0 */
- if (env->le_ses == NULL)
- return NULL;
- return lu_context_key_get(env->le_ses, &mdd_capainfo_key);
-}
-EXPORT_SYMBOL(md_capainfo);
-
static int mdd_changelog_user_register(const struct lu_env *env,
struct mdd_device *mdd, int *id)
{
}
/* type constructor/destructor: mdd_type_init, mdd_type_fini */
-LU_TYPE_INIT_FINI(mdd, &mdd_thread_key, &mdd_capainfo_key);
+LU_TYPE_INIT_FINI(mdd, &mdd_thread_key);
const struct md_device_operations mdd_ops = {
.mdo_statfs = mdd_statfs,
}
static inline struct lustre_capa *mdd_object_capa(const struct lu_env *env,
- const struct mdd_object *obj)
+ const struct mdd_object *obj)
{
- struct md_capainfo *ci = md_capainfo(env);
- const struct lu_fid *fid = mdo2fid(obj);
- int i;
+ struct lu_capainfo *lci = lu_capainfo_get(env);
+ const struct lu_fid *fid = mdo2fid(obj);
+ int i;
- /* NB: in mdt_init0 */
- if (!ci)
- return BYPASS_CAPA;
- for (i = 0; i < MD_CAPAINFO_MAX; i++)
- if (lu_fid_eq(&ci->mc_fid[i], fid))
- return ci->mc_capa[i];
- return NULL;
+ /* NB: in mdt_init0 */
+ if (lci == NULL)
+ return BYPASS_CAPA;
+
+ for (i = 0; i < LU_CAPAINFO_MAX; i++)
+ if (lu_fid_eq(&lci->lci_fid[i], fid))
+ return lci->lci_capa[i];
+ return NULL;
}
static inline void mdd_set_capainfo(const struct lu_env *env, int offset,
- const struct mdd_object *obj,
- struct lustre_capa *capa)
-{
- struct md_capainfo *ci = md_capainfo(env);
- const struct lu_fid *fid = mdo2fid(obj);
-
- LASSERT(offset >= 0 && offset < MD_CAPAINFO_MAX);
- /* NB: in mdt_init0 */
- if (!ci)
- return;
- ci->mc_fid[offset] = *fid;
- ci->mc_capa[offset] = capa;
+ const struct mdd_object *obj,
+ struct lustre_capa *capa)
+{
+ struct lu_capainfo *lci = lu_capainfo_get(env);
+ const struct lu_fid *fid = mdo2fid(obj);
+
+ LASSERT(offset >= 0 && offset < LU_CAPAINFO_MAX);
+ /* NB: in mdt_init0 */
+ if (lci == NULL)
+ return;
+
+ lci->lci_fid[offset] = *fid;
+ lci->lci_capa[offset] = capa;
}
static inline const char *mdd_obj_dev_name(const struct mdd_object *obj)
void mdt_ck_thread_stop(struct mdt_device *mdt);
void mdt_ck_timer_callback(unsigned long castmeharder);
int mdt_capa_keys_init(const struct lu_env *env, struct mdt_device *mdt);
-
-static inline void mdt_set_capainfo(struct mdt_thread_info *info, int offset,
- const struct lu_fid *fid,
- struct lustre_capa *capa)
-{
- struct md_capainfo *ci;
-
- LASSERT(offset >= 0 && offset < MD_CAPAINFO_MAX);
- if (!info->mti_mdt->mdt_opts.mo_mds_capa ||
- !(exp_connect_flags(info->mti_exp) & OBD_CONNECT_MDS_CAPA))
- return;
-
- ci = md_capainfo(info->mti_env);
- LASSERT(ci);
- ci->mc_fid[offset] = *fid;
- ci->mc_capa[offset] = capa;
-}
-
-static inline void mdt_dump_capainfo(struct mdt_thread_info *info)
-{
- struct md_capainfo *ci = md_capainfo(info->mti_env);
- int i;
-
- if (!ci)
- return;
- for (i = 0; i < MD_CAPAINFO_MAX; i++) {
- if (!ci->mc_capa[i]) {
- CERROR("no capa for index %d "DFID"\n",
- i, PFID(&ci->mc_fid[i]));
- continue;
- }
- if (ci->mc_capa[i] == BYPASS_CAPA) {
- CERROR("bypass for index %d "DFID"\n",
- i, PFID(&ci->mc_fid[i]));
- continue;
- }
- DEBUG_CAPA(D_ERROR, ci->mc_capa[i], "index %d", i);
- }
-}
+void mdt_set_capainfo(struct mdt_thread_info *info, int offset,
+ const struct lu_fid *fid, struct lustre_capa *capa);
+void mdt_dump_capainfo(struct mdt_thread_info *info);
static inline struct obd_device *mdt2obd_dev(const struct mdt_device *mdt)
{
CERROR("Unknown attr bits: "LPX64"\n", in);
return out;
}
+
+void mdt_set_capainfo(struct mdt_thread_info *info, int offset,
+ const struct lu_fid *fid, struct lustre_capa *capa)
+{
+ struct lu_capainfo *lci;
+
+ LASSERT(offset >= 0 && offset < LU_CAPAINFO_MAX);
+ if (!info->mti_mdt->mdt_opts.mo_mds_capa ||
+ !(exp_connect_flags(info->mti_exp) & OBD_CONNECT_MDS_CAPA))
+ return;
+
+ lci = lu_capainfo_get(info->mti_env);
+ LASSERT(lci);
+ lci->lci_fid[offset] = *fid;
+ lci->lci_capa[offset] = capa;
+}
+
+#ifdef DEBUG_CAPA
+void mdt_dump_capainfo(struct mdt_thread_info *info)
+{
+ struct lu_capainfo *lci = lu_capainfo_get(info->mti_env);
+ int i;
+
+ if (lci == NULL)
+ return;
+
+ for (i = 0; i < LU_CAPAINFO_MAX; i++) {
+ if (lci->lci_capa[i] == NULL) {
+ CERROR("no capa for index %d "DFID"\n",
+ i, PFID(&lci->lci_fid[i]));
+ continue;
+ }
+ if (lci->lci_capa[i] == BYPASS_CAPA) {
+ CERROR("bypass for index %d "DFID"\n",
+ i, PFID(&lci->lci_fid[i]));
+ continue;
+ }
+ DEBUG_CAPA(D_ERROR, lci->lci_capa[i], "index %d", i);
+ }
+}
+#endif /* DEBUG_CAPA */
+
/* unpacking */
static int mdt_setattr_unpack_rec(struct mdt_thread_info *info)
va_end(args);
}
EXPORT_SYMBOL(_debug_capa);
+
+/*
+ * context key constructor/destructor:
+ * lu_capainfo_key_init, lu_capainfo_key_fini
+ */
+LU_KEY_INIT_FINI(lu_capainfo, struct lu_capainfo);
+
+struct lu_context_key lu_capainfo_key = {
+ .lct_tags = LCT_SESSION,
+ .lct_init = lu_capainfo_key_init,
+ .lct_fini = lu_capainfo_key_fini
+};
+
+struct lu_capainfo *lu_capainfo_get(const struct lu_env *env)
+{
+ /* NB, in mdt_init0 */
+ if (env->le_ses == NULL)
+ return NULL;
+ return lu_context_key_get(env->le_ses, &lu_capainfo_key);
+}
+EXPORT_SYMBOL(lu_capainfo_get);
+
+/**
+ * Initialization of lu_capainfo_key data.
+ */
+int lu_capainfo_init(void)
+{
+ int rc;
+
+ LU_CONTEXT_KEY_INIT(&lu_capainfo_key);
+ rc = lu_context_key_register(&lu_capainfo_key);
+ return rc;
+}
+
+/**
+ * Dual to lu_capainfo_init().
+ */
+void lu_capainfo_fini(void)
+{
+ lu_context_key_degister(&lu_capainfo_key);
+}
return err;
#endif
- err = lu_global_init();
- if (err)
- return err;
+ err = lu_global_init();
+ if (err)
+ return err;
+
+ err = lu_capainfo_init();
+ if (err)
+ return err;
err = cl_global_init();
if (err != 0)
dt_global_fini();
#endif
cl_global_fini();
- lu_global_fini();
+ lu_capainfo_fini();
+ lu_global_fini();
obd_cleanup_caches();
obd_sysctl_clean();
}
int osd_object_auth(const struct lu_env *env, struct dt_object *dt,
- struct lustre_capa *capa, __u64 opc)
+ struct lustre_capa *capa, __u64 opc)
{
- const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
- struct osd_device *dev = osd_dev(dt->do_lu.lo_dev);
- struct md_capainfo *ci;
- int rc;
+ const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
+ struct osd_device *osd = osd_dev(dt->do_lu.lo_dev);
+ struct lu_capainfo *lci;
+ int rc;
- if (!dev->od_fl_capa)
- return 0;
+ if (!osd->od_fl_capa)
+ return 0;
- if (capa == BYPASS_CAPA)
- return 0;
+ if (capa == BYPASS_CAPA)
+ return 0;
- ci = md_capainfo(env);
- if (unlikely(!ci))
- return 0;
+ lci = lu_capainfo_get(env);
+ if (unlikely(lci == NULL))
+ return 0;
- if (ci->mc_auth == LC_ID_NONE)
- return 0;
+ if (lci->lci_auth == LC_ID_NONE)
+ return 0;
- if (!capa) {
- CERROR("no capability is provided for fid "DFID"\n", PFID(fid));
- return -EACCES;
- }
+ if (capa == NULL) {
+ CERROR("%s: no capability provided for FID "DFID": rc = %d\n",
+ osd_name(osd), PFID(fid), -EACCES);
+ return -EACCES;
+ }
- if (!lu_fid_eq(fid, &capa->lc_fid)) {
- DEBUG_CAPA(D_ERROR, capa, "fid "DFID" mismatch with",
- PFID(fid));
- return -EACCES;
- }
+ if (!lu_fid_eq(fid, &capa->lc_fid)) {
+ DEBUG_CAPA(D_ERROR, capa, "fid "DFID" mismatch with",
+ PFID(fid));
+ return -EACCES;
+ }
- if (!capa_opc_supported(capa, opc)) {
- DEBUG_CAPA(D_ERROR, capa, "opc "LPX64" not supported by", opc);
- return -EACCES;
- }
+ if (!capa_opc_supported(capa, opc)) {
+ DEBUG_CAPA(D_ERROR, capa, "opc "LPX64" not supported by", opc);
+ return -EACCES;
+ }
- if ((rc = capa_is_sane(env, dev, capa, dev->od_capa_keys))) {
- DEBUG_CAPA(D_ERROR, capa, "insane (rc %d)", rc);
- return -EACCES;
- }
+ rc = capa_is_sane(env, osd, capa, osd->od_capa_keys);
+ if (rc != 0) {
+ DEBUG_CAPA(D_ERROR, capa, "insane: rc = %d", rc);
+ return -EACCES;
+ }
- return 0;
+ return 0;
}
static struct timespec *osd_inode_time(const struct lu_env *env,
}
static struct obd_capa *osd_capa_get(const struct lu_env *env,
- struct dt_object *dt,
- struct lustre_capa *old,
- __u64 opc)
+ struct dt_object *dt,
+ struct lustre_capa *old, __u64 opc)
{
- struct osd_thread_info *info = osd_oti_get(env);
- const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
- struct osd_object *obj = osd_dt_obj(dt);
- struct osd_device *dev = osd_obj2dev(obj);
- struct lustre_capa_key *key = &info->oti_capa_key;
- struct lustre_capa *capa = &info->oti_capa;
- struct obd_capa *oc;
- struct md_capainfo *ci;
- int rc;
- ENTRY;
+ struct osd_thread_info *info = osd_oti_get(env);
+ const struct lu_fid *fid = lu_object_fid(&dt->do_lu);
+ struct osd_object *obj = osd_dt_obj(dt);
+ struct osd_device *osd = osd_obj2dev(obj);
+ struct lustre_capa_key *key = &info->oti_capa_key;
+ struct lustre_capa *capa = &info->oti_capa;
+ struct obd_capa *oc;
+ struct lu_capainfo *lci;
+ int rc;
+ ENTRY;
- if (!dev->od_fl_capa)
- RETURN(ERR_PTR(-ENOENT));
+ if (!osd->od_fl_capa)
+ RETURN(ERR_PTR(-ENOENT));
LASSERT(dt_object_exists(dt) && !dt_object_remote(dt));
- LINVRNT(osd_invariant(obj));
+ LINVRNT(osd_invariant(obj));
- /* renewal sanity check */
- if (old && osd_object_auth(env, dt, old, opc))
- RETURN(ERR_PTR(-EACCES));
-
- ci = md_capainfo(env);
- if (unlikely(!ci))
- RETURN(ERR_PTR(-ENOENT));
-
- switch (ci->mc_auth) {
- case LC_ID_NONE:
- RETURN(NULL);
- case LC_ID_PLAIN:
- capa->lc_uid = obj->oo_inode->i_uid;
- capa->lc_gid = obj->oo_inode->i_gid;
- capa->lc_flags = LC_ID_PLAIN;
- break;
- case LC_ID_CONVERT: {
- __u32 d[4], s[4];
-
- s[0] = obj->oo_inode->i_uid;
- cfs_get_random_bytes(&(s[1]), sizeof(__u32));
- s[2] = obj->oo_inode->i_gid;
- cfs_get_random_bytes(&(s[3]), sizeof(__u32));
- rc = capa_encrypt_id(d, s, key->lk_key, CAPA_HMAC_KEY_MAX_LEN);
- if (unlikely(rc))
- RETURN(ERR_PTR(rc));
-
- capa->lc_uid = ((__u64)d[1] << 32) | d[0];
- capa->lc_gid = ((__u64)d[3] << 32) | d[2];
- capa->lc_flags = LC_ID_CONVERT;
- break;
- }
- default:
- RETURN(ERR_PTR(-EINVAL));
+ /* renewal sanity check */
+ if (old && osd_object_auth(env, dt, old, opc))
+ RETURN(ERR_PTR(-EACCES));
+
+ lci = lu_capainfo_get(env);
+ if (unlikely(lci == NULL))
+ RETURN(ERR_PTR(-ENOENT));
+
+ switch (lci->lci_auth) {
+ case LC_ID_NONE:
+ RETURN(NULL);
+ case LC_ID_PLAIN:
+ capa->lc_uid = obj->oo_inode->i_uid;
+ capa->lc_gid = obj->oo_inode->i_gid;
+ capa->lc_flags = LC_ID_PLAIN;
+ break;
+ case LC_ID_CONVERT: {
+ __u32 d[4], s[4];
+
+ s[0] = obj->oo_inode->i_uid;
+ cfs_get_random_bytes(&(s[1]), sizeof(__u32));
+ s[2] = obj->oo_inode->i_gid;
+ cfs_get_random_bytes(&(s[3]), sizeof(__u32));
+ rc = capa_encrypt_id(d, s, key->lk_key, CAPA_HMAC_KEY_MAX_LEN);
+ if (unlikely(rc))
+ RETURN(ERR_PTR(rc));
+
+ capa->lc_uid = ((__u64)d[1] << 32) | d[0];
+ capa->lc_gid = ((__u64)d[3] << 32) | d[2];
+ capa->lc_flags = LC_ID_CONVERT;
+ break;
}
+ default:
+ RETURN(ERR_PTR(-EINVAL));
+ }
- capa->lc_fid = *fid;
- capa->lc_opc = opc;
- capa->lc_flags |= dev->od_capa_alg << 24;
- capa->lc_timeout = dev->od_capa_timeout;
- capa->lc_expiry = 0;
+ capa->lc_fid = *fid;
+ capa->lc_opc = opc;
+ capa->lc_flags |= osd->od_capa_alg << 24;
+ capa->lc_timeout = osd->od_capa_timeout;
+ capa->lc_expiry = 0;
- oc = capa_lookup(dev->od_capa_hash, capa, 1);
- if (oc) {
- LASSERT(!capa_is_expired(oc));
- RETURN(oc);
- }
+ oc = capa_lookup(osd->od_capa_hash, capa, 1);
+ if (oc) {
+ LASSERT(!capa_is_expired(oc));
+ RETURN(oc);
+ }
spin_lock(&capa_lock);
- *key = dev->od_capa_keys[1];
+ *key = osd->od_capa_keys[1];
spin_unlock(&capa_lock);
- capa->lc_keyid = key->lk_keyid;
- capa->lc_expiry = cfs_time_current_sec() + dev->od_capa_timeout;
+ capa->lc_keyid = key->lk_keyid;
+ capa->lc_expiry = cfs_time_current_sec() + osd->od_capa_timeout;
- rc = capa_hmac(capa->lc_hmac, capa, key->lk_key);
- if (rc) {
- DEBUG_CAPA(D_ERROR, capa, "HMAC failed: %d for", rc);
- RETURN(ERR_PTR(rc));
- }
+ rc = capa_hmac(capa->lc_hmac, capa, key->lk_key);
+ if (rc) {
+ DEBUG_CAPA(D_ERROR, capa, "HMAC failed: %d for", rc);
+ RETURN(ERR_PTR(rc));
+ }
- oc = capa_add(dev->od_capa_hash, capa);
- RETURN(oc);
+ oc = capa_add(osd->od_capa_hash, capa);
+ RETURN(oc);
}
static int osd_object_sync(const struct lu_env *env, struct dt_object *dt)