/** * All MDT server handle fld lookup operation. But only MDT0 has fld index. * if entry is not found in cache we need to forward lookup request to MDT0 */ static int fld_handle_lookup(struct tgt_session_info *tsi) { struct obd_export *exp = tsi->tsi_exp; struct lu_site *site = exp->exp_obd->obd_lu_dev->ld_site; struct lu_server_fld *fld; struct lu_seq_range *in; struct lu_seq_range *out; int rc; ENTRY; in = req_capsule_client_get(tsi->tsi_pill, &RMF_FLD_MDFLD); if (in == NULL) RETURN(err_serious(-EPROTO)); rc = req_capsule_server_pack(tsi->tsi_pill); if (unlikely(rc != 0)) RETURN(err_serious(rc)); out = req_capsule_server_get(tsi->tsi_pill, &RMF_FLD_MDFLD); if (out == NULL) RETURN(err_serious(-EPROTO)); *out = *in; fld = lu_site2seq(site)->ss_server_fld; rc = fld_server_lookup(tsi->tsi_env, fld, in->lsr_start, out); CDEBUG(D_INFO, "%s: FLD req handle: error %d (range: "DRANGE")\n", fld->lsf_name, rc, PRANGE(out)); RETURN(rc); }
int llog_origin_handle_destroy(struct ptlrpc_request *req) { struct llogd_body *body; struct llog_logid *logid = NULL; struct llog_ctxt *ctxt; 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 < 0) RETURN(err_serious(-ENOMEM)); if (ostid_id(&body->lgd_logid.lgl_oi) > 0) logid = &body->lgd_logid; if (!(body->lgd_llh_flags & LLOG_F_IS_PLAIN)) CERROR("%s: wrong llog flags %x\n", req->rq_export->exp_obd->obd_name, body->lgd_llh_flags); ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); if (ctxt == NULL) RETURN(-ENODEV); rc = llog_erase(req->rq_svc_thread->t_env, ctxt, logid, NULL); llog_ctxt_put(ctxt); RETURN(rc); }
static int fld_handle_read(struct tgt_session_info *tsi) { struct obd_export *exp = tsi->tsi_exp; struct lu_site *site = exp->exp_obd->obd_lu_dev->ld_site; struct lu_seq_range *in; void *data; int rc; ENTRY; req_capsule_set(tsi->tsi_pill, &RQF_FLD_READ); in = req_capsule_client_get(tsi->tsi_pill, &RMF_FLD_MDFLD); if (in == NULL) RETURN(err_serious(-EPROTO)); req_capsule_set_size(tsi->tsi_pill, &RMF_GENERIC_DATA, RCL_SERVER, PAGE_CACHE_SIZE); rc = req_capsule_server_pack(tsi->tsi_pill); if (unlikely(rc != 0)) RETURN(err_serious(rc)); data = req_capsule_server_get(tsi->tsi_pill, &RMF_GENERIC_DATA); rc = fld_server_read(tsi->tsi_env, lu_site2seq(site)->ss_server_fld, in, data, PAGE_CACHE_SIZE); RETURN(rc); }
int llog_origin_handle_next_block(struct ptlrpc_request *req) { struct llog_handle *loghandle; struct llogd_body *body; struct llogd_body *repbody; struct llog_ctxt *ctxt; __u32 flags; void *ptr; int rc; ENTRY; body = req_capsule_client_get(&req->rq_pill, &RMF_LLOGD_BODY); if (body == NULL) RETURN(err_serious(-EFAULT)); req_capsule_set_size(&req->rq_pill, &RMF_EADATA, RCL_SERVER, LLOG_MIN_CHUNK_SIZE); rc = req_capsule_server_pack(&req->rq_pill); if (rc) RETURN(err_serious(-ENOMEM)); if (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) { CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n", req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx); RETURN(-EPROTO); } ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); if (ctxt == NULL) RETURN(-ENODEV); rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, &body->lgd_logid, NULL, LLOG_OPEN_EXISTS); if (rc) GOTO(out_ctxt, rc); flags = body->lgd_llh_flags; rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags, NULL); if (rc) GOTO(out_close, rc); repbody = req_capsule_server_get(&req->rq_pill, &RMF_LLOGD_BODY); *repbody = *body; ptr = req_capsule_server_get(&req->rq_pill, &RMF_EADATA); rc = llog_next_block(req->rq_svc_thread->t_env, loghandle, &repbody->lgd_saved_index, repbody->lgd_index, &repbody->lgd_cur_offset, ptr, LLOG_MIN_CHUNK_SIZE); if (rc) GOTO(out_close, rc); EXIT; out_close: llog_origin_close(req->rq_svc_thread->t_env, loghandle); out_ctxt: llog_ctxt_put(ctxt); return rc; }
static int seq_handler(struct tgt_session_info *tsi) { struct lu_seq_range *out, *tmp; struct lu_site *site; int rc; __u32 *opc; ENTRY; LASSERT(!(lustre_msg_get_flags(tgt_ses_req(tsi)->rq_reqmsg) & MSG_REPLAY)); site = tsi->tsi_exp->exp_obd->obd_lu_dev->ld_site; LASSERT(site != NULL); opc = req_capsule_client_get(tsi->tsi_pill, &RMF_SEQ_OPC); if (opc != NULL) { out = req_capsule_server_get(tsi->tsi_pill, &RMF_SEQ_RANGE); if (out == NULL) RETURN(err_serious(-EPROTO)); tmp = req_capsule_client_get(tsi->tsi_pill, &RMF_SEQ_RANGE); /* seq client passed mdt id, we need to pass that using out * range parameter */ out->lsr_index = tmp->lsr_index; out->lsr_flags = tmp->lsr_flags; rc = seq_server_handle(site, tsi->tsi_env, *opc, out); } else { rc = err_serious(-EPROTO); } RETURN(rc); }
/* 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; }
static int out_create(struct tgt_session_info *tsi) { struct tgt_thread_info *tti = tgt_th_info(tsi->tsi_env); struct object_update *update = tti->tti_u.update.tti_update; struct dt_object *obj = tti->tti_u.update.tti_dt_object; struct dt_object_format *dof = &tti->tti_u.update.tti_update_dof; struct obdo *lobdo = &tti->tti_u.update.tti_obdo; struct lu_attr *attr = &tti->tti_attr; struct lu_fid *fid = NULL; struct obdo *wobdo; int size; int rc; ENTRY; wobdo = object_update_param_get(update, 0, &size); if (wobdo == NULL || size != sizeof(*wobdo)) { CERROR("%s: obdo is NULL, invalid RPC: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } obdo_le_to_cpu(wobdo, wobdo); lustre_get_wire_obdo(NULL, lobdo, wobdo); la_from_obdo(attr, lobdo, lobdo->o_valid); dof->dof_type = dt_mode_to_dft(attr->la_mode); if (update->ou_params_count > 1) { int size; fid = object_update_param_get(update, 1, &size); if (fid == NULL || size != sizeof(*fid)) { CERROR("%s: invalid fid: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } if (ptlrpc_req_need_swab(tsi->tsi_pill->rc_req)) lustre_swab_lu_fid(fid); if (!fid_is_sane(fid)) { CERROR("%s: invalid fid "DFID": rc = %d\n", tgt_name(tsi->tsi_tgt), PFID(fid), -EPROTO); RETURN(err_serious(-EPROTO)); } } if (lu_object_exists(&obj->do_lu)) RETURN(-EEXIST); rc = out_tx_create(tsi->tsi_env, obj, attr, fid, dof, &tti->tti_tea, tti->tti_u.update.tti_update_reply, tti->tti_u.update.tti_update_reply_index); RETURN(rc); }
int llog_origin_handle_read_header(struct ptlrpc_request *req) { struct llog_handle *loghandle; struct llogd_body *body; struct llog_log_hdr *hdr; struct llog_ctxt *ctxt; __u32 flags; 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 (body->lgd_ctxt_idx >= LLOG_MAX_CTXTS) { CDEBUG(D_WARNING, "%s: bad ctxt ID: idx=%d\n", req->rq_export->exp_obd->obd_name, body->lgd_ctxt_idx); RETURN(-EPROTO); } ctxt = llog_get_context(req->rq_export->exp_obd, body->lgd_ctxt_idx); if (ctxt == NULL) RETURN(-ENODEV); rc = llog_open(req->rq_svc_thread->t_env, ctxt, &loghandle, &body->lgd_logid, NULL, LLOG_OPEN_EXISTS); if (rc) GOTO(out_ctxt, rc); /* * llog_init_handle() reads the llog header */ flags = body->lgd_llh_flags; rc = llog_init_handle(req->rq_svc_thread->t_env, loghandle, flags, NULL); if (rc) GOTO(out_close, rc); flags = loghandle->lgh_hdr->llh_flags; hdr = req_capsule_server_get(&req->rq_pill, &RMF_LLOG_LOG_HDR); *hdr = *loghandle->lgh_hdr; EXIT; out_close: llog_origin_close(req->rq_svc_thread->t_env, loghandle); out_ctxt: llog_ctxt_put(ctxt); return rc; }
static int out_create(struct mdt_thread_info *info) { struct update *update = info->mti_u.update.mti_update; struct dt_object *obj = info->mti_u.update.mti_dt_object; struct dt_object_format *dof = &info->mti_u.update.mti_update_dof; struct obdo *lobdo = &info->mti_u.update.mti_obdo; struct lu_attr *attr = &info->mti_attr.ma_attr; struct lu_fid *fid = NULL; struct obdo *wobdo; int size; int rc; ENTRY; wobdo = update_param_buf(update, 0, &size); if (wobdo == NULL || size != sizeof(*wobdo)) { CERROR("%s: obdo is NULL, invalid RPC: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } obdo_le_to_cpu(wobdo, wobdo); lustre_get_wire_obdo(lobdo, wobdo); la_from_obdo(attr, lobdo, lobdo->o_valid); dof->dof_type = dt_mode_to_dft(attr->la_mode); if (S_ISDIR(attr->la_mode)) { int size; fid = update_param_buf(update, 1, &size); if (fid == NULL || size != sizeof(*fid)) { CERROR("%s: invalid fid: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } fid_le_to_cpu(fid, fid); if (!fid_is_sane(fid)) { CERROR("%s: invalid fid "DFID": rc = %d\n", mdt_obd_name(info->mti_mdt), PFID(fid), -EPROTO); RETURN(err_serious(-EPROTO)); } } rc = out_tx_create(info, obj, attr, fid, dof, &info->mti_handle, info->mti_u.update.mti_update_reply, info->mti_u.update.mti_update_reply_index); RETURN(rc); }
static int out_xattr_set(struct tgt_session_info *tsi) { struct tgt_thread_info *tti = tgt_th_info(tsi->tsi_env); struct object_update *update = tti->tti_u.update.tti_update; struct dt_object *obj = tti->tti_u.update.tti_dt_object; struct lu_buf *lbuf = &tti->tti_buf; char *name; char *buf; char *tmp; int buf_len = 0; int flag; int rc; ENTRY; name = object_update_param_get(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for xattr set: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } buf = object_update_param_get(update, 1, &buf_len); if (buf == NULL || buf_len == 0) { CERROR("%s: empty buf for xattr set: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } lbuf->lb_buf = buf; lbuf->lb_len = buf_len; tmp = (char *)object_update_param_get(update, 2, NULL); if (tmp == NULL) { CERROR("%s: empty flag for xattr set: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } if (ptlrpc_req_need_swab(tsi->tsi_pill->rc_req)) __swab32s((__u32 *)tmp); flag = *(int *)tmp; rc = out_tx_xattr_set(tsi->tsi_env, obj, lbuf, name, flag, &tti->tti_tea, tti->tti_u.update.tti_update_reply, tti->tti_u.update.tti_update_reply_index); RETURN(rc); }
static int out_destroy(struct tgt_session_info *tsi) { struct tgt_thread_info *tti = tgt_th_info(tsi->tsi_env); struct update *update = tti->tti_u.update.tti_update; struct dt_object *obj = tti->tti_u.update.tti_dt_object; struct lu_fid *fid; int rc; ENTRY; fid = &update->u_fid; fid_le_to_cpu(fid, fid); if (!fid_is_sane(fid)) { CERROR("%s: invalid FID "DFID": rc = %d\n", tgt_name(tsi->tsi_tgt), PFID(fid), -EPROTO); RETURN(err_serious(-EPROTO)); } if (!lu_object_exists(&obj->do_lu)) RETURN(-ENOENT); rc = out_tx_destroy(tsi->tsi_env, obj, &tti->tti_tea, tti->tti_u.update.tti_update_reply, tti->tti_u.update.tti_update_reply_index); RETURN(rc); }
static int out_attr_set(struct tgt_session_info *tsi) { struct tgt_thread_info *tti = tgt_th_info(tsi->tsi_env); struct update *update = tti->tti_u.update.tti_update; struct lu_attr *attr = &tti->tti_attr; struct dt_object *obj = tti->tti_u.update.tti_dt_object; struct obdo *lobdo = &tti->tti_u.update.tti_obdo; struct obdo *wobdo; int size; int rc; ENTRY; wobdo = update_param_buf(update, 0, &size); if (wobdo == NULL || size != sizeof(*wobdo)) { CERROR("%s: empty obdo in the update: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } attr->la_valid = 0; attr->la_valid = 0; obdo_le_to_cpu(wobdo, wobdo); lustre_get_wire_obdo(NULL, lobdo, wobdo); la_from_obdo(attr, lobdo, lobdo->o_valid); rc = out_tx_attr_set(tsi->tsi_env, obj, attr, &tti->tti_tea, tti->tti_u.update.tti_update_reply, tti->tti_u.update.tti_update_reply_index); RETURN(rc); }
static int out_attr_set(struct mdt_thread_info *info) { struct update *update = info->mti_u.update.mti_update; struct lu_attr *attr = &info->mti_attr.ma_attr; struct dt_object *obj = info->mti_u.update.mti_dt_object; struct obdo *lobdo = &info->mti_u.update.mti_obdo; struct obdo *wobdo; int size; int rc; ENTRY; wobdo = update_param_buf(update, 0, &size); if (wobdo == NULL || size != sizeof(*wobdo)) { CERROR("%s: empty obdo in the update: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } attr->la_valid = 0; attr->la_valid = 0; obdo_le_to_cpu(wobdo, wobdo); lustre_get_wire_obdo(lobdo, wobdo); la_from_obdo(attr, lobdo, lobdo->o_valid); rc = out_tx_attr_set(info, obj, attr, &info->mti_handle, info->mti_u.update.mti_update_reply, info->mti_u.update.mti_update_reply_index); RETURN(rc); }
static int out_xattr_set(struct mdt_thread_info *info) { struct update *update = info->mti_u.update.mti_update; struct dt_object *obj = info->mti_u.update.mti_dt_object; struct lu_buf *lbuf = &info->mti_buf; char *name; char *buf; char *tmp; int buf_len = 0; int flag; int rc; ENTRY; name = update_param_buf(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for xattr set: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } buf = (char *)update_param_buf(update, 1, &buf_len); if (buf == NULL || buf_len == 0) { CERROR("%s: empty buf for xattr set: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } lbuf->lb_buf = buf; lbuf->lb_len = buf_len; tmp = (char *)update_param_buf(update, 2, NULL); if (tmp == NULL) { CERROR("%s: empty flag for xattr set: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } flag = le32_to_cpu(*(int *)tmp); rc = out_tx_xattr_set(info, obj, lbuf, name, flag, &info->mti_handle, info->mti_u.update.mti_update_reply, info->mti_u.update.mti_update_reply_index); RETURN(rc); }
static int mdt_reint_create(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) { struct ptlrpc_request *req = mdt_info_req(info); int rc; ENTRY; if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE)) RETURN(err_serious(-ESTALE)); if (info->mti_dlm_req) ldlm_request_cancel(mdt_info_req(info), info->mti_dlm_req, 0); switch (info->mti_attr.ma_attr.la_mode & S_IFMT) { case S_IFDIR:{ /* Cross-ref case. */ /* TODO: we can add LPROC_MDT_CROSS for cross-ref stats */ if (info->mti_cross_ref) { rc = mdt_md_mkobj(info); } else { LASSERT(info->mti_rr.rr_namelen > 0); mdt_counter_incr(req->rq_export, LPROC_MDT_MKDIR); rc = mdt_md_create(info); } break; } case S_IFREG: case S_IFLNK: case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK:{ /* Special file should stay on the same node as parent. */ LASSERT(info->mti_rr.rr_namelen > 0); mdt_counter_incr(req->rq_export, LPROC_MDT_MKNOD); rc = mdt_md_create(info); break; } default: rc = err_serious(-EOPNOTSUPP); } RETURN(rc); }
int llog_origin_handle_close(struct ptlrpc_request *req) { int rc; ENTRY; rc = req_capsule_server_pack(&req->rq_pill); if (rc) RETURN(err_serious(-ENOMEM)); RETURN(0); }
static int out_index_insert(struct tgt_session_info *tsi) { struct tgt_thread_info *tti = tgt_th_info(tsi->tsi_env); struct object_update *update = tti->tti_u.update.tti_update; struct dt_object *obj = tti->tti_u.update.tti_dt_object; struct lu_fid *fid; char *name; int rc = 0; int size; ENTRY; name = object_update_param_get(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for index insert: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } fid = object_update_param_get(update, 1, &size); if (fid == NULL || size != sizeof(*fid)) { CERROR("%s: invalid fid: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } if (ptlrpc_req_need_swab(tsi->tsi_pill->rc_req)) lustre_swab_lu_fid(fid); if (!fid_is_sane(fid)) { CERROR("%s: invalid FID "DFID": rc = %d\n", tgt_name(tsi->tsi_tgt), PFID(fid), -EPROTO); RETURN(err_serious(-EPROTO)); } rc = out_tx_index_insert(tsi->tsi_env, obj, name, fid, &tti->tti_tea, tti->tti_u.update.tti_update_reply, tti->tti_u.update.tti_update_reply_index); RETURN(rc); }
static int out_index_lookup(struct tgt_session_info *tsi) { const struct lu_env *env = tsi->tsi_env; struct tgt_thread_info *tti = tgt_th_info(env); struct update *update = tti->tti_u.update.tti_update; struct dt_object *obj = tti->tti_u.update.tti_dt_object; char *name; int rc; ENTRY; if (!lu_object_exists(&obj->do_lu)) RETURN(-ENOENT); name = (char *)update_param_buf(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for lookup: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } dt_read_lock(env, obj, MOR_TGT_CHILD); if (!dt_try_as_dir(env, obj)) GOTO(out_unlock, rc = -ENOTDIR); rc = dt_lookup(env, obj, (struct dt_rec *)&tti->tti_fid1, (struct dt_key *)name, NULL); if (rc < 0) GOTO(out_unlock, rc); if (rc == 0) rc += 1; CDEBUG(D_INFO, "lookup "DFID" %s get "DFID" rc %d\n", PFID(lu_object_fid(&obj->do_lu)), name, PFID(&tti->tti_fid1), rc); fid_cpu_to_le(&tti->tti_fid1, &tti->tti_fid1); out_unlock: dt_read_unlock(env, obj); CDEBUG(D_INFO, "%s: insert lookup reply %p index %d: rc = %d\n", tgt_name(tsi->tsi_tgt), tti->tti_u.update.tti_update_reply, 0, rc); update_insert_reply(tti->tti_u.update.tti_update_reply, &tti->tti_fid1, sizeof(tti->tti_fid1), 0, rc); RETURN(rc); }
static int seq_req_handle(struct ptlrpc_request *req, const struct lu_env *env, struct seq_thread_info *info) { struct lu_seq_range *out, *tmp; struct lu_site *site; int rc = -EPROTO; __u32 *opc; ENTRY; LASSERT(!(lustre_msg_get_flags(req->rq_reqmsg) & MSG_REPLAY)); site = req->rq_export->exp_obd->obd_lu_dev->ld_site; LASSERT(site != NULL); rc = req_capsule_server_pack(info->sti_pill); if (rc) RETURN(err_serious(rc)); opc = req_capsule_client_get(info->sti_pill, &RMF_SEQ_OPC); if (opc != NULL) { out = req_capsule_server_get(info->sti_pill, &RMF_SEQ_RANGE); if (out == NULL) RETURN(err_serious(-EPROTO)); tmp = req_capsule_client_get(info->sti_pill, &RMF_SEQ_RANGE); /* seq client passed mdt id, we need to pass that using out * range parameter */ out->lsr_index = tmp->lsr_index; out->lsr_flags = tmp->lsr_flags; rc = seq_server_handle(site, env, *opc, out); } else rc = err_serious(-EPROTO); RETURN(rc); }
static int mdt_reint_create(struct mdt_thread_info *info, struct mdt_lock_handle *lhc) { struct ptlrpc_request *req = mdt_info_req(info); int rc; ENTRY; if (OBD_FAIL_CHECK(OBD_FAIL_MDS_REINT_CREATE)) RETURN(err_serious(-ESTALE)); if (info->mti_dlm_req) ldlm_request_cancel(mdt_info_req(info), info->mti_dlm_req, 0); LASSERT(info->mti_rr.rr_namelen > 0); switch (info->mti_attr.ma_attr.la_mode & S_IFMT) { case S_IFDIR: mdt_counter_incr(req, LPROC_MDT_MKDIR); break; case S_IFREG: case S_IFLNK: case S_IFCHR: case S_IFBLK: case S_IFIFO: case S_IFSOCK: /* Special file should stay on the same node as parent. */ mdt_counter_incr(req, LPROC_MDT_MKNOD); break; default: CERROR("%s: Unsupported mode %o\n", mdt2obd_dev(info->mti_mdt)->obd_name, info->mti_attr.ma_attr.la_mode); RETURN(err_serious(-EOPNOTSUPP)); } rc = mdt_md_create(info); RETURN(rc); }
static int out_index_insert(struct mdt_thread_info *info) { struct update *update = info->mti_u.update.mti_update; struct dt_object *obj = info->mti_u.update.mti_dt_object; struct lu_fid *fid; char *name; int rc = 0; int size; ENTRY; name = (char *)update_param_buf(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for index insert: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } fid = (struct lu_fid *)update_param_buf(update, 1, &size); if (fid == NULL || size != sizeof(*fid)) { CERROR("%s: invalid fid: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } fid_le_to_cpu(fid, fid); if (!fid_is_sane(fid)) { CERROR("%s: invalid FID "DFID": rc = %d\n", mdt_obd_name(info->mti_mdt), PFID(fid), -EPROTO); RETURN(err_serious(-EPROTO)); } rc = out_tx_index_insert(info, obj, name, fid, &info->mti_handle, info->mti_u.update.mti_update_reply, info->mti_u.update.mti_update_reply_index); RETURN(rc); }
static int out_xattr_get(struct tgt_session_info *tsi) { const struct lu_env *env = tsi->tsi_env; struct tgt_thread_info *tti = tgt_th_info(env); struct update *update = tti->tti_u.update.tti_update; struct lu_buf *lbuf = &tti->tti_buf; struct update_reply *reply = tti->tti_u.update.tti_update_reply; struct dt_object *obj = tti->tti_u.update.tti_dt_object; char *name; void *ptr; int rc; ENTRY; name = (char *)update_param_buf(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for xattr get: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } ptr = update_get_buf_internal(reply, 0, NULL); LASSERT(ptr != NULL); /* The first 4 bytes(int) are used to store the result */ lbuf->lb_buf = (char *)ptr + sizeof(int); lbuf->lb_len = UPDATE_BUFFER_SIZE - sizeof(struct update_reply); dt_read_lock(env, obj, MOR_TGT_CHILD); rc = dt_xattr_get(env, obj, lbuf, name, NULL); dt_read_unlock(env, obj); if (rc < 0) { lbuf->lb_len = 0; GOTO(out, rc); } if (rc == 0) { lbuf->lb_len = 0; GOTO(out, rc = -ENOENT); } lbuf->lb_len = rc; rc = 0; CDEBUG(D_INFO, "%s: "DFID" get xattr %s len %d\n", tgt_name(tsi->tsi_tgt), PFID(lu_object_fid(&obj->do_lu)), name, (int)lbuf->lb_len); out: *(int *)ptr = rc; reply->ur_lens[0] = lbuf->lb_len + sizeof(int); RETURN(rc); }
/** * Retrieve the current HSM flags, archive id and undergoing HSM requests for * the fid provided in RPC body. * * Current requests are read from coordinator states. * * This is MDS_HSM_STATE_GET RPC handler. */ int mdt_hsm_state_get(struct tgt_session_info *tsi) { struct mdt_thread_info *info = tsi2mdt_info(tsi); struct mdt_object *obj = info->mti_object; struct md_attr *ma = &info->mti_attr; struct hsm_user_state *hus; struct mdt_lock_handle *lh; int rc; ENTRY; if (info->mti_body == NULL || obj == NULL) GOTO(out, rc = -EPROTO); /* Only valid if client is remote */ rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body); if (rc < 0) GOTO(out, rc = err_serious(rc)); lh = &info->mti_lh[MDT_LH_CHILD]; mdt_lock_reg_init(lh, LCK_PR); rc = mdt_object_lock(info, obj, lh, MDS_INODELOCK_LOOKUP); if (rc < 0) GOTO(out_ucred, rc); ma->ma_valid = 0; ma->ma_need = MA_HSM; rc = mdt_attr_get_complex(info, obj, ma); if (rc) GOTO(out_unlock, rc); hus = req_capsule_server_get(tsi->tsi_pill, &RMF_HSM_USER_STATE); if (hus == NULL) GOTO(out_unlock, rc = -EPROTO); /* Current HSM flags */ hus->hus_states = ma->ma_hsm.mh_flags; hus->hus_archive_id = ma->ma_hsm.mh_arch_id; EXIT; out_unlock: mdt_object_unlock(info, obj, lh, 1); out_ucred: mdt_exit_ucred(info); out: mdt_thread_info_fini(info); return rc; }
static int out_index_lookup(struct mdt_thread_info *info) { struct update *update = info->mti_u.update.mti_update; const struct lu_env *env = info->mti_env; struct dt_object *obj = info->mti_u.update.mti_dt_object; char *name; int rc; ENTRY; if (!lu_object_exists(&obj->do_lu)) RETURN(-ENOENT); name = (char *)update_param_buf(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for lookup: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } dt_read_lock(env, obj, MOR_TGT_CHILD); if (!dt_try_as_dir(env, obj)) GOTO(out_unlock, rc = -ENOTDIR); rc = dt_lookup(env, obj, (struct dt_rec *)&info->mti_tmp_fid1, (struct dt_key *)name, NULL); if (rc < 0) GOTO(out_unlock, rc); if (rc == 0) rc += 1; CDEBUG(D_INFO, "lookup "DFID" %s get "DFID" rc %d\n", PFID(lu_object_fid(&obj->do_lu)), name, PFID(&info->mti_tmp_fid1), rc); fid_cpu_to_le(&info->mti_tmp_fid1, &info->mti_tmp_fid1); out_unlock: dt_read_unlock(env, obj); update_insert_reply(info->mti_u.update.mti_update_reply, &info->mti_tmp_fid1, sizeof(info->mti_tmp_fid1), 0, rc); RETURN(rc); }
static int out_index_delete(struct mdt_thread_info *info) { struct update *update = info->mti_u.update.mti_update; struct dt_object *obj = info->mti_u.update.mti_dt_object; char *name; int rc = 0; if (!lu_object_exists(&obj->do_lu)) RETURN(-ENOENT); name = (char *)update_param_buf(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for index delete: rc = %d\n", mdt_obd_name(info->mti_mdt), -EPROTO); RETURN(err_serious(-EPROTO)); } rc = out_tx_index_delete(info, obj, name, &info->mti_handle, info->mti_u.update.mti_update_reply, info->mti_u.update.mti_update_reply_index); RETURN(rc); }
int mdt_hsm_ct_register(struct tgt_session_info *tsi) { struct mdt_thread_info *info; __u32 *archives; int rc; ENTRY; archives = req_capsule_client_get(tsi->tsi_pill, &RMF_MDS_HSM_ARCHIVE); if (archives == NULL) RETURN(err_serious(-EPROTO)); info = tsi2mdt_info(tsi); if (!mdt_hsm_is_admin(info)) GOTO(out, rc = -EPERM); /* XXX: directly include this function here? */ rc = mdt_hsm_agent_register_mask(info, &tsi->tsi_exp->exp_client_uuid, *archives); out: mdt_thread_info_fini(info); RETURN(rc); }
static int out_index_delete(struct tgt_session_info *tsi) { struct tgt_thread_info *tti = tgt_th_info(tsi->tsi_env); struct update *update = tti->tti_u.update.tti_update; struct dt_object *obj = tti->tti_u.update.tti_dt_object; char *name; int rc = 0; if (!lu_object_exists(&obj->do_lu)) RETURN(-ENOENT); name = (char *)update_param_buf(update, 0, NULL); if (name == NULL) { CERROR("%s: empty name for index delete: rc = %d\n", tgt_name(tsi->tsi_tgt), -EPROTO); RETURN(err_serious(-EPROTO)); } rc = out_tx_index_delete(tsi->tsi_env, obj, name, &tti->tti_tea, tti->tti_u.update.tti_update_reply, tti->tti_u.update.tti_update_reply_index); RETURN(rc); }
/** * Extract information coming from a copytool and asks coordinator to update * a request status depending on the update content. * * Copytools could use this to report failure in their process. * * This is HSM_PROGRESS RPC handler. */ int mdt_hsm_progress(struct tgt_session_info *tsi) { struct mdt_thread_info *info; struct hsm_progress_kernel *hpk; int rc; ENTRY; if (tsi->tsi_mdt_body == NULL) RETURN(-EPROTO); hpk = req_capsule_client_get(tsi->tsi_pill, &RMF_MDS_HSM_PROGRESS); if (hpk == NULL) RETURN(err_serious(-EPROTO)); hpk->hpk_errval = lustre_errno_ntoh(hpk->hpk_errval); CDEBUG(D_HSM, "Progress on "DFID": len="LPU64" err=%d\n", PFID(&hpk->hpk_fid), hpk->hpk_extent.length, hpk->hpk_errval); if (hpk->hpk_errval) CDEBUG(D_HSM, "Copytool progress on "DFID" failed (%d); %s.\n", PFID(&hpk->hpk_fid), hpk->hpk_errval, hpk->hpk_flags & HP_FLAG_RETRY ? "will retry" : "fatal"); if (hpk->hpk_flags & HP_FLAG_COMPLETED) CDEBUG(D_HSM, "Finished "DFID" (%d) cancel cookie="LPX64"\n", PFID(&hpk->hpk_fid), hpk->hpk_errval, hpk->hpk_cookie); info = tsi2mdt_info(tsi); if (!mdt_hsm_is_admin(info)) GOTO(out, rc = -EPERM); rc = mdt_hsm_coordinator_update(info, hpk); out: mdt_thread_info_fini(info); RETURN(rc); }
int mdt_reint_setxattr(struct mdt_thread_info *info, struct mdt_lock_handle *unused) { struct ptlrpc_request *req = mdt_info_req(info); struct md_ucred *uc = mdt_ucred(info); struct mdt_lock_handle *lh; const struct lu_env *env = info->mti_env; struct lu_buf *buf = &info->mti_buf; struct mdt_reint_record *rr = &info->mti_rr; struct md_attr *ma = &info->mti_attr; struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_object *obj; struct md_object *child; __u64 valid = attr->la_valid; const char *xattr_name = rr->rr_name; int xattr_len = rr->rr_eadatalen; __u64 lockpart; int rc; posix_acl_xattr_header *new_xattr = NULL; __u32 remote = exp_connect_rmtclient(info->mti_exp); __u32 perm; ENTRY; CDEBUG(D_INODE, "setxattr for "DFID"\n", PFID(rr->rr_fid1)); if (OBD_FAIL_CHECK(OBD_FAIL_MDS_SETXATTR)) RETURN(err_serious(-ENOMEM)); CDEBUG(D_INODE, "%s xattr %s\n", valid & OBD_MD_FLXATTR ? "set" : "remove", xattr_name); rc = mdt_init_ucred_reint(info); if (rc != 0) RETURN(rc); if (valid & OBD_MD_FLRMTRSETFACL) { if (unlikely(!remote)) GOTO(out, rc = err_serious(-EINVAL)); perm = mdt_identity_get_perm(uc->mu_identity, remote, req->rq_peer.nid); if (!(perm & CFS_RMTACL_PERM)) GOTO(out, rc = err_serious(-EPERM)); } if (strncmp(xattr_name, XATTR_USER_PREFIX, sizeof(XATTR_USER_PREFIX) - 1) == 0) { if (!(req->rq_export->exp_connect_flags & OBD_CONNECT_XATTR)) GOTO(out, rc = -EOPNOTSUPP); if (strcmp(xattr_name, XATTR_NAME_LOV) == 0) GOTO(out, rc = -EACCES); if (strcmp(xattr_name, XATTR_NAME_LMA) == 0) GOTO(out, rc = 0); if (strcmp(xattr_name, XATTR_NAME_LINK) == 0) GOTO(out, rc = 0); } else if ((valid & OBD_MD_FLXATTR) && (strncmp(xattr_name, XATTR_NAME_ACL_ACCESS, sizeof(XATTR_NAME_ACL_ACCESS) - 1) == 0 || strncmp(xattr_name, XATTR_NAME_ACL_DEFAULT, sizeof(XATTR_NAME_ACL_DEFAULT) - 1) == 0)) { /* currently lustre limit acl access size */ if (xattr_len > LUSTRE_POSIX_ACL_MAX_SIZE) GOTO(out, -ERANGE); } lockpart = MDS_INODELOCK_UPDATE; /* Revoke all clients' lookup lock, since the access * permissions for this inode is changed when ACL_ACCESS is * set. This isn't needed for ACL_DEFAULT, since that does * not change the access permissions of this inode, nor any * other existing inodes. It is setting the ACLs inherited * by new directories/files at create time. */ if (!strcmp(xattr_name, XATTR_NAME_ACL_ACCESS)) lockpart |= MDS_INODELOCK_LOOKUP; lh = &info->mti_lh[MDT_LH_PARENT]; /* ACLs were sent to clients under LCK_CR locks, so taking LCK_EX * to cancel them. */ mdt_lock_reg_init(lh, LCK_EX); obj = mdt_object_find_lock(info, rr->rr_fid1, lh, lockpart); if (IS_ERR(obj)) GOTO(out, rc = PTR_ERR(obj)); info->mti_mos = obj; rc = mdt_version_get_check_save(info, obj, 0); if (rc) GOTO(out_unlock, rc); if (unlikely(!(valid & OBD_MD_FLCTIME))) { /* This isn't strictly an error, but all current clients * should set OBD_MD_FLCTIME when setting attributes. */ CWARN("%s: client miss to set OBD_MD_FLCTIME when " "setxattr %s: [object "DFID"] [valid "LPU64"]\n", info->mti_exp->exp_obd->obd_name, xattr_name, PFID(rr->rr_fid1), valid); attr->la_ctime = cfs_time_current_sec(); } attr->la_valid = LA_CTIME; child = mdt_object_child(obj); if (valid & OBD_MD_FLXATTR) { char *xattr = (void *)rr->rr_eadata; if (xattr_len > 0) { int flags = 0; if (valid & OBD_MD_FLRMTLSETFACL) { if (unlikely(!remote)) GOTO(out_unlock, rc = -EINVAL); xattr_len = mdt_rmtlsetfacl(info, child, xattr_name, (ext_acl_xattr_header *)xattr, &new_xattr); if (xattr_len < 0) GOTO(out_unlock, rc = xattr_len); xattr = (char *)new_xattr; } if (attr->la_flags & XATTR_REPLACE) flags |= LU_XATTR_REPLACE; if (attr->la_flags & XATTR_CREATE) flags |= LU_XATTR_CREATE; mdt_fail_write(env, info->mti_mdt->mdt_bottom, OBD_FAIL_MDS_SETXATTR_WRITE); buf->lb_buf = xattr; buf->lb_len = xattr_len; rc = mo_xattr_set(env, child, buf, xattr_name, flags); /* update ctime after xattr changed */ if (rc == 0) { ma->ma_attr_flags |= MDS_PERM_BYPASS; mo_attr_set(env, child, ma); } } } else if (valid & OBD_MD_FLXATTRRM) { rc = mo_xattr_del(env, child, xattr_name); /* update ctime after xattr changed */ if (rc == 0) { ma->ma_attr_flags |= MDS_PERM_BYPASS; mo_attr_set(env, child, ma); } } else { CDEBUG(D_INFO, "valid bits: "LPX64"\n", valid); rc = -EINVAL; } if (rc == 0) mdt_counter_incr(req->rq_export, LPROC_MDT_SETXATTR); EXIT; out_unlock: mdt_object_unlock_put(info, obj, lh, rc); if (unlikely(new_xattr != NULL)) lustre_posix_acl_xattr_free(new_xattr, xattr_len); out: mdt_exit_ucred(info); return rc; }
int mdt_getxattr(struct mdt_thread_info *info) { struct ptlrpc_request *req = mdt_info_req(info); struct mdt_export_data *med = mdt_req2med(req); struct md_ucred *uc = mdt_ucred(info); struct mdt_body *reqbody; struct mdt_body *repbody = NULL; struct md_object *next; struct lu_buf *buf; __u32 remote = exp_connect_rmtclient(info->mti_exp); __u32 perm; int easize, rc; ENTRY; LASSERT(info->mti_object != NULL); LASSERT(lu_object_assert_exists(&info->mti_object->mot_obj.mo_lu)); CDEBUG(D_INODE, "getxattr "DFID"\n", PFID(&info->mti_body->fid1)); reqbody = req_capsule_client_get(info->mti_pill, &RMF_MDT_BODY); if (reqbody == NULL) RETURN(err_serious(-EFAULT)); rc = mdt_init_ucred(info, reqbody); if (rc) RETURN(err_serious(rc)); next = mdt_object_child(info->mti_object); if (info->mti_body->valid & OBD_MD_FLRMTRGETFACL) { if (unlikely(!remote)) GOTO(out, rc = err_serious(-EINVAL)); perm = mdt_identity_get_perm(uc->mu_identity, remote, req->rq_peer.nid); if (!(perm & CFS_RMTACL_PERM)) GOTO(out, rc = err_serious(-EPERM)); rc = mo_permission(info->mti_env, NULL, next, NULL, MAY_RGETFACL); if (rc) GOTO(out, rc = err_serious(rc)); } easize = mdt_getxattr_pack_reply(info); if (easize < 0) GOTO(out, rc = err_serious(easize)); repbody = req_capsule_server_get(info->mti_pill, &RMF_MDT_BODY); LASSERT(repbody != NULL); /* No need further getxattr. */ if (easize == 0 || reqbody->eadatasize == 0) GOTO(out, rc = easize); buf = &info->mti_buf; buf->lb_buf = req_capsule_server_get(info->mti_pill, &RMF_EADATA); buf->lb_len = easize; if (info->mti_body->valid & OBD_MD_FLXATTR) { int flags = CFS_IC_NOTHING; char *xattr_name = req_capsule_client_get(info->mti_pill, &RMF_NAME); CDEBUG(D_INODE, "getxattr %s\n", xattr_name); rc = mo_xattr_get(info->mti_env, next, buf, xattr_name); if (rc < 0) { CERROR("getxattr failed: %d\n", rc); GOTO(out, rc); } if (info->mti_body->valid & (OBD_MD_FLRMTLSETFACL | OBD_MD_FLRMTLGETFACL)) flags = CFS_IC_ALL; else if (info->mti_body->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; } } else if (info->mti_body->valid & OBD_MD_FLXATTRLS) { CDEBUG(D_INODE, "listxattr\n"); rc = mo_xattr_list(info->mti_env, next, buf); if (rc < 0) CDEBUG(D_INFO, "listxattr failed: %d\n", rc); } else LBUG(); EXIT; out: if (rc >= 0) { mdt_counter_incr(req->rq_export, LPROC_MDT_GETXATTR); repbody->eadatasize = rc; rc = 0; } mdt_exit_ucred(info); return rc; }