Esempio n. 1
0
/**
 * Copy an extended attribute into the buffer provided, or compute
 * the required buffer size if \a buf is NULL.
 *
 * On success, the number of bytes used or required is stored in \a sizep.
 *
 * Note that no locking is done here.
 *
 * \param[in] env      execution environment
 * \param[in] obj      object for which to retrieve xattr
 * \param[out] buf     buffer to store xattr value in
 * \param[in] name     name of xattr to copy
 * \param[out] sizep   bytes used or required to store xattr
 *
 * \retval 0           on success
 * \retval negative    negated errno on failure
 */
int __osd_xattr_get(const struct lu_env *env, struct osd_object *obj,
		    struct lu_buf *buf, const char *name, int *sizep)
{
	int rc;

	/* check SA_ZPL_DXATTR first then fallback to directory xattr */
	rc = __osd_sa_xattr_get(env, obj, buf, name, sizep);
	if (rc != -ENOENT)
		return rc;

	return __osd_xattr_get_large(env, osd_obj2dev(obj), obj->oo_xattr,
				     buf, name, sizep);
}
Esempio n. 2
0
int __osd_xattr_get(const struct lu_env *env, struct osd_object *obj,
		struct lu_buf *buf, const char *name, int *sizep)
{
	struct osd_device *osd = osd_obj2dev(obj);
	udmu_objset_t     *uos = &osd->od_objset;
	uint64_t           xa_data_obj;
	dmu_buf_t         *xa_data_db;
	sa_handle_t       *sa_hdl = NULL;
	uint64_t           size;
	int                rc;

	/* check SA_ZPL_DXATTR first then fallback to directory xattr */
	rc = __osd_sa_xattr_get(env, obj, buf, name, sizep);
	if (rc != -ENOENT)
		return rc;

	/* are there any extended attributes? */
	if (obj->oo_xattr == ZFS_NO_OBJECT)
		return -ENOENT;

	/* Lookup the object number containing the xattr data */
	rc = -zap_lookup(uos->os, obj->oo_xattr, name, sizeof(uint64_t), 1,
			&xa_data_obj);
	if (rc)
		return rc;

	rc = __osd_obj2dbuf(env, uos->os, xa_data_obj, &xa_data_db, FTAG);
	if (rc)
		return rc;

	rc = -sa_handle_get(uos->os, xa_data_obj, NULL, SA_HDL_PRIVATE,
			&sa_hdl);
	if (rc)
		goto out_rele;

	/* Get the xattr value length / object size */
	rc = -sa_lookup(sa_hdl, SA_ZPL_SIZE(uos), &size, 8);
	if (rc)
		goto out;

	if (size > INT_MAX) {
		rc = -EOVERFLOW;
		goto out;
	}

	*sizep = (int)size;

	if (buf == NULL || buf->lb_buf == NULL) {
		/* We only need to return the required size */
		goto out;
	}
	if (*sizep > buf->lb_len) {
		rc = -ERANGE; /* match ldiskfs error */
		goto out;
	}

	rc = -dmu_read(uos->os, xa_data_db->db_object, 0,
			size, buf->lb_buf, DMU_READ_PREFETCH);

out:
	sa_handle_destroy(sa_hdl);
out_rele:
	dmu_buf_rele(xa_data_db, FTAG);
	return rc;
}