Ejemplo n.º 1
0
static int mdt_setattr_unpack(struct mdt_thread_info *info)
{
        struct mdt_reint_record *rr = &info->mti_rr;
        struct md_attr          *ma = &info->mti_attr;
        struct req_capsule      *pill = info->mti_pill;
        int rc;
        ENTRY;

        rc = mdt_setattr_unpack_rec(info);
        if (rc)
                RETURN(rc);

        /* Epoch may be absent */
        mdt_ioepoch_unpack(info);

        if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
                rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
                rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                        RCL_CLIENT);
                ma->ma_lmm_size = rr->rr_eadatalen;
                if (ma->ma_lmm_size > 0) {
                        ma->ma_lmm = (void *)rr->rr_eadata;
                        ma->ma_valid |= MA_LOV;
                }
        }

        rc = mdt_dlmreq_unpack(info);
        RETURN(rc);
}
Ejemplo n.º 2
0
int llog_origin_handle_create(struct ptlrpc_request *req)
{
        struct obd_export    *exp = req->rq_export;
        struct obd_device    *obd = exp->exp_obd;
        struct obd_device    *disk_obd;
        struct llog_handle   *loghandle;
        struct llogd_body    *body;
        struct lvfs_run_ctxt  saved;
        struct llog_logid    *logid = NULL;
        struct llog_ctxt     *ctxt;
        char                 *name = NULL;
        int                   rc, rc2;
        ENTRY;

        body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
        if (body == NULL)
                RETURN(-EFAULT);

        if (body->lgd_logid.lgl_oid > 0)
                logid = &body->lgd_logid;

        if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
                name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
                if (name == NULL)
                        RETURN(-EFAULT);
                CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name);
        }

        ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
        if (ctxt == NULL) {
                CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n",
                       obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name);
                RETURN(-ENODEV);
        }
        disk_obd = ctxt->loc_exp->exp_obd;
        push_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);

        rc = llog_create(ctxt, &loghandle, logid, name);
        if (rc)
                GOTO(out_pop, rc);

        rc = req_capsule_server_pack(&req->rq_pill);
        if (rc)
                GOTO(out_close, rc = -ENOMEM);

        body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
        body->lgd_logid = loghandle->lgh_id;

        GOTO(out_close, rc);
out_close:
        rc2 = llog_close(loghandle);
        if (!rc)
                rc = rc2;
out_pop:
        pop_ctxt(&saved, &disk_obd->obd_lvfs_ctxt, NULL);
        llog_ctxt_put(ctxt);
        return rc;
}
Ejemplo n.º 3
0
/* Only open is supported, no new llog can be created remotely */
int llog_origin_handle_open(struct ptlrpc_request *req)
{
	struct obd_export	*exp = req->rq_export;
	struct obd_device	*obd = exp->exp_obd;
	struct llog_handle	*loghandle;
	struct llogd_body	*body;
	struct llog_logid	*logid = NULL;
	struct llog_ctxt	*ctxt;
	char			*name = NULL;
	int			 rc;

	ENTRY;

	body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY);
	if (body == NULL)
		RETURN(err_serious(-EFAULT));

	rc = req_capsule_server_pack(&req->rq_pill);
	if (rc)
		RETURN(err_serious(-ENOMEM));

	if (ostid_id(&body->lgd_logid.lgl_oi) > 0)
		logid = &body->lgd_logid;

	if (req_capsule_field_present(&req->rq_pill, &RMF_NAME, RCL_CLIENT)) {
		name = req_capsule_client_get(&req->rq_pill, &RMF_NAME);
		if (name == NULL)
			RETURN(-EFAULT);
		CDEBUG(D_INFO, "%s: opening log %s\n", obd->obd_name, name);
	}

	if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) {
		CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d name=%s\n",
		       obd->obd_name, body->lgd_ctxt_idx, name);
		RETURN(-EPROTO);
	}

	ctxt = llog_get_context(obd, body->lgd_ctxt_idx);
	if (ctxt == NULL) {
		CDEBUG(D_WARNING, "%s: no ctxt. group=%p idx=%d name=%s\n",
		       obd->obd_name, &obd->obd_olg, body->lgd_ctxt_idx, name);
		RETURN(-ENODEV);
	}

	rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, logid,
		       name, LLOG_OPEN_EXISTS);
	if (rc)
		GOTO(out_ctxt, rc);

	body = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY);
	body->lgd_logid = loghandle->lgh_id;

	llog_origin_close(req->rq_svc_thread->t_env, loghandle);
	EXIT;
