Ejemplo n.º 1
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);
}
Ejemplo n.º 2
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);

}
Ejemplo n.º 3
0
/**
 * Return pointer to the record under iterator.
 *
 * \param  di    - osd iterator
 * \param  attr  - not used
 */
static int osd_it_acct_rec(const struct lu_env *env,
			   const struct dt_it *di,
			   struct dt_rec *dtrec, __u32 attr)
{
	struct osd_thread_info	*info = osd_oti_get(env);
	char			*buf  = info->oti_buf;
	struct osd_it_quota	*it = (struct osd_it_quota *)di;
	struct lquota_acct_rec	*rec  = (struct lquota_acct_rec *)dtrec;
	struct osd_object	*obj = it->oiq_obj;
	struct osd_device	*osd = osd_obj2dev(obj);
	int			 bytes_read;
	int			 rc;
	ENTRY;

	it->oiq_reset = 0;
	rec->ispace = rec->bspace = 0;

	/* retrieve block usage from the DMU accounting object */
	rc = -udmu_zap_cursor_retrieve_value(env, it->oiq_zc,
					     (char *)&rec->bspace,
					     sizeof(uint64_t), &bytes_read);
	if (rc)
		RETURN(rc);

	if (osd->od_quota_iused_est) {
		if (rec->bspace != 0)
			/* estimate #inodes in use */
			rec->ispace = udmu_objset_user_iused(&osd->od_objset,
							     rec->bspace);
		RETURN(0);
	}

	/* retrieve key associated with the current cursor */
	rc = -udmu_zap_cursor_retrieve_key(env, it->oiq_zc, buf, 32);
	if (rc)
		RETURN(rc);

	/* inode accounting is not maintained by DMU, so we use our own ZAP to
	 * track inode usage */
	rc = -zap_lookup(osd->od_objset.os, it->oiq_obj->oo_db->db_object,
			 buf, sizeof(uint64_t), 1, &rec->ispace);
	if (rc == -ENOENT)
		/* user/group has not created any file yet */
		CDEBUG(D_QUOTA, "%s: id %s not found in accounting ZAP\n",
		       osd->od_svname, buf);
	else if (rc)
		RETURN(rc);

	RETURN(0);
}
Ejemplo n.º 4
0
/**
 * Move on to the next valid entry.
 *
 * \param  di   - osd iterator
 *
 * \retval +ve  - iterator reached the end
 * \retval   0  - iterator has not reached the end yet
 * \retval -ve  - unexpected failure
 */
static int osd_it_acct_next(const struct lu_env *env, struct dt_it *di)
{
	struct osd_it_quota	*it = (struct osd_it_quota *)di;
	int			 rc;
	ENTRY;

	if (it->oiq_reset == 0)
		zap_cursor_advance(it->oiq_zc);
	it->oiq_reset = 0;
	rc = -udmu_zap_cursor_retrieve_key(env, it->oiq_zc, NULL, 32);
	if (rc == -ENOENT) /* reached the end */
		RETURN(+1);
	RETURN(rc);
}
Ejemplo n.º 5
0
static int osd_zap_it_key_size(const struct lu_env *env, const struct dt_it *di)
{
	struct osd_zap_it *it = (struct osd_zap_it *)di;
	int                rc;
	ENTRY;

	it->ozi_reset = 0;
	rc = -udmu_zap_cursor_retrieve_key(env, it->ozi_zc, it->ozi_name,
					   NAME_MAX + 1);
	if (!rc)
		RETURN(strlen(it->ozi_name));
	else
		RETURN(rc);
}
Ejemplo n.º 6
0
static struct dt_key *osd_zap_it_key(const struct lu_env *env,
					const struct dt_it *di)
{
	struct osd_zap_it *it = (struct osd_zap_it *)di;
	int                rc = 0;
	ENTRY;

	it->ozi_reset = 0;
	rc = -udmu_zap_cursor_retrieve_key(env, it->ozi_zc, it->ozi_name,
					   NAME_MAX + 1);
	if (!rc)
		RETURN((struct dt_key *)it->ozi_name);
	else
		RETURN(ERR_PTR(rc));
}
Ejemplo n.º 7
0
/**
 * Return pointer to the key under iterator.
 *
 * \param  di   - osd iterator
 */
static struct dt_key *osd_it_acct_key(const struct lu_env *env,
				      const struct dt_it *di)
{
	struct osd_it_quota	*it = (struct osd_it_quota *)di;
	struct osd_thread_info	*info = osd_oti_get(env);
	char			*buf  = info->oti_buf;
	char			*p;
	int			 rc;
	ENTRY;

	it->oiq_reset = 0;
	rc = -udmu_zap_cursor_retrieve_key(env, it->oiq_zc, buf, 32);
	if (rc)
		RETURN(ERR_PTR(rc));
	it->oiq_id = simple_strtoull(buf, &p, 16);
	RETURN((struct dt_key *) &it->oiq_id);
}
Ejemplo n.º 8
0
/**
 * to load a directory entry at a time and stored it in
 * iterator's in-memory data structure.
 *
 * \param di, struct osd_it_ea, iterator's in memory structure
 *
 * \retval +ve, iterator reached to end
 * \retval   0, iterator not reached to end
 * \retval -ve, on error
 */
static int osd_zap_it_next(const struct lu_env *env, struct dt_it *di)
{
	struct osd_zap_it *it = (struct osd_zap_it *)di;
	int                rc;
	ENTRY;

	if (it->ozi_reset == 0)
		zap_cursor_advance(it->ozi_zc);
	it->ozi_reset = 0;

	/*
	 * According to current API we need to return error if its last entry.
	 * zap_cursor_advance() does return any value. So we need to call
	 * retrieve to check if there is any record.  We should make
	 * changes to Iterator API to not return status for this API
	 */
	rc = -udmu_zap_cursor_retrieve_key(env, it->ozi_zc, NULL, NAME_MAX);
	if (rc == -ENOENT) /* end of dir*/
		RETURN(+1);

	RETURN((rc));
}
Ejemplo n.º 9
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);
}