Пример #1
0
static inline size_t libcfs_ioctl_packlen(struct libcfs_ioctl_data *data)
{
	size_t len = sizeof(*data);

	len += cfs_size_round(data->ioc_inllen1);
	len += cfs_size_round(data->ioc_inllen2);
	return len;
}
Пример #2
0
static int llog_print_cb(struct llog_handle *handle, struct llog_rec_hdr *rec,
                         void *data)
{
        struct obd_ioctl_data *ioc_data = (struct obd_ioctl_data *)data;
        static int l, remains, from, to;
        static char *out;
        char *endp;
        int cur_index;

        ENTRY;
        if (ioc_data->ioc_inllen1) {
                l = 0;
                remains = ioc_data->ioc_inllen4 +
                        cfs_size_round(ioc_data->ioc_inllen1) +
                        cfs_size_round(ioc_data->ioc_inllen2) +
                        cfs_size_round(ioc_data->ioc_inllen3);
                from = simple_strtol(ioc_data->ioc_inlbuf2, &endp, 0);
                if (*endp != '\0')
                        RETURN(-EINVAL);
                to = simple_strtol(ioc_data->ioc_inlbuf3, &endp, 0);
                if (*endp != '\0')
                        RETURN(-EINVAL);
                out = ioc_data->ioc_bulk;
                ioc_data->ioc_inllen1 = 0;
        }

        cur_index = rec->lrh_index;
        if (cur_index < from)
                RETURN(0);
        if (to > 0 && cur_index > to)
                RETURN(-LLOG_EEMPTY);

        if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) {
                struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
                if (rec->lrh_type != LLOG_LOGID_MAGIC) {
                        CERROR("invalid record in catalog\n");
                        RETURN(-EINVAL);
                }

                l = snprintf(out, remains,
                             "[index]: %05d  [logid]: #"LPX64"#"LPX64"#%08x\n",
                             cur_index, lir->lid_id.lgl_oid,
                             lir->lid_id.lgl_oseq, lir->lid_id.lgl_ogen);
        } else {
                l = snprintf(out, remains,
                             "[index]: %05d  [type]: %02x  [len]: %04d\n",
                             cur_index, rec->lrh_type,
                             rec->lrh_len);
        }
        out += l;
        remains -= l;
        if (remains <= 0) {
                CERROR("not enough space for print log records\n");
                RETURN(-LLOG_EEMPTY);
        }

        RETURN(0);
}
Пример #3
0
Файл: llog.c Проект: 7799/linux
int llog_write_rec(const struct lu_env *env, struct llog_handle *handle,
		   struct llog_rec_hdr *rec, struct llog_cookie *logcookies,
		   int numcookies, void *buf, int idx, struct thandle *th)
{
	struct llog_operations	*lop;
	int			 raised, rc, buflen;

	rc = llog_handle2ops(handle, &lop);
	if (rc)
		return rc;

	LASSERT(lop);
	if (lop->lop_write_rec == NULL)
		return -EOPNOTSUPP;

	if (buf)
		buflen = rec->lrh_len + sizeof(struct llog_rec_hdr) +
			 sizeof(struct llog_rec_tail);
	else
		buflen = rec->lrh_len;
	LASSERT(cfs_size_round(buflen) == buflen);

	raised = cfs_cap_raised(CFS_CAP_SYS_RESOURCE);
	if (!raised)
		cfs_cap_raise(CFS_CAP_SYS_RESOURCE);
	rc = lop->lop_write_rec(env, handle, rec, logcookies, numcookies,
				buf, idx, th);
	if (!raised)
		cfs_cap_lower(CFS_CAP_SYS_RESOURCE);
	return rc;
}
Пример #4
0
int llog_write_rec(const struct lu_env *env, struct llog_handle *handle,
		   struct llog_rec_hdr *rec, struct llog_cookie *logcookies,
		   int idx, struct thandle *th)
{
	struct llog_operations	*lop;
	int			 raised, rc, buflen;

	ENTRY;

	rc = llog_handle2ops(handle, &lop);
	if (rc)
		RETURN(rc);

	LASSERT(lop);
	if (lop->lop_write_rec == NULL)
		RETURN(-EOPNOTSUPP);

	buflen = rec->lrh_len;
	LASSERT(cfs_size_round(buflen) == buflen);

	raised = cfs_cap_raised(CFS_CAP_SYS_RESOURCE);
	if (!raised)
		cfs_cap_raise(CFS_CAP_SYS_RESOURCE);
	rc = lop->lop_write_rec(env, handle, rec, logcookies, idx, th);
	if (!raised)
		cfs_cap_lower(CFS_CAP_SYS_RESOURCE);
	RETURN(rc);
}
Пример #5
0
struct lu_object *vvp_object_alloc(const struct lu_env *env,
				   const struct lu_object_header *unused,
				   struct lu_device *dev)
{
	struct vvp_object *vob;
	struct lu_object  *obj;

