Beispiel #1
0
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 */
	eadatasize = mo_xattr_list(env, next, buf);
	if (eadatasize < 0)
		GOTO(out, rc = eadatasize);

	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->eadatasize - eavallen;
		rc = mdt_getxattr_one(info, b, next, buf, med, uc);
		if (rc < 0)
			GOTO(out, rc);

		sizes[eavallens] = rc;
		eavallens++;
		eavallen += rc;
	}

	repbody->aclsize = eavallen;
	repbody->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);

	GOTO(out, rc = eadatasize);
out:
	return rc;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
	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 = mo_xattr_get(env, next, buf, b);
		if (rc < 0)
			GOTO(out_shrink, rc);
		rc = mdt_nodemap_map_acl(info, buf->lb_buf, rc, b,
					 NODEMAP_FS_TO_CLIENT);
		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;
}
Beispiel #4
0
/* 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);
}