static int mdt_hsm_release_unpack(struct mdt_thread_info *info) { struct md_attr *ma = &info->mti_attr; struct req_capsule *pill = info->mti_pill; ENTRY; if (!(ma->ma_attr_flags & MDS_HSM_RELEASE)) RETURN(0); req_capsule_extend(pill, &RQF_MDS_RELEASE_CLOSE); if (!(req_capsule_has_field(pill, &RMF_CLOSE_DATA, RCL_CLIENT) && req_capsule_field_present(pill, &RMF_CLOSE_DATA, RCL_CLIENT))) RETURN(-EFAULT); RETURN(0); }
/* return EADATA length to the caller. negative value means error */ static int mdt_getxattr_pack_reply(struct mdt_thread_info * info) { struct req_capsule *pill = info->mti_pill; struct ptlrpc_request *req = mdt_info_req(info); const char *xattr_name; u64 valid; static const char user_string[] = "user."; int size; int rc = 0; int rc2; ENTRY; valid = info->mti_body->mbo_valid & (OBD_MD_FLXATTR | OBD_MD_FLXATTRLS); /* Determine how many bytes we need */ if (valid == OBD_MD_FLXATTR) { xattr_name = req_capsule_client_get(pill, &RMF_NAME); if (!xattr_name) RETURN(-EFAULT); if (!(exp_connect_flags(req->rq_export) & OBD_CONNECT_XATTR) && !strncmp(xattr_name, user_string, sizeof(user_string) - 1)) RETURN(-EOPNOTSUPP); size = mo_xattr_get(info->mti_env, mdt_object_child(info->mti_object), &LU_BUF_NULL, xattr_name); if (size == -ENODATA) { /* XXX: Some client code will not handle -ENODATA * for XATTR_NAME_LOV (trusted.lov) properly. */ if (strcmp(xattr_name, XATTR_NAME_LOV) == 0) rc = 0; else rc = -ENODATA; size = 0; } } else if (valid == OBD_MD_FLXATTRLS) { xattr_name = "list"; size = mo_xattr_list(info->mti_env, mdt_object_child(info->mti_object), &LU_BUF_NULL); } else if (valid == OBD_MD_FLXATTRALL) { xattr_name = "all"; /* N.B. eadatasize = 0 is not valid for FLXATTRALL */ /* We could calculate accurate sizes, but this would * introduce a lot of overhead, let's do it later... */ size = info->mti_body->mbo_eadatasize; req_capsule_set_size(pill, &RMF_EAVALS, RCL_SERVER, size); req_capsule_set_size(pill, &RMF_EAVALS_LENS, RCL_SERVER, size); } else { CDEBUG(D_INFO, "Valid bits: %#llx\n", info->mti_body->mbo_valid); RETURN(-EINVAL); } if (size < 0) { if (size != -EOPNOTSUPP && size != -ENOENT) CERROR("%s: error geting EA size for '%s': rc = %d\n", mdt_obd_name(info->mti_mdt), xattr_name, size); RETURN(size); } if (req_capsule_has_field(pill, &RMF_ACL, RCL_SERVER)) req_capsule_set_size(pill, &RMF_ACL, RCL_SERVER, LUSTRE_POSIX_ACL_MAX_SIZE_OLD); req_capsule_set_size(pill, &RMF_EADATA, RCL_SERVER, info->mti_body->mbo_eadatasize == 0 ? 0 : size); rc2 = req_capsule_server_pack(pill); if (rc2 < 0) RETURN(rc2); if (OBD_FAIL_CHECK(OBD_FAIL_MDS_GETXATTR_PACK)) RETURN(-ENOMEM); RETURN(rc < 0 ? rc : size); }
void mdt_shrink_reply(struct mdt_thread_info *info) { struct req_capsule *pill = info->mti_pill; struct mdt_body *body; int md_size; int acl_size; ENTRY; body = req_capsule_server_get(pill, &RMF_MDT_BODY); LASSERT(body != NULL); if (body->valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE | OBD_MD_LINKNAME)) md_size = body->eadatasize; else md_size = 0; acl_size = body->aclsize; /* this replay - not send info to client */ if (info->mti_spec.no_create == 1) { md_size = 0; acl_size = 0; } CDEBUG(D_INFO, "Shrink to md_size = %d cookie/acl_size = %d" " MDSCAPA = %llx, OSSCAPA = %llx\n", md_size, acl_size, (unsigned long long)(body->valid & OBD_MD_FLMDSCAPA), (unsigned long long)(body->valid & OBD_MD_FLOSSCAPA)); /* &RMF_MDT_BODY, &RMF_MDT_MD, &RMF_ACL, or &RMF_LOGCOOKIES (optional) &RMF_CAPA1, (optional) &RMF_CAPA2, (optional) something else */ if (req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER)) req_capsule_shrink(pill, &RMF_MDT_MD, md_size, RCL_SERVER); if (req_capsule_has_field(pill, &RMF_ACL, RCL_SERVER)) req_capsule_shrink(pill, &RMF_ACL, acl_size, RCL_SERVER); else if (req_capsule_has_field(pill, &RMF_LOGCOOKIES, RCL_SERVER)) req_capsule_shrink(pill, &RMF_LOGCOOKIES, acl_size, RCL_SERVER); if (req_capsule_has_field(pill, &RMF_CAPA1, RCL_SERVER) && !(body->valid & OBD_MD_FLMDSCAPA)) req_capsule_shrink(pill, &RMF_CAPA1, 0, RCL_SERVER); if (req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) && !(body->valid & OBD_MD_FLOSSCAPA)) req_capsule_shrink(pill, &RMF_CAPA2, 0, RCL_SERVER); /* * Some more field should be shrinked if needed. * This should be done by those who added fields to reply message. */ EXIT; }
/* Shrink and/or grow reply buffers */ int mdt_fix_reply(struct mdt_thread_info *info) { struct req_capsule *pill = info->mti_pill; struct mdt_body *body; int md_size, md_packed = 0; int acl_size; int rc = 0; ENTRY; body = req_capsule_server_get(pill, &RMF_MDT_BODY); LASSERT(body != NULL); if (body->valid & (OBD_MD_FLDIREA | OBD_MD_FLEASIZE | OBD_MD_LINKNAME)) md_size = body->eadatasize; else md_size = 0; acl_size = body->aclsize; /* this replay - not send info to client */ if (info->mti_spec.no_create) { md_size = 0; acl_size = 0; } CDEBUG(D_INFO, "Shrink to md_size = %d cookie/acl_size = %d" " MDSCAPA = %llx, OSSCAPA = %llx\n", md_size, acl_size, (unsigned long long)(body->valid & OBD_MD_FLMDSCAPA), (unsigned long long)(body->valid & OBD_MD_FLOSSCAPA)); /* &RMF_MDT_BODY, &RMF_MDT_MD, &RMF_ACL, or &RMF_LOGCOOKIES (optional) &RMF_CAPA1, (optional) &RMF_CAPA2, (optional) something else */ /* MDT_MD buffer may be bigger than packed value, let's shrink all * buffers before growing it */ if (info->mti_big_lmm_used) { LASSERT(req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER)); /* free big lmm if md_size is not needed */ if (md_size == 0) { info->mti_big_lmm_used = 0; } else { md_packed = req_capsule_get_size(pill, &RMF_MDT_MD, RCL_SERVER); LASSERT(md_packed > 0); /* buffer must be allocated separately */ LASSERT(info->mti_attr.ma_lmm != req_capsule_server_get(pill, &RMF_MDT_MD)); req_capsule_shrink(pill, &RMF_MDT_MD, 0, RCL_SERVER); } } else if (req_capsule_has_field(pill, &RMF_MDT_MD, RCL_SERVER)) { req_capsule_shrink(pill, &RMF_MDT_MD, md_size, RCL_SERVER); } if (req_capsule_has_field(pill, &RMF_ACL, RCL_SERVER)) req_capsule_shrink(pill, &RMF_ACL, acl_size, RCL_SERVER); else if (req_capsule_has_field(pill, &RMF_LOGCOOKIES, RCL_SERVER)) req_capsule_shrink(pill, &RMF_LOGCOOKIES, acl_size, RCL_SERVER); if (req_capsule_has_field(pill, &RMF_CAPA1, RCL_SERVER) && !(body->valid & OBD_MD_FLMDSCAPA)) req_capsule_shrink(pill, &RMF_CAPA1, 0, RCL_SERVER); if (req_capsule_has_field(pill, &RMF_CAPA2, RCL_SERVER) && !(body->valid & OBD_MD_FLOSSCAPA)) req_capsule_shrink(pill, &RMF_CAPA2, 0, RCL_SERVER); /* * Some more field should be shrinked if needed. * This should be done by those who added fields to reply message. */ /* Grow MD buffer if needed finally */ if (info->mti_big_lmm_used) { void *lmm; LASSERT(md_size > md_packed); CDEBUG(D_INFO, "Enlarge reply buffer, need extra %d bytes\n", md_size - md_packed); rc = req_capsule_server_grow(pill, &RMF_MDT_MD, md_size); if (rc) { /* we can't answer with proper LOV EA, drop flags, * the rc is also returned so this request is * considered as failed */ body->valid &= ~(OBD_MD_FLDIREA | OBD_MD_FLEASIZE); /* don't return transno along with error */ lustre_msg_set_transno(pill->rc_req->rq_repmsg, 0); } else { /* now we need to pack right LOV/LMV EA */ lmm = req_capsule_server_get(pill, &RMF_MDT_MD); if (info->mti_attr.ma_valid & MA_LOV) { LASSERT(req_capsule_get_size(pill, &RMF_MDT_MD, RCL_SERVER) == info->mti_attr.ma_lmm_size); memcpy(lmm, info->mti_attr.ma_lmm, info->mti_attr.ma_lmm_size); } else if (info->mti_attr.ma_valid & MA_LMV) { LASSERT(req_capsule_get_size(pill, &RMF_MDT_MD, RCL_SERVER) == info->mti_attr.ma_lmv_size); memcpy(lmm, info->mti_attr.ma_lmv, info->mti_attr.ma_lmv_size); } } /* update mdt_max_mdsize so clients will be aware about that */ if (info->mti_mdt->mdt_max_mdsize < info->mti_attr.ma_lmm_size) info->mti_mdt->mdt_max_mdsize = info->mti_attr.ma_lmm_size; info->mti_big_lmm_used = 0; } RETURN(rc); }