Пример #1
0
static dmu_buf_t* osd_mkreg(const struct lu_env *env, struct osd_device *osd,
			    struct lu_attr *la, struct osd_thandle *oh)
{
	dmu_buf_t *db;
	int	    rc;

	LASSERT(S_ISREG(la->la_mode));
	rc = __osd_object_create(env, &osd->od_objset, &db, oh->ot_tx, la,
				 osd_obj_tag);
	if (rc)
		return ERR_PTR(rc);

	/*
	 * XXX: a hack, OST to use bigger blocksize. we need
	 * a method in OSD API to control this from OFD/MDD
	 */
	if (!lu_device_is_md(osd2lu_dev(osd))) {
		rc = -dmu_object_set_blocksize(osd->od_objset.os,
					       db->db_object,
				128 << 10, 0, oh->ot_tx);
		if (unlikely(rc)) {
			CERROR("%s: can't change blocksize: %d\n",
			       osd->od_svname, rc);
			return ERR_PTR(rc);
		}
	}

	return db;
}
Пример #2
0
static dmu_buf_t *osd_mkreg(const struct lu_env *env, struct osd_object *obj,
			    struct lu_attr *la, struct osd_thandle *oh)
{
	const struct lu_fid *fid = lu_object_fid(&obj->oo_dt.do_lu);
	dmu_buf_t	    *db;
	int		     rc;
	struct osd_device *osd = osd_obj2dev(obj);

	LASSERT(S_ISREG(la->la_mode));
	rc = __osd_object_create(env, obj, &db, oh->ot_tx, la);
	if (rc)
		return ERR_PTR(rc);

	if ((fid_is_idif(fid) || fid_is_norm(fid) || fid_is_echo(fid)) &&
	    osd->od_is_ost) {
		/* The minimum block size must be at least page size otherwise
		 * it will break the assumption in tgt_thread_big_cache where
		 * the array size is PTLRPC_MAX_BRW_PAGES. It will also affect
		 * RDMA due to subpage transfer size */
		rc = -dmu_object_set_blocksize(osd->od_os, db->db_object,
					       PAGE_SIZE, 0, oh->ot_tx);
		if (unlikely(rc)) {
			CERROR("%s: can't change blocksize: %d\n",
			       osd->od_svname, rc);
			return ERR_PTR(rc);
		}
	}

	return db;
}
Пример #3
0
static dmu_buf_t *osd_mkreg(const struct lu_env *env, struct osd_object *obj,
			    struct lu_attr *la, uint64_t parent,
			    struct osd_thandle *oh)
{
	dmu_buf_t	  *db;
	int		   rc;
	struct osd_device *osd = osd_obj2dev(obj);

	LASSERT(S_ISREG(la->la_mode));
	rc = __osd_object_create(env, obj, &db, oh->ot_tx, la, parent);
	if (rc)
		return ERR_PTR(rc);

	/*
	 * XXX: This heuristic is non-optimal.  It would be better to
	 * increase the blocksize up to osd->od_max_blksz during the write.
	 * This is exactly how the ZPL behaves and it ensures that the right
	 * blocksize is selected based on the file size rather than the
	 * making broad assumptions based on the osd type.
	 */
	if (!lu_device_is_md(osd2lu_dev(osd))) {
		rc = -dmu_object_set_blocksize(osd->od_os, db->db_object,
					       osd->od_max_blksz, 0, oh->ot_tx);
		if (unlikely(rc)) {
			CERROR("%s: can't change blocksize: %d\n",
			       osd->od_svname, rc);
			return ERR_PTR(rc);
		}
	}

	return db;
}
Пример #4
0
static dmu_buf_t *osd_mkreg(const struct lu_env *env, struct osd_object *obj,
			    struct lu_attr *la, uint64_t parent,
			    struct osd_thandle *oh)
{
	dmu_buf_t	  *db;
	int		   rc;
	struct osd_device *osd = osd_obj2dev(obj);

	LASSERT(S_ISREG(la->la_mode));
	rc = __osd_object_create(env, obj, &db, oh->ot_tx, la, parent);
	if (rc)
		return ERR_PTR(rc);

	if (!lu_device_is_md(osd2lu_dev(osd))) {
		/* uses 4K as default block size because clients write data
		 * with page size that is 4K at minimum */
		rc = -dmu_object_set_blocksize(osd->od_os, db->db_object,
					       4096, 0, oh->ot_tx);
		if (unlikely(rc)) {
			CERROR("%s: can't change blocksize: %d\n",
			       osd->od_svname, rc);
			return ERR_PTR(rc);
		}
	}

	return db;
}
Пример #5
0
static dmu_buf_t *osd_mksym(const struct lu_env *env, struct osd_object *obj,
			    struct lu_attr *la, struct osd_thandle *oh)
{
	dmu_buf_t *db;
	int	   rc;

