/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved
* Use is subject to license terms.
+ *
+ * Copyright (c) 2012, Intel Corporation.
*/
/*
* lustre/lod/lod_lov.c
*/
void lod_getref(struct lod_device *lod)
{
- cfs_down_read(&lod->lod_rw_sem);
- cfs_mutex_lock(&lod->lod_mutex);
+ down_read(&lod->lod_rw_sem);
+ mutex_lock(&lod->lod_mutex);
lod->lod_refcount++;
- cfs_mutex_unlock(&lod->lod_mutex);
+ mutex_unlock(&lod->lod_mutex);
}
/*
*/
void lod_putref(struct lod_device *lod)
{
- cfs_mutex_lock(&lod->lod_mutex);
+ mutex_lock(&lod->lod_mutex);
lod->lod_refcount--;
if (lod->lod_refcount == 0 && lod->lod_death_row) {
struct lod_ost_desc *ost_desc, *tmp;
lod->lod_desc.ld_active_tgt_count--;
lod->lod_death_row--;
}
- cfs_mutex_unlock(&lod->lod_mutex);
- cfs_up_read(&lod->lod_rw_sem);
+ mutex_unlock(&lod->lod_mutex);
+ up_read(&lod->lod_rw_sem);
cfs_list_for_each_entry_safe(ost_desc, tmp, &kill, ltd_kill) {
int rc;
cfs_list_del(&ost_desc->ltd_kill);
- /* XXX: remove from QoS structures */
- /* disconnect from OSP */
+ /* remove from QoS structures */
+ rc = qos_del_tgt(lod, ost_desc);
+ if (rc)
+ CERROR("%s: qos_del_tgt(%s) failed: rc = %d\n",
+ lod2obd(lod)->obd_name,
+ obd_uuid2str(&ost_desc->ltd_uuid), rc);
rc = obd_disconnect(ost_desc->ltd_exp);
if (rc)
- CERROR("%s: failed to disconnect %s (%d)\n",
+ CERROR("%s: failed to disconnect %s: rc = %d\n",
lod2obd(lod)->obd_name,
obd_uuid2str(&ost_desc->ltd_uuid), rc);
OBD_FREE_PTR(ost_desc);
}
} else {
- cfs_mutex_unlock(&lod->lod_mutex);
- cfs_up_read(&lod->lod_rw_sem);
+ mutex_unlock(&lod->lod_mutex);
+ up_read(&lod->lod_rw_sem);
}
}
/* grab write reference on the lod. Relocating the array requires
* exclusive access */
- cfs_down_write(&lod->lod_rw_sem);
+ down_write(&lod->lod_rw_sem);
if (newsize <= lod->lod_osts_size)
/* someone else has already resize the array */
EXIT;
out:
- cfs_up_write(&lod->lod_rw_sem);
+ up_write(&lod->lod_rw_sem);
return rc;
}
lod_getref(lod);
}
- cfs_mutex_lock(&lod->lod_mutex);
+ mutex_lock(&lod->lod_mutex);
if (cfs_bitmap_check(lod->lod_ost_bitmap, index)) {
CERROR("%s: device %d is registered already\n", obd->obd_name,
index);
GOTO(out_mutex, rc);
}
+ rc = qos_add_tgt(lod, ost_desc);
+ if (rc) {
+ CERROR("%s: qos_add_tgt(%s) failed: rc = %d\n", obd->obd_name,
+ obd_uuid2str(&ost_desc->ltd_uuid), rc);
+ GOTO(out_pool, rc);
+ }
+
/* The new OST is now a full citizen */
if (index >= lod->lod_desc.ld_tgt_count)
lod->lod_desc.ld_tgt_count = index + 1;
OST_TGT(lod, index) = ost_desc;
cfs_bitmap_set(lod->lod_ost_bitmap, index);
lod->lod_ostnr++;
- cfs_mutex_unlock(&lod->lod_mutex);
+ mutex_unlock(&lod->lod_mutex);
lod_putref(lod);
if (lod->lod_recovery_completed)
RETURN(0);
+out_pool:
lod_ost_pool_remove(&lod->lod_pool_info, index);
out_mutex:
- cfs_mutex_unlock(&lod->lod_mutex);
+ mutex_unlock(&lod->lod_mutex);
lod_putref(lod);
out_desc:
OBD_FREE_PTR(ost_desc);
obd_str2uuid(&uuid, osp);
lod_getref(lod);
- cfs_mutex_lock(&lod->lod_mutex);
+ mutex_lock(&lod->lod_mutex);
/* check that the index is allocated in the bitmap */
if (!cfs_bitmap_check(lod->lod_ost_bitmap, idx) || !OST_TGT(lod,idx)) {
CERROR("%s: device %d is not set up\n", obd->obd_name, idx);
__lod_del_device(lod, idx);
EXIT;
out:
- cfs_mutex_unlock(&lod->lod_mutex);
+ mutex_unlock(&lod->lod_mutex);
lod_putref(lod);
return(rc);
}
RETURN(0);
}
+/*
+ * generate and write LOV EA for given striped object
+ */
+int lod_generate_and_set_lovea(const struct lu_env *env,
+ struct lod_object *lo, struct thandle *th)
+{
+ struct lod_thread_info *info = lod_env_info(env);
+ struct dt_object *next = dt_object_child(&lo->ldo_obj);
+ const struct lu_fid *fid = lu_object_fid(&lo->ldo_obj.do_lu);
+ struct lov_mds_md_v1 *lmm;
+ struct lov_ost_data_v1 *objs;
+ __u32 magic;
+ int i, rc, lmm_size;
+ ENTRY;
+
+ LASSERT(lo);
+ LASSERT(lo->ldo_stripenr > 0);
+
+ magic = lo->ldo_pool ? LOV_MAGIC_V3 : LOV_MAGIC_V1;
+ lmm_size = lov_mds_md_size(lo->ldo_stripenr, magic);
+ if (info->lti_ea_store_size < lmm_size) {
+ rc = lod_ea_store_resize(info, lmm_size);
+ if (rc)
+ RETURN(rc);
+ }
+
+ lmm = info->lti_ea_store;
+
+ lmm->lmm_magic = cpu_to_le32(magic);
+ lmm->lmm_pattern = cpu_to_le32(LOV_PATTERN_RAID0);
+ lmm->lmm_object_id = cpu_to_le64(fid_ver_oid(fid));
+ lmm->lmm_object_seq = cpu_to_le64(fid_seq(fid));
+ lmm->lmm_stripe_size = cpu_to_le32(lo->ldo_stripe_size);
+ lmm->lmm_stripe_count = cpu_to_le16(lo->ldo_stripenr);
+ lmm->lmm_layout_gen = 0;
+ if (magic == LOV_MAGIC_V1) {
+ objs = &lmm->lmm_objects[0];
+ } else {
+ struct lov_mds_md_v3 *v3 = (struct lov_mds_md_v3 *) lmm;
+ strncpy(v3->lmm_pool_name, lo->ldo_pool, LOV_MAXPOOLNAME);
+ objs = &v3->lmm_objects[0];
+ }
+
+ for (i = 0; i < lo->ldo_stripenr; i++) {
+ const struct lu_fid *fid;
+
+ LASSERT(lo->ldo_stripe[i]);
+ fid = lu_object_fid(&lo->ldo_stripe[i]->do_lu);
+
+ rc = fid_ostid_pack(fid, &info->lti_ostid);
+ LASSERT(rc == 0);
+ LASSERT(info->lti_ostid.oi_seq == FID_SEQ_OST_MDT0);
+
+ objs[i].l_object_id = cpu_to_le64(info->lti_ostid.oi_id);
+ objs[i].l_object_seq = cpu_to_le64(info->lti_ostid.oi_seq);
+ objs[i].l_ost_gen = cpu_to_le32(0);
+ objs[i].l_ost_idx = cpu_to_le32(fid_idif_ost_idx(fid));
+ }
+
+ info->lti_buf.lb_buf = lmm;
+ info->lti_buf.lb_len = lmm_size;
+ rc = dt_xattr_set(env, next, &info->lti_buf, XATTR_NAME_LOV, 0,
+ th, BYPASS_CAPA);
+
+ RETURN(rc);
+}
+
int lod_get_lov_ea(const struct lu_env *env, struct lod_object *lo)
{
struct lod_thread_info *info = lod_env_info(env);
RETURN(rc);
}
+int lod_store_def_striping(const struct lu_env *env, struct dt_object *dt,
+ struct thandle *th)
+{
+ struct lod_thread_info *info = lod_env_info(env);
+ struct lod_object *lo = lod_dt_obj(dt);
+ struct dt_object *next = dt_object_child(dt);
+ struct lov_user_md_v3 *v3;
+ int rc;
+ ENTRY;
+
+ LASSERT(S_ISDIR(dt->do_lu.lo_header->loh_attr));
+
+ /*
+ * store striping defaults into new directory
+ * used to implement defaults inheritance
+ */
+
+ /* probably nothing to inherite */
+ if (lo->ldo_striping_cached == 0)
+ RETURN(0);
+
+ if (LOVEA_DELETE_VALUES(lo->ldo_def_stripe_size, lo->ldo_def_stripenr,
+ lo->ldo_def_stripe_offset))
+ RETURN(0);
+
+ /* XXX: use thread info */
+ OBD_ALLOC_PTR(v3);
+ if (v3 == NULL)
+ RETURN(-ENOMEM);
+
+ v3->lmm_magic = cpu_to_le32(LOV_MAGIC_V3);
+ v3->lmm_pattern = cpu_to_le32(LOV_PATTERN_RAID0);
+ v3->lmm_object_id = 0;
+ v3->lmm_object_seq = 0;
+ v3->lmm_stripe_size = cpu_to_le32(lo->ldo_def_stripe_size);
+ v3->lmm_stripe_count = cpu_to_le16(lo->ldo_def_stripenr);
+ v3->lmm_stripe_offset = cpu_to_le16(lo->ldo_def_stripe_offset);
+ if (lo->ldo_pool)
+ strncpy(v3->lmm_pool_name, lo->ldo_pool, LOV_MAXPOOLNAME);
+
+ info->lti_buf.lb_buf = v3;
+ info->lti_buf.lb_len = sizeof(*v3);
+ rc = dt_xattr_set(env, next, &info->lti_buf, XATTR_NAME_LOV, 0, th,
+ BYPASS_CAPA);
+
+ OBD_FREE_PTR(v3);
+
+ RETURN(rc);
+}
+
/*
* allocate array of objects pointers, find/create objects
* stripenr and other fields should be initialized by this moment
RETURN(rc);
}
+int lod_verify_striping(struct lod_device *d, const struct lu_buf *buf,
+ int specific)
+{
+ struct lov_user_md_v1 *lum;
+ struct lov_user_md_v3 *v3 = NULL;
+ struct pool_desc *pool = NULL;
+ int rc;
+ ENTRY;
+
+ lum = buf->lb_buf;
+
+ if (lum->lmm_magic != LOV_USER_MAGIC_V1 &&
+ lum->lmm_magic != LOV_USER_MAGIC_V3 &&
+ lum->lmm_magic != LOV_MAGIC_V1_DEF &&
+ lum->lmm_magic != LOV_MAGIC_V3_DEF) {
+ CDEBUG(D_IOCTL, "bad userland LOV MAGIC: %#x\n",
+ lum->lmm_magic);
+ RETURN(-EINVAL);
+ }
+
+ if ((specific && lum->lmm_pattern != LOV_PATTERN_RAID0) ||
+ (specific == 0 && lum->lmm_pattern != 0)) {
+ CDEBUG(D_IOCTL, "bad userland stripe pattern: %#x\n",
+ lum->lmm_pattern);
+ RETURN(-EINVAL);
+ }
+
+ /* 64kB is the largest common page size we see (ia64), and matches the
+ * check in lfs */
+ if (lum->lmm_stripe_size & (LOV_MIN_STRIPE_SIZE - 1)) {
+ CDEBUG(D_IOCTL, "stripe size %u not multiple of %u, fixing\n",
+ lum->lmm_stripe_size, LOV_MIN_STRIPE_SIZE);
+ RETURN(-EINVAL);
+ }
+
+ /* an offset of -1 is treated as a "special" valid offset */
+ if (lum->lmm_stripe_offset != (typeof(lum->lmm_stripe_offset))(-1)) {
+ /* if offset is not within valid range [0, osts_size) */
+ if (lum->lmm_stripe_offset >= d->lod_osts_size) {
+ CDEBUG(D_IOCTL, "stripe offset %u >= bitmap size %u\n",
+ lum->lmm_stripe_offset, d->lod_osts_size);
+ RETURN(-EINVAL);
+ }
+
+ /* if lmm_stripe_offset is *not* in bitmap */
+ if (!cfs_bitmap_check(d->lod_ost_bitmap,
+ lum->lmm_stripe_offset)) {
+ CDEBUG(D_IOCTL, "stripe offset %u not in bitmap\n",
+ lum->lmm_stripe_offset);
+ RETURN(-EINVAL);
+ }
+ }
+
+ if (lum->lmm_magic == LOV_USER_MAGIC_V3)
+ v3 = buf->lb_buf;
+
+ if (v3)
+ pool = lod_find_pool(d, v3->lmm_pool_name);
+
+ if (pool != NULL) {
+ __u16 offs = v3->lmm_stripe_offset;
+
+ if (offs != (typeof(v3->lmm_stripe_offset))(-1)) {
+ rc = lod_check_index_in_pool(offs, pool);
+ if (rc < 0) {
+ lod_pool_putref(pool);
+ RETURN(-EINVAL);
+ }
+ }
+
+ if (specific && lum->lmm_stripe_count > pool_tgt_count(pool)) {
+ CDEBUG(D_IOCTL,
+ "stripe count %u > # OSTs %u in the pool\n",
+ lum->lmm_stripe_count, pool_tgt_count(pool));
+ lod_pool_putref(pool);
+ RETURN(-EINVAL);
+ }
+
+ lod_pool_putref(pool);
+ }
+
+ RETURN(0);
+}
+
void lod_fix_desc_stripe_size(__u64 *val)
{
if (*val < PTLRPC_MAX_BRW_SIZE) {
int lod_pools_init(struct lod_device *lod, struct lustre_cfg *lcfg)
{
- struct lprocfs_static_vars lvars = { 0 };
struct obd_device *obd;
struct lov_desc *desc;
int rc;
/* Set up allocation policy (QoS and RR) */
CFS_INIT_LIST_HEAD(&lod->lod_qos.lq_oss_list);
- cfs_init_rwsem(&lod->lod_qos.lq_rw_sem);
+ init_rwsem(&lod->lod_qos.lq_rw_sem);
lod->lod_qos.lq_dirty = 1;
lod->lod_qos.lq_rr.lqr_dirty = 1;
lod->lod_qos.lq_reset = 1;
lod->lod_death_row = 0;
lod->lod_refcount = 0;
- lprocfs_lod_init_vars(&lvars);
- lprocfs_obd_setup(obd, lvars.obd_vars);
-
-#ifdef LPROCFS
- rc = lprocfs_seq_create(obd->obd_proc_entry, "target_obd",
- 0444, &lod_proc_target_fops, obd);
- if (rc) {
- CWARN("%s: Error adding the target_obd file %d\n",
- obd->obd_name, rc);
- GOTO(out_lproc, rc);
- }
- lod->lod_pool_proc_entry = lprocfs_register("pools",
- obd->obd_proc_entry,
- NULL, NULL);
- if (IS_ERR(lod->lod_pool_proc_entry)) {
- int ret = PTR_ERR(lod->lod_pool_proc_entry);
- lod->lod_pool_proc_entry = NULL;
- CWARN("%s: Failed to create pool proc file %d\n",
- obd->obd_name, ret);
- rc = lod_pools_fini(lod);
- RETURN(ret);
- }
-#endif
-
RETURN(0);
-out_lproc:
- lprocfs_obd_cleanup(obd);
- lod_ost_pool_free(&lod->lod_qos.lq_rr.lqr_pool);
out_pool_info:
lod_ost_pool_free(&lod->lod_pool_info);
out_hash:
if (lod->lod_osts_size > 0) {
int idx;
lod_getref(lod);
- cfs_mutex_lock(&lod->lod_mutex);
+ mutex_lock(&lod->lod_mutex);
cfs_foreach_bit(lod->lod_ost_bitmap, idx)
__lod_del_device(lod, idx);
- cfs_mutex_unlock(&lod->lod_mutex);
+ mutex_unlock(&lod->lod_mutex);
lod_putref(lod);
CFS_FREE_BITMAP(lod->lod_ost_bitmap);
for (idx = 0; idx < OST_PTRS; idx++) {
cfs_hash_putref(lod->lod_pools_hash_body);
lod_ost_pool_free(&(lod->lod_qos.lq_rr.lqr_pool));
lod_ost_pool_free(&lod->lod_pool_info);
-
- /* clear pools parent proc entry only after all pools are killed */
- if (lod->lod_pool_proc_entry) {
- lprocfs_remove(&lod->lod_pool_proc_entry);
- lod->lod_pool_proc_entry = NULL;
- }
-
- lprocfs_obd_cleanup(obd);
-
OBD_FREE_PTR(lod->lod_qos.lq_statfs_data);
RETURN(0);
}