+ repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY);
+ repbody->mbo_fid1 = *fid;
+ repbody->mbo_valid = OBD_MD_FLID;
+
+ RETURN(rc);
+}
+
+/**
+ * Find name matching hash
+ *
+ * We search \a child LinkEA for a name whose hash matches \a lname
+ * (it contains an encoded hash).
+ *
+ * \param info mdt thread info
+ * \param lname encoded hash to find
+ * \param parent parent object
+ * \param child object to search with LinkEA
+ *
+ * \retval 1 match found
+ * \retval 0 no match found
+ * \retval -ev negative errno upon error
+ */
+int find_name_matching_hash(struct mdt_thread_info *info, struct lu_name *lname,
+ struct mdt_object *parent, struct mdt_object *child)
+{
+ /* Here, lname is an encoded hash of on-disk name, and
+ * client is doing access without encryption key.
+ * So we need to get LinkEA, check parent fid is correct and
+ * compare name hash with the one in the request.
+ */
+ struct lu_buf *buf = &info->mti_big_buf;
+ struct lu_name name;
+ struct lu_fid pfid;
+ struct linkea_data ldata = { NULL };
+ struct link_ea_header *leh;
+ struct link_ea_entry *lee;
+ struct lu_buf link = { 0 };
+ char *hash;
+ int reclen, count, rc;
+
+ ENTRY;
+ if (lname->ln_namelen < LL_CRYPTO_BLOCK_SIZE)
+ RETURN(-EINVAL);
+
+ buf = lu_buf_check_and_alloc(buf, PATH_MAX);
+ if (!buf->lb_buf)
+ RETURN(-ENOMEM);
+
+ ldata.ld_buf = buf;
+ rc = mdt_links_read(info, child, &ldata);
+ if (rc < 0)
+ RETURN(rc);
+
+ hash = kmalloc(lname->ln_namelen, GFP_NOFS);
+ if (!hash)
+ RETURN(-ENOMEM);
+ rc = critical_decode(lname->ln_name, lname->ln_namelen, hash);
+
+ leh = buf->lb_buf;
+ lee = (struct link_ea_entry *)(leh + 1);
+ for (count = 0; count < leh->leh_reccount; count++) {
+ linkea_entry_unpack(lee, &reclen, &name, &pfid);
+ if (!parent || lu_fid_eq(&pfid, mdt_object_fid(parent))) {
+ lu_buf_check_and_alloc(&link, name.ln_namelen);
+ if (!link.lb_buf)
+ GOTO(out_match, rc = -ENOMEM);
+ rc = critical_decode(name.ln_name, name.ln_namelen,
+ link.lb_buf);
+
+ if (memcmp(LLCRYPT_EXTRACT_DIGEST(link.lb_buf, rc),
+ hash, LL_CRYPTO_BLOCK_SIZE) == 0) {
+ *lname = name;
+ break;
+ }
+ }
+ lee = (struct link_ea_entry *) ((char *)lee + reclen);
+ }
+ if (count == leh->leh_reccount)
+ rc = 0;
+ else
+ rc = 1;
+
+out_match:
+ lu_buf_free(&link);
+ kfree(hash);
+