Esempio n. 1
0
/**
 * Initialize osd Iterator for given osd index object.
 *
 * \param  dt    - osd index object
 * \param  attr  - not used
 * \param  capa  - BYPASS_CAPA
 */
static struct dt_it *osd_it_acct_init(const struct lu_env *env,
				      struct dt_object *dt,
				      __u32 attr,
				      struct lustre_capa *capa)
{
	struct osd_thread_info	*info = osd_oti_get(env);
	struct osd_it_quota	*it;
	struct lu_object	*lo   = &dt->do_lu;
	struct osd_device	*osd  = osd_dev(lo->lo_dev);
	int			 rc;
	ENTRY;

	LASSERT(lu_object_exists(lo));

	if (info == NULL)
		RETURN(ERR_PTR(-ENOMEM));

	it = &info->oti_it_quota;
	memset(it, 0, sizeof(*it));
	it->oiq_oid = osd_quota_fid2dmu(lu_object_fid(lo));

	/* initialize zap cursor */
	rc = -udmu_zap_cursor_init(&it->oiq_zc, &osd->od_objset, it->oiq_oid,0);
	if (rc)
		RETURN(ERR_PTR(rc));

	/* take object reference */
	lu_object_get(lo);
	it->oiq_obj   = osd_dt_obj(dt);
	it->oiq_reset = 1;

	RETURN((struct dt_it *)it);
}
Esempio n. 2
0
/*
 * return status :
 *  rc == 0 -> end of directory.
 *  rc >  0 -> ok, proceed.
 *  rc <  0 -> error.  ( EOVERFLOW  can be masked.)
 */
static int osd_dir_it_load(const struct lu_env *env,
			const struct dt_it *di, __u64 hash)
{
	struct osd_zap_it *it = (struct osd_zap_it *)di;
	struct osd_object *obj = it->ozi_obj;
	struct osd_device *osd = osd_obj2dev(obj);
	zap_attribute_t   *za = &osd_oti_get(env)->oti_za;
	int		   rc;
	ENTRY;

	udmu_zap_cursor_fini(it->ozi_zc);
	if (udmu_zap_cursor_init(&it->ozi_zc, &osd->od_objset,
				 obj->oo_db->db_object, hash))
		RETURN(-ENOMEM);

	if (hash <= 2) {
		it->ozi_pos = hash;
		rc = +1;
	} else {
		it->ozi_pos = 3;
		/* to return whether the end has been reached */
		rc = osd_index_retrieve_skip_dots(it, za);
		if (rc == 0)
			rc = +1;
		else if (rc == -ENOENT)
			rc = 0;
	}

	RETURN(rc);
}
Esempio n. 3
0
static struct dt_it *osd_index_it_init(const struct lu_env *env,
				       struct dt_object *dt,
				       __u32 unused,
				       struct lustre_capa *capa)
{
	struct osd_thread_info  *info = osd_oti_get(env);
	struct osd_zap_it       *it;
	struct osd_object       *obj = osd_dt_obj(dt);
	struct osd_device       *osd = osd_obj2dev(obj);
	struct lu_object        *lo  = &dt->do_lu;
	ENTRY;

	/* XXX: check capa ? */

	LASSERT(lu_object_exists(lo));
	LASSERT(obj->oo_db);
	LASSERT(udmu_object_is_zap(obj->oo_db));
	LASSERT(info);

	it = &info->oti_it_zap;

	if (udmu_zap_cursor_init(&it->ozi_zc, &osd->od_objset,
				 obj->oo_db->db_object, 0))
		RETURN(ERR_PTR(-ENOMEM));

	it->ozi_obj   = obj;
	it->ozi_capa  = capa;
	it->ozi_reset = 1;
	lu_object_get(lo);

	RETURN((struct dt_it *)it);
}
Esempio n. 4
0
/*
 * return status :
 *  rc == 0 -> ok, proceed.
 *  rc >  0 -> end of directory.
 *  rc <  0 -> error.  ( EOVERFLOW  can be masked.)
 */
static int osd_zap_it_load(const struct lu_env *env,
			const struct dt_it *di, __u64 hash)
{
	struct osd_zap_it *it = (struct osd_zap_it *)di;
	struct osd_object *obj = it->ozi_obj;
	struct osd_device *osd = osd_obj2dev(obj);
	int                rc;
	ENTRY;

	udmu_zap_cursor_fini(it->ozi_zc);
	if (udmu_zap_cursor_init(&it->ozi_zc, &osd->od_objset,
				 obj->oo_db->db_object, hash))
		RETURN(-ENOMEM);
	it->ozi_reset = 0;

	/* same as osd_zap_it_next()*/
	rc = -udmu_zap_cursor_retrieve_key(env, it->ozi_zc, NULL,
					   NAME_MAX + 1);
	if (rc == 0)
		RETURN(+1);
	else if (rc == -ENOENT) /* end of dir*/
		RETURN(0);

	RETURN(rc);
}
Esempio n. 5
0
int osd_xattr_list(const struct lu_env *env, struct dt_object *dt,
		struct lu_buf *lb, struct lustre_capa *capa)
{
	struct osd_thread_info *oti = osd_oti_get(env);
	struct osd_object      *obj = osd_dt_obj(dt);
	struct osd_device      *osd = osd_obj2dev(obj);
	udmu_objset_t          *uos = &osd->od_objset;
	zap_cursor_t           *zc;
	int                    rc, counted = 0, remain = lb->lb_len;
	ENTRY;

