From 72714911b716b9ec8eba294d852164e7a3e4b380 Mon Sep 17 00:00:00 2001 From: Bobi Jam Date: Tue, 28 Oct 2014 11:30:38 +0800 Subject: [PATCH] LU-5823 clio: add coo_getstripe interface Use cl_object_operations::coo_getstripe() to handle LL_IOC_LOV_GETSTRIPE ops. Signed-off-by: Bobi Jam Change-Id: Iee0d007f773ead35434eb88e7ca2f31c0bc42c11 Reviewed-on: http://review.whamcloud.com/12452 Reviewed-by: John L. Hammond Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Jinshan Xiong Reviewed-by: Oleg Drokin --- lustre/include/cl_object.h | 8 +++ lustre/llite/file.c | 42 ++++++------- lustre/llite/llite_internal.h | 2 +- lustre/lov/lov_cl_internal.h | 4 ++ lustre/lov/lov_internal.h | 2 - lustre/lov/lov_obd.c | 3 - lustre/lov/lov_object.c | 66 ++++++++++++-------- lustre/lov/lov_pack.c | 140 ++++++++++++++++++++++-------------------- lustre/obdclass/cl_object.c | 22 +++++++ 9 files changed, 173 insertions(+), 116 deletions(-) diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index 862d092..c2c3b2d 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -394,6 +394,11 @@ struct cl_object_operations { * mainly pages and locks. */ int (*coo_prune)(const struct lu_env *env, struct cl_object *obj); + /** + * Object getstripe method. + */ + int (*coo_getstripe)(const struct lu_env *env, struct cl_object *obj, + struct lov_user_md __user *lum); }; /** @@ -448,6 +453,7 @@ struct cl_object_header { list_for_each_entry_reverse((slice), \ &(obj)->co_lu.lo_header->loh_layers,\ co_lu.lo_linkage) + /** @} cl_object */ #define CL_PAGE_EOF ((pgoff_t)~0ull) @@ -2258,6 +2264,8 @@ int cl_conf_set (const struct lu_env *env, struct cl_object *obj, const struct cl_object_conf *conf); int cl_object_prune (const struct lu_env *env, struct cl_object *obj); void cl_object_kill (const struct lu_env *env, struct cl_object *obj); +int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj, + struct lov_user_md __user *lum); /** * Returns true, iff \a o0 and \a o1 are slices of the same object. diff --git a/lustre/llite/file.c b/lustre/llite/file.c index 723bf92..d1ca438 100644 --- a/lustre/llite/file.c +++ b/lustre/llite/file.c @@ -1581,6 +1581,23 @@ static int ll_lov_setea(struct inode *inode, struct file *file, RETURN(rc); } +static int ll_file_getstripe(struct inode *inode, + struct lov_user_md __user *lum) +{ + struct lu_env *env; + int refcheck; + int rc; + ENTRY; + + env = cl_env_get(&refcheck); + if (IS_ERR(env)) + RETURN(PTR_ERR(env)); + + rc = cl_object_getstripe(env, ll_i2info(inode)->lli_clob, lum); + cl_env_put(env, &refcheck); + RETURN(rc); +} + static int ll_lov_setstripe(struct inode *inode, struct file *file, unsigned long arg) { @@ -1597,36 +1614,18 @@ static int ll_lov_setstripe(struct inode *inode, struct file *file, lum_size = rc; rc = ll_lov_setstripe_ea_info(inode, file, flags, klum, lum_size); if (rc == 0) { - struct lov_stripe_md *lsm; __u32 gen; put_user(0, &lum->lmm_stripe_count); ll_layout_refresh(inode, &gen); - lsm = ccc_inode_lsm_get(inode); - rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode), - 0, lsm, lum); - ccc_inode_lsm_put(inode, lsm); + rc = ll_file_getstripe(inode, (struct lov_user_md __user *)arg); } OBD_FREE(klum, lum_size); RETURN(rc); } -static int ll_lov_getstripe(struct inode *inode, unsigned long arg) -{ - struct lov_stripe_md *lsm; - int rc = -ENODATA; - ENTRY; - - lsm = ccc_inode_lsm_get(inode); - if (lsm != NULL) - rc = obd_iocontrol(LL_IOC_LOV_GETSTRIPE, ll_i2dtexp(inode), 0, - lsm, (void __user *)arg); - ccc_inode_lsm_put(inode, lsm); - RETURN(rc); -} - static int ll_get_grouplock(struct inode *inode, struct file *file, unsigned long arg) { @@ -2324,8 +2323,9 @@ ll_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg) fput(file2); RETURN(rc); } - case LL_IOC_LOV_GETSTRIPE: - RETURN(ll_lov_getstripe(inode, arg)); + case LL_IOC_LOV_GETSTRIPE: + RETURN(ll_file_getstripe(inode, + (struct lov_user_md __user *)arg)); case FSFILT_IOC_FIEMAP: RETURN(ll_ioctl_fiemap(inode, arg)); case FSFILT_IOC_GETFLAGS: diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 2ce7639..60c44da 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -260,7 +260,7 @@ struct ll_inode_info { * some of the following members can be moved into u.f. */ bool lli_has_smd; - struct cl_object *lli_clob; + struct cl_object *lli_clob; /* mutex to request for layout lock exclusively. */ struct mutex lli_layout_mutex; diff --git a/lustre/lov/lov_cl_internal.h b/lustre/lov/lov_cl_internal.h index 93bec95..c136dce 100644 --- a/lustre/lov/lov_cl_internal.h +++ b/lustre/lov/lov_cl_internal.h @@ -767,6 +767,10 @@ static inline struct lov_layout_raid0 *lov_r0(struct lov_object *lov) return &lov->u.raid0; } +/* lov_pack.c */ +int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm, + struct lov_user_md __user *lump); + /** @} lov */ #endif diff --git a/lustre/lov/lov_internal.h b/lustre/lov/lov_internal.h index 5d5b793..c7814e1 100644 --- a/lustre/lov/lov_internal.h +++ b/lustre/lov/lov_internal.h @@ -195,8 +195,6 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmm, struct lov_stripe_md *lsm); int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, struct lov_mds_md *lmm, int lmm_bytes); -int lov_getstripe(struct obd_export *exp, - struct lov_stripe_md *lsm, struct lov_user_md __user *lump); int lov_alloc_memmd(struct lov_stripe_md **lsmp, __u16 stripe_count, int pattern, int magic); int lov_free_memmd(struct lov_stripe_md **lsmp); diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index 7f3cd20..200abda 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -1430,9 +1430,6 @@ static int lov_iocontrol(unsigned int cmd, struct obd_export *exp, int len, obd_ioctl_freedata(buf, len); break; } - case LL_IOC_LOV_GETSTRIPE: - rc = lov_getstripe(exp, karg, uarg); - break; case OBD_IOC_QUOTACTL: { struct if_quotactl *qctl = karg; struct lov_tgt_desc *tgt = NULL; diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index f7ef365..718d035 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -80,6 +80,29 @@ struct lov_layout_operations { static int lov_layout_wait(const struct lu_env *env, struct lov_object *lov); +struct lov_stripe_md *lov_lsm_get(struct cl_object *clobj) +{ + struct lu_object *luobj; + struct lov_stripe_md *lsm = NULL; + + if (clobj == NULL) + return NULL; + + luobj = lu_object_locate(&cl_object_header(clobj)->coh_lu, + &lov_device_type); + if (luobj != NULL) + lsm = lov_lsm_addref(lu2lov(luobj)); + return lsm; +} +EXPORT_SYMBOL(lov_lsm_get); + +void lov_lsm_put(struct cl_object *unused, struct lov_stripe_md *lsm) +{ + if (lsm != NULL) + lov_free_memmd(&lsm); +} +EXPORT_SYMBOL(lov_lsm_put); + /***************************************************************************** * * Lov object layout operations. @@ -917,13 +940,31 @@ int lov_lock_init(const struct lu_env *env, struct cl_object *obj, io); } +static int lov_object_getstripe(const struct lu_env *env, struct cl_object *obj, + struct lov_user_md __user *lum) +{ + struct lov_object *lov = cl2lov(obj); + struct lov_stripe_md *lsm; + int rc = 0; + ENTRY; + + lsm = lov_lsm_addref(lov); + if (lsm == NULL) + RETURN(-ENODATA); + + rc = lov_getstripe(cl2lov(obj), lsm, lum); + lov_lsm_put(obj, lsm); + RETURN(rc); +} + static const struct cl_object_operations lov_ops = { .coo_page_init = lov_page_init, .coo_lock_init = lov_lock_init, .coo_io_init = lov_io_init, .coo_attr_get = lov_attr_get, .coo_attr_set = lov_attr_set, - .coo_conf_set = lov_conf_set + .coo_conf_set = lov_conf_set, + .coo_getstripe = lov_object_getstripe }; static const struct lu_object_operations lov_lu_obj_ops = { @@ -975,29 +1016,6 @@ struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov) return lsm; } -struct lov_stripe_md *lov_lsm_get(struct cl_object *clobj) -{ - struct lu_object *luobj; - struct lov_stripe_md *lsm = NULL; - - if (clobj == NULL) - return NULL; - - luobj = lu_object_locate(&cl_object_header(clobj)->coh_lu, - &lov_device_type); - if (luobj != NULL) - lsm = lov_lsm_addref(lu2lov(luobj)); - return lsm; -} -EXPORT_SYMBOL(lov_lsm_get); - -void lov_lsm_put(struct cl_object *unused, struct lov_stripe_md *lsm) -{ - if (lsm != NULL) - lov_free_memmd(&lsm); -} -EXPORT_SYMBOL(lov_lsm_put); - int lov_read_and_clear_async_rc(struct cl_object *clob) { struct lu_object *luobj; diff --git a/lustre/lov/lov_pack.c b/lustre/lov/lov_pack.c index 3c6f7c9..d4e6c71 100644 --- a/lustre/lov/lov_pack.c +++ b/lustre/lov/lov_pack.c @@ -49,6 +49,7 @@ #include #include "lov_internal.h" +#include "lov_cl_internal.h" void lov_dump_lmm_common(int level, void *lmmp) { @@ -128,11 +129,9 @@ void lov_dump_lmm(int level, void *lmm) * LOVs properly. For now lov_mds_md_size() just assumes one obd_id * per stripe. */ -int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, - struct lov_stripe_md *lsm) +static int lov_obd_packmd(struct lov_obd *lov, struct lov_mds_md **lmmp, + struct lov_stripe_md *lsm) { - struct obd_device *obd = class_exp2obd(exp); - struct lov_obd *lov = &obd->u.lov; struct lov_mds_md_v1 *lmmv1; struct lov_mds_md_v3 *lmmv3; __u16 stripe_count; @@ -243,6 +242,15 @@ int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, RETURN(lmm_size); } +int lov_packmd(struct obd_export *exp, struct lov_mds_md **lmmp, + struct lov_stripe_md *lsm) +{ + struct obd_device *obd = class_exp2obd(exp); + struct lov_obd *lov = &obd->u.lov; + + return lov_obd_packmd(lov, lmmp, lsm); +} + /* Find the max stripecount we should use */ __u16 lov_get_stripecnt(struct lov_obd *lov, __u32 magic, __u16 stripe_count) { @@ -407,78 +415,79 @@ int lov_unpackmd(struct obd_export *exp, struct lov_stripe_md **lsmp, * the maximum number of OST indices which will fit in the user buffer. * lmm_magic must be LOV_USER_MAGIC. */ -int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm, +int lov_getstripe(struct lov_object *obj, struct lov_stripe_md *lsm, struct lov_user_md __user *lump) { - /* - * XXX huge struct allocated on stack. - */ - /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */ - struct lov_user_md_v3 lum; - struct lov_mds_md *lmmk = NULL; - int rc, lmm_size; - int lum_size; - ENTRY; - - if (!lsm) - RETURN(-ENODATA); + /* + * XXX huge struct allocated on stack. + */ + /* we use lov_user_md_v3 because it is larger than lov_user_md_v1 */ + struct lov_obd *lov; + struct lov_mds_md *lmmk = NULL; + struct lov_user_md_v3 lum; + int rc; + int lmmk_size; + int lmm_size; + int lum_size; + ENTRY; - /* we only need the header part from user space to get lmm_magic and - * lmm_stripe_count, (the header part is common to v1 and v3) */ - lum_size = sizeof(struct lov_user_md_v1); + /* we only need the header part from user space to get lmm_magic and + * lmm_stripe_count, (the header part is common to v1 and v3) */ + lum_size = sizeof(struct lov_user_md_v1); if (copy_from_user(&lum, lump, lum_size)) - GOTO(out_set, rc = -EFAULT); + GOTO(out, rc = -EFAULT); if (lum.lmm_magic != LOV_USER_MAGIC_V1 && lum.lmm_magic != LOV_USER_MAGIC_V3 && lum.lmm_magic != LOV_USER_MAGIC_SPECIFIC) - GOTO(out_set, rc = -EINVAL); + GOTO(out, rc = -EINVAL); - if (lum.lmm_stripe_count && - (lum.lmm_stripe_count < lsm->lsm_stripe_count)) { - /* Return right size of stripe to user */ - lum.lmm_stripe_count = lsm->lsm_stripe_count; + if (lum.lmm_stripe_count && + (lum.lmm_stripe_count < lsm->lsm_stripe_count)) { + /* Return right size of stripe to user */ + lum.lmm_stripe_count = lsm->lsm_stripe_count; rc = copy_to_user(lump, &lum, lum_size); - GOTO(out_set, rc = -EOVERFLOW); - } - rc = lov_packmd(exp, &lmmk, lsm); - if (rc < 0) - GOTO(out_set, rc); - lmm_size = rc; - rc = 0; - - /* FIXME: Bug 1185 - copy fields properly when structs change */ - /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */ - CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3)); - CLASSERT(sizeof lum.lmm_objects[0] == sizeof lmmk->lmm_objects[0]); - - if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) && - ((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) || - (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) { - lustre_swab_lov_mds_md(lmmk); - lustre_swab_lov_user_md_objects( - (struct lov_user_ost_data*)lmmk->lmm_objects, - lmmk->lmm_stripe_count); - } - if (lum.lmm_magic == LOV_USER_MAGIC) { - /* User request for v1, we need skip lmm_pool_name */ - if (lmmk->lmm_magic == LOV_MAGIC_V3) { + GOTO(out, rc = -EOVERFLOW); + } + lov = lu2lov_dev(obj->lo_cl.co_lu.lo_dev)->ld_lov; + rc = lov_obd_packmd(lov, &lmmk, lsm); + if (rc < 0) + GOTO(out, rc); + lmmk_size = lmm_size = rc; + rc = 0; + + /* FIXME: Bug 1185 - copy fields properly when structs change */ + /* struct lov_user_md_v3 and struct lov_mds_md_v3 must be the same */ + CLASSERT(sizeof(lum) == sizeof(struct lov_mds_md_v3)); + CLASSERT(sizeof lum.lmm_objects[0] == sizeof lmmk->lmm_objects[0]); + + if ((cpu_to_le32(LOV_MAGIC) != LOV_MAGIC) && + ((lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V1)) || + (lmmk->lmm_magic == cpu_to_le32(LOV_MAGIC_V3)))) { + lustre_swab_lov_mds_md(lmmk); + lustre_swab_lov_user_md_objects( + (struct lov_user_ost_data *)lmmk->lmm_objects, + lmmk->lmm_stripe_count); + } + if (lum.lmm_magic == LOV_USER_MAGIC) { + /* User request for v1, we need skip lmm_pool_name */ + if (lmmk->lmm_magic == LOV_MAGIC_V3) { memmove(((struct lov_mds_md_v1 *)lmmk)->lmm_objects, ((struct lov_mds_md_v3 *)lmmk)->lmm_objects, - lmmk->lmm_stripe_count * - sizeof(struct lov_ost_data_v1)); - lmm_size -= LOV_MAXPOOLNAME; - } - } else { - /* if v3 we just have to update the lum_size */ - lum_size = sizeof(struct lov_user_md_v3); - } + lmmk->lmm_stripe_count * + sizeof(struct lov_ost_data_v1)); + lmm_size -= LOV_MAXPOOLNAME; + } + } else { + /* if v3 we just have to update the lum_size */ + lum_size = sizeof(struct lov_user_md_v3); + } - /* User wasn't expecting this many OST entries */ - if (lum.lmm_stripe_count == 0) - lmm_size = lum_size; - else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count) - GOTO(out_set, rc = -EOVERFLOW); + /* User wasn't expecting this many OST entries */ + if (lum.lmm_stripe_count == 0) + lmm_size = lum_size; + else if (lum.lmm_stripe_count < lmmk->lmm_stripe_count) + GOTO(out_free, rc = -EOVERFLOW); /* * Have a difference between lov_mds_md & lov_user_md. * So we have to re-order the data before copy to user. @@ -490,7 +499,8 @@ int lov_getstripe(struct obd_export *exp, struct lov_stripe_md *lsm, if (copy_to_user(lump, lmmk, lmm_size)) rc = -EFAULT; - obd_free_diskmd(exp, &lmmk); -out_set: +out_free: + OBD_FREE_LARGE(lmmk, lmmk_size); +out: RETURN(rc); } diff --git a/lustre/obdclass/cl_object.c b/lustre/obdclass/cl_object.c index c37bcd0..97978f8 100644 --- a/lustre/obdclass/cl_object.c +++ b/lustre/obdclass/cl_object.c @@ -341,6 +341,28 @@ int cl_object_prune(const struct lu_env *env, struct cl_object *obj) EXPORT_SYMBOL(cl_object_prune); /** + * Get stripe information of this object. + */ +int cl_object_getstripe(const struct lu_env *env, struct cl_object *obj, + struct lov_user_md __user *uarg) +{ + struct lu_object_header *top; + int result = 0; + ENTRY; + + top = obj->co_lu.lo_header; + list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) { + if (obj->co_ops->coo_getstripe != NULL) { + result = obj->co_ops->coo_getstripe(env, obj, uarg); + if (result != 0) + break; + } + } + RETURN(result); +} +EXPORT_SYMBOL(cl_object_getstripe); + +/** * Helper function removing all object locks, and marking object for * deletion. All object pages must have been deleted at this point. * -- 1.8.3.1