From: John L. Hammond Date: Thu, 26 Mar 2015 04:00:26 +0000 (-0700) Subject: LU-5814 llite: add cl_object_maxbytes() X-Git-Tag: 2.7.54~23 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=94fe3dadb5774af0eb0fec6d21aa73a22ac4838c LU-5814 llite: add cl_object_maxbytes() Add cl_object_maxbytes() to return the maximum supported size of a cl_object. Remove the lli_maxbytes member from struct ll_inode_info. Change the lsm_maxbytes member of struct lov_stripe_md from __u64 to loff_t. Correct the computation of lsm_maxbytes in the released layout case. Signed-off-by: John L. Hammond Signed-off-by: Jinshan Xiong Change-Id: Idfa6d38ed1192d562f7d99bf21b924fd711f77dc Reviewed-on: http://review.whamcloud.com/13694 Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: James Simmons --- diff --git a/lustre/include/cl_object.h b/lustre/include/cl_object.h index c32bb0c..52860d1 100644 --- a/lustre/include/cl_object.h +++ b/lustre/include/cl_object.h @@ -450,6 +450,10 @@ struct cl_object_operations { */ int (*coo_layout_get)(const struct lu_env *env, struct cl_object *obj, struct cl_layout *layout); + /** + * Get maximum size of the object. + */ + loff_t (*coo_maxbytes)(struct cl_object *obj); }; /** @@ -2232,6 +2236,7 @@ int cl_object_data_version(const struct lu_env *env, struct cl_object *obj, __u64 *version, int flags); int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj, struct cl_layout *cl); +loff_t cl_object_maxbytes(struct cl_object *obj); /** * Returns true, iff \a o0 and \a o1 are slices of the same object. diff --git a/lustre/include/obd.h b/lustre/include/obd.h index e1c4e73..71f1662 100644 --- a/lustre/include/obd.h +++ b/lustre/include/obd.h @@ -96,7 +96,7 @@ struct lov_stripe_md { /* maximum possible file size, might change as OSTs status changes, * e.g. disconnected, deactivated */ - __u64 lsm_maxbytes; + loff_t lsm_maxbytes; struct ost_id lsm_oi; __u32 lsm_magic; __u32 lsm_stripe_size; diff --git a/lustre/llite/llite_internal.h b/lustre/llite/llite_internal.h index 2048730..a1e9f80 100644 --- a/lustre/llite/llite_internal.h +++ b/lustre/llite/llite_internal.h @@ -212,7 +212,6 @@ struct ll_inode_info { struct { struct mutex lli_size_mutex; char *lli_symlink_name; - __u64 lli_maxbytes; /* * struct rw_semaphore { * signed long count; // align d.d_def_acl @@ -1094,9 +1093,14 @@ static inline struct lu_fid *ll_inode2fid(struct inode *inode) return fid; } -static inline __u64 ll_file_maxbytes(struct inode *inode) +static inline loff_t ll_file_maxbytes(struct inode *inode) { - return ll_i2info(inode)->lli_maxbytes; + struct cl_object *obj = ll_i2info(inode)->lli_clob; + + if (obj == NULL) + return MAX_LFS_FILESIZE; + + return min_t(loff_t, cl_object_maxbytes(obj), MAX_LFS_FILESIZE); } /* llite/xattr.c */ diff --git a/lustre/llite/llite_lib.c b/lustre/llite/llite_lib.c index 89a0de2..9e6d912 100644 --- a/lustre/llite/llite_lib.c +++ b/lustre/llite/llite_lib.c @@ -950,7 +950,6 @@ void ll_lli_init(struct ll_inode_info *lli) { lli->lli_inode_magic = LLI_INODE_MAGIC; lli->lli_flags = 0; - lli->lli_maxbytes = MAX_LFS_FILESIZE; spin_lock_init(&lli->lli_lock); lli->lli_posix_acl = NULL; lli->lli_remote_perms = NULL; @@ -1892,14 +1891,9 @@ int ll_update_inode(struct inode *inode, struct lustre_md *md) struct ll_sb_info *sbi = ll_i2sbi(inode); LASSERT((lsm != NULL) == ((body->mbo_valid & OBD_MD_FLEASIZE) != 0)); - if (lsm != NULL) { + if (lsm != NULL) cl_file_inode_init(inode, md); - lli->lli_maxbytes = lsm->lsm_maxbytes; - if (lli->lli_maxbytes > MAX_LFS_FILESIZE) - lli->lli_maxbytes = MAX_LFS_FILESIZE; - } - if (S_ISDIR(inode->i_mode)) { int rc; diff --git a/lustre/lov/lov_ea.c b/lustre/lov/lov_ea.c index 2e2357c..b98f924 100644 --- a/lustre/lov/lov_ea.c +++ b/lustre/lov/lov_ea.c @@ -122,9 +122,41 @@ void lsm_free_plain(struct lov_stripe_md *lsm) stripe_count * sizeof(struct lov_oinfo *)); } -static void lsm_unpackmd_common(struct lov_stripe_md *lsm, - struct lov_mds_md *lmm) +/* Find minimum stripe maxbytes value. For inactive or + * reconnecting targets use LUSTRE_EXT3_STRIPE_MAXBYTES. */ +static loff_t lov_tgt_maxbytes(struct lov_tgt_desc *tgt) +{ + struct obd_import *imp; + loff_t maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; + + if (!tgt->ltd_active) + return maxbytes; + + imp = tgt->ltd_obd->u.cli.cl_import; + if (imp == NULL) + return maxbytes; + + spin_lock(&imp->imp_lock); + if (imp->imp_state == LUSTRE_IMP_FULL && + (imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_MAXBYTES) && + imp->imp_connect_data.ocd_maxbytes > 0) + maxbytes = imp->imp_connect_data.ocd_maxbytes; + + spin_unlock(&imp->imp_lock); + + return maxbytes; +} + +static int lsm_unpackmd_common(struct lov_obd *lov, + struct lov_stripe_md *lsm, + struct lov_mds_md *lmm, + struct lov_ost_data_v1 *objects) { + struct lov_oinfo *loi; + loff_t stripe_maxbytes = LLONG_MAX; + unsigned int stripe_count; + unsigned int i; + /* * This supposes lov_mds_md_v1/v3 first fields are * are the same @@ -134,6 +166,44 @@ static void lsm_unpackmd_common(struct lov_stripe_md *lsm, lsm->lsm_pattern = le32_to_cpu(lmm->lmm_pattern); lsm->lsm_layout_gen = le16_to_cpu(lmm->lmm_layout_gen); lsm->lsm_pool_name[0] = '\0'; + + stripe_count = lsm_is_released(lsm) ? 0 : lsm->lsm_stripe_count; + + for (i = 0; i < stripe_count; i++) { + loi = lsm->lsm_oinfo[i]; + ostid_le_to_cpu(&objects[i].l_ost_oi, &loi->loi_oi); + loi->loi_ost_idx = le32_to_cpu(objects[i].l_ost_idx); + loi->loi_ost_gen = le32_to_cpu(objects[i].l_ost_gen); + if (lov_oinfo_is_dummy(loi)) + continue; + + if (loi->loi_ost_idx >= lov->desc.ld_tgt_count) { + CERROR("OST index %d more than OST count %d\n", + loi->loi_ost_idx, lov->desc.ld_tgt_count); + lov_dump_lmm_v1(D_WARNING, lmm); + return -EINVAL; + } + + if (!lov->lov_tgts[loi->loi_ost_idx]) { + CERROR("OST index %d missing\n", loi->loi_ost_idx); + lov_dump_lmm_v1(D_WARNING, lmm); + return -EINVAL; + } + + stripe_maxbytes = min_t(loff_t, stripe_maxbytes, + lov_tgt_maxbytes( + lov->lov_tgts[loi->loi_ost_idx])); + } + + if (stripe_maxbytes == LLONG_MAX) + stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; + + if (lsm->lsm_stripe_count == 0) + lsm->lsm_maxbytes = stripe_maxbytes * lov->desc.ld_tgt_count; + else + lsm->lsm_maxbytes = stripe_maxbytes * lsm->lsm_stripe_count; + + return 0; } static void @@ -152,29 +222,6 @@ lsm_stripe_by_offset_plain(struct lov_stripe_md *lsm, int *stripeno, *swidth = (loff_t)lsm->lsm_stripe_size * lsm->lsm_stripe_count; } -/* Find minimum stripe maxbytes value. For inactive or - * reconnecting targets use LUSTRE_EXT3_STRIPE_MAXBYTES. */ -static void lov_tgt_maxbytes(struct lov_tgt_desc *tgt, __u64 *stripe_maxbytes) -{ - struct obd_import *imp = tgt->ltd_obd->u.cli.cl_import; - - if (imp == NULL || !tgt->ltd_active) { - *stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; - return; - } - - spin_lock(&imp->imp_lock); - if (imp->imp_state == LUSTRE_IMP_FULL && - (imp->imp_connect_data.ocd_connect_flags & OBD_CONNECT_MAXBYTES) && - imp->imp_connect_data.ocd_maxbytes > 0) { - if (*stripe_maxbytes > imp->imp_connect_data.ocd_maxbytes) - *stripe_maxbytes = imp->imp_connect_data.ocd_maxbytes; - } else { - *stripe_maxbytes = LUSTRE_EXT3_STRIPE_MAXBYTES; - } - spin_unlock(&imp->imp_lock); -} - static int lsm_lmm_verify_v1(struct lov_mds_md_v1 *lmm, int lmm_bytes, __u16 *stripe_count) { @@ -201,45 +248,7 @@ static int lsm_lmm_verify_v1(struct lov_mds_md_v1 *lmm, int lmm_bytes, static int lsm_unpackmd_v1(struct lov_obd *lov, struct lov_stripe_md *lsm, struct lov_mds_md_v1 *lmm) { - struct lov_oinfo *loi; - int i; - int stripe_count; - __u64 stripe_maxbytes = OBD_OBJECT_EOF; - - lsm_unpackmd_common(lsm, lmm); - - stripe_count = lsm_is_released(lsm) ? 0 : lsm->lsm_stripe_count; - - for (i = 0; i < stripe_count; i++) { - /* XXX LOV STACKING call down to osc_unpackmd() */ - loi = lsm->lsm_oinfo[i]; - ostid_le_to_cpu(&lmm->lmm_objects[i].l_ost_oi, &loi->loi_oi); - loi->loi_ost_idx = le32_to_cpu(lmm->lmm_objects[i].l_ost_idx); - loi->loi_ost_gen = le32_to_cpu(lmm->lmm_objects[i].l_ost_gen); - if (lov_oinfo_is_dummy(loi)) - continue; - - if (loi->loi_ost_idx >= lov->desc.ld_tgt_count) { - CERROR("OST index %d more than OST count %d\n", - loi->loi_ost_idx, lov->desc.ld_tgt_count); - lov_dump_lmm_v1(D_WARNING, lmm); - return -EINVAL; - } - if (!lov->lov_tgts[loi->loi_ost_idx]) { - CERROR("OST index %d missing\n", loi->loi_ost_idx); - lov_dump_lmm_v1(D_WARNING, lmm); - return -EINVAL; - } - /* calculate the minimum stripe max bytes */ - lov_tgt_maxbytes(lov->lov_tgts[loi->loi_ost_idx], - &stripe_maxbytes); - } - - lsm->lsm_maxbytes = stripe_maxbytes * lsm->lsm_stripe_count; - if (lsm->lsm_stripe_count == 0) - lsm->lsm_maxbytes = stripe_maxbytes * lov->desc.ld_tgt_count; - - return 0; + return lsm_unpackmd_common(lov, lsm, lmm, lmm->lmm_objects); } const struct lsm_operations lsm_v1_ops = { @@ -279,55 +288,21 @@ static int lsm_lmm_verify_v3(struct lov_mds_md *lmmv1, int lmm_bytes, } static int lsm_unpackmd_v3(struct lov_obd *lov, struct lov_stripe_md *lsm, - struct lov_mds_md *lmmv1) + struct lov_mds_md *lmm) { - struct lov_mds_md_v3 *lmm; - struct lov_oinfo *loi; - int i; - int stripe_count; - __u64 stripe_maxbytes = OBD_OBJECT_EOF; - int cplen = 0; + struct lov_mds_md_v3 *lmm_v3 = (struct lov_mds_md_v3 *)lmm; + size_t cplen; + int rc; - lmm = (struct lov_mds_md_v3 *)lmmv1; + rc = lsm_unpackmd_common(lov, lsm, lmm, lmm_v3->lmm_objects); + if (rc != 0) + return rc; - lsm_unpackmd_common(lsm, (struct lov_mds_md_v1 *)lmm); - - stripe_count = lsm_is_released(lsm) ? 0 : lsm->lsm_stripe_count; - - cplen = strlcpy(lsm->lsm_pool_name, lmm->lmm_pool_name, + cplen = strlcpy(lsm->lsm_pool_name, lmm_v3->lmm_pool_name, sizeof(lsm->lsm_pool_name)); if (cplen >= sizeof(lsm->lsm_pool_name)) return -E2BIG; - for (i = 0; i < stripe_count; i++) { - /* XXX LOV STACKING call down to osc_unpackmd() */ - loi = lsm->lsm_oinfo[i]; - ostid_le_to_cpu(&lmm->lmm_objects[i].l_ost_oi, &loi->loi_oi); - loi->loi_ost_idx = le32_to_cpu(lmm->lmm_objects[i].l_ost_idx); - loi->loi_ost_gen = le32_to_cpu(lmm->lmm_objects[i].l_ost_gen); - if (lov_oinfo_is_dummy(loi)) - continue; - - if (loi->loi_ost_idx >= lov->desc.ld_tgt_count) { - CERROR("OST index %d more than OST count %d\n", - loi->loi_ost_idx, lov->desc.ld_tgt_count); - lov_dump_lmm_v3(D_WARNING, lmm); - return -EINVAL; - } - if (!lov->lov_tgts[loi->loi_ost_idx]) { - CERROR("OST index %d missing\n", loi->loi_ost_idx); - lov_dump_lmm_v3(D_WARNING, lmm); - return -EINVAL; - } - /* calculate the minimum stripe max bytes */ - lov_tgt_maxbytes(lov->lov_tgts[loi->loi_ost_idx], - &stripe_maxbytes); - } - - lsm->lsm_maxbytes = stripe_maxbytes * lsm->lsm_stripe_count; - if (lsm->lsm_stripe_count == 0) - lsm->lsm_maxbytes = stripe_maxbytes * lov->desc.ld_tgt_count; - return 0; } diff --git a/lustre/lov/lov_object.c b/lustre/lov/lov_object.c index c852ab5..21c24c2 100644 --- a/lustre/lov/lov_object.c +++ b/lustre/lov/lov_object.c @@ -1599,6 +1599,22 @@ static int lov_object_layout_get(const struct lu_env *env, RETURN(rc < 0 ? rc : 0); } +static loff_t lov_object_maxbytes(struct cl_object *obj) +{ + struct lov_object *lov = cl2lov(obj); + struct lov_stripe_md *lsm = lov_lsm_addref(lov); + loff_t maxbytes; + + if (lsm == NULL) + return LLONG_MAX; + + maxbytes = lsm->lsm_maxbytes; + + lov_lsm_put(lsm); + + return maxbytes; +} + static int lov_object_find_cbdata(const struct lu_env *env, struct cl_object *obj, ldlm_iterator_t iter, void *data) @@ -1621,6 +1637,7 @@ static const struct cl_object_operations lov_ops = { .coo_conf_set = lov_conf_set, .coo_getstripe = lov_object_getstripe, .coo_layout_get = lov_object_layout_get, + .coo_maxbytes = lov_object_maxbytes, .coo_find_cbdata = lov_object_find_cbdata, .coo_fiemap = lov_object_fiemap, .coo_data_version = lov_object_data_version, diff --git a/lustre/obdclass/cl_object.c b/lustre/obdclass/cl_object.c index a63b0cf..9b3e71b 100644 --- a/lustre/obdclass/cl_object.c +++ b/lustre/obdclass/cl_object.c @@ -474,6 +474,22 @@ int cl_object_layout_get(const struct lu_env *env, struct cl_object *obj, } EXPORT_SYMBOL(cl_object_layout_get); +loff_t cl_object_maxbytes(struct cl_object *obj) +{ + struct lu_object_header *top = obj->co_lu.lo_header; + loff_t maxbytes = LLONG_MAX; + ENTRY; + + list_for_each_entry(obj, &top->loh_layers, co_lu.lo_linkage) { + if (obj->co_ops->coo_maxbytes != NULL) + maxbytes = min_t(loff_t, obj->co_ops->coo_maxbytes(obj), + maxbytes); + } + + RETURN(maxbytes); +} +EXPORT_SYMBOL(cl_object_maxbytes); + /** * Helper function removing all object locks, and marking object for * deletion. All object pages must have been deleted at this point.