	LASSERT(obj->oo_db != NULL);
	LASSERT(osd_invariant(obj));
	LASSERT(dt_object_exists(dt));

	down(&obj->oo_guard);

	rc = osd_sa_xattr_list(env, obj, lb);
	if (rc < 0)
		GOTO(out, rc);
	counted = rc;
	remain -= counted;

	/* continue with dnode xattr if any */
	if (obj->oo_xattr == ZFS_NO_OBJECT)
		GOTO(out, rc = counted);

	rc = -udmu_zap_cursor_init(&zc, uos, obj->oo_xattr, 0);
	if (rc)
		GOTO(out, rc);

	while ((rc = -udmu_zap_cursor_retrieve_key(env, zc, oti->oti_key,
						MAXNAMELEN)) == 0) {
		rc = strlen(oti->oti_key);
		if (lb->lb_buf != NULL) {
			if (rc + 1 > remain)
				RETURN(-ERANGE);

			memcpy(lb->lb_buf, oti->oti_key, rc);
			lb->lb_buf += rc;
			*((char *)lb->lb_buf) = '\0';
			lb->lb_buf++;
			remain -= rc + 1;
		}
		counted += rc + 1;

		zap_cursor_advance(zc);
	}
	if (rc < 0)
		GOTO(out_fini, rc);
	rc = counted;

out_fini:
	udmu_zap_cursor_fini(zc);
out:
	up(&obj->oo_guard);
	RETURN(rc);

}
Esempio n. 6
0
static void __osd_declare_object_destroy(const struct lu_env *env,
					 struct osd_object *obj,
					 struct osd_thandle *oh)
{
	struct osd_device	*osd = osd_obj2dev(obj);
	udmu_objset_t		*uos = &osd->od_objset;
	dmu_buf_t		*db = obj->oo_db;
	zap_attribute_t		*za = &osd_oti_get(env)->oti_za;
	uint64_t		 oid = db->db_object, xid;
	dmu_tx_t		*tx = oh->ot_tx;
	zap_cursor_t		*zc;
	int			 rc = 0;

	dmu_tx_hold_free(tx, oid, 0, DMU_OBJECT_END);

	/* zap holding xattrs */
	if (obj->oo_xattr != ZFS_NO_OBJECT) {
		oid = obj->oo_xattr;

		dmu_tx_hold_free(tx, oid, 0, DMU_OBJECT_END);

		rc = -udmu_zap_cursor_init(&zc, uos, oid, 0);
		if (rc)
			goto out;

		while ((rc = -zap_cursor_retrieve(zc, za)) == 0) {
			BUG_ON(za->za_integer_length != sizeof(uint64_t));
			BUG_ON(za->za_num_integers != 1);

			rc = -zap_lookup(uos->os, obj->oo_xattr, za->za_name,
					 sizeof(uint64_t), 1, &xid);
			if (rc) {
				CERROR("%s: xattr lookup failed: rc = %d\n",
				       osd->od_svname, rc);
				goto out_err;
			}
			dmu_tx_hold_free(tx, xid, 0, DMU_OBJECT_END);

			zap_cursor_advance(zc);
		}
		if (rc == -ENOENT)
			rc = 0;
out_err:
		udmu_zap_cursor_fini(zc);
	}
out:
	if (rc && tx->tx_err == 0)
		tx->tx_err = -rc;
}
Esempio n. 7
0
/*
 * Delete a DMU object
 *
 * The transaction passed to this routine must have
 * dmu_tx_hold_free(tx, oid, 0, DMU_OBJECT_END) called
 * and then assigned to a transaction group.
 *
 * This will release db and set it to NULL to prevent further dbuf releases.
 */