	LASSERT(S_ISLNK(la->la_mode));
	rc = __osd_object_create(env, obj, &db, oh->ot_tx, la);
	if (rc)
		return ERR_PTR(rc);
	return db;
}
Пример #6
0
static dmu_buf_t *osd_mknod(const struct lu_env *env, struct osd_object *obj,
			    struct lu_attr *la, struct osd_thandle *oh)
{
	dmu_buf_t *db;
	int	   rc;

	if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode))
		la->la_valid |= LA_RDEV;

	rc = __osd_object_create(env, obj, &db, oh->ot_tx, la);
	if (rc)
		return ERR_PTR(rc);
	return db;
}
Пример #7
0
static dmu_buf_t *osd_mknod(const struct lu_env *env, struct osd_device *osd,
			    struct lu_attr *la, struct osd_thandle *oh)
{
	dmu_buf_t *db;
	int	   rc;

	la->la_valid = LA_MODE;
	if (S_ISCHR(la->la_mode) || S_ISBLK(la->la_mode))
		la->la_valid |= LA_RDEV;

	rc = __osd_object_create(env, &osd->od_objset, &db, oh->ot_tx, la,
				 osd_obj_tag);
	if (rc)
		return ERR_PTR(rc);
	return db;
}
Пример #8
0
int
__osd_xattr_set(const struct lu_env *env, struct osd_object *obj,
		const struct lu_buf *buf, const char *name, int fl,
		struct osd_thandle *oh)
{
	struct osd_device *osd = osd_obj2dev(obj);
	dmu_buf_t         *xa_zap_db = NULL;
	dmu_buf_t         *xa_data_db = NULL;
	uint64_t           xa_data_obj;
	sa_handle_t       *sa_hdl = NULL;
	dmu_tx_t          *tx = oh->ot_tx;
	uint64_t           size;
	int                rc;

	LASSERT(obj->oo_sa_hdl);

	if (obj->oo_xattr == ZFS_NO_OBJECT) {
		struct lu_attr *la = &osd_oti_get(env)->oti_la;

		la->la_valid = LA_MODE;
		la->la_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO;
		rc = __osd_zap_create(env, osd, &xa_zap_db, tx, la,
				      obj->oo_db->db_object, 0);
		if (rc)
			return rc;

		obj->oo_xattr = xa_zap_db->db_object;
		rc = osd_object_sa_update(obj, SA_ZPL_XATTR(osd),
				&obj->oo_xattr, 8, oh);
		if (rc)
			goto out;
	}

	rc = -zap_lookup(osd->od_os, obj->oo_xattr, name, sizeof(uint64_t), 1,
			 &xa_data_obj);
	if (rc == 0) {
		if (fl & LU_XATTR_CREATE) {
			rc = -EEXIST;
			goto out;
		}
		/*
		 * Entry already exists.
		 * We'll truncate the existing object.
		 */
		rc = __osd_obj2dbuf(env, osd->od_os, xa_data_obj,
					&xa_data_db);
		if (rc)
			goto out;

		rc = -sa_handle_get(osd->od_os, xa_data_obj, NULL,
					SA_HDL_PRIVATE, &sa_hdl);
		if (rc)
			goto out;

		rc = -sa_lookup(sa_hdl, SA_ZPL_SIZE(osd), &size, 8);
		if (rc)
			goto out_sa;

		rc = -dmu_free_range(osd->od_os, xa_data_db->db_object,
				     0, DMU_OBJECT_END, tx);
		if (rc)
			goto out_sa;
	} else if (rc == -ENOENT) {
		struct lu_attr *la = &osd_oti_get(env)->oti_la;
		/*
		 * Entry doesn't exist, we need to create a new one and a new
		 * object to store the value.
		 */
		if (fl & LU_XATTR_REPLACE) {
			/* should be ENOATTR according to the
			 * man, but that is undefined here */
			rc = -ENODATA;
			goto out;
		}

		la->la_valid = LA_MODE;
		la->la_mode = S_IFREG | S_IRUGO | S_IWUSR;
		rc = __osd_object_create(env, obj, &xa_data_db, tx, la,
					 obj->oo_xattr);
		if (rc)
			goto out;
		xa_data_obj = xa_data_db->db_object;

		rc = -sa_handle_get(osd->od_os, xa_data_obj, NULL,
					SA_HDL_PRIVATE, &sa_hdl);
		if (rc)
			goto out;

		rc = -zap_add(osd->od_os, obj->oo_xattr, name, sizeof(uint64_t),
				1, &xa_data_obj, tx);
		if (rc)
			goto out_sa;
	} else {
		/* There was an error looking up the xattr name */
		goto out;
	}

	/* Finally write the xattr value */
	dmu_write(osd->od_os, xa_data_obj, 0, buf->lb_len, buf->lb_buf, tx);

	size = buf->lb_len;
	rc = -sa_update(sa_hdl, SA_ZPL_SIZE(osd), &size, 8, tx);

out_sa:
	sa_handle_destroy(sa_hdl);
out:
	if (xa_data_db != NULL)
		dmu_buf_rele(xa_data_db, FTAG);
	if (xa_zap_db != NULL)
		dmu_buf_rele(xa_zap_db, FTAG);

	return rc;
}