X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Finclude%2Flu_object.h;h=73fe7af54fc4dfb555bc38bfc87c926b5a209a23;hb=4c98c57e9fe2c30f5401f18f5ab024cdb7cf5b7b;hp=293cc28be11231abd875bf67bfc6d934d7261b5a;hpb=10beeaac59f4d8b9aff0587f0db235044320c44d;p=fs%2Flustre-release.git diff --git a/lustre/include/lu_object.h b/lustre/include/lu_object.h index 293cc28..73fe7af 100644 --- a/lustre/include/lu_object.h +++ b/lustre/include/lu_object.h @@ -143,7 +143,7 @@ struct lu_device_operations { * repeatedly, until no new objects are created. * * \post ergo(!IS_ERR(result), result->lo_dev == d && - * result->lo_ops != NULL); + * result->lo_ops != NULL); */ struct lu_object *(*ldo_object_alloc)(const struct lu_env *env, const struct lu_object_header *h, @@ -156,6 +156,24 @@ struct lu_device_operations { int (*ldo_recovery_complete)(const struct lu_env *, struct lu_device *); + /** + * initialize local objects for device. this method called after layer has + * been initialized (after LCFG_SETUP stage) and before it starts serving + * user requests. + */ + + int (*ldo_prepare)(const struct lu_env *, + struct lu_device *parent, + struct lu_device *dev); + +}; + +/** + * Object configuration, describing particulars of object being created. On + * server this is not used, as server objects are full identified by fid. On + * client configuration contains struct lustre_md. + */ +struct lu_object_conf { }; /** @@ -169,7 +187,7 @@ typedef int (*lu_printer_t)(const struct lu_env *env, void *cookie, const char *format, ...) __attribute__ ((format (printf, 3, 4))); -/* +/** * Operations specific for particular lu_object. */ struct lu_object_operations { @@ -239,7 +257,7 @@ struct lu_device { * * \todo XXX which means that atomic_t is probably too small. */ - atomic_t ld_ref; + atomic_t ld_ref; /** * Pointer to device type. Never modified once set. */ @@ -251,11 +269,11 @@ struct lu_device { /** * Stack this device belongs to. */ - struct lu_site *ld_site; - struct proc_dir_entry *ld_proc_entry; + struct lu_site *ld_site; + struct proc_dir_entry *ld_proc_entry; /** \todo XXX: temporary back pointer into obd. */ - struct obd_device *ld_obd; + struct obd_device *ld_obd; /** * A list of references to this object, for debugging. */ @@ -284,11 +302,11 @@ struct lu_device_type { /** * Tag bits. Taken from enum lu_device_tag. Never modified once set. */ - __u32 ldt_tags; + __u32 ldt_tags; /** * Name of this class. Unique system-wide. Never modified once set. */ - char *ldt_name; + char *ldt_name; /** * Operations for this type. */ @@ -296,11 +314,11 @@ struct lu_device_type { /** * \todo XXX: temporary pointer to associated obd_type. */ - struct obd_type *ldt_obd_type; + struct obd_type *ldt_obd_type; /** * \todo XXX: temporary: context tags used by obd_*() calls. */ - __u32 ldt_ctx_tags; + __u32 ldt_ctx_tags; /** * Number of existing device type instances. */ @@ -429,38 +447,42 @@ enum la_valid { LA_BLKSIZE = 1 << 12, }; -/* +/** * Layer in the layered object. */ struct lu_object { - /* + /** * Header for this object. */ - struct lu_object_header *lo_header; - /* + struct lu_object_header *lo_header; + /** * Device for this layer. */ - struct lu_device *lo_dev; - /* + struct lu_device *lo_dev; + /** * Operations for this object. */ - struct lu_object_operations *lo_ops; - /* + const struct lu_object_operations *lo_ops; + /** * Linkage into list of all layers. */ - struct list_head lo_linkage; - /* + struct list_head lo_linkage; + /** * Depth. Top level layer depth is 0. */ - int lo_depth; - /* + int lo_depth; + /** * Flags from enum lu_object_flags. */ - unsigned long lo_flags; + unsigned long lo_flags; + /** + * Link to the device, for debugging. + */ + struct lu_ref_link *lo_dev_ref; }; enum lu_object_header_flags { - /* + /** * Don't keep this object in cache. Object will be destroyed as soon * as last reference to it is released. This flag cannot be cleared * once set. @@ -471,14 +493,14 @@ enum lu_object_header_flags { enum lu_object_header_attr { LOHA_EXISTS = 1 << 0, LOHA_REMOTE = 1 << 1, - /* + /** * UNIX file type is stored in S_IFMT bits. */ - LOHA_FT_START = 1 << 12, /* S_IFIFO */ - LOHA_FT_END = 1 << 15, /* S_IFREG */ + LOHA_FT_START = 1 << 12, /**< S_IFIFO */ + LOHA_FT_END = 1 << 15, /**< S_IFREG */ }; -/* +/** * "Compound" object, consisting of multiple layers. * * Compound object with given fid is unique with given lu_site. @@ -494,33 +516,33 @@ struct lu_object_header { * Object flags from enum lu_object_header_flags. Set and checked * atomically. */ - unsigned long loh_flags; + unsigned long loh_flags; /** * Object reference count. Protected by lu_site::ls_guard. */ - atomic_t loh_ref; + atomic_t loh_ref; /** * Fid, uniquely identifying this object. */ - struct lu_fid loh_fid; + struct lu_fid loh_fid; /** * Common object attributes, cached for efficiency. From enum * lu_object_header_attr. */ - __u32 loh_attr; + __u32 loh_attr; /** * Linkage into per-site hash table. Protected by lu_site::ls_guard. */ - struct hlist_node loh_hash; + struct hlist_node loh_hash; /** * Linkage into per-site LRU list. Protected by lu_site::ls_guard. */ - struct list_head loh_lru; + struct list_head loh_lru; /** * Linkage into list of layers. Never modified once set (except lately * during object destruction). No locking is necessary. */ - struct list_head loh_layers; + struct list_head loh_layers; /** * A list of references to this object, for debugging. */ @@ -596,38 +618,26 @@ struct lu_site { * Top-level device for this stack. */ struct lu_device *ls_top_dev; - /* - * mds number of this site. - */ - mdsno_t ls_node_id; - /* - * Fid location database - */ - struct lu_server_fld *ls_server_fld; - struct lu_client_fld *ls_client_fld; - - /* - * Server Seq Manager - */ - struct lu_server_seq *ls_server_seq; - - /* - * Controller Seq Manager - */ - struct lu_server_seq *ls_control_seq; - struct obd_export *ls_control_exp; - /* - * Client Seq Manager + /** + * Wait-queue signaled when an object in this site is ultimately + * destroyed (lu_object_free()). It is used by lu_object_find() to + * wait before re-trying when object in the process of destruction is + * found in the hash table. + * + * If having a single wait-queue turns out to be a problem, a + * wait-queue per hash-table bucket can be easily implemented. + * + * \see htable_lookup(). */ - struct lu_client_seq *ls_client_seq; + cfs_waitq_t ls_marche_funebre; - /* statistical counters. Protected by nothing, races are accepted. */ + /** statistical counters. Protected by nothing, races are accepted. */ struct { __u32 s_created; __u32 s_cache_hit; __u32 s_cache_miss; - /* + /** * Number of hash-table entry checks made. * * ->s_cache_check / (->s_cache_miss + ->s_cache_hit) @@ -667,10 +677,10 @@ void lu_device_get (struct lu_device *d); void lu_device_put (struct lu_device *d); int lu_device_init (struct lu_device *d, struct lu_device_type *t); void lu_device_fini (struct lu_device *d); -int lu_object_header_init(struct lu_object_header *h); +int lu_object_header_init(struct lu_object_header *h); void lu_object_header_fini(struct lu_object_header *h); int lu_object_init (struct lu_object *o, - struct lu_object_header *h, struct lu_device *d); + struct lu_object_header *h, struct lu_device *d); void lu_object_fini (struct lu_object *o); void lu_object_add_top (struct lu_object_header *h, struct lu_object *o); void lu_object_add (struct lu_object *before, struct lu_object *o); @@ -710,37 +720,31 @@ static inline int lu_object_is_dying(const struct lu_object_header *h) return test_bit(LU_OBJECT_HEARD_BANSHEE, &h->loh_flags); } -/* - * Decrease reference counter on object. If last reference is freed, return - * object to the cache, unless lu_object_is_dying(o) holds. In the latter - * case, free object immediately. - */ -void lu_object_put(const struct lu_env *env, - struct lu_object *o); +void lu_object_put(const struct lu_env *env, struct lu_object *o); -/* - * Free @nr objects from the cold end of the site LRU list. - */ int lu_site_purge(const struct lu_env *env, struct lu_site *s, int nr); -/* - * Print all objects in @s. - */ void lu_site_print(const struct lu_env *env, struct lu_site *s, void *cookie, lu_printer_t printer); -/* - * Search cache for an object with the fid @f. If such object is found, return - * it. Otherwise, create new object, insert it into cache and return it. In - * any case, additional reference is acquired on the returned object. - */ struct lu_object *lu_object_find(const struct lu_env *env, - struct lu_site *s, const struct lu_fid *f); - -/* + struct lu_device *dev, const struct lu_fid *f, + const struct lu_object_conf *conf); +struct lu_object *lu_object_find_at(const struct lu_env *env, + struct lu_device *dev, + const struct lu_fid *f, + const struct lu_object_conf *conf); +struct lu_object *lu_object_find_slice(const struct lu_env *env, + struct lu_device *dev, + const struct lu_fid *f, + const struct lu_object_conf *conf); +/** @} caching */ + +/** \name helpers * Helpers. + * @{ */ -/* +/** * First (topmost) sub-object of given compound object */ static inline struct lu_object *lu_object_top(struct lu_object_header *h) @@ -765,21 +769,21 @@ static inline const struct lu_fid *lu_object_fid(const struct lu_object *o) return &o->lo_header->loh_fid; } -/* +/** * return device operations vector for this object */ -static inline struct lu_device_operations * +static const inline struct lu_device_operations * lu_object_ops(const struct lu_object *o) { return o->lo_dev->ld_ops; } -/* +/** * Given a compound object, find its slice, corresponding to the device type - * @dtype. + * \a dtype. */ struct lu_object *lu_object_locate(struct lu_object_header *h, - struct lu_device_type *dtype); + const struct lu_device_type *dtype); struct lu_cdebug_print_info { int lpi_subsys; @@ -789,7 +793,7 @@ struct lu_cdebug_print_info { int lpi_line; }; -/* +/** * Printer function emitting messages through libcfs_debug_msg(). */ int lu_cdebug_printer(const struct lu_env *env, @@ -802,36 +806,50 @@ int lu_cdebug_printer(const struct lu_env *env, .lpi_file = __FILE__, \ .lpi_fn = __FUNCTION__, \ .lpi_line = __LINE__ \ - }; + } -/* - * Print object description followed by user-supplied message. +/** + * Print object description followed by a user-supplied message. */ #define LU_OBJECT_DEBUG(mask, env, object, format, ...) \ -({ \ +do { \ static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask); \ \ - lu_object_print(env, &__info, lu_cdebug_printer, object); \ - CDEBUG(mask, format , ## __VA_ARGS__); \ -}) + if (cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ + lu_object_print(env, &__info, lu_cdebug_printer, object); \ + CDEBUG(mask, format , ## __VA_ARGS__); \ + } \ +} while (0) -/* - * Print human readable representation of the @o to the @f. +/** + * Print short object description followed by a user-supplied message. */ -void lu_object_print(const struct lu_env *env, void *cookie, - lu_printer_t printer, const struct lu_object *o); +#define LU_OBJECT_HEADER(mask, env, object, format, ...) \ +do { \ + static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask); \ + \ + if (cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ + lu_object_header_print(env, &__info, lu_cdebug_printer, \ + (object)->lo_header); \ + lu_cdebug_printer(env, &__info, "\n"); \ + CDEBUG(mask, format , ## __VA_ARGS__); \ + } \ +} while (0) -/* +void lu_object_print (const struct lu_env *env, void *cookie, + lu_printer_t printer, const struct lu_object *o); +void lu_object_header_print(const struct lu_env *env, void *cookie, + lu_printer_t printer, + const struct lu_object_header *hdr); + +/** * Check object consistency. */ int lu_object_invariant(const struct lu_object *o); -/* - * Finalize and free devices in the device stack. - */ void lu_stack_fini(const struct lu_env *env, struct lu_device *top); -/* +/** * Returns 1 iff object @o exists on the stable storage, * returns -1 iff object @o is on remote server. */ @@ -867,12 +885,38 @@ static inline __u32 lu_object_attr(const struct lu_object *o) return o->lo_header->loh_attr; } +static inline struct lu_ref_link *lu_object_ref_add(struct lu_object *o, + const char *scope, + const void *source) +{ + return lu_ref_add(&o->lo_header->loh_reference, scope, source); +} + +static inline void lu_object_ref_del(struct lu_object *o, + const char *scope, const void *source) +{ + lu_ref_del(&o->lo_header->loh_reference, scope, source); +} + +static inline void lu_object_ref_del_at(struct lu_object *o, + struct lu_ref_link *link, + const char *scope, const void *source) +{ + lu_ref_del_at(&o->lo_header->loh_reference, link, scope, source); +} + +/** input params, should be filled out by mdt */ struct lu_rdpg { - /* input params, should be filled out by mdt */ - __u64 rp_hash; /* hash */ - int rp_count; /* count in bytes */ - int rp_npages; /* number of pages */ - struct page **rp_pages; /* pointers to pages */ + /** hash */ + __u64 rp_hash; + /** count in bytes */ + unsigned int rp_count; + /** number of pages */ + unsigned int rp_npages; + /** requested attr */ + __u32 rp_attrs; + /** pointers to pages */ + struct page **rp_pages; }; enum lu_xattr_flags { @@ -910,12 +954,15 @@ enum lu_context_state { * that allows each layer to associate arbitrary pieces of data with each * context (see pthread_key_create(3) for similar interface). * + * On a client, lu_context is bound to a thread, see cl_env_get(). + * + * \see lu_context_key */ struct lu_context { - /* - * Theoretically we'd want to use lu_objects and lu_contexts on the - * client side too. On the other hand, we don't want to allocate - * values of server-side keys for the client contexts and vice versa. + /** + * lu_context is used on the client side too. Yet we don't want to + * allocate values of server-side keys for the client contexts and + * vice versa. * * To achieve this, set of tags in introduced. Contexts and keys are * marked with tags. Key value are created only for context whose set @@ -923,97 +970,165 @@ struct lu_context { * from enum lu_context_tag. */ __u32 lc_tags; - /* + /** * Pointer to the home service thread. NULL for other execution * contexts. */ struct ptlrpc_thread *lc_thread; - /* + /** * Pointer to an array with key values. Internal implementation * detail. */ void **lc_value; enum lu_context_state lc_state; + /** + * Linkage into a list of all remembered contexts. Only + * `non-transient' contexts, i.e., ones created for service threads + * are placed here. + */ + struct list_head lc_remember; + /** + * Version counter used to skip calls to lu_context_refill() when no + * keys were registered. + */ + unsigned lc_version; + /** + * Debugging cookie. + */ + unsigned lc_cookie; }; -/* +/** * lu_context_key interface. Similar to pthread_key. */ enum lu_context_tag { - /* + /** * Thread on md server */ LCT_MD_THREAD = 1 << 0, - /* + /** * Thread on dt server */ LCT_DT_THREAD = 1 << 1, - /* + /** * Context for transaction handle */ LCT_TX_HANDLE = 1 << 2, - /* + /** * Thread on client */ LCT_CL_THREAD = 1 << 3, - /* - * Per-request session on server + /** + * A per-request session on a server, and a per-system-call session on + * a client. */ LCT_SESSION = 1 << 4, - /* + + /** + * Set when at least one of keys, having values in this context has + * non-NULL lu_context_key::lct_exit() method. This is used to + * optimize lu_context_exit() call. + */ + LCT_HAS_EXIT = 1 << 28, + /** * Don't add references for modules creating key values in that context. * This is only for contexts used internally by lu_object framework. */ - LCT_NOREF = 1 << 30, - /* + LCT_NOREF = 1 << 29, + /** + * Key is being prepared for retiring, don't create new values for it. + */ + LCT_QUIESCENT = 1 << 30, + /** + * Context should be remembered. + */ + LCT_REMEMBER = 1 << 31, + /** * Contexts usable in cache shrinker thread. */ LCT_SHRINKER = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD|LCT_NOREF }; -/* +/** * Key. Represents per-context value slot. + * + * Keys are usually registered when module owning the key is initialized, and + * de-registered when module is unloaded. Once key is registered, all new + * contexts with matching tags, will get key value. "Old" contexts, already + * initialized at the time of key registration, can be forced to get key value + * by calling lu_context_refill(). + * + * Every key value is counted in lu_context_key::lct_used and acquires a + * reference on an owning module. This means, that all key values have to be + * destroyed before module can be unloaded. This is usually achieved by + * stopping threads started by the module, that created contexts in their + * entry functions. Situation is complicated by the threads shared by multiple + * modules, like ptlrpcd daemon on a client. To work around this problem, + * contexts, created in such threads, are `remembered' (see + * LCT_REMEMBER)---i.e., added into a global list. When module is preparing + * for unloading it does the following: + * + * - marks its keys as `quiescent' (lu_context_tag::LCT_QUIESCENT) + * preventing new key values from being allocated in the new contexts, + * and + * + * - scans a list of remembered contexts, destroying values of module + * keys, thus releasing references to the module. + * + * This is done by lu_context_key_quiesce(). If module is re-activated + * before key has been de-registered, lu_context_key_revive() call clears + * `quiescent' marker. + * + * lu_context code doesn't provide any internal synchronization for these + * activities---it's assumed that startup (including threads start-up) and + * shutdown are serialized by some external means. + * + * \see lu_context */ struct lu_context_key { - /* + /** * Set of tags for which values of this key are to be instantiated. */ __u32 lct_tags; - /* + /** * Value constructor. This is called when new value is created for a * context. Returns pointer to new value of error pointer. */ void *(*lct_init)(const struct lu_context *ctx, struct lu_context_key *key); - /* + /** * Value destructor. Called when context with previously allocated - * value of this slot is destroyed. @data is a value that was returned - * by a matching call to ->lct_init(). + * value of this slot is destroyed. \a data is a value that was returned + * by a matching call to lu_context_key::lct_init(). */ void (*lct_fini)(const struct lu_context *ctx, struct lu_context_key *key, void *data); - /* + /** * Optional method called on lu_context_exit() for all allocated * keys. Can be used by debugging code checking that locks are * released, etc. */ void (*lct_exit)(const struct lu_context *ctx, struct lu_context_key *key, void *data); - /* - * Internal implementation detail: index within ->lc_value[] reserved - * for this key. + /** + * Internal implementation detail: index within lu_context::lc_value[] + * reserved for this key. */ int lct_index; - /* + /** * Internal implementation detail: number of values created for this * key. */ atomic_t lct_used; - /* + /** * Internal implementation detail: module for this key. */ struct module *lct_owner; + /** + * References to this key. For debugging. + */ + struct lu_ref lct_reference; }; #define LU_KEY_INIT(mod, type) \ @@ -1058,135 +1173,119 @@ do { \ (key)->lct_owner = THIS_MODULE; \ } while (0) - -/* - * Register new key. - */ int lu_context_key_register(struct lu_context_key *key); -/* - * Deregister key. - */ void lu_context_key_degister(struct lu_context_key *key); +void *lu_context_key_get (const struct lu_context *ctx, + const struct lu_context_key *key); +void lu_context_key_quiesce (struct lu_context_key *key); +void lu_context_key_revive (struct lu_context_key *key); -#define LU_KEY_REGISTER_GENERIC(mod) \ - static int mod##_key_register_generic(struct lu_context_key *k, ...) \ - { \ - struct lu_context_key* key = k; \ - va_list args; \ - int result; \ - \ - va_start(args, k); \ - \ - do { \ - LU_CONTEXT_KEY_INIT(key); \ - result = lu_context_key_register(key); \ - if (result) \ - break; \ - key = va_arg(args, struct lu_context_key*); \ - } while (key != NULL); \ - \ - va_end(args); \ - \ - if (result) { \ - va_start(args, k); \ - while (k != key) { \ - lu_context_key_degister(k); \ - k = va_arg(args, struct lu_context_key*); \ - } \ - va_end(args); \ - } \ - \ - return result; \ - } -#define LU_KEY_DEGISTER_GENERIC(mod) \ - static void mod##_key_degister_generic(struct lu_context_key *k, ...) \ - { \ - va_list args; \ - \ - va_start(args, k); \ - \ - do { \ - lu_context_key_degister(k); \ - k = va_arg(args, struct lu_context_key*); \ - } while (k != NULL); \ - \ - va_end(args); \ +/* + * LU_KEY_INIT_GENERIC() has to be a macro to correctly determine an + * owning module. + */ + +#define LU_KEY_INIT_GENERIC(mod) \ + static void mod##_key_init_generic(struct lu_context_key *k, ...) \ + { \ + struct lu_context_key *key = k; \ + va_list args; \ + \ + va_start(args, k); \ + do { \ + LU_CONTEXT_KEY_INIT(key); \ + key = va_arg(args, struct lu_context_key *); \ + } while (key != NULL); \ + va_end(args); \ } -#define LU_TYPE_INIT(mod, ...) \ - LU_KEY_REGISTER_GENERIC(mod) \ - static int mod##_type_init(struct lu_device_type *t) \ - { \ - return mod##_key_register_generic(__VA_ARGS__, NULL); \ - } \ +#define LU_TYPE_INIT(mod, ...) \ + LU_KEY_INIT_GENERIC(mod) \ + static int mod##_type_init(struct lu_device_type *t) \ + { \ + mod##_key_init_generic(__VA_ARGS__, NULL); \ + return lu_context_key_register_many(__VA_ARGS__, NULL); \ + } \ struct __##mod##_dummy_type_init {;} -#define LU_TYPE_FINI(mod, ...) \ - LU_KEY_DEGISTER_GENERIC(mod) \ - static void mod##_type_fini(struct lu_device_type *t) \ - { \ - mod##_key_degister_generic(__VA_ARGS__, NULL); \ - } \ +#define LU_TYPE_FINI(mod, ...) \ + static void mod##_type_fini(struct lu_device_type *t) \ + { \ + lu_context_key_degister_many(__VA_ARGS__, NULL); \ + } \ struct __##mod##_dummy_type_fini {;} -#define LU_TYPE_INIT_FINI(mod, ...) \ - LU_TYPE_INIT(mod, __VA_ARGS__); \ - LU_TYPE_FINI(mod, __VA_ARGS__) +#define LU_TYPE_START(mod, ...) \ + static void mod##_type_start(struct lu_device_type *t) \ + { \ + lu_context_key_revive_many(__VA_ARGS__, NULL); \ + } \ + struct __##mod##_dummy_type_start {;} -/* - * Return value associated with key @key in context @ctx. - */ -void *lu_context_key_get(const struct lu_context *ctx, - struct lu_context_key *key); +#define LU_TYPE_STOP(mod, ...) \ + static void mod##_type_stop(struct lu_device_type *t) \ + { \ + lu_context_key_quiesce_many(__VA_ARGS__, NULL); \ + } \ + struct __##mod##_dummy_type_stop {;} -/* - * Initialize context data-structure. Create values for all keys. - */ -int lu_context_init(struct lu_context *ctx, __u32 tags); -/* - * Finalize context data-structure. Destroy key values. - */ -void lu_context_fini(struct lu_context *ctx); -/* - * Called before entering context. - */ -void lu_context_enter(struct lu_context *ctx); -/* - * Called after exiting from @ctx - */ -void lu_context_exit(struct lu_context *ctx); + +#define LU_TYPE_INIT_FINI(mod, ...) \ + LU_TYPE_INIT(mod, __VA_ARGS__); \ + LU_TYPE_FINI(mod, __VA_ARGS__); \ + LU_TYPE_START(mod, __VA_ARGS__); \ + LU_TYPE_STOP(mod, __VA_ARGS__) + +int lu_context_init (struct lu_context *ctx, __u32 tags); +void lu_context_fini (struct lu_context *ctx); +void lu_context_enter (struct lu_context *ctx); +void lu_context_exit (struct lu_context *ctx); +int lu_context_refill(struct lu_context *ctx); /* - * Allocate for context all missing keys that were registered after context - * creation. + * Helper functions to operate on multiple keys. These are used by the default + * device type operations, defined by LU_TYPE_INIT_FINI(). */ -int lu_context_refill(const struct lu_context *ctx); -/* +int lu_context_key_register_many(struct lu_context_key *k, ...); +void lu_context_key_degister_many(struct lu_context_key *k, ...); +void lu_context_key_revive_many (struct lu_context_key *k, ...); +void lu_context_key_quiesce_many (struct lu_context_key *k, ...); + +/** * Environment. */ struct lu_env { - /* + /** * "Local" context, used to store data instead of stack. */ struct lu_context le_ctx; - /* + /** * "Session" context for per-request data. */ struct lu_context *le_ses; }; -int lu_env_init(struct lu_env *env, struct lu_context *ses, __u32 tags); -void lu_env_fini(struct lu_env *env); +int lu_env_init (struct lu_env *env, __u32 tags); +void lu_env_fini (struct lu_env *env); +int lu_env_refill(struct lu_env *env); -/* +/** @} lu_context */ + +/** + * Output site statistical counters into a buffer. Suitable for + * ll_rd_*()-style functions. + */ +int lu_site_stats_print(const struct lu_site *s, char *page, int count); + +/** * Common name structure to be passed around for various name related methods. */ struct lu_name { - char *ln_name; - int ln_namelen; + const char *ln_name; + int ln_namelen; }; /** @@ -1196,6 +1295,7 @@ struct lu_name { struct lu_buf { void *lb_buf; ssize_t lb_len; + int lb_vmalloc:1; }; /** null buffer */ @@ -1227,4 +1327,14 @@ enum { extern const char *lu_time_names[LU_TIME_NR]; +struct lu_kmem_descr { + cfs_mem_cache_t **ckd_cache; + const char *ckd_name; + const size_t ckd_size; +}; + +int lu_kmem_init(struct lu_kmem_descr *caches); +void lu_kmem_fini(struct lu_kmem_descr *caches); + +/** @} lu */ #endif /* __LUSTRE_LU_OBJECT_H */