Beispiel #1
0
/*
 * Look-up a slave index file.
 *
 * \param env - is the environment passed by the caller
 * \param dev - is the backend dt_device where to look-up/create the slave index
 * \param parent - is the parent directory where to lookup the slave index
 * \param glb_fid - is the fid of the global index file associated with this
 *                  slave index.
 * \param uuid    - is the uuid of slave which is (re)connecting to the master
 *                  target
 *
 * \retval     - pointer to the dt_object of the slave index on success,
 *               appropriate error on failure
 */
struct dt_object *lquota_disk_slv_find(const struct lu_env *env,
				       struct dt_device *dev,
				       struct dt_object *parent,
				       const struct lu_fid *glb_fid,
				       struct obd_uuid *uuid)
{
	struct lquota_thread_info	*qti = lquota_info(env);
	struct dt_object		*slv_idx;
	int				 rc;
	ENTRY;

	LASSERT(uuid != NULL);

	CDEBUG(D_QUOTA, "lookup slave index file for %s\n",
	       obd_uuid2str(uuid));

	/* generate filename associated with the slave */
	rc = lquota_disk_slv_filename(glb_fid, uuid, qti->qti_buf);
	if (rc)
		RETURN(ERR_PTR(rc));

	/* lookup slave index file */
	rc = dt_lookup_dir(env, parent, qti->qti_buf, &qti->qti_fid);
	if (rc)
                RETURN(ERR_PTR(rc));

	/* name is found, get the object */
	slv_idx = dt_locate(env, dev, &qti->qti_fid);
	if (IS_ERR(slv_idx))
		RETURN(slv_idx);

	if (slv_idx->do_index_ops == NULL) {
		rc = slv_idx->do_ops->do_index_try(env, slv_idx,
						   &dt_quota_slv_features);
		if (rc) {
			CERROR("%s: failed to setup slave index operations for "
			       "%s, rc:%d\n", dev->dd_lu_dev.ld_obd->obd_name,
			       obd_uuid2str(uuid), rc);
			lu_object_put(env, &slv_idx->do_lu);
			slv_idx = ERR_PTR(rc);
		}
	}

	RETURN(slv_idx);
}
Beispiel #2
0
/**
 * Implementation of the llog_operations::lop_open
 *
 * This function opens the llog by its logid or by name, it may open also
 * non existent llog and assing then new id to it.
 * The llog_open/llog_close pair works similar to lu_object_find/put,
 * the object may not exist prior open. The result of open is just dt_object
 * in the llog header.
 *
 * \param[in] env		execution environment
 * \param[in] handle		llog handle of the current llog
 * \param[in] logid		logid of llog to open (nameless llog)
 * \param[in] name		name of llog to open (named llog)
 * \param[in] open_param
 *				LLOG_OPEN_NEW - new llog, may not exist
 *				LLOG_OPEN_EXIST - old llog, must exist
 *
 * \retval			0 on successful open, llog_handle::lgh_obj
 *				contains the dt_object of the llog.
 * \retval			negative value on error
 */
static int llog_osd_open(const struct lu_env *env, struct llog_handle *handle,
			 struct llog_logid *logid, char *name,
			 enum llog_open_param open_param)
{
	struct llog_thread_info		*lgi = llog_info(env);
	struct llog_ctxt		*ctxt = handle->lgh_ctxt;
	struct dt_object		*o;
	struct dt_device		*dt;
	struct ls_device		*ls;
	struct local_oid_storage	*los;
	int				 rc = 0;

	ENTRY;

	LASSERT(env);
	LASSERT(ctxt);
	LASSERT(ctxt->loc_exp);
	LASSERT(ctxt->loc_exp->exp_obd);
	dt = ctxt->loc_exp->exp_obd->obd_lvfs_ctxt.dt;
	LASSERT(dt);

	ls = ls_device_get(dt);
	if (IS_ERR(ls))
		RETURN(PTR_ERR(ls));

	mutex_lock(&ls->ls_los_mutex);
	los = dt_los_find(ls, name != NULL ? FID_SEQ_LLOG_NAME : FID_SEQ_LLOG);
	mutex_unlock(&ls->ls_los_mutex);
	LASSERT(los);
	ls_device_put(env, ls);

	LASSERT(handle);

