+
+int mdt_pack_encctx_in_reply(struct mdt_thread_info *info,
+ struct mdt_object *child)
+{
+ struct lu_buf *buffer;
+ struct mdt_body *repbody;
+ struct req_capsule *pill = info->mti_pill;
+ struct obd_export *exp = mdt_info_req(info)->rq_export;
+ int rc = 0;
+
+ if (!exp_connect_encrypt(exp))
+ return rc;
+
+ if (req_capsule_has_field(pill, &RMF_FILE_ENCCTX, RCL_SERVER) &&
+ req_capsule_get_size(pill, &RMF_FILE_ENCCTX, RCL_SERVER) != 0) {
+ struct lu_attr la = { 0 };
+ struct dt_object *dt = mdt_obj2dt(child);
+
+ if (dt && dt->do_ops && dt->do_ops->do_attr_get)
+ dt_attr_get(info->mti_env, mdt_obj2dt(child), &la);
+
+ if (la.la_valid & LA_FLAGS && la.la_flags & LUSTRE_ENCRYPT_FL) {
+ buffer = &info->mti_buf;
+
+ /* fill reply buffer with encryption context now */
+ buffer->lb_len =
+ req_capsule_get_size(pill, &RMF_FILE_ENCCTX,
+ RCL_SERVER);
+ buffer->lb_buf =
+ req_capsule_server_get(pill, &RMF_FILE_ENCCTX);
+ rc = mo_xattr_get(info->mti_env,
+ mdt_object_child(child),
+ buffer,
+ LL_XATTR_NAME_ENCRYPTION_CONTEXT);
+ if (rc >= 0) {
+ CDEBUG(D_SEC,
+ "found encryption ctx of size %d for "DFID"\n",
+ rc, PFID(mdt_object_fid(child)));
+
+ repbody = req_capsule_server_get(pill,
+ &RMF_MDT_BODY);
+ repbody->mbo_valid |= OBD_MD_ENCCTX;
+ if (rc < buffer->lb_len)
+ req_capsule_shrink(pill,
+ &RMF_FILE_ENCCTX, rc,
+ RCL_SERVER);
+ rc = 0;
+ } else {
+ CDEBUG(D_SEC,
+ "encryption ctx not found for "DFID": rc = %d\n",
+ PFID(mdt_object_fid(child)), rc);
+ req_capsule_shrink(pill, &RMF_FILE_ENCCTX, 0,
+ RCL_SERVER);
+ /* handling -ENOENT is important because it may
+ * change object state in DNE env dropping
+ * LOHA_EXISTS flag, it is important to return
+ * that to the caller.
+ * Check LU-13115 for details.
+ */
+ if (rc != -ENOENT)
+ rc = 0;
+ }
+ } else {
+ req_capsule_shrink(pill, &RMF_FILE_ENCCTX, 0,
+ RCL_SERVER);
+ }
+ }
+ return rc;
+}