	OBD_SLAB_ALLOC_PTR_GFP(vob, vvp_object_kmem, GFP_NOFS);
	if (vob != NULL) {
		struct cl_object_header *hdr;

		obj = &vob->vob_cl.co_lu;
		hdr = &vob->vob_header;
		cl_object_header_init(hdr);
		hdr->coh_page_bufsize = cfs_size_round(sizeof(struct cl_page));

		lu_object_init(obj, &hdr->coh_lu, dev);
		lu_object_add_top(&hdr->coh_lu, obj);

		vob->vob_cl.co_ops = &vvp_ops;
		obj->lo_ops = &vvp_lu_obj_ops;
	} else
		obj = NULL;
	return obj;
}
Пример #6
0
/* temporary for testing */
static int mdc_wr_kuc(struct file *file, const char *buffer,
		      unsigned long count, void *data)
{
	struct obd_device	*obd = data;
	struct kuc_hdr		*lh;
	struct hsm_action_list	*hal;
	struct hsm_action_item	*hai;
	int			 len;
	int			 fd, rc;
	ENTRY;

	rc = lprocfs_write_helper(buffer, count, &fd);
	if (rc)
		RETURN(rc);

	if (fd < 0)
		RETURN(-ERANGE);
	CWARN("message to fd %d\n", fd);

	len = sizeof(*lh) + sizeof(*hal) + MTI_NAME_MAXLEN +
		/* for mockup below */ 2 * cfs_size_round(sizeof(*hai));

	OBD_ALLOC(lh, len);

	lh->kuc_magic = KUC_MAGIC;
	lh->kuc_transport = KUC_TRANSPORT_HSM;
	lh->kuc_msgtype = HMT_ACTION_LIST;
	lh->kuc_msglen = len;

	hal = (struct hsm_action_list *)(lh + 1);
	hal->hal_version = HAL_VERSION;
	hal->hal_archive_id = 1;
	hal->hal_flags = 0;
	obd_uuid2fsname(hal->hal_fsname, obd->obd_name, MTI_NAME_MAXLEN);

	/* mock up an action list */
	hal->hal_count = 2;
	hai = hai_zero(hal);
	hai->hai_action = HSMA_ARCHIVE;
	hai->hai_fid.f_oid = 5;
	hai->hai_len = sizeof(*hai);
	hai = hai_next(hai);
	hai->hai_action = HSMA_RESTORE;
	hai->hai_fid.f_oid = 10;
	hai->hai_len = sizeof(*hai);

	/* This works for either broadcast or unicast to a single fd */
	if (fd == 0) {
		rc = libcfs_kkuc_group_put(KUC_GRP_HSM, lh);
	} else {
		cfs_file_t *fp = cfs_get_fd(fd);
		rc = libcfs_kkuc_msg_put(fp, lh);
		cfs_put_file(fp);
	}
	OBD_FREE(lh, len);
	if (rc < 0)
		RETURN(rc);
	RETURN(count);
}
Пример #7
0
static inline bool libcfs_ioctl_is_invalid(struct libcfs_ioctl_data *data)
{
	if (data->ioc_hdr.ioc_len > BIT(30)) {
		CERROR("LIBCFS ioctl: ioc_len larger than 1<<30\n");
		return true;
	}
	if (data->ioc_inllen1 > BIT(30)) {
		CERROR("LIBCFS ioctl: ioc_inllen1 larger than 1<<30\n");
		return true;
	}
	if (data->ioc_inllen2 > BIT(30)) {
		CERROR("LIBCFS ioctl: ioc_inllen2 larger than 1<<30\n");
		return true;
	}
	if (data->ioc_inlbuf1 && !data->ioc_inllen1) {
		CERROR("LIBCFS ioctl: inlbuf1 pointer but 0 length\n");
		return true;
	}
	if (data->ioc_inlbuf2 && !data->ioc_inllen2) {
		CERROR("LIBCFS ioctl: inlbuf2 pointer but 0 length\n");
		return true;
	}
	if (data->ioc_pbuf1 && !data->ioc_plen1) {
		CERROR("LIBCFS ioctl: pbuf1 pointer but 0 length\n");
		return true;
	}
	if (data->ioc_pbuf2 && !data->ioc_plen2) {
		CERROR("LIBCFS ioctl: pbuf2 pointer but 0 length\n");
		return true;
	}
	if (data->ioc_plen1 && !data->ioc_pbuf1) {
		CERROR("LIBCFS ioctl: plen1 nonzero but no pbuf1 pointer\n");
		return true;
	}
	if (data->ioc_plen2 && !data->ioc_pbuf2) {
		CERROR("LIBCFS ioctl: plen2 nonzero but no pbuf2 pointer\n");
		return true;
	}
	if ((__u32)libcfs_ioctl_packlen(data) != data->ioc_hdr.ioc_len) {
		CERROR("LIBCFS ioctl: packlen != ioc_len\n");
		return true;
	}
	if (data->ioc_inllen1 &&
	    data->ioc_bulk[data->ioc_inllen1 - 1] != '\0') {
		CERROR("LIBCFS ioctl: inlbuf1 not 0 terminated\n");
		return true;
	}
	if (data->ioc_inllen2 &&
	    data->ioc_bulk[cfs_size_round(data->ioc_inllen1) +
			   data->ioc_inllen2 - 1] != '\0') {
		CERROR("LIBCFS ioctl: inlbuf2 not 0 terminated\n");
		return true;
	}
	return false;
}
Пример #8
0
static int lov_page_slice_fixup(struct lov_object *lov,
				struct cl_object *stripe)
{
	struct cl_object_header *hdr = cl_object_header(&lov->lo_cl);
	struct cl_object *o;

	if (stripe == NULL)
		return hdr->coh_page_bufsize - lov->lo_cl.co_slice_off -
		       cfs_size_round(sizeof(struct lov_page));

	cl_object_for_each(o, stripe)
		o->co_slice_off += hdr->coh_page_bufsize;

	return cl_object_header(stripe)->coh_page_bufsize;
}
Пример #9
0
int libcfs_ioctl_getdata(char *buf, char *end, void *arg)
{
        struct libcfs_ioctl_hdr   *hdr;
        struct libcfs_ioctl_data  *data;
        int err;
        ENTRY;

        hdr = (struct libcfs_ioctl_hdr *)buf;
        data = (struct libcfs_ioctl_data *)buf;

        err = copy_from_user(buf, (void *)arg, sizeof(*hdr));
        if (err)
                RETURN(err);

        if (hdr->ioc_version != LIBCFS_IOCTL_VERSION) {
                CERROR("PORTALS: version mismatch kernel vs application\n");
                RETURN(-EINVAL);
        }

        if (hdr->ioc_len + buf >= end) {
                CERROR("PORTALS: user buffer exceeds kernel buffer\n");
                RETURN(-EINVAL);
        }


        if (hdr->ioc_len < sizeof(struct libcfs_ioctl_data)) {
                CERROR("PORTALS: user buffer too small for ioctl\n");
                RETURN(-EINVAL);
        }

        err = copy_from_user(buf, (void *)arg, hdr->ioc_len);
        if (err)
                RETURN(err);

        if (libcfs_ioctl_is_invalid(data)) {
                CERROR("PORTALS: ioctl not correctly formatted\n");
                RETURN(-EINVAL);
        }

        if (data->ioc_inllen1)
                data->ioc_inlbuf1 = &data->ioc_bulk[0];

        if (data->ioc_inllen2)
                data->ioc_inlbuf2 = &data->ioc_bulk[0] +
                        cfs_size_round(data->ioc_inllen1);

        RETURN(0);
}
Пример #10
0
int libcfs_ioctl_getdata(char *buf, char *end, void *arg)
{
	struct libcfs_ioctl_hdr   *hdr;
	struct libcfs_ioctl_data  *data;
	int orig_len;

	hdr = (struct libcfs_ioctl_hdr *)buf;
	data = (struct libcfs_ioctl_data *)buf;

	if (copy_from_user(buf, (void *)arg, sizeof(*hdr)))
		return -EFAULT;

	if (hdr->ioc_version != LIBCFS_IOCTL_VERSION) {
		CERROR("PORTALS: version mismatch kernel vs application\n");
		return -EINVAL;
	}

	if (hdr->ioc_len + buf >= end) {
		CERROR("PORTALS: user buffer exceeds kernel buffer\n");
		return -EINVAL;
	}


	if (hdr->ioc_len < sizeof(struct libcfs_ioctl_data)) {
		CERROR("PORTALS: user buffer too small for ioctl\n");
		return -EINVAL;
	}

	orig_len = hdr->ioc_len;
	if (copy_from_user(buf, (void *)arg, hdr->ioc_len))
		return -EFAULT;
	if (orig_len != data->ioc_len)
		return -EINVAL;

	if (libcfs_ioctl_is_invalid(data)) {
		CERROR("PORTALS: ioctl not correctly formatted\n");
		return -EINVAL;
	}

	if (data->ioc_inllen1)
		data->ioc_inlbuf1 = &data->ioc_bulk[0];

	if (data->ioc_inllen2)
		data->ioc_inlbuf2 = &data->ioc_bulk[0] +
			cfs_size_round(data->ioc_inllen1);

	return 0;
}
Пример #11
0
int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data)
{
	if (libcfs_ioctl_is_invalid(data)) {
		CERROR("libcfs ioctl: parameter not correctly formatted\n");
		return -EINVAL;
	}

	if (data->ioc_inllen1)
		data->ioc_inlbuf1 = &data->ioc_bulk[0];

	if (data->ioc_inllen2)
		data->ioc_inlbuf2 = &data->ioc_bulk[0] +
			cfs_size_round(data->ioc_inllen1);

	return 0;
}
Пример #12
0
int libcfs_ioctl_data_adjust(struct libcfs_ioctl_data *data)
{
	ENTRY;

	if (libcfs_ioctl_is_invalid(data)) {
		CERROR("libcfs ioctl: parameter not correctly formatted\n");
		RETURN(-EINVAL);
	}

	if (data->ioc_inllen1 != 0)
		data->ioc_inlbuf1 = &data->ioc_bulk[0];

	if (data->ioc_inllen2 != 0)
		data->ioc_inlbuf2 = &data->ioc_bulk[0] +
				    cfs_size_round(data->ioc_inllen1);

	RETURN(0);
}
Пример #13
0
/**
 * Object updates between Targets. Because all the updates has been
 * dis-assemblied into object updates at sender side, so OUT will
 * call OSD API directly to execute these updates.
 *
 * In DNE phase I all of the updates in the request need to be executed
 * in one transaction, and the transaction has to be synchronously.
 *
 * Please refer to lustre/include/lustre/lustre_idl.h for req/reply
 * format.
 */
