X-Git-Url: https://git.whamcloud.com/?p=fs%2Flustre-release.git;a=blobdiff_plain;f=lustre%2Flov%2Flov_cl_internal.h;h=65009f9a8410470d708a96a8f611fea4a70510eb;hp=6a98fbc4ad4aab7f11daa3280e94789a97b5f91f;hb=0b1ad400c8f64575292a7ff54a8ce872a124b19e;hpb=89f659febd4220cc517a181f8ac6cc52235b76ca diff --git a/lustre/lov/lov_cl_internal.h b/lustre/lov/lov_cl_internal.h index 6a98fbc..65009f9 100644 --- a/lustre/lov/lov_cl_internal.h +++ b/lustre/lov/lov_cl_internal.h @@ -1,6 +1,4 @@ -/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- - * vim:expandtab:shiftwidth=8:tabstop=8: - * +/* * GPL HEADER START * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -26,8 +24,10 @@ * GPL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved + * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Use is subject to license terms. + * + * Copyright (c) 2012, 2015, Intel Corporation. */ /* * This file is part of Lustre, http://www.lustre.org/ @@ -40,23 +40,17 @@ * Internal interfaces of LOV layer. * * Author: Nikita Danilov + * Author: Jinshan Xiong */ #ifndef LOV_CL_INTERNAL_H #define LOV_CL_INTERNAL_H -#ifdef __KERNEL__ -# include -#else -# include -#endif - +#include #include #include #include "lov_internal.h" -/** \addtogroup lov lov @{ */ - /** \defgroup lov lov * Logical object volume layer. This layer implements data striping (raid0). * @@ -78,24 +72,11 @@ * - top-page keeps a reference to its sub-page, and destroys it when it * is destroyed. * - * - sub-lock keep a reference to its top-locks. Top-lock keeps a - * reference (and a hold, see cl_lock_hold()) on its sub-locks when it - * actively using them (that is, in cl_lock_state::CLS_QUEUING, - * cl_lock_state::CLS_ENQUEUED, cl_lock_state::CLS_HELD states). When - * moving into cl_lock_state::CLS_CACHED state, top-lock releases a - * hold. From this moment top-lock has only a 'weak' reference to its - * sub-locks. This reference is protected by top-lock - * cl_lock::cll_guard, and will be automatically cleared by the sub-lock - * when the latter is destroyed. When a sub-lock is canceled, a - * reference to it is removed from the top-lock array, and top-lock is - * moved into CLS_NEW state. It is guaranteed that all sub-locks exits - * while their top-lock is in CLS_HELD or CLS_CACHED states. - * * - IO's are not reference counted. * * To implement a connection between top and sub entities, lov layer is split * into two pieces: lov ("upper half"), and lovsub ("bottom half"), both - * implementing full set of cl-interfaces. For example, top-object has clu and + * implementing full set of cl-interfaces. For example, top-object has vvp and * lov layers, and it's sub-object has lovsub and osc layers. lovsub layer is * used to track child-parent relationship. * @@ -140,7 +121,7 @@ struct lov_device_emerg { * * \see cl_env_get() */ - int emrg_refcheck; + __u16 emrg_refcheck; }; struct lov_device { @@ -160,22 +141,35 @@ struct lov_device { * Serializes access to lov_device::ld_emrg in low-memory * conditions. */ - struct mutex ld_mutex; + struct mutex ld_mutex; }; /** * Layout type. */ enum lov_layout_type { - /** empty file without body */ - LLT_EMPTY, - /** striped file */ - LLT_RAID0, - /** join file */ - LLT_JOIN, - LLT_NR + LLT_EMPTY, /** empty file without body (mknod + truncate) */ + LLT_RAID0, /** striped file */ + LLT_RELEASED, /** file with no objects (data in HSM) */ + LLT_NR }; +static inline char *llt2str(enum lov_layout_type llt) +{ + switch (llt) { + case LLT_EMPTY: + return "EMPTY"; + case LLT_RAID0: + return "RAID0"; + case LLT_RELEASED: + return "RELEASED"; + case LLT_NR: + LBUG(); + } + LBUG(); + return ""; +} + /** * lov-specific file state. * @@ -191,152 +185,116 @@ enum lov_layout_type { * function corresponding to the current layout type. */ struct lov_object { - struct cl_object lo_cl; - /** - * Serializes object operations with transitions between layout types. - * - * This semaphore is taken in shared mode by all object methods, and - * is taken in exclusive mode when object type is changed. - * - * \see lov_object::lo_type - */ - struct rw_semaphore lo_type_guard; - /** - * Type of an object. Protected by lov_object::lo_type_guard. - */ - enum lov_layout_type lo_type; - - union lov_layout_state { - struct lov_layout_raid0 { - unsigned lo_nr; - struct lov_stripe_md *lo_lsm; - /** - * Array of sub-objects. Allocated when top-object is - * created (lov_init_raid0()). - * - * Top-object is a strict master of its sub-objects: - * it is created before them, and outlives its - * children (this later is necessary so that basic - * functions like cl_object_top() always - * work). Top-object keeps a reference on every - * sub-object. - * - * When top-object is destroyed (lov_delete_raid0()) - * it releases its reference to a sub-object and waits - * until the latter is finally destroyed. - */ - struct lovsub_object **lo_sub; - /** - * When this is true, lov_object::lo_attr contains - * valid up to date attributes for a top-level - * object. This field is reset to 0 when attributes of - * any sub-object change. - */ - int lo_attr_valid; - /** - * Cached object attribute, built from sub-object - * attributes. - */ - struct cl_attr lo_attr; - } raid0; - struct lov_layout_state_empty { - } empty; - struct lov_layout_state_join { - } join; - } u; - /** - * Thread that acquired lov_object::lo_type_guard in an exclusive - * mode. - */ - cfs_task_t *lo_owner; -}; - -/** - * Flags that top-lock can set on each of its sub-locks. - */ -enum lov_sub_flags { - /** Top-lock acquired a hold (cl_lock_hold()) on a sub-lock. */ - LSF_HELD = 1 << 0 + struct cl_object lo_cl; + /** + * Serializes object operations with transitions between layout types. + * + * This semaphore is taken in shared mode by all object methods, and + * is taken in exclusive mode when object type is changed. + * + * \see lov_object::lo_type + */ + struct rw_semaphore lo_type_guard; + /** + * Type of an object. Protected by lov_object::lo_type_guard. + */ + enum lov_layout_type lo_type; + /** + * True if layout is invalid. This bit is cleared when layout lock + * is lost. + */ + bool lo_layout_invalid; + /** + * How many IOs are on going on this object. Layout can be changed + * only if there is no active IO. + */ + atomic_t lo_active_ios; + /** + * Waitq - wait for no one else is using lo_lsm + */ + wait_queue_head_t lo_waitq; + /** + * Layout metadata. NULL if empty layout. + */ + struct lov_stripe_md *lo_lsm; + + union lov_layout_state { + struct lov_layout_raid0 { + unsigned lo_nr; + /** + * When this is true, lov_object::lo_attr contains + * valid up to date attributes for a top-level + * object. This field is reset to 0 when attributes of + * any sub-object change. + */ + int lo_attr_valid; + /** + * Array of sub-objects. Allocated when top-object is + * created (lov_init_raid0()). + * + * Top-object is a strict master of its sub-objects: + * it is created before them, and outlives its + * children (this later is necessary so that basic + * functions like cl_object_top() always + * work). Top-object keeps a reference on every + * sub-object. + * + * When top-object is destroyed (lov_delete_raid0()) + * it releases its reference to a sub-object and waits + * until the latter is finally destroyed. + * + * May be vmalloc'd, must be freed with OBD_FREE_LARGE. + */ + struct lovsub_object **lo_sub; + /** + * protect lo_sub + */ + spinlock_t lo_sub_lock; + /** + * Cached object attribute, built from sub-object + * attributes. + */ + struct cl_attr lo_attr; + } raid0; + struct lov_layout_state_empty { + } empty; + struct lov_layout_state_released { + } released; + } u; + /** + * Thread that acquired lov_object::lo_type_guard in an exclusive + * mode. + */ + struct task_struct *lo_owner; }; /** * State lov_lock keeps for each sub-lock. */ struct lov_lock_sub { - /** sub-lock itself */ - struct lovsub_lock *sub_lock; - /** An array of per-sub-lock flags, taken from enum lov_sub_flags */ - unsigned sub_flags; - int sub_stripe; - struct cl_lock_descr sub_descr; - struct cl_lock_descr sub_got; + /** sub-lock itself */ + struct cl_lock sub_lock; + /** Set if the sublock has ever been enqueued, meaning it may + * hold resources of underlying layers */ + unsigned int sub_is_enqueued:1, + sub_initialized:1; + int sub_stripe; }; /** * lov-specific lock state. */ struct lov_lock { - struct cl_lock_slice lls_cl; - /** Number of sub-locks in this lock */ - int lls_nr; - /** - * Number of existing sub-locks. - */ - unsigned lls_nr_filled; - /** - * Set when sub-lock was canceled, while top-lock was being - * unlocked. - */ - int lls_unuse_race; - /** - * An array of sub-locks - * - * There are two issues with managing sub-locks: - * - * - sub-locks are concurrently canceled, and - * - * - sub-locks are shared with other top-locks. - * - * To manage cancellation, top-lock acquires a hold on a sublock - * (lov_sublock_adopt()) when the latter is inserted into - * lov_lock::lls_sub[]. This hold is released (lov_sublock_release()) - * when top-lock is going into CLS_CACHED state or destroyed. Hold - * prevents sub-lock from cancellation. - * - * Sub-lock sharing means, among other things, that top-lock that is - * in the process of creation (i.e., not yet inserted into lock list) - * is already accessible to other threads once at least one of its - * sub-locks is created, see lov_lock_sub_init(). - * - * Sub-lock can be in one of the following states: - * - * - doesn't exist, lov_lock::lls_sub[]::sub_lock == NULL. Such - * sub-lock was either never created (top-lock is in CLS_NEW - * state), or it was created, then canceled, then destroyed - * (lov_lock_unlink() cleared sub-lock pointer in the top-lock). - * - * - sub-lock exists and is on - * hold. (lov_lock::lls_sub[]::sub_flags & LSF_HELD). This is a - * normal state of a sub-lock in CLS_HELD and CLS_CACHED states - * of a top-lock. - * - * - sub-lock exists, but is not held by the top-lock. This - * happens after top-lock released a hold on sub-locks before - * going into cache (lov_lock_unuse()). - * - * \todo To support wide-striping, array has to be replaced with a set - * of queues to avoid scanning. - */ - struct lov_lock_sub *lls_sub; - /** - * Original description with which lock was enqueued. - */ - struct cl_lock_descr lls_orig; + struct cl_lock_slice lls_cl; + /** Number of sub-locks in this lock */ + int lls_nr; + /** sublock array */ + struct lov_lock_sub lls_sub[0]; }; struct lov_page { - struct cl_page_slice lps_cl; - int lps_invalid; + struct cl_page_slice lps_cl; + unsigned int lps_stripe; /* stripe index */ }; /* @@ -372,7 +330,7 @@ struct lov_lock_link { * A linkage into per sub-lock list of all corresponding top-locks, * hanging off lovsub_lock::lss_parents. */ - struct list_head lll_list; + struct list_head lll_list; }; /** @@ -384,7 +342,7 @@ struct lovsub_lock { * List of top-locks that have given sub-lock as their part. Protected * by cl_lock::cll_guard mutex. */ - struct list_head lss_parents; + struct list_head lss_parents; /** * Top-lock that initiated current operation on this sub-lock. This is * only set during top-to-bottom lock operations like enqueue, and is @@ -411,55 +369,53 @@ struct lovsub_page { struct lov_thread_info { - struct cl_object_conf lti_stripe_conf; - struct lu_fid lti_fid; - struct cl_lock_descr lti_ldescr; - struct ost_lvb lti_lvb; - struct cl_2queue lti_cl2q; - union lov_layout_state lti_state; - struct cl_lock_closure lti_closure; - cfs_waitlink_t lti_waiter; + struct cl_object_conf lti_stripe_conf; + struct lu_fid lti_fid; + struct cl_lock_descr lti_ldescr; + struct ost_lvb lti_lvb; + struct cl_2queue lti_cl2q; + struct cl_page_list lti_plist; + wait_queue_t lti_waiter; + struct cl_attr lti_attr; }; /** * State that lov_io maintains for every sub-io. */ struct lov_io_sub { - int sub_stripe; - /** - * sub-io for a stripe. Ideally sub-io's can be stopped and resumed - * independently, with lov acting as a scheduler to maximize overall - * throughput. - */ - struct cl_io *sub_io; - /** - * Linkage into a list (hanging off lov_io::lis_active) of all - * sub-io's active for the current IO iteration. - */ - struct list_head sub_linkage; - /** - * true, iff cl_io_init() was successfully executed against - * lov_io_sub::sub_io. - */ - int sub_io_initialized; - /** - * True, iff lov_io_sub::sub_io and lov_io_sub::sub_env weren't - * allocated, but borrowed from a per-device emergency pool. - */ - int sub_borrowed; - /** - * environment, in which sub-io executes. - */ - struct lu_env *sub_env; - /** - * environment's refcheck. - * - * \see cl_env_get() - */ - int sub_refcheck; - int sub_refcheck2; - int sub_reenter; - void *sub_cookie; + __u16 sub_stripe; + /** + * environment's refcheck. + * + * \see cl_env_get() + */ + __u16 sub_refcheck; + __u16 sub_reenter; + /** + * true, iff cl_io_init() was successfully executed against + * lov_io_sub::sub_io. + */ + __u16 sub_io_initialized:1, + /** + * True, iff lov_io_sub::sub_io and lov_io_sub::sub_env weren't + * allocated, but borrowed from a per-device emergency pool. + */ + sub_borrowed:1; + /** + * Linkage into a list (hanging off lov_io::lis_active) of all + * sub-io's active for the current IO iteration. + */ + struct list_head sub_linkage; + /** + * sub-io for a stripe. Ideally sub-io's can be stopped and resumed + * independently, with lov acting as a scheduler to maximize overall + * throughput. + */ + struct cl_io *sub_io; + /** + * environment, in which sub-io executes. + */ + struct lu_env *sub_env; }; /** @@ -487,32 +443,33 @@ struct lov_io { * starting position within a file, for the current io loop iteration * (stripe), used by ci_io_loop(). */ - obd_off lis_pos; - /** - * end position with in a file, for the current stripe io. This is - * exclusive (i.e., next offset after last byte affected by io). - */ - obd_off lis_endpos; - - int lis_mem_frozen; - int lis_stripe_count; - int lis_active_subios; - - /** - * the index of ls_single_subio in ls_subios array - */ - int lis_single_subio_index; - struct cl_io lis_single_subio; - - /** - * size of ls_subios array, actually the highest stripe # - */ - int lis_nr_subios; - struct lov_io_sub *lis_subs; - /** - * List of active sub-io's. - */ - struct list_head lis_active; + loff_t lis_pos; + /** + * end position with in a file, for the current stripe io. This is + * exclusive (i.e., next offset after last byte affected by io). + */ + loff_t lis_endpos; + + int lis_mem_frozen; + int lis_stripe_count; + int lis_active_subios; + + /** + * the index of ls_single_subio in ls_subios array + */ + int lis_single_subio_index; + struct cl_io lis_single_subio; + + /** + * size of ls_subios array, actually the highest stripe # + * May be vmalloc'd, must be freed with OBD_FREE_LARGE(). + */ + int lis_nr_subios; + struct lov_io_sub *lis_subs; + /** + * List of active sub-io's. + */ + struct list_head lis_active; }; struct lov_session { @@ -520,39 +477,21 @@ struct lov_session { struct lov_sublock_env ls_subenv; }; -/** - * State of transfer for lov. - */ -struct lov_req { - struct cl_req_slice lr_cl; -}; - -/** - * State of transfer for lovsub. - */ -struct lovsub_req { - struct cl_req_slice lsrq_cl; -}; - extern struct lu_device_type lov_device_type; extern struct lu_device_type lovsub_device_type; extern struct lu_context_key lov_key; extern struct lu_context_key lov_session_key; -extern cfs_mem_cache_t *lov_page_kmem; -extern cfs_mem_cache_t *lov_lock_kmem; -extern cfs_mem_cache_t *lov_object_kmem; -extern cfs_mem_cache_t *lov_thread_kmem; -extern cfs_mem_cache_t *lov_session_kmem; -extern cfs_mem_cache_t *lov_req_kmem; +extern struct kmem_cache *lov_lock_kmem; +extern struct kmem_cache *lov_object_kmem; +extern struct kmem_cache *lov_thread_kmem; +extern struct kmem_cache *lov_session_kmem; -extern cfs_mem_cache_t *lovsub_page_kmem; -extern cfs_mem_cache_t *lovsub_lock_kmem; -extern cfs_mem_cache_t *lovsub_object_kmem; -extern cfs_mem_cache_t *lovsub_req_kmem; +extern struct kmem_cache *lovsub_lock_kmem; +extern struct kmem_cache *lovsub_object_kmem; -extern cfs_mem_cache_t *lov_lock_link_kmem; +extern struct kmem_cache *lov_lock_link_kmem; int lov_object_init (const struct lu_env *env, struct lu_object *obj, const struct lu_object_conf *conf); @@ -567,10 +506,14 @@ int lovsub_lock_init (const struct lu_env *env, struct cl_object *obj, int lov_lock_init_raid0 (const struct lu_env *env, struct cl_object *obj, struct cl_lock *lock, const struct cl_io *io); +int lov_lock_init_empty (const struct lu_env *env, struct cl_object *obj, + struct cl_lock *lock, const struct cl_io *io); int lov_io_init_raid0 (const struct lu_env *env, struct cl_object *obj, struct cl_io *io); int lov_io_init_empty (const struct lu_env *env, struct cl_object *obj, struct cl_io *io); +int lov_io_init_released(const struct lu_env *env, struct cl_object *obj, + struct cl_io *io); void lov_lock_unlink (const struct lu_env *env, struct lov_lock_link *link, struct lovsub_lock *sub); @@ -582,17 +525,14 @@ int lov_sublock_modify (const struct lu_env *env, struct lov_lock *lov, const struct cl_lock_descr *d, int idx); -struct cl_page *lov_page_init (const struct lu_env *env, struct cl_object *ob, - struct cl_page *page, cfs_page_t *vmpage); -struct cl_page *lovsub_page_init(const struct lu_env *env, struct cl_object *ob, - struct cl_page *page, cfs_page_t *vmpage); - -struct cl_page *lov_page_init_empty(const struct lu_env *env, - struct cl_object *obj, - struct cl_page *page, cfs_page_t *vmpage); -struct cl_page *lov_page_init_raid0(const struct lu_env *env, - struct cl_object *obj, - struct cl_page *page, cfs_page_t *vmpage); +int lov_page_init (const struct lu_env *env, struct cl_object *ob, + struct cl_page *page, pgoff_t index); +int lovsub_page_init (const struct lu_env *env, struct cl_object *ob, + struct cl_page *page, pgoff_t index); +int lov_page_init_empty (const struct lu_env *env, struct cl_object *obj, + struct cl_page *page, pgoff_t index); +int lov_page_init_raid0 (const struct lu_env *env, struct cl_object *obj, + struct cl_page *page, pgoff_t index); struct lu_object *lov_object_alloc (const struct lu_env *env, const struct lu_object_header *hdr, struct lu_device *dev); @@ -607,6 +547,8 @@ struct lov_io_sub *lov_page_subio (const struct lu_env *env, struct lov_io *lio, const struct cl_page_slice *slice); +struct lov_stripe_md *lov_lsm_addref(struct lov_object *lov); +int lov_page_stripe(const struct cl_page *page); #define lov_foreach_target(lov, var) \ for (var = 0; var < lov_targets_nr(lov); ++var) @@ -748,11 +690,6 @@ static inline struct lov_page *cl2lov_page(const struct cl_page_slice *slice) return container_of0(slice, struct lov_page, lps_cl); } -static inline struct lov_req *cl2lov_req(const struct cl_req_slice *slice) -{ - return container_of0(slice, struct lov_req, lr_cl); -} - static inline struct lovsub_page * cl2lovsub_page(const struct cl_page_slice *slice) { @@ -760,16 +697,6 @@ cl2lovsub_page(const struct cl_page_slice *slice) return container_of0(slice, struct lovsub_page, lsb_cl); } -static inline struct lovsub_req *cl2lovsub_req(const struct cl_req_slice *slice) -{ - return container_of0(slice, struct lovsub_req, lsrq_cl); -} - -static inline struct cl_page *lov_sub_page(const struct cl_page_slice *slice) -{ - return slice->cpl_page->cp_child; -} - static inline struct lov_io *cl2lov_io(const struct lu_env *env, const struct cl_io_slice *ios) { @@ -796,15 +723,16 @@ static inline struct lov_thread_info *lov_env_info(const struct lu_env *env) static inline struct lov_layout_raid0 *lov_r0(struct lov_object *lov) { - struct lov_layout_raid0 *raid0; - - LASSERT(lov->lo_type == LLT_RAID0); - raid0 = &lov->u.raid0; - LASSERT(raid0->lo_lsm->lsm_wire.lw_magic == LOV_MAGIC); - return raid0; + LASSERT(lov->lo_type == LLT_RAID0); + LASSERT(lov->lo_lsm->lsm_magic == LOV_MAGIC || + lov->lo_lsm->lsm_magic == LOV_MAGIC_V3); + 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 -