static int __osd_object_destroy(const struct lu_env *env,
				struct osd_object *obj,
				dmu_tx_t *tx, void *tag)
{
	struct osd_device	*osd = osd_obj2dev(obj);
	udmu_objset_t		*uos = &osd->od_objset;
	uint64_t		 xid;
	zap_attribute_t		*za = &osd_oti_get(env)->oti_za;
	zap_cursor_t		*zc;
	int			 rc;

	/* Assert that the transaction has been assigned to a
	   transaction group. */
	LASSERT(tx->tx_txg != 0);

	/* zap holding xattrs */
	if (obj->oo_xattr != ZFS_NO_OBJECT) {
		rc = -udmu_zap_cursor_init(&zc, uos, obj->oo_xattr, 0);
		if (rc)
			return rc;
		while ((rc = -zap_cursor_retrieve(zc, za)) == 0) {
			BUG_ON(za->za_integer_length != sizeof(uint64_t));
			BUG_ON(za->za_num_integers != 1);

			rc = -zap_lookup(uos->os, obj->oo_xattr, za->za_name,
					 sizeof(uint64_t), 1, &xid);
			if (rc) {
				CERROR("%s: lookup xattr %s failed: rc = %d\n",
				       osd->od_svname, za->za_name, rc);
				continue;
			}
			rc = __osd_object_free(uos, xid, tx);
			if (rc)
				CERROR("%s: fetch xattr %s failed: rc = %d\n",
				       osd->od_svname, za->za_name, rc);
			zap_cursor_advance(zc);
		}
		udmu_zap_cursor_fini(zc);

		rc = __osd_object_free(uos, obj->oo_xattr, tx);
		if (rc)
			CERROR("%s: freeing xattr failed: rc = %d\n",
			       osd->od_svname, rc);
	}

	return __osd_object_free(uos, obj->oo_db->db_object, tx);
}
Esempio n. 8
0
/**
 *  Move Iterator to record specified by \a key
 *
 *  \param  di      osd iterator
 *  \param  key     key for index
 *
 *  \retval +ve  di points to record with least key not larger than key
 *  \retval  0   di points to exact matched key
 *  \retval -ve  failure
 */
static int osd_dir_it_get(const struct lu_env *env,
			  struct dt_it *di, const struct dt_key *key)
{
	struct osd_zap_it *it = (struct osd_zap_it *)di;
	struct osd_object *obj = it->ozi_obj;
	struct osd_device *osd = osd_obj2dev(obj);
	char		  *name = (char *)key;
	int		   rc;
	ENTRY;

	LASSERT(it);
	LASSERT(it->ozi_zc);

	udmu_zap_cursor_fini(it->ozi_zc);

	if (udmu_zap_cursor_init(&it->ozi_zc, &osd->od_objset,
				 obj->oo_db->db_object, 0))
		RETURN(-ENOMEM);

	/* XXX: implementation of the API is broken at the moment */
	LASSERT(((const char *)key)[0] == 0);

	if (name[0] == 0) {
		it->ozi_pos = 0;
		RETURN(1);
	}

	if (name[0] == '.') {
		if (name[1] == 0) {
			it->ozi_pos = 1;
			GOTO(out, rc = 1);
		} else if (name[1] == '.' && name[2] == 0) {
			it->ozi_pos = 2;
			GOTO(out, rc = 1);
		}
	}

	/* neither . nor .. - some real record */
	it->ozi_pos = 3;
	rc = +1;

out:
	RETURN(rc);
}
Esempio n. 9
0
static int osd_zap_it_get(const struct lu_env *env,
			  struct dt_it *di, const struct dt_key *key)
{
	struct osd_zap_it *it = (struct osd_zap_it *)di;
	struct osd_object *obj = it->ozi_obj;
	struct osd_device *osd = osd_obj2dev(obj);
	ENTRY;

	LASSERT(it);
	LASSERT(it->ozi_zc);

	/* XXX: API is broken at the moment */
	LASSERT(((const char *)key)[0] == '\0');

	udmu_zap_cursor_fini(it->ozi_zc);
	if (udmu_zap_cursor_init(&it->ozi_zc, &osd->od_objset,
				 obj->oo_db->db_object, 0))
		RETURN(-ENOMEM);

	it->ozi_reset = 1;

	RETURN(+1);
}
Esempio n. 10
0
/**
 * Restore iterator from cookie. if the \a hash isn't found,
 * restore the first valid record.
 *
 * \param  di    - osd iterator
 * \param  hash  - iterator location cookie
 *
 * \retval +ve  - di points to exact matched key
 * \retval  0   - di points to the first valid record
 * \retval -ve  - failure
 */
static int osd_it_acct_load(const struct lu_env *env,
			    const struct dt_it *di, __u64 hash)
{
	struct osd_it_quota	*it  = (struct osd_it_quota *)di;
	struct osd_device	*osd = osd_obj2dev(it->oiq_obj);
	zap_cursor_t		*zc;
	int			 rc;
	ENTRY;

	/* create new cursor pointing to the new hash */
	rc = -udmu_zap_cursor_init(&zc, &osd->od_objset, it->oiq_oid, hash);
	if (rc)
		RETURN(rc);
	udmu_zap_cursor_fini(it->oiq_zc);
	it->oiq_zc = zc;
	it->oiq_reset = 0;

	rc = -udmu_zap_cursor_retrieve_key(env, it->oiq_zc, NULL, 32);
	if (rc == 0)
		RETURN(+1);
	else if (rc == -ENOENT)
		RETURN(0);
	RETURN(rc);
}