From: Alex Zhuravlev Date: Tue, 8 Jul 2014 13:52:30 +0000 (+0400) Subject: LU-4974 lod: documentation for lod_object.c X-Git-Tag: 2.6.90~89 X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=commitdiff_plain;h=refs%2Fchanges%2F22%2F11022%2F10 LU-4974 lod: documentation for lod_object.c Comments in Doxygen markup. Signed-off-by: Alex Zhuravlev Signed-off-by: Richard Henwood Change-Id: Ib60ae4eb89aeef5c3118f43c0fb640d5820b8b62 Reviewed-on: http://review.whamcloud.com/11022 Tested-by: Jenkins Reviewed-by: John L. Hammond Reviewed-by: Ned Bass Reviewed-by: Andreas Dilger Tested-by: Andreas Dilger --- diff --git a/lustre/lod/lod_object.c b/lustre/lod/lod_object.c index 2094ae9..c1e25bd 100644 --- a/lustre/lod/lod_object.c +++ b/lustre/lod/lod_object.c @@ -28,6 +28,13 @@ /* * lustre/lod/lod_object.c * + * This file contains implementations of methods for the OSD API + * for the Logical Object Device (LOD) layer, which provides a virtual + * local OSD object interface to the MDD layer, and abstracts the + * addressing of local (OSD) and remote (OSP) objects. The API is + * described in the file lustre/include/dt_object.h and in + * lustre/doc/osd-api.txt. + * * Author: Alex Zhuravlev */ @@ -54,6 +61,13 @@ static const char dotdot[] = ".."; extern struct kmem_cache *lod_object_kmem; static const struct dt_body_operations lod_body_lnk_ops; +/** + * Implementation of dt_index_operations::dio_lookup + * + * Used with regular (non-striped) objects. + * + * \see dt_index_operations::dio_lookup() in the API description for details. + */ static int lod_index_lookup(const struct lu_env *env, struct dt_object *dt, struct dt_rec *rec, const struct dt_key *key, struct lustre_capa *capa) @@ -62,6 +76,14 @@ static int lod_index_lookup(const struct lu_env *env, struct dt_object *dt, return next->do_index_ops->dio_lookup(env, next, rec, key, capa); } +/** + * Implementation of dt_index_operations::dio_declare_insert. + * + * Used with regular (non-striped) objects. + * + * \see dt_index_operations::dio_declare_insert() in the API description + * for details. + */ static int lod_declare_index_insert(const struct lu_env *env, struct dt_object *dt, const struct dt_rec *rec, @@ -71,6 +93,13 @@ static int lod_declare_index_insert(const struct lu_env *env, return dt_declare_insert(env, dt_object_child(dt), rec, key, handle); } +/** + * Implementation of dt_index_operations::dio_insert. + * + * Used with regular (non-striped) objects + * + * \see dt_index_operations::dio_insert() in the API description for details. + */ static int lod_index_insert(const struct lu_env *env, struct dt_object *dt, const struct dt_rec *rec, @@ -82,6 +111,14 @@ static int lod_index_insert(const struct lu_env *env, return dt_insert(env, dt_object_child(dt), rec, key, th, capa, ign); } +/** + * Implementation of dt_index_operations::dio_declare_delete. + * + * Used with regular (non-striped) objects. + * + * \see dt_index_operations::dio_declare_delete() in the API description + * for details. + */ static int lod_declare_index_delete(const struct lu_env *env, struct dt_object *dt, const struct dt_key *key, @@ -90,6 +127,13 @@ static int lod_declare_index_delete(const struct lu_env *env, return dt_declare_delete(env, dt_object_child(dt), key, th); } +/** + * Implementation of dt_index_operations::dio_delete. + * + * Used with regular (non-striped) objects. + * + * \see dt_index_operations::dio_delete() in the API description for details. + */ static int lod_index_delete(const struct lu_env *env, struct dt_object *dt, const struct dt_key *key, @@ -99,6 +143,13 @@ static int lod_index_delete(const struct lu_env *env, return dt_delete(env, dt_object_child(dt), key, th, capa); } +/** + * Implementation of dt_it_ops::init. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::init() in the API description for details. + */ static struct dt_it *lod_it_init(const struct lu_env *env, struct dt_object *dt, __u32 attr, struct lustre_capa *capa) @@ -130,6 +181,13 @@ do { \ LASSERT((it)->lit_it != NULL); \ } while (0) +/** + * Implementation of dt_index_operations::dio_it.fini. + * + * Used with regular (non-striped) objects. + * + * \see dt_index_operations::dio_it.fini() in the API description for details. + */ void lod_it_fini(const struct lu_env *env, struct dt_it *di) { struct lod_it *it = (struct lod_it *)di; @@ -142,6 +200,13 @@ void lod_it_fini(const struct lu_env *env, struct dt_it *di) it->lit_it = NULL; } +/** + * Implementation of dt_it_ops::get. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::get() in the API description for details. + */ int lod_it_get(const struct lu_env *env, struct dt_it *di, const struct dt_key *key) { @@ -151,6 +216,13 @@ int lod_it_get(const struct lu_env *env, struct dt_it *di, return it->lit_obj->do_index_ops->dio_it.get(env, it->lit_it, key); } +/** + * Implementation of dt_it_ops::put. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::put() in the API description for details. + */ void lod_it_put(const struct lu_env *env, struct dt_it *di) { struct lod_it *it = (struct lod_it *)di; @@ -159,6 +231,13 @@ void lod_it_put(const struct lu_env *env, struct dt_it *di) return it->lit_obj->do_index_ops->dio_it.put(env, it->lit_it); } +/** + * Implementation of dt_it_ops::next. + * + * Used with regular (non-striped) objects + * + * \see dt_it_ops::next() in the API description for details. + */ int lod_it_next(const struct lu_env *env, struct dt_it *di) { struct lod_it *it = (struct lod_it *)di; @@ -167,6 +246,13 @@ int lod_it_next(const struct lu_env *env, struct dt_it *di) return it->lit_obj->do_index_ops->dio_it.next(env, it->lit_it); } +/** + * Implementation of dt_it_ops::key. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::key() in the API description for details. + */ struct dt_key *lod_it_key(const struct lu_env *env, const struct dt_it *di) { const struct lod_it *it = (const struct lod_it *)di; @@ -175,6 +261,13 @@ struct dt_key *lod_it_key(const struct lu_env *env, const struct dt_it *di) return it->lit_obj->do_index_ops->dio_it.key(env, it->lit_it); } +/** + * Implementation of dt_it_ops::key_size. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::key_size() in the API description for details. + */ int lod_it_key_size(const struct lu_env *env, const struct dt_it *di) { struct lod_it *it = (struct lod_it *)di; @@ -183,6 +276,13 @@ int lod_it_key_size(const struct lu_env *env, const struct dt_it *di) return it->lit_obj->do_index_ops->dio_it.key_size(env, it->lit_it); } +/** + * Implementation of dt_it_ops::rec. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::rec() in the API description for details. + */ int lod_it_rec(const struct lu_env *env, const struct dt_it *di, struct dt_rec *rec, __u32 attr) { @@ -193,6 +293,13 @@ int lod_it_rec(const struct lu_env *env, const struct dt_it *di, attr); } +/** + * Implementation of dt_it_ops::rec_size. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::rec_size() in the API description for details. + */ int lod_it_rec_size(const struct lu_env *env, const struct dt_it *di, __u32 attr) { @@ -203,6 +310,13 @@ int lod_it_rec_size(const struct lu_env *env, const struct dt_it *di, attr); } +/** + * Implementation of dt_it_ops::store. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::store() in the API description for details. + */ __u64 lod_it_store(const struct lu_env *env, const struct dt_it *di) { const struct lod_it *it = (const struct lod_it *)di; @@ -211,6 +325,13 @@ __u64 lod_it_store(const struct lu_env *env, const struct dt_it *di) return it->lit_obj->do_index_ops->dio_it.store(env, it->lit_it); } +/** + * Implementation of dt_it_ops::load. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::load() in the API description for details. + */ int lod_it_load(const struct lu_env *env, const struct dt_it *di, __u64 hash) { const struct lod_it *it = (const struct lod_it *)di; @@ -219,6 +340,13 @@ int lod_it_load(const struct lu_env *env, const struct dt_it *di, __u64 hash) return it->lit_obj->do_index_ops->dio_it.load(env, it->lit_it, hash); } +/** + * Implementation of dt_it_ops::key_rec. + * + * Used with regular (non-striped) objects. + * + * \see dt_it_ops::rec() in the API description for details. + */ int lod_it_key_rec(const struct lu_env *env, const struct dt_it *di, void *key_rec) { @@ -252,22 +380,12 @@ static struct dt_index_operations lod_index_ops = { }; /** - * Implementation of dt_index_operations:: dio_it.init + * Implementation of dt_it_ops::init. * - * This function is to initialize the iterator for striped directory, - * basically these lod_striped_it_xxx will just locate the stripe - * and call the correspondent api of its next lower layer. + * Used with striped objects. Internally just initializes the iterator + * on the first stripe. * - * \param[in] env execution environment. - * \param[in] dt the striped directory object to be iterated. - * \param[in] attr the attribute of iterator, mostly used to indicate - * the entry attribute in the object to be iterated. - * \param[in] capa capability(useless in current implementation) - * - * \retval initialized iterator(dt_it) if successful initialize the - * iteration. lit_stripe_index will be used to indicate the - * current iterate position among stripes. - * \retval ERR pointer if initialization is failed. + * \see dt_it_ops::init() in the API description for details. */ static struct dt_it *lod_striped_it_init(const struct lu_env *env, struct dt_object *dt, __u32 attr, @@ -311,13 +429,11 @@ do { \ } while (0) /** - * Implementation of dt_index_operations:: dio_it.fini - * - * This function is to finish the iterator for striped directory. + * Implementation of dt_it_ops::fini. * - * \param[in] env execution environment. - * \param[in] di the iterator for the striped directory + * Used with striped objects. * + * \see dt_it_ops::fini() in the API description for details. */ static void lod_striped_it_fini(const struct lu_env *env, struct dt_it *di) { @@ -340,16 +456,13 @@ static void lod_striped_it_fini(const struct lu_env *env, struct dt_it *di) } /** - * Implementation of dt_index_operations:: dio_it.get - * - * This function is to position the iterator with given key + * Implementation of dt_it_ops::get. * - * \param[in] env execution environment. - * \param[in] di the iterator for striped directory. - * \param[in] key the key the iterator will be positioned. + * Right now it's not used widely, only to reset the iterator to the + * initial position. It should be possible to implement a full version + * which chooses a correct stripe to be able to position with any key. * - * \retval 0 if successfully position iterator by the key. - * \retval negative error if position is failed. + * \see dt_it_ops::get() in the API description for details. */ static int lod_striped_it_get(const struct lu_env *env, struct dt_it *di, const struct dt_key *key) @@ -369,10 +482,11 @@ static int lod_striped_it_get(const struct lu_env *env, struct dt_it *di, } /** - * Implementation of dt_index_operations:: dio_it.put + * Implementation of dt_it_ops::put. * - * This function is supposed to be the pair of it_get, but currently do - * nothing. see (osd_it_ea_put or osd_index_it_put) + * Used with striped objects. + * + * \see dt_it_ops::put() in the API description for details. */ static void lod_striped_it_put(const struct lu_env *env, struct dt_it *di) { @@ -390,18 +504,12 @@ static void lod_striped_it_put(const struct lu_env *env, struct dt_it *di) } /** - * Implementation of dt_index_operations:: dio_it.next - * - * This function is to position the iterator to the next entry, if current - * stripe is finished by checking the return value of next() in current - * stripe. it will go to next stripe. In the mean time, the sub-iterator - * for next stripe needs to be initialized. + * Implementation of dt_it_ops::next. * - * \param[in] env execution environment. - * \param[in] di the iterator for striped directory. + * Used with striped objects. When the end of the current stripe is + * reached, the method takes the next stripe's iterator. * - * \retval 0 if successfully position iterator to the next entry. - * \retval negative error if position is failed. + * \see dt_it_ops::next() in the API description for details. */ static int lod_striped_it_next(const struct lu_env *env, struct dt_it *di) { @@ -478,15 +586,11 @@ again: } /** - * Implementation of dt_index_operations:: dio_it.key + * Implementation of dt_it_ops::key. * - * This function is to get the key of the iterator at current position. + * Used with striped objects. * - * \param[in] env execution environment. - * \param[in] di the iterator for striped directory. - * - * \retval key(dt_key) if successfully get the key. - * \retval negative error if can not get the key. + * \see dt_it_ops::key() in the API description for details. */ static struct dt_key *lod_striped_it_key(const struct lu_env *env, const struct dt_it *di) @@ -505,15 +609,11 @@ static struct dt_key *lod_striped_it_key(const struct lu_env *env, } /** - * Implementation of dt_index_operations:: dio_it.key_size - * - * This function is to get the key_size of current key. + * Implementation of dt_it_ops::key_size. * - * \param[in] env execution environment. - * \param[in] di the iterator for striped directory. + * Used with striped objects. * - * \retval key_size if successfully get the key_size. - * \retval negative error if can not get the key_size. + * \see dt_it_ops::size() in the API description for details. */ static int lod_striped_it_key_size(const struct lu_env *env, const struct dt_it *di) @@ -532,18 +632,11 @@ static int lod_striped_it_key_size(const struct lu_env *env, } /** - * Implementation of dt_index_operations:: dio_it.rec + * Implementation of dt_it_ops::rec. * - * This function is to get the record at current position. + * Used with striped objects. * - * \param[in] env execution environment. - * \param[in] di the iterator for striped directory. - * \param[in] attr the attribute of iterator, mostly used to indicate - * the entry attribute in the object to be iterated. - * \param[out] rec hold the return record. - * - * \retval 0 if successfully get the entry. - * \retval negative error if can not get entry. + * \see dt_it_ops::rec() in the API description for details. */ static int lod_striped_it_rec(const struct lu_env *env, const struct dt_it *di, struct dt_rec *rec, __u32 attr) @@ -562,17 +655,11 @@ static int lod_striped_it_rec(const struct lu_env *env, const struct dt_it *di, } /** - * Implementation of dt_index_operations:: dio_it.rec_size - * - * This function is to get the record_size at current record. + * Implementation of dt_it_ops::rec_size. * - * \param[in] env execution environment. - * \param[in] di the iterator for striped directory. - * \param[in] attr the attribute of iterator, mostly used to indicate - * the entry attribute in the object to be iterated. + * Used with striped objects. * - * \retval rec_size if successfully get the entry size. - * \retval negative error if can not get entry size. + * \see dt_it_ops::rec_size() in the API description for details. */ static int lod_striped_it_rec_size(const struct lu_env *env, const struct dt_it *di, __u32 attr) @@ -591,15 +678,11 @@ static int lod_striped_it_rec_size(const struct lu_env *env, } /** - * Implementation of dt_index_operations:: dio_it.store + * Implementation of dt_it_ops::store. * - * This function will a cookie for current position of the iterator head, - * so that user can use this cookie to load/start the iterator next time. + * Used with striped objects. * - * \param[in] env execution environment. - * \param[in] di the iterator for striped directory. - * - * \retval the cookie. + * \see dt_it_ops::store() in the API description for details. */ static __u64 lod_striped_it_store(const struct lu_env *env, const struct dt_it *di) @@ -618,17 +701,11 @@ static __u64 lod_striped_it_store(const struct lu_env *env, } /** - * Implementation of dt_index_operations:: dio_it.load - * - * This function will position the iterator with the given hash(usually - * get from store), + * Implementation of dt_it_ops::load. * - * \param[in] env execution environment. - * \param[in] di the iterator for striped directory. - * \param[in] hash the given hash. + * Used with striped objects. * - * \retval >0 if successfuly load the iterator to the given position. - * \retval <0 if load is failed. + * \see dt_it_ops::load() in the API description for details. */ static int lod_striped_it_load(const struct lu_env *env, const struct dt_it *di, __u64 hash) @@ -866,21 +943,9 @@ next: } /** - * Implementation of dt_object_operations:: do_index_try - * - * This function will try to initialize the index api pointer for the - * given object, usually it the entry point of the index api. i.e. - * the index object should be initialized in index_try, then start - * using index api. For striped directory, it will try to initialize - * all of its sub_stripes. + * Implementation of dt_object_operations::do_index_try. * - * \param[in] env execution environment. - * \param[in] dt the index object to be initialized. - * \param[in] feat the features of this object, for example fixed or - * variable key size etc. - * - * \retval >0 if the initialization is successful. - * \retval <0 if the initialization is failed. + * \see dt_object_operations::do_index_try() in the API description for details. */ static int lod_index_try(const struct lu_env *env, struct dt_object *dt, const struct dt_index_features *feat) @@ -920,36 +985,70 @@ static int lod_index_try(const struct lu_env *env, struct dt_object *dt, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_read_lock. + * + * \see dt_object_operations::do_read_lock() in the API description for details. + */ static void lod_object_read_lock(const struct lu_env *env, struct dt_object *dt, unsigned role) { dt_read_lock(env, dt_object_child(dt), role); } +/** + * Implementation of dt_object_operations::do_write_lock. + * + * \see dt_object_operations::do_write_lock() in the API description for + * details. + */ static void lod_object_write_lock(const struct lu_env *env, struct dt_object *dt, unsigned role) { dt_write_lock(env, dt_object_child(dt), role); } +/** + * Implementation of dt_object_operations::do_read_unlock. + * + * \see dt_object_operations::do_read_unlock() in the API description for + * details. + */ static void lod_object_read_unlock(const struct lu_env *env, struct dt_object *dt) { dt_read_unlock(env, dt_object_child(dt)); } +/** + * Implementation of dt_object_operations::do_write_unlock. + * + * \see dt_object_operations::do_write_unlock() in the API description for + * details. + */ static void lod_object_write_unlock(const struct lu_env *env, struct dt_object *dt) { dt_write_unlock(env, dt_object_child(dt)); } +/** + * Implementation of dt_object_operations::do_write_locked. + * + * \see dt_object_operations::do_write_locked() in the API description for + * details. + */ static int lod_object_write_locked(const struct lu_env *env, struct dt_object *dt) { return dt_write_locked(env, dt_object_child(dt)); } +/** + * Implementation of dt_object_operations::do_attr_get. + * + * \see dt_object_operations::do_attr_get() in the API description for details. + */ static int lod_attr_get(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, @@ -963,7 +1062,22 @@ static int lod_attr_get(const struct lu_env *env, } /** - * Mark all of sub-stripes dead of the striped directory. + * Mark all of the striped directory sub-stripes dead. + * + * When a striped object is a subject to removal, we have + * to mark all the stripes to prevent further access to + * them (e.g. create a new file in those). So we mark + * all the stripes with LMV_HASH_FLAG_DEAD. The function + * can be used to declare the changes and to apply them. + * If the object isn't striped, then just return success. + * + * \param[in] env execution environment + * \param[in] dt the striped object + * \param[in] handle transaction handle + * \param[in] declare whether to declare the change or apply + * + * \retval 0 on success + * \retval negative if failed **/ static int lod_mark_dead_object(const struct lu_env *env, struct dt_object *dt, @@ -1018,6 +1132,14 @@ static int lod_mark_dead_object(const struct lu_env *env, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_declare_attr_set. + * + * If the object is striped, then apply the changes to all the stripes. + * + * \see dt_object_operations::do_declare_attr_set() in the API description + * for details. + */ static int lod_declare_attr_set(const struct lu_env *env, struct dt_object *dt, const struct lu_attr *attr, @@ -1107,6 +1229,14 @@ static int lod_declare_attr_set(const struct lu_env *env, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_attr_set. + * + * If the object is striped, then apply the changes to all or subset of + * the stripes depending on the object type and specific attributes. + * + * \see dt_object_operations::do_attr_set() in the API description for details. + */ static int lod_attr_set(const struct lu_env *env, struct dt_object *dt, const struct lu_attr *attr, @@ -1206,6 +1336,14 @@ static int lod_attr_set(const struct lu_env *env, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_xattr_get. + * + * If LOV EA is requested from the root object and it's not + * found, then return default striping for the filesystem. + * + * \see dt_object_operations::do_xattr_get() in the API description for details. + */ static int lod_xattr_get(const struct lu_env *env, struct dt_object *dt, struct lu_buf *buf, const char *name, struct lustre_capa *capa) @@ -1291,6 +1429,17 @@ static int lod_xattr_get(const struct lu_env *env, struct dt_object *dt, RETURN(rc); } +/** + * Verify LVM EA. + * + * Checks that the magic and the number of the stripes are sane. + * + * \param[in] lod lod device + * \param[in] lum a buffer storing LMV EA to verify + * + * \retval 0 if the EA is sane + * \retval negative otherwise + */ static int lod_verify_md_striping(struct lod_device *lod, const struct lmv_user_md_v1 *lum) { @@ -1313,9 +1462,13 @@ out: } /** - * Master LMVEA will be same as slave LMVEA, except - * 1. different magic - * 2. lmv_master_mdt_index on slave LMV EA will be stripe_index. + * Initialize LMV EA for a slave. + * + * Initialize slave's LMV EA from the master's LMV EA. + * + * \param[in] master_lmv a buffer containing master's EA + * \param[out] slave_lmv a buffer where slave's EA will be stored + * */ static void lod_prep_slave_lmv_md(struct lmv_mds_md_v1 *slave_lmv, const struct lmv_mds_md_v1 *master_lmv) @@ -1324,6 +1477,19 @@ static void lod_prep_slave_lmv_md(struct lmv_mds_md_v1 *slave_lmv, slave_lmv->lmv_magic = cpu_to_le32(LMV_MAGIC_STRIPE); } +/** + * Generate LMV EA. + * + * Generate LMV EA from the object passed as \a dt. The object must have + * the stripes created and initialized. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[out] lmv_buf buffer storing generated LMV EA + * + * \retval 0 on success + * \retval negative if failed + */ int lod_prep_lmv_md(const struct lu_env *env, struct dt_object *dt, struct lu_buf *lmv_buf) { @@ -1366,6 +1532,21 @@ int lod_prep_lmv_md(const struct lu_env *env, struct dt_object *dt, RETURN(rc); } +/** + * Create in-core represenation for a striped directory. + * + * Parse the buffer containing LMV EA and instantiate LU objects + * representing the stripe objects. The pointers to the objects are + * stored in ldo_stripe field of \a lo. This function is used when + * we need to access an already created object (i.e. load from a disk). + * + * \param[in] env execution environment + * \param[in] lo lod object + * \param[in] buf buffer containing LMV EA + * + * \retval 0 on success + * \retval negative if failed + */ int lod_parse_dir_striping(const struct lu_env *env, struct lod_object *lo, const struct lu_buf *buf) { @@ -1443,6 +1624,26 @@ out: RETURN(rc); } +/** + * Create a striped directory. + * + * Create a striped directory with a given stripe pattern on the specified MDTs. + * A striped directory is represented as a regular directory - an index listing + * all the stripes. The stripes point back to the master object with ".." and + * LinkEA. The master object gets LMV EA which identifies it as a striped + * directory. The function allocates FIDs for all the stripes. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[in] attr attributes to initialize the objects with + * \param[in] lum a pattern specifying the number of stripes and + * MDT to start from + * \param[in] dof type of objects to be created + * \param[in] th transaction handle + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_prep_md_striped_create(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, @@ -1733,6 +1934,22 @@ out_free: /** * Declare create striped md object. + * + * The function declares intention to create a striped directory. This is a + * wrapper for lod_prep_md_striped_create(). The only additional functionality + * is to verify pattern \a lum_buf is good. Check that function for the details. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[in] attr attributes to initialize the objects with + * \param[in] lum_buf a pattern specifying the number of stripes and + * MDT to start from + * \param[in] dof type of objects to be created + * \param[in] th transaction handle + * + * \retval 0 on success + * \retval negative if failed + * */ static int lod_declare_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt, @@ -1773,6 +1990,17 @@ out: RETURN(rc); } + +/** + * Implementation of dt_object_operations::do_declare_xattr_set. + * + * Used with regular (non-striped) objects. Basically it + * initializes the striping information and applies the + * change to all the stripes. + * + * \see dt_object_operations::do_declare_xattr_set() in the API description + * for details. + */ static int lod_dir_declare_xattr_set(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, @@ -1823,15 +2051,15 @@ static int lod_dir_declare_xattr_set(const struct lu_env *env, RETURN(rc); } -/* - * LOV xattr is a storage for striping, and LOD owns this xattr. - * but LOD allows others to control striping to some extent - * - to reset strping - * - to set new defined striping - * - to set new semi-defined striping - * - number of stripes is defined - * - number of stripes + osts are defined - * - ?? +/** + * Implementation of dt_object_operations::do_declare_xattr_set. + * + * \see dt_object_operations::do_declare_xattr_set() in the API description + * for details. + * + * the extension to the API: + * - declaring LOVEA requests striping creation + * - LU_XATTR_REPLACE means layout swap */ static int lod_declare_xattr_set(const struct lu_env *env, struct dt_object *dt, @@ -1876,6 +2104,11 @@ static int lod_declare_xattr_set(const struct lu_env *env, RETURN(rc); } +/** + * Resets cached default striping in the object. + * + * \param[in] lo object + */ static void lod_lov_stripe_cache_clear(struct lod_object *lo) { lo->ldo_striping_cached = 0; @@ -1887,6 +2120,22 @@ static void lod_lov_stripe_cache_clear(struct lod_object *lo) lo->ldo_dir_striping_cached = 0; } +/** + * Apply xattr changes to the object. + * + * Applies xattr changes to the object and the stripes if the latter exist. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[in] buf buffer pointing to the new value of xattr + * \param[in] name name of xattr + * \param[in] fl flags + * \param[in] th transaction handle + * \param[in] capa not used currently + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_xattr_set_internal(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, @@ -1921,6 +2170,20 @@ static int lod_xattr_set_internal(const struct lu_env *env, RETURN(rc); } +/** + * Delete an extended attribute. + * + * Deletes specified xattr from the object and the stripes if the latter exist. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[in] name name of xattr + * \param[in] th transaction handle + * \param[in] capa not used currently + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_xattr_del_internal(const struct lu_env *env, struct dt_object *dt, const char *name, struct thandle *th, @@ -1950,6 +2213,25 @@ static int lod_xattr_del_internal(const struct lu_env *env, RETURN(rc); } +/** + * Set default striping on a directory. + * + * Sets specified striping on a directory object unless it matches the default + * striping (LOVEA_DELETE_VALUES() macro). In the latter case remove existing + * EA. This striping will be used when regular file is being created in this + * directory. + * + * \param[in] env execution environment + * \param[in] dt the striped object + * \param[in] buf buffer with the striping + * \param[in] name name of EA + * \param[in] fl xattr flag (see OSD API description) + * \param[in] th transaction handle + * \param[in] capa not used + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_xattr_set_lov_on_dir(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, @@ -2003,6 +2285,25 @@ static int lod_xattr_set_lov_on_dir(const struct lu_env *env, RETURN(rc); } +/** + * Set default striping on a directory object. + * + * Sets specified striping on a directory object unless it matches the default + * striping (LOVEA_DELETE_VALUES() macro). In the latter case remove existing + * EA. This striping will be used when a new directory is being created in the + * directory. + * + * \param[in] env execution environment + * \param[in] dt the striped object + * \param[in] buf buffer with the striping + * \param[in] name name of EA + * \param[in] fl xattr flag (see OSD API description) + * \param[in] th transaction handle + * \param[in] capa not used + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_xattr_set_default_lmv_on_dir(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, @@ -2048,6 +2349,26 @@ static int lod_xattr_set_default_lmv_on_dir(const struct lu_env *env, RETURN(rc); } +/** + * Turn directory into a striped directory. + * + * During replay the client sends the striping created before MDT + * failure, then the layer above LOD sends this defined striping + * using ->do_xattr_set(), so LOD uses this method to replay creation + * of the stripes. Notice the original information for the striping + * (#stripes, FIDs, etc) was transfered in declare path. + * + * \param[in] env execution environment + * \param[in] dt the striped object + * \param[in] buf not used currently + * \param[in] name not used currently + * \param[in] fl xattr flag (see OSD API description) + * \param[in] th transaction handle + * \param[in] capa not used + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_xattr_set_lmv(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, const char *name, int fl, struct thandle *th, @@ -2202,6 +2523,28 @@ out: RETURN(rc); } +/** + * Helper function to declare/execute creation of a striped directory + * + * Called in declare/create object path, prepare striping for a directory + * and prepare defaults data striping for the objects to be created in + * that directory. Notice the function calls "declaration" or "execution" + * methods depending on \a declare param. This is a consequence of the + * current approach while we don't have natural distributed transactions: + * we basically execute non-local updates in the declare phase. So, the + * arguments for the both phases are the same and this is the reason for + * this function to exist. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[in] attr attributes the stripes will be created with + * \param[in] dof format of stripes (see OSD API description) + * \param[in] th transaction handle + * \param[in] declare where to call "declare" or "execute" methods + * + * \retval 0 on success + * \retval negative if failed + */ int lod_dir_striping_create_internal(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, @@ -2341,6 +2684,24 @@ static int lod_dir_striping_create(const struct lu_env *env, return lod_dir_striping_create_internal(env, dt, attr, dof, th, false); } +/** + * Implementation of dt_object_operations::do_xattr_set. + * + * Sets specified extended attribute on the object. Three types of EAs are + * special: + * LOV EA - stores striping for a regular file or default striping (when set + * on a directory) + * LMV EA - stores a marker for the striped directories + * DMV EA - stores default directory striping + * + * When striping is applied to a non-striped existing object (this is called + * late striping), then LOD notices the caller wants to turn the object into a + * striped one. The stripe objects are created and appropriate EA is set: + * LOV EA storing all the stripes directly or LMV EA storing just a small header + * with striping configuration. + * + * \see dt_object_operations::do_xattr_set() in the API description for details. + */ static int lod_xattr_set(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, const char *name, int fl, struct thandle *th, @@ -2397,6 +2758,12 @@ static int lod_xattr_set(const struct lu_env *env, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_declare_xattr_del. + * + * \see dt_object_operations::do_declare_xattr_del() in the API description + * for details. + */ static int lod_declare_xattr_del(const struct lu_env *env, struct dt_object *dt, const char *name, struct thandle *th) @@ -2404,6 +2771,14 @@ static int lod_declare_xattr_del(const struct lu_env *env, return dt_declare_xattr_del(env, dt_object_child(dt), name, th); } +/** + * Implementation of dt_object_operations::do_xattr_del. + * + * If EA storing a regular striping is being deleted, then release + * all the references to the stripe objects in core. + * + * \see dt_object_operations::do_xattr_del() in the API description for details. + */ static int lod_xattr_del(const struct lu_env *env, struct dt_object *dt, const char *name, struct thandle *th, struct lustre_capa *capa) @@ -2413,6 +2788,12 @@ static int lod_xattr_del(const struct lu_env *env, struct dt_object *dt, return dt_xattr_del(env, dt_object_child(dt), name, th, capa); } +/** + * Implementation of dt_object_operations::do_xattr_list. + * + * \see dt_object_operations::do_xattr_list() in the API description + * for details. + */ static int lod_xattr_list(const struct lu_env *env, struct dt_object *dt, struct lu_buf *buf, struct lustre_capa *capa) @@ -2420,6 +2801,19 @@ static int lod_xattr_list(const struct lu_env *env, return dt_xattr_list(env, dt_object_child(dt), buf, capa); } +/** + * Initialize a pool the object belongs to. + * + * When a striped object is being created, striping configuration + * may demand the stripes are allocated on a limited set of the + * targets. These limited sets are known as "pools". So we copy + * a pool name into the object and later actual creation methods + * (like lod_object_create()) will use this information to allocate + * the stripes properly. + * + * \param[in] o object + * \param[in] pool pool name + */ int lod_object_set_pool(struct lod_object *o, char *pool) { int len; @@ -2445,6 +2839,18 @@ static inline int lod_object_will_be_striped(int is_reg, const struct lu_fid *fi } +/** + * Cache default regular striping in the object. + * + * To improve performance of striped regular object creation we cache + * default LOV striping (if it exists) in the parent directory object. + * + * \param[in] env execution environment + * \param[in] lp object + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_cache_parent_lov_striping(const struct lu_env *env, struct lod_object *lp) { @@ -2509,6 +2915,18 @@ unlock: } +/** + * Cache default directory striping in the object. + * + * To improve performance of striped directory creation we cache default + * directory striping (if it exists) in the parent directory object. + * + * \param[in] env execution environment + * \param[in] lp object + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_cache_parent_lmv_striping(const struct lu_env *env, struct lod_object *lp) { @@ -2550,6 +2968,22 @@ unlock: return rc; } +/** + * Cache default striping in the object. + * + * To improve performance of striped object creation we cache default striping + * (if it exists) in the parent directory object. We always cache default + * striping for the regular files (stored in LOV EA) and we cache default + * striping for the directories if requested by \a child_mode (when a new + * directory is being created). + * + * \param[in] env execution environment + * \param[in] lp object + * \param[in] child_mode new object's mode + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_cache_parent_striping(const struct lu_env *env, struct lod_object *lp, umode_t child_mode) @@ -2576,7 +3010,15 @@ static int lod_cache_parent_striping(const struct lu_env *env, } /** - * used to transfer default striping data to the object being created + * Implementation of dt_object_operations::do_ah_init. + * + * This method is used to make a decision on the striping configuration for the + * object being created. It can be taken from the \a parent object if it exists, + * or filesystem's default. The resulting configuration (number of stripes, + * stripe size/offset, pool name, etc) is stored in the object itself and will + * be used by the methods like ->doo_declare_create(). + * + * \see dt_object_operations::do_ah_init() in the API description for details. */ static void lod_ah_init(const struct lu_env *env, struct dt_allocation_hint *ah, @@ -2757,11 +3199,21 @@ out: } #define ll_do_div64(aaa,bbb) do_div((aaa), (bbb)) -/* - * this function handles a special case when truncate was done - * on a stripeless object and now striping is being created - * we can't lose that size, so we have to propagate it to newly - * created object +/** + * Size initialization on late striping. + * + * Propagate the size of a truncated object to a deferred striping. + * This function handles a special case when truncate was done on a + * non-striped object and now while the striping is being created + * we can't lose that size, so we have to propagate it to the stripes + * being created. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[in] th transaction handle + * + * \retval 0 on success + * \retval negative if failed */ static int lod_declare_init_size(const struct lu_env *env, struct dt_object *dt, struct thandle *th) @@ -2803,7 +3255,23 @@ static int lod_declare_init_size(const struct lu_env *env, } /** - * Create declaration of striped object + * Declare creation of striped object. + * + * The function declares creation stripes for a regular object. The function + * also declares whether the stripes will be created with non-zero size if + * previously size was set non-zero on the master object. If object \a dt is + * not local, then only fully defined striping can be applied in \a lovea. + * Otherwise \a lovea can be in the form of pattern, see lod_qos_parse_config() + * for the details. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[in] attr attributes the stripes will be created with + * \param[in] lovea a buffer containing striping description + * \param[in] th transaction handle + * + * \retval 0 on success + * \retval negative if failed */ int lod_declare_striped_object(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, @@ -2864,6 +3332,17 @@ out: RETURN(rc); } +/** + * Implementation of dt_object_operations::do_declare_create. + * + * The method declares creation of a new object. If the object will be striped, + * then helper functions are called to find FIDs for the stripes, declare + * creation of the stripes and declare initialization of the striping + * information to be stored in the master object. + * + * \see dt_object_operations::do_declare_create() in the API description + * for details. + */ static int lod_declare_object_create(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, @@ -2914,6 +3393,25 @@ out: RETURN(rc); } +/** + * Creation of a striped regular object. + * + * The function is called to create the stripe objects for a regular + * striped file. This can happen at the initial object creation or + * when the caller asks LOD to do so using ->do_xattr_set() method + * (so called late striping). Notice all the information are already + * prepared in the form of the list of objects (ldo_stripe field). + * This is done during declare phase. + * + * \param[in] env execution environment + * \param[in] dt object + * \param[in] attr attributes the stripes will be created with + * \param[in] dof format of stripes (see OSD API description) + * \param[in] th transaction handle + * + * \retval 0 on success + * \retval negative if failed + */ int lod_striping_create(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, struct dt_object_format *dof, struct thandle *th) @@ -2938,6 +3436,15 @@ int lod_striping_create(const struct lu_env *env, struct dt_object *dt, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_create. + * + * If any of preceeding methods (like ->do_declare_create(), + * ->do_ah_init(), etc) chose to create a striped object, + * then this method will create the master and the stripes. + * + * \see dt_object_operations::do_create() in the API description for details. + */ static int lod_object_create(const struct lu_env *env, struct dt_object *dt, struct lu_attr *attr, struct dt_allocation_hint *hint, @@ -2960,6 +3467,17 @@ static int lod_object_create(const struct lu_env *env, struct dt_object *dt, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_declare_destroy. + * + * If the object is a striped directory, then the function declares reference + * removal from the master object (this is an index) to the stripes and declares + * destroy of all the stripes. In all the cases, it declares an intention to + * destroy the object itself. + * + * \see dt_object_operations::do_declare_destroy() in the API description + * for details. + */ static int lod_declare_object_destroy(const struct lu_env *env, struct dt_object *dt, struct thandle *th) @@ -3022,6 +3540,15 @@ static int lod_declare_object_destroy(const struct lu_env *env, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_destroy. + * + * If the object is a striped directory, then the function removes references + * from the master object (this is an index) to the stripes and destroys all + * the stripes. In all the cases, the function destroys the object itself. + * + * \see dt_object_operations::do_destroy() in the API description for details. + */ static int lod_object_destroy(const struct lu_env *env, struct dt_object *dt, struct thandle *th) { @@ -3081,30 +3608,57 @@ static int lod_object_destroy(const struct lu_env *env, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_declare_ref_add. + * + * \see dt_object_operations::do_declare_ref_add() in the API description + * for details. + */ static int lod_declare_ref_add(const struct lu_env *env, struct dt_object *dt, struct thandle *th) { return dt_declare_ref_add(env, dt_object_child(dt), th); } +/** + * Implementation of dt_object_operations::do_ref_add. + * + * \see dt_object_operations::do_ref_add() in the API description for details. + */ static int lod_ref_add(const struct lu_env *env, struct dt_object *dt, struct thandle *th) { return dt_ref_add(env, dt_object_child(dt), th); } +/** + * Implementation of dt_object_operations::do_declare_ref_del. + * + * \see dt_object_operations::do_declare_ref_del() in the API description + * for details. + */ static int lod_declare_ref_del(const struct lu_env *env, struct dt_object *dt, struct thandle *th) { return dt_declare_ref_del(env, dt_object_child(dt), th); } +/** + * Implementation of dt_object_operations::do_ref_del + * + * \see dt_object_operations::do_ref_del() in the API description for details. + */ static int lod_ref_del(const struct lu_env *env, struct dt_object *dt, struct thandle *th) { return dt_ref_del(env, dt_object_child(dt), th); } +/** + * Implementation of dt_object_operations::do_capa_get. + * + * \see dt_object_operations::do_capa_get() in the API description for details. + */ static struct obd_capa *lod_capa_get(const struct lu_env *env, struct dt_object *dt, struct lustre_capa *old, __u64 opc) @@ -3112,6 +3666,12 @@ static struct obd_capa *lod_capa_get(const struct lu_env *env, return dt_capa_get(env, dt_object_child(dt), old, opc); } +/** + * Implementation of dt_object_operations::do_object_sync. + * + * \see dt_object_operations::do_object_sync() in the API description + * for details. + */ static int lod_object_sync(const struct lu_env *env, struct dt_object *dt, __u64 start, __u64 end) { @@ -3123,6 +3683,20 @@ struct lod_slave_locks { struct lustre_handle lsl_handle[0]; }; +/** + * Release LDLM locks on the stripes of a striped directory. + * + * Iterates over all the locks taken on the stripe objects and + * release them using ->do_object_unlock() method. + * + * \param[in] env execution environment + * \param[in] dt striped object + * \param[in] einfo lock description + * \param[in] policy data describing requested lock + * + * \retval 0 on success + * \retval negative if failed + */ static int lod_object_unlock_internal(const struct lu_env *env, struct dt_object *dt, struct ldlm_enqueue_info *einfo, @@ -3152,6 +3726,14 @@ static int lod_object_unlock_internal(const struct lu_env *env, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_object_unlock. + * + * Used to release LDLM lock(s). + * + * \see dt_object_operations::do_object_unlock() in the API description + * for details. + */ static int lod_object_unlock(const struct lu_env *env, struct dt_object *dt, struct ldlm_enqueue_info *einfo, union ldlm_policy_data *policy) @@ -3188,6 +3770,14 @@ static int lod_object_unlock(const struct lu_env *env, struct dt_object *dt, RETURN(rc); } +/** + * Implementation of dt_object_operations::do_object_lock. + * + * Used to get LDLM lock on the non-striped and striped objects. + * + * \see dt_object_operations::do_object_lock() in the API description + * for details. + */ static int lod_object_lock(const struct lu_env *env, struct dt_object *dt, struct lustre_handle *lh, @@ -3289,6 +3879,11 @@ struct dt_object_operations lod_obj_ops = { .do_object_unlock = lod_object_unlock, }; +/** + * Implementation of dt_body_operations::dbo_read. + * + * \see dt_body_operations::dbo_read() in the API description for details. + */ static ssize_t lod_read(const struct lu_env *env, struct dt_object *dt, struct lu_buf *buf, loff_t *pos, struct lustre_capa *capa) @@ -3297,6 +3892,12 @@ static ssize_t lod_read(const struct lu_env *env, struct dt_object *dt, return next->do_body_ops->dbo_read(env, next, buf, pos, capa); } +/** + * Implementation of dt_body_operations::dbo_declare_write. + * + * \see dt_body_operations::dbo_declare_write() in the API description + * for details. + */ static ssize_t lod_declare_write(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, loff_t pos, @@ -3306,6 +3907,11 @@ static ssize_t lod_declare_write(const struct lu_env *env, buf, pos, th); } +/** + * Implementation of dt_body_operations::dbo_write. + * + * \see dt_body_operations::dbo_write() in the API description for details. + */ static ssize_t lod_write(const struct lu_env *env, struct dt_object *dt, const struct lu_buf *buf, loff_t *pos, struct thandle *th, struct lustre_capa *capa, int iq) @@ -3321,6 +3927,17 @@ static const struct dt_body_operations lod_body_lnk_ops = { .dbo_write = lod_write }; +/** + * Implementation of lu_object_operations::loo_object_init. + * + * The function determines the type and the index of the target device using + * sequence of the object's FID. Then passes control down to the + * corresponding device: + * OSD for the local objects, OSP for remote + * + * \see lu_object_operations::loo_object_init() in the API description + * for details. + */ static int lod_object_init(const struct lu_env *env, struct lu_object *lo, const struct lu_object_conf *conf) { @@ -3376,6 +3993,16 @@ static int lod_object_init(const struct lu_env *env, struct lu_object *lo, RETURN(0); } +/** + * + * Release resources associated with striping. + * + * If the object is striped (regular or directory), then release + * the stripe objects references and free the ldo_stripe array. + * + * \param[in] env execution environment + * \param[in] lo object + */ void lod_object_free_striping(const struct lu_env *env, struct lod_object *lo) { int i; @@ -3402,9 +4029,11 @@ void lod_object_free_striping(const struct lu_env *env, struct lod_object *lo) lo->ldo_pattern = 0; } -/* - * ->start is called once all slices are initialized, including header's - * cache for mode (object type). using the type we can initialize ops +/** + * Implementation of lu_object_operations::loo_object_start. + * + * \see lu_object_operations::loo_object_start() in the API description + * for details. */ static int lod_object_start(const struct lu_env *env, struct lu_object *o) { @@ -3413,6 +4042,12 @@ static int lod_object_start(const struct lu_env *env, struct lu_object *o) return 0; } +/** + * Implementation of lu_object_operations::loo_object_free. + * + * \see lu_object_operations::loo_object_free() in the API description + * for details. + */ static void lod_object_free(const struct lu_env *env, struct lu_object *o) { struct lod_object *mo = lu2lod_obj(o); @@ -3429,12 +4064,24 @@ static void lod_object_free(const struct lu_env *env, struct lu_object *o) OBD_SLAB_FREE_PTR(mo, lod_object_kmem); } +/** + * Implementation of lu_object_operations::loo_object_release. + * + * \see lu_object_operations::loo_object_release() in the API description + * for details. + */ static void lod_object_release(const struct lu_env *env, struct lu_object *o) { /* XXX: shouldn't we release everything here in case if object * creation failed before? */ } +/** + * Implementation of lu_object_operations::loo_object_print. + * + * \see lu_object_operations::loo_object_print() in the API description + * for details. + */ static int lod_object_print(const struct lu_env *env, void *cookie, lu_printer_t p, const struct lu_object *l) {