int out_handle(struct tgt_session_info *tsi)
{
	const struct lu_env		*env = tsi->tsi_env;
	struct tgt_thread_info		*tti = tgt_th_info(env);
	struct thandle_exec_args	*ta = &tti->tti_tea;
	struct req_capsule		*pill = tsi->tsi_pill;
	struct dt_device		*dt = tsi->tsi_tgt->lut_bottom;
	struct update_buf		*ubuf;
	struct update			*update;
	struct update_reply		*update_reply;
	int				 bufsize;
	int				 count;
	int				 old_batchid = -1;
	unsigned			 off;
	int				 i;
	int				 rc = 0;
	int				 rc1 = 0;

	ENTRY;

	req_capsule_set(pill, &RQF_UPDATE_OBJ);
	bufsize = req_capsule_get_size(pill, &RMF_UPDATE, RCL_CLIENT);
	if (bufsize != UPDATE_BUFFER_SIZE) {
		CERROR("%s: invalid bufsize %d: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), bufsize, -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	ubuf = req_capsule_client_get(pill, &RMF_UPDATE);
	if (ubuf == NULL) {
		CERROR("%s: No buf!: rc = %d\n", tgt_name(tsi->tsi_tgt),
		       -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	if (le32_to_cpu(ubuf->ub_magic) != UPDATE_BUFFER_MAGIC) {
		CERROR("%s: invalid magic %x expect %x: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), le32_to_cpu(ubuf->ub_magic),
		       UPDATE_BUFFER_MAGIC, -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	count = le32_to_cpu(ubuf->ub_count);
	if (count <= 0) {
		CERROR("%s: No update!: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	req_capsule_set_size(pill, &RMF_UPDATE_REPLY, RCL_SERVER,
			     UPDATE_BUFFER_SIZE);
	rc = req_capsule_server_pack(pill);
	if (rc != 0) {
		CERROR("%s: Can't pack response: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), rc);
		RETURN(rc);
	}

	/* Prepare the update reply buffer */
	update_reply = req_capsule_server_get(pill, &RMF_UPDATE_REPLY);
	if (update_reply == NULL)
		RETURN(err_serious(-EPROTO));
	update_init_reply_buf(update_reply, count);
	tti->tti_u.update.tti_update_reply = update_reply;

	rc = out_tx_start(env, dt, ta);
	if (rc != 0)
		RETURN(rc);

	tti->tti_mult_trans = !req_is_replay(tgt_ses_req(tsi));

	/* Walk through updates in the request to execute them synchronously */
	off = cfs_size_round(offsetof(struct update_buf, ub_bufs[0]));
	for (i = 0; i < count; i++) {
		struct tgt_handler	*h;
		struct dt_object	*dt_obj;

		update = (struct update *)((char *)ubuf + off);
		if (old_batchid == -1) {
			old_batchid = update->u_batchid;
		} else if (old_batchid != update->u_batchid) {
			/* Stop the current update transaction,
			 * create a new one */
			rc = out_tx_end(env, ta);
			if (rc != 0)
				RETURN(rc);

			rc = out_tx_start(env, dt, ta);
			if (rc != 0)
				RETURN(rc);
			old_batchid = update->u_batchid;
		}

		fid_le_to_cpu(&update->u_fid, &update->u_fid);
		if (!fid_is_sane(&update->u_fid)) {
			CERROR("%s: invalid FID "DFID": rc = %d\n",
			       tgt_name(tsi->tsi_tgt), PFID(&update->u_fid),
			       -EPROTO);
			GOTO(out, rc = err_serious(-EPROTO));
		}

		dt_obj = dt_locate(env, dt, &update->u_fid);
		if (IS_ERR(dt_obj))
			GOTO(out, rc = PTR_ERR(dt_obj));

		tti->tti_u.update.tti_dt_object = dt_obj;
		tti->tti_u.update.tti_update = update;
		tti->tti_u.update.tti_update_reply_index = i;

		h = out_handler_find(update->u_type);
		if (likely(h != NULL)) {
			/* For real modification RPC, check if the update
			 * has been executed */
			if (h->th_flags & MUTABOR) {
				struct ptlrpc_request *req = tgt_ses_req(tsi);

				if (out_check_resent(env, dt, dt_obj, req,
						     out_reconstruct,
						     update_reply, i))
					GOTO(next, rc);
			}

			rc = h->th_act(tsi);
		} else {
			CERROR("%s: The unsupported opc: 0x%x\n",
			       tgt_name(tsi->tsi_tgt), update->u_type);
			lu_object_put(env, &dt_obj->do_lu);
			GOTO(out, rc = -ENOTSUPP);
		}
next:
		lu_object_put(env, &dt_obj->do_lu);
		if (rc < 0)
			GOTO(out, rc);
		off += cfs_size_round(update_size(update));
	}
out:
	rc1 = out_tx_end(env, ta);
	if (rc == 0)
		rc = rc1;
	RETURN(rc);
}
Пример #14
0
static int llog_print_cb(const struct lu_env *env, struct llog_handle *handle,
			 struct llog_rec_hdr *rec, void *data)
{
	struct obd_ioctl_data *ioc_data = (struct obd_ioctl_data *)data;
	static int l, remains, from, to;
	static char *out;
	char *endp;
	int cur_index;

	if (ioc_data != NULL && ioc_data->ioc_inllen1 > 0) {
		l = 0;
		remains = ioc_data->ioc_inllen4 +
			cfs_size_round(ioc_data->ioc_inllen1) +
			cfs_size_round(ioc_data->ioc_inllen2) +
			cfs_size_round(ioc_data->ioc_inllen3);
		from = simple_strtol(ioc_data->ioc_inlbuf2, &endp, 0);
		if (*endp != '\0')
			return -EINVAL;
		to = simple_strtol(ioc_data->ioc_inlbuf3, &endp, 0);
		if (*endp != '\0')
			return -EINVAL;
		out = ioc_data->ioc_bulk;
		ioc_data->ioc_inllen1 = 0;
	}

	cur_index = rec->lrh_index;
	if (cur_index < from)
		return 0;
	if (to > 0 && cur_index > to)
		return -LLOG_EEMPTY;

	if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) {
		struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;

		if (rec->lrh_type != LLOG_LOGID_MAGIC) {
			CERROR("invalid record in catalog\n");
			return -EINVAL;
		}

		l = snprintf(out, remains,
			     "[index]: %05d  [logid]: #"DOSTID"#%08x\n",
			     cur_index, POSTID(&lir->lid_id.lgl_oi),
			     lir->lid_id.lgl_ogen);
	} else if (rec->lrh_type == OBD_CFG_REC) {
		int rc;

		rc = class_config_parse_rec(rec, out, remains);
		if (rc < 0)
			return rc;
		l = rc;
	} else {
		l = snprintf(out, remains,
			     "[index]: %05d  [type]: %02x  [len]: %04d\n",
			     cur_index, rec->lrh_type, rec->lrh_len);
	}
	out += l;
	remains -= l;
	if (remains <= 0) {
		CERROR("not enough space for print log records\n");
		return -LLOG_EEMPTY;
	}

	return 0;
}
Пример #15
0
/**
 * Process the HSM actions described in a struct hsm_user_request.
 *
 * The action described in hur will be send to coordinator to be saved and
 * processed later or either handled directly if hur.hur_action is HUA_RELEASE.
 *
 * This is MDS_HSM_REQUEST RPC handler.
 */
int mdt_hsm_request(struct tgt_session_info *tsi)
{
	struct mdt_thread_info		*info;
	struct req_capsule		*pill = tsi->tsi_pill;
	struct hsm_request		*hr;
	struct hsm_user_item		*hui;
	struct hsm_action_list		*hal;
	struct hsm_action_item		*hai;
	const void			*data;
	int				 hui_list_size;
	int				 data_size;
	enum hsm_copytool_action	 action = HSMA_NONE;
	__u64				 compound_id;
	int				 hal_size, i, rc;
	ENTRY;

	hr = req_capsule_client_get(pill, &RMF_MDS_HSM_REQUEST);
	hui = req_capsule_client_get(pill, &RMF_MDS_HSM_USER_ITEM);
	data = req_capsule_client_get(pill, &RMF_GENERIC_DATA);

	if (tsi->tsi_mdt_body == NULL || hr == NULL || hui == NULL || data == NULL)
		RETURN(-EPROTO);

	/* Sanity check. Nothing to do with an empty list */
	if (hr->hr_itemcount == 0)
		RETURN(0);

	hui_list_size = req_capsule_get_size(pill, &RMF_MDS_HSM_USER_ITEM,
					     RCL_CLIENT);
	if (hui_list_size < hr->hr_itemcount * sizeof(*hui))
		RETURN(-EPROTO);

	data_size = req_capsule_get_size(pill, &RMF_GENERIC_DATA, RCL_CLIENT);
	if (data_size != hr->hr_data_len)
		RETURN(-EPROTO);

	info = tsi2mdt_info(tsi);
	/* Only valid if client is remote */
	rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
	if (rc)
		GOTO(out, rc);

	switch (hr->hr_action) {
	/* code to be removed in hsm1_merge and final patch */
	case HUA_RELEASE:
		CERROR("Release action is not working in hsm1_coord\n");
		GOTO(out_ucred, rc = -EINVAL);
		break;
	/* end of code to be removed */
	case HUA_ARCHIVE:
		action = HSMA_ARCHIVE;
		break;
	case HUA_RESTORE:
		action = HSMA_RESTORE;
		break;
	case HUA_REMOVE:
		action = HSMA_REMOVE;
		break;
	case HUA_CANCEL:
		action = HSMA_CANCEL;
		break;
	default:
		CERROR("Unknown hsm action: %d\n", hr->hr_action);
		GOTO(out_ucred, rc = -EINVAL);
	}

	hal_size = sizeof(*hal) + cfs_size_round(MTI_NAME_MAXLEN) /* fsname */ +
		   (sizeof(*hai) + cfs_size_round(hr->hr_data_len)) *
		   hr->hr_itemcount;

	MDT_HSM_ALLOC(hal, hal_size);
	if (hal == NULL)
		GOTO(out_ucred, rc = -ENOMEM);

	hal->hal_version = HAL_VERSION;
	hal->hal_archive_id = hr->hr_archive_id;
	hal->hal_flags = hr->hr_flags;
	obd_uuid2fsname(hal->hal_fsname, mdt_obd_name(info->mti_mdt),
			MTI_NAME_MAXLEN);

	hal->hal_count = 0;
	hai = hai_first(hal);
	for (i = 0; i < hr->hr_itemcount; i++, hai = hai_next(hai)) {
		/* Get rid of duplicate entries. Otherwise we get
		 * duplicated work in the llog. */
		if (is_fid_in_hal(hal, &hui[i].hui_fid))
			continue;

		hai->hai_action = action;
		hai->hai_cookie = 0;
		hai->hai_gid = 0;
		hai->hai_fid = hui[i].hui_fid;
		hai->hai_extent = hui[i].hui_extent;
		memcpy(hai->hai_data, data, hr->hr_data_len);
		hai->hai_len = sizeof(*hai) + hr->hr_data_len;

		hal->hal_count++;
	}

	rc = mdt_hsm_add_actions(info, hal, &compound_id);

	MDT_HSM_FREE(hal, hal_size);

	GOTO(out_ucred, rc);

out_ucred:
	mdt_exit_ucred(info);
out:
	mdt_thread_info_fini(info);
	return rc;
}
Пример #16
0
/**
 * Retrieve undergoing HSM requests for the fid provided in RPC body.
 * Current requests are read from coordinator states.
 *
 * This is MDS_HSM_ACTION RPC handler.
 */
int mdt_hsm_action(struct tgt_session_info *tsi)
{
	struct mdt_thread_info		*info;
	struct hsm_current_action	*hca;
	struct hsm_action_list		*hal = NULL;
	struct hsm_action_item		*hai;
	int				 hal_size;
	int				 rc;
	ENTRY;

	hca = req_capsule_server_get(tsi->tsi_pill,
				     &RMF_MDS_HSM_CURRENT_ACTION);
	if (hca == NULL)
		RETURN(err_serious(-EPROTO));

	if (tsi->tsi_mdt_body == NULL)
		RETURN(-EPROTO);

	info = tsi2mdt_info(tsi);
	/* Only valid if client is remote */
	rc = mdt_init_ucred(info, (struct mdt_body *)info->mti_body);
	if (rc)
		GOTO(out, rc = err_serious(rc));

	/* Coordinator information */
	hal_size = sizeof(*hal) +
		   cfs_size_round(MTI_NAME_MAXLEN) /* fsname */ +
		   cfs_size_round(sizeof(*hai));

	MDT_HSM_ALLOC(hal, hal_size);
	if (hal == NULL)
		GOTO(out_ucred, rc = -ENOMEM);

	hal->hal_version = HAL_VERSION;
	hal->hal_archive_id = 0;
	hal->hal_flags = 0;
	obd_uuid2fsname(hal->hal_fsname, mdt_obd_name(info->mti_mdt),
			MTI_NAME_MAXLEN);
	hal->hal_count = 1;
	hai = hai_first(hal);
	hai->hai_action = HSMA_NONE;
	hai->hai_cookie = 0;
	hai->hai_gid = 0;
	hai->hai_fid = info->mti_body->mbo_fid1;
	hai->hai_len = sizeof(*hai);

	rc = mdt_hsm_get_actions(info, hal);
	if (rc)
		GOTO(out_free, rc);

	/* cookie is used to give back request status */
	if (hai->hai_cookie == 0)
		hca->hca_state = HPS_WAITING;
	else
		hca->hca_state = HPS_RUNNING;

	switch (hai->hai_action) {
	case HSMA_NONE:
		hca->hca_action = HUA_NONE;
		break;
	case HSMA_ARCHIVE:
		hca->hca_action = HUA_ARCHIVE;
		break;
	case HSMA_RESTORE:
		hca->hca_action = HUA_RESTORE;
		break;
	case HSMA_REMOVE:
		hca->hca_action = HUA_REMOVE;
		break;
	case HSMA_CANCEL:
		hca->hca_action = HUA_CANCEL;
		break;
	default:
		hca->hca_action = HUA_NONE;
		CERROR("%s: Unknown hsm action: %d on "DFID"\n",
		       mdt_obd_name(info->mti_mdt),
		       hai->hai_action, PFID(&hai->hai_fid));
		break;
	}

	hca->hca_location = hai->hai_extent;

	EXIT;
out_free:
	MDT_HSM_FREE(hal, hal_size);
out_ucred:
	mdt_exit_ucred(info);
out:
	mdt_thread_info_fini(info);
	return rc;
}
Пример #17
0
static int out_read(struct tgt_session_info *tsi)
{
	const struct lu_env	*env = tsi->tsi_env;
	struct tgt_thread_info	*tti = tgt_th_info(env);
	struct object_update	*update = tti->tti_u.update.tti_update;
	struct dt_object	*obj = tti->tti_u.update.tti_dt_object;
	struct object_update_reply *reply = tti->tti_u.update.tti_update_reply;
	int index = tti->tti_u.update.tti_update_reply_index;
	struct lu_rdbuf	*rdbuf;
	struct object_update_result *update_result;
	struct out_read_reply	*orr;
	void *tmp;
	size_t size;
	size_t total_size = 0;
	__u64 pos;
	unsigned int i;
	unsigned int nbufs;
	int rc = 0;
	ENTRY;

	update_result = object_update_result_get(reply, index, NULL);
	LASSERT(update_result != NULL);
	update_result->our_datalen = sizeof(*orr);

	if (!lu_object_exists(&obj->do_lu))
		GOTO(out, rc = -ENOENT);

	tmp = object_update_param_get(update, 0, NULL);
	if (IS_ERR(tmp)) {
		CERROR("%s: empty size for read: rc = %ld\n",
		       tgt_name(tsi->tsi_tgt), PTR_ERR(tmp));
		GOTO(out, rc = PTR_ERR(tmp));
	}
	size = le64_to_cpu(*(size_t *)(tmp));

	tmp = object_update_param_get(update, 1, NULL);
	if (IS_ERR(tmp)) {
		CERROR("%s: empty pos for read: rc = %ld\n",
		       tgt_name(tsi->tsi_tgt), PTR_ERR(tmp));
		GOTO(out, rc = PTR_ERR(tmp));
	}
	pos = le64_to_cpu(*(__u64 *)(tmp));

	/* Put the offset into the begining of the buffer in reply */
	orr = (struct out_read_reply *)update_result->our_data;

	nbufs = (size + OUT_BULK_BUFFER_SIZE - 1) / OUT_BULK_BUFFER_SIZE;
	OBD_ALLOC(rdbuf, sizeof(struct lu_rdbuf) +
			 nbufs * sizeof(rdbuf->rb_bufs[0]));
	if (rdbuf == NULL)
		GOTO(out, rc = -ENOMEM);

	rdbuf->rb_nbufs = 0;
	total_size = 0;
	for (i = 0; i < nbufs; i++) {
		__u32 read_size;

		read_size = size > OUT_BULK_BUFFER_SIZE ?
			    OUT_BULK_BUFFER_SIZE : size;
		OBD_ALLOC(rdbuf->rb_bufs[i].lb_buf, read_size);
		if (rdbuf->rb_bufs[i].lb_buf == NULL)
			GOTO(out_free, rc = -ENOMEM);

		rdbuf->rb_bufs[i].lb_len = read_size;
		dt_read_lock(env, obj, MOR_TGT_CHILD);
		rc = dt_read(env, obj, &rdbuf->rb_bufs[i], &pos);
		dt_read_unlock(env, obj);

		total_size += rc < 0 ? 0 : rc;
		if (rc <= 0)
			break;

		rdbuf->rb_nbufs++;
		size -= read_size;
	}

	/* send pages to client */
	rc = tgt_send_buffer(tsi, rdbuf);
	if (rc < 0)
		GOTO(out_free, rc);

	orr->orr_size = total_size;
	orr->orr_offset = pos;

	orr_cpu_to_le(orr, orr);
	update_result->our_datalen += orr->orr_size;
out_free:
	for (i = 0; i < nbufs; i++) {
		if (rdbuf->rb_bufs[i].lb_buf != NULL) {
			OBD_FREE(rdbuf->rb_bufs[i].lb_buf,
				 rdbuf->rb_bufs[i].lb_len);
		}
	}
	OBD_FREE(rdbuf, sizeof(struct lu_rdbuf) +
			nbufs * sizeof(rdbuf->rb_bufs[0]));
out:
	/* Insert read buffer */
	update_result->our_rc = ptlrpc_status_hton(rc);
	reply->ourp_lens[index] = cfs_size_round(update_result->our_datalen +
						 sizeof(*update_result));
	RETURN(rc);
}
Пример #18
0
static int llog_check_cb(struct llog_handle *handle, struct llog_rec_hdr *rec,
                         void *data)
{
        struct obd_ioctl_data *ioc_data = (struct obd_ioctl_data *)data;
        static int l, remains, from, to;
        static char *out;
        char *endp;
        int cur_index, rc = 0;

        ENTRY;
        cur_index = rec->lrh_index;

        if (ioc_data && (ioc_data->ioc_inllen1)) {
                l = 0;
                remains = ioc_data->ioc_inllen4 +
                        cfs_size_round(ioc_data->ioc_inllen1) +
                        cfs_size_round(ioc_data->ioc_inllen2) +
                        cfs_size_round(ioc_data->ioc_inllen3);
                from = simple_strtol(ioc_data->ioc_inlbuf2, &endp, 0);
                if (*endp != '\0')
                        RETURN(-EINVAL);
                to = simple_strtol(ioc_data->ioc_inlbuf3, &endp, 0);
                if (*endp != '\0')
                        RETURN(-EINVAL);
                ioc_data->ioc_inllen1 = 0;
                out = ioc_data->ioc_bulk;
                if (cur_index < from)
                        RETURN(0);
                if (to > 0 && cur_index > to)
                        RETURN(-LLOG_EEMPTY);
        }
        if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) {
                struct llog_logid_rec *lir = (struct llog_logid_rec *)rec;
                struct llog_handle *log_handle;

                if (rec->lrh_type != LLOG_LOGID_MAGIC) {
                        l = snprintf(out, remains, "[index]: %05d  [type]: "
                                     "%02x  [len]: %04d failed\n",
                                     cur_index, rec->lrh_type,
                                     rec->lrh_len);
                }
                if (handle->lgh_ctxt == NULL)
                        RETURN(-EOPNOTSUPP);
                rc = llog_cat_id2handle(handle, &log_handle, &lir->lid_id);
                if (rc) {
                        CDEBUG(D_IOCTL,
                               "cannot find log #"LPX64"#"LPX64"#%08x\n",
                               lir->lid_id.lgl_oid, lir->lid_id.lgl_oseq,
                               lir->lid_id.lgl_ogen);
                        RETURN(rc);
                }
                rc = llog_process(log_handle, llog_check_cb, NULL, NULL);
                llog_close(log_handle);
        } else {
                switch (rec->lrh_type) {
                case OST_SZ_REC:
                case OST_RAID1_REC:
                case MDS_UNLINK_REC:
                case MDS_SETATTR_REC:
                case MDS_SETATTR64_REC:
                case OBD_CFG_REC:
                case LLOG_HDR_MAGIC: {
                         l = snprintf(out, remains, "[index]: %05d  [type]: "
                                      "%02x  [len]: %04d ok\n",
                                      cur_index, rec->lrh_type,
                                      rec->lrh_len);
                         out += l;
                         remains -= l;
                         if (remains <= 0) {
                                CERROR("no space to print log records\n");
                                RETURN(-LLOG_EEMPTY);
                         }
                         RETURN(0);
                }
                default: {
                         l = snprintf(out, remains, "[index]: %05d  [type]: "
                                      "%02x  [len]: %04d failed\n",
                                      cur_index, rec->lrh_type,
                                      rec->lrh_len);
                         out += l;
                         remains -= l;
                         if (remains <= 0) {
                                CERROR("no space to print log records\n");
                                RETURN(-LLOG_EEMPTY);
                         }
                         RETURN(0);
                }
                }
        }
        RETURN(rc);
}
Пример #19
0
int llog_ioctl(struct llog_ctxt *ctxt, int cmd, struct obd_ioctl_data *data)
{
        struct llog_logid logid;
        int err = 0;
        struct llog_handle *handle = NULL;

        ENTRY;
        if (*data->ioc_inlbuf1 == '#') {
                err = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1);
                if (err)
                        GOTO(out, err);
                err = llog_create(ctxt, &handle, &logid, NULL);
                if (err)
                        GOTO(out, err);
        } else if (*data->ioc_inlbuf1 == '$') {
                char *name = data->ioc_inlbuf1 + 1;
                err = llog_create(ctxt, &handle, NULL, name);
                if (err)
                        GOTO(out, err);
        } else {
                GOTO(out, err = -EINVAL);
        }

        err = llog_init_handle(handle, 0, NULL);
        if (err)
                GOTO(out_close, err = -ENOENT);

        switch (cmd) {
        case OBD_IOC_LLOG_INFO: {
                int l;
                int remains = data->ioc_inllen2 +
                        cfs_size_round(data->ioc_inllen1);
                char *out = data->ioc_bulk;

                l = snprintf(out, remains,
                             "logid:            #"LPX64"#"LPX64"#%08x\n"
                             "flags:            %x (%s)\n"
                             "records count:    %d\n"
                             "last index:       %d\n",
                             handle->lgh_id.lgl_oid, handle->lgh_id.lgl_oseq,
                             handle->lgh_id.lgl_ogen,
                             handle->lgh_hdr->llh_flags,
                             handle->lgh_hdr->llh_flags &
                             LLOG_F_IS_CAT ? "cat" : "plain",
                             handle->lgh_hdr->llh_count,
                             handle->lgh_last_idx);
                out += l;
                remains -= l;
                if (remains <= 0)
                        CERROR("not enough space for log header info\n");

                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_CHECK: {
                LASSERT(data->ioc_inllen1);
                err = llog_process(handle, llog_check_cb, data, NULL);
                if (err == -LLOG_EEMPTY)
                        err = 0;
                GOTO(out_close, err);
        }

        case OBD_IOC_LLOG_PRINT: {
                LASSERT(data->ioc_inllen1);
                err = llog_process(handle, class_config_dump_handler,data,NULL);
                if (err == -LLOG_EEMPTY)
                        err = 0;
                else
                        err = llog_process(handle, llog_print_cb, data, NULL);

                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_CANCEL: {
                struct llog_cookie cookie;
                struct llog_logid plain;
                char *endp;

                cookie.lgc_index = simple_strtoul(data->ioc_inlbuf3, &endp, 0);
                if (*endp != '\0')
                        GOTO(out_close, err = -EINVAL);

                if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) {
                        cfs_down_write(&handle->lgh_lock);
                        err = llog_cancel_rec(handle, cookie.lgc_index);
                        cfs_up_write(&handle->lgh_lock);
                        GOTO(out_close, err);
                }

                err = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
                if (err)
                        GOTO(out_close, err);
                cookie.lgc_lgl = plain;

                if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT))
                        GOTO(out_close, err = -EINVAL);

                err = llog_cat_cancel_records(handle, 1, &cookie);
                GOTO(out_close, err);
        }
        case OBD_IOC_LLOG_REMOVE: {
                struct llog_logid plain;

                if (handle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN) {
                        err = llog_destroy(handle);
                        if (!err)
                                llog_free_handle(handle);
                        GOTO(out, err);
                }

                if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT))
                        GOTO(out_close, err = -EINVAL);

                if (data->ioc_inlbuf2) {
                        /*remove indicate log from the catalog*/
                        err = str2logid(&plain, data->ioc_inlbuf2,
                                        data->ioc_inllen2);
                        if (err)
                                GOTO(out_close, err);
                        err = llog_remove_log(handle, &plain);
                } else {
                        /*remove all the log of the catalog*/
                        llog_process(handle, llog_delete_cb, NULL, NULL);
                }
                GOTO(out_close, err);
        }
        }

out_close:
        if (handle->lgh_hdr &&
            handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
                llog_cat_put(handle);
        else
                llog_close(handle);
out:
        RETURN(err);
}
Пример #20
0
int llog_ioctl(const struct lu_env *env, struct llog_ctxt *ctxt, int cmd,
	       struct obd_ioctl_data *data)
{
	struct llog_logid	 logid;
	int			 rc = 0;
	struct llog_handle	*handle = NULL;

	if (*data->ioc_inlbuf1 == '#') {
		rc = str2logid(&logid, data->ioc_inlbuf1, data->ioc_inllen1);
		if (rc)
			return rc;
		rc = llog_open(env, ctxt, &handle, &logid, NULL,
			       LLOG_OPEN_EXISTS);
		if (rc)
			return rc;
	} else if (*data->ioc_inlbuf1 == '$') {
		char *name = data->ioc_inlbuf1 + 1;

		rc = llog_open(env, ctxt, &handle, NULL, name,
			       LLOG_OPEN_EXISTS);
		if (rc)
			return rc;
	} else {
		return -EINVAL;
	}

	rc = llog_init_handle(env, handle, 0, NULL);
	if (rc)
		GOTO(out_close, rc = -ENOENT);

	switch (cmd) {
	case OBD_IOC_LLOG_INFO: {
		int	 l;
		int	 remains = data->ioc_inllen2 +
				   cfs_size_round(data->ioc_inllen1);
		char	*out = data->ioc_bulk;

		l = snprintf(out, remains,
			     "logid:	    #"DOSTID"#%08x\n"
			     "flags:	    %x (%s)\n"
			     "records count:    %d\n"
			     "last index:       %d\n",
			     POSTID(&handle->lgh_id.lgl_oi),
			     handle->lgh_id.lgl_ogen,
			     handle->lgh_hdr->llh_flags,
			     handle->lgh_hdr->llh_flags &
			     LLOG_F_IS_CAT ? "cat" : "plain",
			     handle->lgh_hdr->llh_count,
			     handle->lgh_last_idx);
		out += l;
		remains -= l;
		if (remains <= 0) {
			CERROR("%s: not enough space for log header info\n",
			       ctxt->loc_obd->obd_name);
			rc = -ENOSPC;
		}
		break;
	}
	case OBD_IOC_LLOG_CHECK:
		LASSERT(data->ioc_inllen1 > 0);
		rc = llog_process(env, handle, llog_check_cb, data, NULL);
		if (rc == -LLOG_EEMPTY)
			rc = 0;
		else if (rc)
			GOTO(out_close, rc);
		break;
	case OBD_IOC_LLOG_PRINT:
		LASSERT(data->ioc_inllen1 > 0);
		rc = llog_process(env, handle, llog_print_cb, data, NULL);
		if (rc == -LLOG_EEMPTY)
			rc = 0;
		else if (rc)
			GOTO(out_close, rc);
		break;
	case OBD_IOC_LLOG_CANCEL: {
		struct llog_cookie cookie;
		struct llog_logid plain;
		char *endp;

		cookie.lgc_index = simple_strtoul(data->ioc_inlbuf3, &endp, 0);
		if (*endp != '\0')
			GOTO(out_close, rc = -EINVAL);

		if (handle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN) {
			rc = llog_cancel_rec(NULL, handle, cookie.lgc_index);
			GOTO(out_close, rc);
		} else if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)) {
			GOTO(out_close, rc = -EINVAL);
		}

		if (data->ioc_inlbuf2 == NULL) /* catalog but no logid */
			GOTO(out_close, rc = -ENOTTY);

		rc = str2logid(&plain, data->ioc_inlbuf2, data->ioc_inllen2);
		if (rc)
			GOTO(out_close, rc);
		cookie.lgc_lgl = plain;
		rc = llog_cat_cancel_records(env, handle, 1, &cookie);
		if (rc)
			GOTO(out_close, rc);
		break;
	}
	case OBD_IOC_LLOG_REMOVE: {
		struct llog_logid plain;

		if (handle->lgh_hdr->llh_flags & LLOG_F_IS_PLAIN) {
			rc = llog_destroy(env, handle);
			GOTO(out_close, rc);
		} else if (!(handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)) {
			GOTO(out_close, rc = -EINVAL);
		}

		if (data->ioc_inlbuf2 > 0) {
			/* remove indicate log from the catalog */
			rc = str2logid(&plain, data->ioc_inlbuf2,
				       data->ioc_inllen2);
			if (rc)
				GOTO(out_close, rc);
			rc = llog_remove_log(env, handle, &plain);
		} else {
			/* remove all the log of the catalog */
			rc = llog_process(env, handle, llog_delete_cb, NULL,
					  NULL);
			if (rc)
				GOTO(out_close, rc);
		}
		break;
	}
	default:
		CERROR("%s: Unknown ioctl cmd %#x\n",
		       ctxt->loc_obd->obd_name, cmd);
		GOTO(out_close, rc = -ENOTTY);
	}

out_close:
	if (handle->lgh_hdr &&
	    handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT)
		llog_cat_close(env, handle);
	else
		llog_close(env, handle);
	return rc;
}
Пример #21
0
/* temporary for testing */
static ssize_t mdc_kuc_write(struct file *file,
				const char __user *buffer,
				size_t count, loff_t *off)
{
	struct obd_device *obd =
			((struct seq_file *)file->private_data)->private;
	struct kuc_hdr		*lh;
	struct hsm_action_list	*hal;
	struct hsm_action_item	*hai;
	int			 len;
	int			 fd, rc;

	rc = lprocfs_write_helper(buffer, count, &fd);
	if (rc)
		return rc;

	if (fd < 0)
		return -ERANGE;
	CWARN("message to fd %d\n", fd);

	len = sizeof(*lh) + sizeof(*hal) + MTI_NAME_MAXLEN +
		/* for mockup below */ 2 * cfs_size_round(sizeof(*hai));

	OBD_ALLOC(lh, len);
	if (!lh)
		return -ENOMEM;

	lh->kuc_magic = KUC_MAGIC;
	lh->kuc_transport = KUC_TRANSPORT_HSM;
	lh->kuc_msgtype = HMT_ACTION_LIST;
	lh->kuc_msglen = len;

	hal = (struct hsm_action_list *)(lh + 1);
	hal->hal_version = HAL_VERSION;
	hal->hal_archive_id = 1;
	hal->hal_flags = 0;
	obd_uuid2fsname(hal->hal_fsname, obd->obd_name, MTI_NAME_MAXLEN);

	/* mock up an action list */
	hal->hal_count = 2;
	hai = hai_zero(hal);
	hai->hai_action = HSMA_ARCHIVE;
	hai->hai_fid.f_oid = 5;
	hai->hai_len = sizeof(*hai);
	hai = hai_next(hai);
	hai->hai_action = HSMA_RESTORE;
	hai->hai_fid.f_oid = 10;
	hai->hai_len = sizeof(*hai);

	/* This works for either broadcast or unicast to a single fd */
	if (fd == 0) {
		rc = libcfs_kkuc_group_put(KUC_GRP_HSM, lh);
	} else {
		struct file *fp = fget(fd);

		rc = libcfs_kkuc_msg_put(fp, lh);
		fput(fp);
	}
	OBD_FREE(lh, len);
	if (rc < 0)
		return rc;
	return count;
}
Пример #22
0
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 object_update	   *update = tti->tti_u.update.tti_update;
	struct lu_buf		   *lbuf = &tti->tti_buf;
	struct object_update_reply *reply = tti->tti_u.update.tti_update_reply;
	struct dt_object           *obj = tti->tti_u.update.tti_dt_object;
	char			   *name;
	struct object_update_result *update_result;
	int			idx = tti->tti_u.update.tti_update_reply_index;
	int			   rc;

	ENTRY;

	if (!lu_object_exists(&obj->do_lu)) {
		set_bit(LU_OBJECT_HEARD_BANSHEE,
			&obj->do_lu.lo_header->loh_flags);
		RETURN(-ENOENT);
	}

	name = object_update_param_get(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));
	}

	update_result = object_update_result_get(reply, 0, NULL);
	if (update_result == NULL) {
		CERROR("%s: empty name for xattr get: rc = %d\n",
		       tgt_name(tsi->tsi_tgt), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	lbuf->lb_buf = update_result->our_data;
	lbuf->lb_len = OUT_UPDATE_REPLY_SIZE -
		       cfs_size_round((unsigned long)update_result->our_data -
				      (unsigned long)update_result);
	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);

	GOTO(out, rc);

out:
	object_update_result_insert(reply, lbuf->lb_buf, lbuf->lb_len, idx, rc);
	RETURN(rc);
}
Пример #23
0
/**
 * Object updates between Targets. Because all the updates has been
 * dis-assemblied into object updates in master MDD layer, so out
 * will skip MDD layer, and call OSD API directly to execute these
 * updates.
 *
 * In phase I, all of the updates in the request need to be executed
 * in one transaction, and the transaction has to be synchronously.
 *
 * Please refer to lustre/include/lustre/lustre_idl.h for req/reply
 * format.
 */