	if (logid != NULL) {
		logid_to_fid(logid, &lgi->lgi_fid);
	} else if (name) {
		struct dt_object *llog_dir;

		llog_dir = llog_osd_dir_get(env, ctxt);
		if (IS_ERR(llog_dir))
			GOTO(out, rc = PTR_ERR(llog_dir));
		dt_read_lock(env, llog_dir, 0);
		rc = dt_lookup_dir(env, llog_dir, name, &lgi->lgi_fid);
		dt_read_unlock(env, llog_dir);
		lu_object_put(env, &llog_dir->do_lu);
		if (rc == -ENOENT && open_param == LLOG_OPEN_NEW) {
			/* generate fid for new llog */
			rc = local_object_fid_generate(env, los,
						       &lgi->lgi_fid);
		}
		if (rc < 0)
			GOTO(out, rc);
		OBD_ALLOC(handle->lgh_name, strlen(name) + 1);
		if (handle->lgh_name)
			strcpy(handle->lgh_name, name);
		else
			GOTO(out, rc = -ENOMEM);
	} else {
		LASSERTF(open_param & LLOG_OPEN_NEW, "%#x\n", open_param);
		/* generate fid for new llog */
		rc = local_object_fid_generate(env, los, &lgi->lgi_fid);
		if (rc < 0)
			GOTO(out, rc);
	}

	o = ls_locate(env, ls, &lgi->lgi_fid, NULL);
	if (IS_ERR(o))
		GOTO(out_name, rc = PTR_ERR(o));

	/* No new llog is expected but doesn't exist */
	if (open_param != LLOG_OPEN_NEW && !dt_object_exists(o))
		GOTO(out_put, rc = -ENOENT);

	fid_to_logid(&lgi->lgi_fid, &handle->lgh_id);
	handle->lgh_obj = o;
	handle->private_data = los;
	LASSERT(handle->lgh_ctxt);

	RETURN(rc);

out_put:
	lu_object_put(env, &o->do_lu);
out_name:
	if (handle->lgh_name != NULL)
		OBD_FREE(handle->lgh_name, strlen(name) + 1);
out:
	dt_los_put(los);
	RETURN(rc);
}
Beispiel #3
0
/*
 * Iterate over all slave index files associated with global index \glb_fid and
 * invoke a callback function for each slave index file.
 *
 * \param env     - is the environment passed by the caller
 * \param parent  - is the parent directory where the slave index files are
 *                  stored
 * \param glb_fid - is the fid of the global index file associated with the
 *                  slave indexes to scan
 * \param func    - is the callback function to call each time a slave index
 *                  file is found
 * \param arg     - is an opaq argument passed to the callback function \func
 */
int lquota_disk_for_each_slv(const struct lu_env *env, struct dt_object *parent,
			     struct lu_fid *glb_fid, lquota_disk_slv_cb_t func,
			     void *arg)
{
	struct lquota_thread_info	*qti = lquota_info(env);
	struct dt_it			*it;
	const struct dt_it_ops		*iops;
	char				*name;
	int				 rc;
	ENTRY;

	OBD_ALLOC(name, LQUOTA_NAME_MAX);
	if (name == NULL)
		RETURN(-ENOMEM);

	/* filename associated with slave index files are prefixed with the most
	 * signicant bits of the global FID */
	sprintf(name, "0x%x-", glb_fid->f_oid);

	iops = &parent->do_index_ops->dio_it;
	it = iops->init(env, parent, 0, BYPASS_CAPA);
	if (IS_ERR(it)) {
		OBD_FREE(name, LQUOTA_NAME_MAX);
		RETURN(PTR_ERR(it));
	}

	rc = iops->load(env, it, 0);
	if (rc == 0) {
		/*
		 * Iterator didn't find record with exactly the key requested.
		 *
		 * It is currently either
		 *
		 *     - positioned above record with key less than
		 *     requested---skip it.
		 *
		 *     - or not positioned at all (is in IAM_IT_SKEWED
		 *     state)---position it on the next item.
		 */
		rc = iops->next(env, it);
	} else if (rc > 0)
		rc = 0;

	while (rc == 0) {
		struct dt_key	*key;
		int		 len;

		len = iops->key_size(env, it);
		/* IAM iterator can return record with zero len. */
		if (len == 0 || len <= strlen(name) || len >= LQUOTA_NAME_MAX)
			goto next;

		key = iops->key(env, it);
		if (IS_ERR(key)) {
			rc = PTR_ERR(key);
			break;
		}

		if (strncmp((char *)key, name, strlen(name)) != 0)
			goto next;

		/* ldiskfs OSD returns filename as stored in directory entry
		 * which does not end up with '\0' */
		memcpy(&qti->qti_buf, key, len);
		qti->qti_buf[len] = '\0';

		/* lookup fid associated with this slave index file */
		rc = dt_lookup_dir(env, parent, qti->qti_buf, &qti->qti_fid);
		if (rc)
			break;

		if (qti->qti_fid.f_seq != FID_SEQ_QUOTA)
			goto next;

		rc = func(env, glb_fid, (char *)key, &qti->qti_fid, arg);
		if (rc)
			break;
next:
		do {
			rc = iops->next(env, it);
		} while (rc == -ESTALE);
	}

	iops->put(env, it);
	iops->fini(env, it);
	OBD_FREE(name, LQUOTA_NAME_MAX);
	if (rc > 0)
		rc = 0;
	RETURN(rc);
}