out_ctxt:
	llog_ctxt_put(ctxt);
	return rc;
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
static int mdt_setattr_unpack(struct mdt_thread_info *info)
{
        struct mdt_reint_record *rr = &info->mti_rr;
        struct md_attr          *ma = &info->mti_attr;
        struct req_capsule      *pill = info->mti_pill;
        int rc;
        ENTRY;

        rc = mdt_setattr_unpack_rec(info);
        if (rc)
                RETURN(rc);

        /* Epoch may be absent */
        mdt_ioepoch_unpack(info);

        if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
                rr->rr_eadata = req_capsule_client_get(pill, &RMF_EADATA);
                rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                        RCL_CLIENT);
		if (rr->rr_eadatalen > 0) {
			const struct lmv_user_md	*lum;

			lum = rr->rr_eadata;
			/* Sigh ma_valid(from req) does not indicate whether
			 * it will set LOV/LMV EA, so we have to check magic */
			if (le32_to_cpu(lum->lum_magic) == LMV_USER_MAGIC) {
				ma->ma_valid |= MA_LMV;
				ma->ma_lmv = (void *)rr->rr_eadata;
				ma->ma_lmv_size = rr->rr_eadatalen;
			} else {
				ma->ma_valid |= MA_LOV;
				ma->ma_lmm = (void *)rr->rr_eadata;
				ma->ma_lmm_size = rr->rr_eadatalen;
			}
		}
	}

	rc = mdt_dlmreq_unpack(info);
	RETURN(rc);
}
Ejemplo n.º 6
0
Archivo: mdt_lib.c Proyecto: hpc/lustre
static int mdt_create_unpack(struct mdt_thread_info *info)
{
        struct md_ucred         *uc  = mdt_ucred(info);
        struct mdt_rec_create   *rec;
        struct lu_attr          *attr = &info->mti_attr.ma_attr;
        struct mdt_reint_record *rr = &info->mti_rr;
        struct req_capsule      *pill = info->mti_pill;
        struct md_op_spec       *sp = &info->mti_spec;
        int rc;
        ENTRY;

        CLASSERT(sizeof(struct mdt_rec_create) == sizeof(struct mdt_rec_reint));
        rec = req_capsule_client_get(pill, &RMF_REC_REINT);
        if (rec == NULL)
                RETURN(-EFAULT);

        uc->mu_fsuid = rec->cr_fsuid;
        uc->mu_fsgid = rec->cr_fsgid;
        uc->mu_cap   = rec->cr_cap;
        uc->mu_suppgids[0] = rec->cr_suppgid1;
        uc->mu_suppgids[1] = -1;

        rr->rr_fid1 = &rec->cr_fid1;
        rr->rr_fid2 = &rec->cr_fid2;
        attr->la_mode = rec->cr_mode;
        attr->la_rdev  = rec->cr_rdev;
        attr->la_uid   = rec->cr_fsuid;
        attr->la_gid   = rec->cr_fsgid;
        attr->la_ctime = rec->cr_time;
        attr->la_mtime = rec->cr_time;
        attr->la_atime = rec->cr_time;
        attr->la_valid = LA_MODE | LA_RDEV | LA_UID | LA_GID |
                         LA_CTIME | LA_MTIME | LA_ATIME;
        memset(&sp->u, 0, sizeof(sp->u));
        sp->sp_cr_flags = get_mrc_cr_flags(rec);
        sp->sp_ck_split = !!(rec->cr_bias & MDS_CHECK_SPLIT);
        info->mti_cross_ref = !!(rec->cr_bias & MDS_CROSS_REF);

        if (req_capsule_get_size(pill, &RMF_CAPA1, RCL_CLIENT))
                mdt_set_capainfo(info, 0, rr->rr_fid1,
                                 req_capsule_client_get(pill, &RMF_CAPA1));
        mdt_set_capainfo(info, 1, rr->rr_fid2, BYPASS_CAPA);

        if (!info->mti_cross_ref) {
                rr->rr_name = req_capsule_client_get(pill, &RMF_NAME);
                rr->rr_namelen = req_capsule_get_size(pill, &RMF_NAME,
                                                      RCL_CLIENT) - 1;
                LASSERT(rr->rr_name && rr->rr_namelen > 0);
        } else {
                rr->rr_name = NULL;
                rr->rr_namelen = 0;
        }

#ifdef CONFIG_FS_POSIX_ACL
        if (sp->sp_cr_flags & MDS_CREATE_RMT_ACL) {
                if (S_ISDIR(attr->la_mode))
                        sp->u.sp_pfid = rr->rr_fid1;
                req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_RMT_ACL);
                LASSERT(req_capsule_field_present(pill, &RMF_EADATA,
                                                  RCL_CLIENT));
                sp->u.sp_ea.eadata = req_capsule_client_get(pill, &RMF_EADATA);
                sp->u.sp_ea.eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                             RCL_CLIENT);
                sp->u.sp_ea.fid = rr->rr_fid1;
                RETURN(0);
        }
