+static int
+mdt_getxattr_one(struct mdt_thread_info *info,
+ char *xattr_name, struct md_object *next,
+ struct lu_buf *buf, struct mdt_export_data *med,
+ struct lu_ucred *uc)
+{
+ __u32 remote = exp_connect_rmtclient(info->mti_exp);
+ int flags = CFS_IC_NOTHING, rc;
+
+ ENTRY;
+
+ CDEBUG(D_INODE, "getxattr %s\n", xattr_name);
+
+ rc = mo_xattr_get(info->mti_env, next, buf, xattr_name);
+ if (rc < 0)
+ GOTO(out, rc);
+
+ if (info->mti_body->mbo_valid &
+ (OBD_MD_FLRMTLSETFACL | OBD_MD_FLRMTLGETFACL))
+ flags = CFS_IC_ALL;
+ else if (info->mti_body->mbo_valid & OBD_MD_FLRMTRGETFACL)
+ flags = CFS_IC_MAPPED;
+
+ if (rc > 0 && flags != CFS_IC_NOTHING) {
+ int rc1;
+
+ if (unlikely(!remote))
+ GOTO(out, rc = -EINVAL);
+
+ 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;
+ }
+
+out:
+ return rc;
+}
+
+static int mdt_getxattr_all(struct mdt_thread_info *info,
+ struct mdt_body *reqbody, struct mdt_body *repbody,
+ struct lu_buf *buf, struct md_object *next)
+{
+ const struct lu_env *env = info->mti_env;
+ struct ptlrpc_request *req = mdt_info_req(info);
+ struct mdt_export_data *med = mdt_req2med(req);
+ struct lu_ucred *uc = mdt_ucred(info);
+ char *v, *b, *eadatahead, *eadatatail;
+ __u32 *sizes;
+ int eadatasize, eavallen = 0, eavallens = 0, rc;
+
+ ENTRY;
+
+ /*
+ * The format of the pill is the following:
+ * EADATA: attr1\0attr2\0...attrn\0
+ * EAVALS: val1val2...valn
+ * EAVALS_LENS: 4,4,...4
+ */
+
+ eadatahead = buf->lb_buf;
+
+ /* Fill out EADATA first */
+ rc = mo_xattr_list(env, next, buf);
+ if (rc < 0)
+ GOTO(out_shrink, rc);
+
+ eadatasize = rc;
+ eadatatail = eadatahead + eadatasize;
+
+ v = req_capsule_server_get(info->mti_pill, &RMF_EAVALS);
+ sizes = req_capsule_server_get(info->mti_pill, &RMF_EAVALS_LENS);
+
+ /* Fill out EAVALS and EAVALS_LENS */
+ for (b = eadatahead; b < eadatatail; b += strlen(b) + 1, v += rc) {
+ buf->lb_buf = v;
+ buf->lb_len = reqbody->mbo_eadatasize - eavallen;
+ rc = mdt_getxattr_one(info, b, next, buf, med, uc);
+ if (rc < 0)
+ GOTO(out_shrink, rc);
+
+ sizes[eavallens] = rc;
+ eavallens++;
+ eavallen += rc;
+ }
+
+out_shrink:
+ if (rc < 0) {
+ eadatasize = 0;
+ eavallens = 0;
+ eavallen = 0;
+ }
+ repbody->mbo_aclsize = eavallen;
+ repbody->mbo_max_mdsize = eavallens;
+
+ req_capsule_shrink(info->mti_pill, &RMF_EAVALS, eavallen, RCL_SERVER);
+ req_capsule_shrink(info->mti_pill, &RMF_EAVALS_LENS,
+ eavallens * sizeof(__u32), RCL_SERVER);
+ req_capsule_shrink(info->mti_pill, &RMF_EADATA, eadatasize, RCL_SERVER);
+
+ if (rc >= 0)
+ RETURN(eadatasize);
+ return rc;
+}
+