int out_handle(struct mdt_thread_info *info)
{
	struct req_capsule	  *pill = info->mti_pill;
	struct update_buf	  *ubuf;
	struct update		  *update;
	struct thandle_exec_args  *th = &info->mti_handle;
	int			  bufsize;
	int			  count;
	unsigned		  off;
	int			  i;
	int			  rc = 0;
	int			  rc1 = 0;
	ENTRY;

	req_capsule_set(pill, &RQF_UPDATE_OBJ);
	bufsize = req_capsule_get_size(pill, &RMF_UPDATE, RCL_CLIENT);
	if (bufsize != UPDATE_BUFFER_SIZE) {
		CERROR("%s: invalid bufsize %d: rc = %d\n",
		       mdt_obd_name(info->mti_mdt), bufsize, -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	ubuf = req_capsule_client_get(pill, &RMF_UPDATE);
	if (ubuf == NULL) {
		CERROR("%s: No buf!: rc = %d\n", mdt_obd_name(info->mti_mdt),
		       -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	if (le32_to_cpu(ubuf->ub_magic) != UPDATE_BUFFER_MAGIC) {
		CERROR("%s: invalid magic %x expect %x: rc = %d\n",
		       mdt_obd_name(info->mti_mdt), le32_to_cpu(ubuf->ub_magic),
		       UPDATE_BUFFER_MAGIC, -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	count = le32_to_cpu(ubuf->ub_count);
	if (count <= 0) {
		CERROR("%s: No update!: rc = %d\n",
		       mdt_obd_name(info->mti_mdt), -EPROTO);
		RETURN(err_serious(-EPROTO));
	}

	req_capsule_set_size(pill, &RMF_UPDATE_REPLY, RCL_SERVER,
			     UPDATE_BUFFER_SIZE);
	rc = req_capsule_server_pack(pill);
	if (rc != 0) {
		CERROR("%s: Can't pack response: rc = %d\n",
		       mdt_obd_name(info->mti_mdt), rc);
		RETURN(rc);
	}

	/* Prepare the update reply buffer */
	info->mti_u.update.mti_update_reply =
			req_capsule_server_get(pill, &RMF_UPDATE_REPLY);
	update_init_reply_buf(info->mti_u.update.mti_update_reply, count);

	rc = out_tx_start(info->mti_env, info->mti_mdt, th);
	if (rc != 0)
		RETURN(rc);

	/* Walk through updates in the request to execute them synchronously */
	off = cfs_size_round(offsetof(struct update_buf, ub_bufs[0]));
	for (i = 0; i < count; i++) {
		struct out_handler *h;
		struct dt_object   *dt_obj;

		update = (struct update *)((char *)ubuf + off);

		fid_le_to_cpu(&update->u_fid, &update->u_fid);
		if (!fid_is_sane(&update->u_fid)) {
			CERROR("%s: invalid FID "DFID": rc = %d\n",
			       mdt_obd_name(info->mti_mdt),
			       PFID(&update->u_fid), -EPROTO);
			GOTO(out, rc = err_serious(-EPROTO));
		}
		dt_obj = out_object_find(info, &update->u_fid);
		if (IS_ERR(dt_obj))
			GOTO(out, rc = PTR_ERR(dt_obj));

		info->mti_u.update.mti_dt_object = dt_obj;
		info->mti_u.update.mti_update = update;
		info->mti_u.update.mti_update_reply_index = i;

		h = mdt_handler_find(update->u_type, out_handlers);
		if (likely(h != NULL)) {
			rc = h->mh_act(info);
		} else {
			CERROR("%s: The unsupported opc: 0x%x\n",
			       mdt_obd_name(info->mti_mdt), update->u_type);
			lu_object_put(info->mti_env, &dt_obj->do_lu);
			GOTO(out, rc = -ENOTSUPP);
		}
		lu_object_put(info->mti_env, &dt_obj->do_lu);
		if (rc < 0)
			GOTO(out, rc);
		off += cfs_size_round(update_size(update));
	}

out:
	rc1 = out_tx_end(info, th);
	rc = rc == 0 ? rc1 : rc;
	info->mti_fail_id = OBD_FAIL_UPDATE_OBJ_NET;
	RETURN(rc);
}
Пример #24
0
static int llog_check_cb(const struct lu_env *env, struct llog_handle *handle,
			 struct llog_rec_hdr *rec, void *data)
{
	struct obd_ioctl_data *ioc_data = (struct obd_ioctl_data *)data;
	static int l, remains, from, to;
	static char *out;
	char *endp;
	int cur_index, rc = 0;

	if (ioc_data && ioc_data->ioc_inllen1 > 0) {
		l = 0;
		remains = ioc_data->ioc_inllen4 +
			cfs_size_round(ioc_data->ioc_inllen1) +
			cfs_size_round(ioc_data->ioc_inllen2) +
			cfs_size_round(ioc_data->ioc_inllen3);
		from = simple_strtol(ioc_data->ioc_inlbuf2, &endp, 0);
		if (*endp != '\0')
			return -EINVAL;
		to = simple_strtol(ioc_data->ioc_inlbuf3, &endp, 0);
		if (*endp != '\0')
			return -EINVAL;
		ioc_data->ioc_inllen1 = 0;
		out = ioc_data->ioc_bulk;
	}

	cur_index = rec->lrh_index;
	if (cur_index < from)
		return 0;
	if (to > 0 && cur_index > to)
		return -LLOG_EEMPTY;

	if (handle->lgh_hdr->llh_flags & LLOG_F_IS_CAT) {
		struct llog_logid_rec	*lir = (struct llog_logid_rec *)rec;
		struct llog_handle	*loghandle;

		if (rec->lrh_type != LLOG_LOGID_MAGIC) {
			l = snprintf(out, remains, "[index]: %05d  [type]: "
				     "%02x  [len]: %04d failed\n",
				     cur_index, rec->lrh_type,
				     rec->lrh_len);
		}
		if (handle->lgh_ctxt == NULL)
			return -EOPNOTSUPP;
		rc = llog_cat_id2handle(env, handle, &loghandle, &lir->lid_id);
		if (rc) {
			CDEBUG(D_IOCTL, "cannot find log #"DOSTID"#%08x\n",
			       POSTID(&lir->lid_id.lgl_oi),
			       lir->lid_id.lgl_ogen);
			return rc;
		}
		rc = llog_process(env, loghandle, llog_check_cb, NULL, NULL);
		llog_handle_put(loghandle);
	} else {
		bool ok;

		switch (rec->lrh_type) {
		case OST_SZ_REC:
		case MDS_UNLINK_REC:
		case MDS_UNLINK64_REC:
		case MDS_SETATTR64_REC:
		case OBD_CFG_REC:
		case LLOG_GEN_REC:
		case LLOG_HDR_MAGIC:
			ok = true;
			break;
		default:
			ok = false;
		}

		l = snprintf(out, remains, "[index]: %05d  [type]: "
			     "%02x  [len]: %04d %s\n",
			     cur_index, rec->lrh_type, rec->lrh_len,
			     ok ? "ok" : "failed");
		out += l;
		remains -= l;
		if (remains <= 0) {
			CERROR("%s: no space to print log records\n",
			       handle->lgh_ctxt->loc_obd->obd_name);
			return -LLOG_EEMPTY;
		}
	}
	return rc;
}