#endif
        if (S_ISDIR(attr->la_mode)) {
                /* pass parent fid for cross-ref cases */
                sp->u.sp_pfid = rr->rr_fid1;
                if (sp->sp_cr_flags & MDS_CREATE_SLAVE_OBJ) {
                        /* create salve object req, need
                         * unpack split ea here
                         */
                       req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_SLAVE);
                       LASSERT(req_capsule_field_present(pill, &RMF_EADATA,
                                                         RCL_CLIENT));
                       sp->u.sp_ea.eadata = req_capsule_client_get(pill,
                                                                   &RMF_EADATA);
                       sp->u.sp_ea.eadatalen = req_capsule_get_size(pill,
                                                                    &RMF_EADATA,
                                                                    RCL_CLIENT);
                       sp->u.sp_ea.fid = rr->rr_fid1;
                       RETURN(0);
                }
                req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_RMT_ACL);
        } else if (S_ISLNK(attr->la_mode)) {
                const char *tgt = NULL;

                req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_SYM);
                if (req_capsule_get_size(pill, &RMF_SYMTGT, RCL_CLIENT)) {
                        tgt = req_capsule_client_get(pill, &RMF_SYMTGT);
                        sp->u.sp_symname = tgt;
                }
                if (tgt == NULL)
                        RETURN(-EFAULT);
        } else {
                req_capsule_extend(pill, &RQF_MDS_REINT_CREATE_RMT_ACL);
        }
        rc = mdt_dlmreq_unpack(info);
        RETURN(rc);
}
Ejemplo n.º 7
0
static int mdt_setxattr_unpack(struct mdt_thread_info *info)
{
	struct mdt_reint_record	*rr	= &info->mti_rr;
	struct lu_ucred		*uc	= mdt_ucred(info);
	struct lu_attr		*attr	= &info->mti_attr.ma_attr;
	struct req_capsule	*pill	= info->mti_pill;
	struct mdt_rec_setxattr	*rec;
	int			 rc;
	ENTRY;


        CLASSERT(sizeof(struct mdt_rec_setxattr) ==
                         sizeof(struct mdt_rec_reint));

        rec = req_capsule_client_get(pill, &RMF_REC_REINT);
        if (rec == NULL)
                RETURN(-EFAULT);

	/* This prior initialization is needed for old_init_ucred_reint() */
	uc->uc_fsuid  = rec->sx_fsuid;
	uc->uc_fsgid  = rec->sx_fsgid;
	uc->uc_cap    = rec->sx_cap;
	uc->uc_suppgids[0] = rec->sx_suppgid1;
	uc->uc_suppgids[1] = -1;

        rr->rr_opcode = rec->sx_opcode;
        rr->rr_fid1   = &rec->sx_fid;
        attr->la_valid = rec->sx_valid;
        attr->la_ctime = rec->sx_time;
        attr->la_size = rec->sx_size;
        attr->la_flags = rec->sx_flags;

        if (req_capsule_get_size(pill, &RMF_CAPA1, RCL_CLIENT))
                mdt_set_capainfo(info, 0, rr->rr_fid1,
                                 req_capsule_client_get(pill, &RMF_CAPA1));
        else
                mdt_set_capainfo(info, 0, rr->rr_fid1, BYPASS_CAPA);

	rc = mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, 0);
	if (rc < 0)
		RETURN(rc);

        if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
                rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                        RCL_CLIENT);
                if (rr->rr_eadatalen > 0) {
                        rr->rr_eadata = req_capsule_client_get(pill,
                                                               &RMF_EADATA);
                        if (rr->rr_eadata == NULL)
                                RETURN(-EFAULT);
                } else {
                        rr->rr_eadata = NULL;
                }
        } else if (!(attr->la_valid & OBD_MD_FLXATTRRM)) {
                CDEBUG(D_INFO, "no xattr data supplied\n");
                RETURN(-EFAULT);
        }

	if (mdt_dlmreq_unpack(info) < 0)
		RETURN(-EPROTO);

        RETURN(0);
}
Ejemplo n.º 8
0
static int mdt_open_unpack(struct mdt_thread_info *info)
{
	struct lu_ucred         *uc = mdt_ucred(info);
        struct mdt_rec_create   *rec;
        struct lu_attr          *attr = &info->mti_attr.ma_attr;
        struct req_capsule      *pill = info->mti_pill;
        struct mdt_reint_record *rr   = &info->mti_rr;
        struct ptlrpc_request   *req  = mdt_info_req(info);
        struct md_op_spec       *sp   = &info->mti_spec;
        ENTRY;

        CLASSERT(sizeof(struct mdt_rec_create) == sizeof(struct mdt_rec_reint));
        rec = req_capsule_client_get(pill, &RMF_REC_REINT);
        if (rec == NULL)
                RETURN(-EFAULT);

	/* This prior initialization is needed for old_init_ucred_reint() */
	uc->uc_fsuid = rec->cr_fsuid;
	uc->uc_fsgid = rec->cr_fsgid;
	uc->uc_cap   = rec->cr_cap;
	uc->uc_suppgids[0] = rec->cr_suppgid1;
	uc->uc_suppgids[1] = rec->cr_suppgid2;
	uc->uc_umask = rec->cr_umask;

        rr->rr_fid1   = &rec->cr_fid1;
        rr->rr_fid2   = &rec->cr_fid2;
        rr->rr_handle = &rec->cr_old_handle;
        attr->la_mode = rec->cr_mode;
        attr->la_rdev  = rec->cr_rdev;
        attr->la_uid   = rec->cr_fsuid;
        attr->la_gid   = rec->cr_fsgid;
        attr->la_ctime = rec->cr_time;
        attr->la_mtime = rec->cr_time;
        attr->la_atime = rec->cr_time;
        attr->la_valid = LA_MODE  | LA_RDEV  | LA_UID   | LA_GID |
                         LA_CTIME | LA_MTIME | LA_ATIME;
        memset(&info->mti_spec.u, 0, sizeof(info->mti_spec.u));
        info->mti_spec.sp_cr_flags = get_mrc_cr_flags(rec);
        /* Do not trigger ASSERTION if client miss to set such flags. */
        if (unlikely(info->mti_spec.sp_cr_flags == 0))
                RETURN(-EPROTO);
        info->mti_replayepoch = rec->cr_ioepoch;

        info->mti_cross_ref = !!(rec->cr_bias & MDS_CROSS_REF);

        if (req_capsule_get_size(pill, &RMF_CAPA1, RCL_CLIENT))
                mdt_set_capainfo(info, 0, rr->rr_fid1,
                                 req_capsule_client_get(pill, &RMF_CAPA1));
        if (req_is_replay(req) &&
            req_capsule_get_size(pill, &RMF_CAPA2, RCL_CLIENT)) {
#if 0
                mdt_set_capainfo(info, 1, rr->rr_fid2,
                                 req_capsule_client_get(pill, &RMF_CAPA2));
#else
                /*
                 * FIXME: capa in replay open request might have expired,
                 * bypass capa check. Security hole?
                 */
                mdt_set_capainfo(info, 0, rr->rr_fid1, BYPASS_CAPA);
                mdt_set_capainfo(info, 1, rr->rr_fid2, BYPASS_CAPA);
#endif
        }

	mdt_name_unpack(pill, &RMF_NAME, &rr->rr_name, MNF_FIX_ANON);

        if (req_capsule_field_present(pill, &RMF_EADATA, RCL_CLIENT)) {
                rr->rr_eadatalen = req_capsule_get_size(pill, &RMF_EADATA,
                                                        RCL_CLIENT);
                if (rr->rr_eadatalen > 0) {
                        rr->rr_eadata = req_capsule_client_get(pill,
                                                               &RMF_EADATA);
                        sp->u.sp_ea.eadatalen = rr->rr_eadatalen;
                        sp->u.sp_ea.eadata = rr->rr_eadata;
                        sp->no_create = !!req_is_replay(req);
			mdt_fix_lov_magic(info);
                }

                /*
                 * Client default md_size may be 0 right after client start,
                 * until all osc are connected, set here just some reasonable
                 * value to prevent misbehavior.
                 */
                if (rr->rr_eadatalen == 0 &&
                    !(info->mti_spec.sp_cr_flags & MDS_OPEN_DELAY_CREATE))
			rr->rr_eadatalen = MIN_MD_SIZE;
	}

        RETURN(0);
}