Data Structures | |
| struct | lu_device_operations |
| Operations common for data and meta-data devices. More... | |
| struct | lu_object_conf |
| Object configuration, describing particulars of object being created. More... | |
| struct | lu_object_operations |
| Operations specific for particular lu_object. More... | |
| struct | lu_object_operations |
| Operations specific for particular lu_object. More... | |
| struct | lu_device |
| Device: a layer in the server side abstraction stacking. More... | |
| struct | lu_device_type |
| Type of device. More... | |
| struct | lu_device_type_operations |
| Operations on a device type. More... | |
| struct | lu_attr |
| Common object attributes. More... | |
| struct | lu_object |
| Layer in the layered object. More... | |
| struct | lu_object_header |
| "Compound" object, consisting of multiple layers. More... | |
| struct | lu_site |
| lu_site is a "compartment" within which objects are unique, and LRU discipline is maintained. More... | |
| struct | lu_cdebug_print_info |
| struct | lu_rdpg |
| input params, should be filled out by mdt More... | |
| struct | lu_context |
| lu_context. More... | |
| struct | lu_context_key |
| Key. More... | |
| struct | lu_env |
| Environment. More... | |
| struct | lu_name |
| Common name structure to be passed around for various name related methods. More... | |
| struct | lu_buf |
| Common buffer structure to be passed around for various xattr_{s,g}et() methods. More... | |
| struct | lu_kmem_descr |
helpers | |
| Helpers. | |
| #define | DECLARE_LU_CDEBUG_PRINT_INFO(var, mask) |
| #define | LU_OBJECT_DEBUG(mask, env, object, format,) |
| Print object description followed by a user-supplied message. | |
| #define | LU_OBJECT_HEADER(mask, env, object, format,) |
| Print short object description followed by a user-supplied message. | |
| enum | lu_xattr_flags { LU_XATTR_REPLACE = (1 << 0), LU_XATTR_CREATE = (1 << 1) } |
| lu_object * | lu_object_locate (struct lu_object_header *h, const struct lu_device_type *dtype) |
| Given a compound object, find its slice, corresponding to the device type dtype. | |
| int | lu_cdebug_printer (const struct lu_env *env, void *cookie, const char *format,...) |
| Printer function emitting messages through libcfs_debug_msg(). | |
| void | lu_object_print (const struct lu_env *env, void *cookie, lu_printer_t printer, const struct lu_object *o) |
| Print human readable representation of the o to the printer. | |
| void | lu_object_header_print (const struct lu_env *env, void *cookie, lu_printer_t printer, const struct lu_object_header *hdr) |
| Print object header. | |
| int | lu_object_invariant (const struct lu_object *o) |
| Check object consistency. | |
lu_context | |
| #define | LU_KEY_INIT(mod, type) |
| #define | LU_KEY_FINI(mod, type) |
| #define | LU_KEY_INIT_FINI(mod, type) |
| #define | LU_CONTEXT_KEY_DEFINE(mod, tags) |
| #define | LU_CONTEXT_KEY_INIT(key) |
| #define | LU_KEY_INIT_GENERIC(mod) |
| #define | LU_TYPE_INIT(mod,) |
| #define | LU_TYPE_FINI(mod,) |
| #define | LU_TYPE_START(mod,) |
| #define | LU_TYPE_STOP(mod,) |
| #define | LU_TYPE_INIT_FINI(mod,) |
| enum | lu_context_state { LCS_INITIALIZED = 1, LCS_ENTERED, LCS_LEFT, LCS_FINALIZED } |
| For lu_context health-checks. | |
| enum | lu_context_tag { LCT_MD_THREAD = 1 << 0, LCT_DT_THREAD = 1 << 1, LCT_TX_HANDLE = 1 << 2, LCT_CL_THREAD = 1 << 3, LCT_SESSION = 1 << 4, LCT_HAS_EXIT = 1 << 28, LCT_NOREF = 1 << 29, LCT_QUIESCENT = 1 << 30, LCT_REMEMBER = 1 << 31, LCT_SHRINKER = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD|LCT_NOREF } |
| lu_context_key interface. More... | |
| int | lu_context_key_register (struct lu_context_key *key) |
| Register new key. | |
| void | lu_context_key_degister (struct lu_context_key *key) |
| Deregister key. | |
| void * | lu_context_key_get (const struct lu_context *ctx, const struct lu_context_key *key) |
| Return value associated with key key in context ctx. | |
| void | lu_context_key_quiesce (struct lu_context_key *key) |
| Destroy key in all remembered contexts. | |
| void | lu_context_key_revive (struct lu_context_key *key) |
| int | lu_context_init (struct lu_context *ctx, __u32 tags) |
| Initialize context data-structure. | |
| void | lu_context_fini (struct lu_context *ctx) |
| Finalize context data-structure. | |
| void | lu_context_enter (struct lu_context *ctx) |
| Called before entering context. | |
| void | lu_context_exit (struct lu_context *ctx) |
| Called after exiting from ctx. | |
| int | lu_context_refill (struct lu_context *ctx) |
| Allocate for context all missing keys that were registered after context creation. | |
| int | lu_context_key_register_many (struct lu_context_key *k,...) |
| Register a number of keys. | |
| void | lu_context_key_degister_many (struct lu_context_key *k,...) |
| De-register a number of keys. | |
| void | lu_context_key_revive_many (struct lu_context_key *k,...) |
| Revive a number of keys. | |
| void | lu_context_key_quiesce_many (struct lu_context_key *k,...) |
| Quiescent a number of keys. | |
| 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) |
ctors | |
| Constructors/destructors. | |
| int | lu_site_init (struct lu_site *s, struct lu_device *d) |
| Initialize site s, with d as the top level device. | |
| void | lu_site_fini (struct lu_site *s) |
| Finalize s and release its resources. | |
| int | lu_site_init_finish (struct lu_site *s) |
| Called when initialization of stack for this site is completed. | |
| void | lu_stack_fini (const struct lu_env *env, struct lu_device *top) |
| Finalize and free devices in the device stack. | |
| void | lu_device_get (struct lu_device *d) |
| Acquire additional reference on device d. | |
| void | lu_device_put (struct lu_device *d) |
| Release reference on device d. | |
| int | lu_device_init (struct lu_device *d, struct lu_device_type *t) |
| Initialize device d of type t. | |
| void | lu_device_fini (struct lu_device *d) |
| Finalize device d. | |
| int | lu_object_header_init (struct lu_object_header *h) |
| Initialize compound object. | |
| void | lu_object_header_fini (struct lu_object_header *h) |
| Finalize compound object. | |
| int | lu_object_init (struct lu_object *o, struct lu_object_header *h, struct lu_device *d) |
| Initialize object o that is part of compound object h and was created by device d. | |
| void | lu_object_fini (struct lu_object *o) |
| Finalize object and release its resources. | |
| void | lu_object_add_top (struct lu_object_header *h, struct lu_object *o) |
| Add object o as first layer of compound object h. | |
| void | lu_object_add (struct lu_object *before, struct lu_object *o) |
| Add object o as a layer of compound object, going after before. | |
| int | lu_device_type_init (struct lu_device_type *ldt) |
| Helpers to initialize and finalize device types. | |
| void | lu_device_type_fini (struct lu_device_type *ldt) |
| void | lu_types_stop (void) |
caching | |
| Caching and reference counting. | |
| void | lu_object_put (const struct lu_env *env, struct lu_object *o) |
| Decrease reference counter on object. | |
| int | lu_site_purge (const struct lu_env *env, struct lu_site *s, int nr) |
| Free nr objects from the cold end of the site LRU list. | |
| void | lu_site_print (const struct lu_env *env, struct lu_site *s, void *cookie, lu_printer_t printer) |
| Print all objects in s. | |
| lu_object * | lu_object_find (const struct lu_env *env, struct lu_device *dev, const struct lu_fid *f, const struct lu_object_conf *conf) |
| Search cache for an object with the fid f. | |
| 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) |
| Much like lu_object_find(), but top level device of object is specifically dev rather than top level device of the site. | |
| 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) |
| Find object with given fid, and return its slice belonging to given device. | |
Defines | |
| #define | DLUBUF "(%p %z)" |
| #define | PLUBUF(buf) (buf)->lb_buf, (buf)->lb_len |
Typedefs | |
| typedef int(*) | lu_printer_t (const struct lu_env *env, void *cookie, const char *format,...) __attribute__((format(printf |
| Type of "printer" function used by lu_object_operations::loo_object_print() method. | |
Enumerations | |
| enum | lu_device_tag { LU_DEVICE_MD = (1 << 0), LU_DEVICE_DT = (1 << 1), LU_DEVICE_CL = (1 << 2) } |
| Tag bits for device type. More... | |
| enum | lu_object_flags { LU_OBJECT_ALLOCATED = (1 << 0) } |
| Flags for the object layers. More... | |
| enum | la_valid { LA_ATIME = 1 << 0, LA_MTIME = 1 << 1, LA_CTIME = 1 << 2, LA_SIZE = 1 << 3, LA_MODE = 1 << 4, LA_UID = 1 << 5, LA_GID = 1 << 6, LA_BLOCKS = 1 << 7, LA_TYPE = 1 << 8, LA_FLAGS = 1 << 9, LA_NLINK = 1 << 10, LA_RDEV = 1 << 11, LA_BLKSIZE = 1 << 12 } |
| Bit-mask of valid attributes. | |
| enum | lu_object_header_flags { LU_OBJECT_HEARD_BANSHEE = 0 } |
| enum | lu_object_header_attr { LOHA_EXISTS = 1 << 0, LOHA_REMOTE = 1 << 1, LOHA_FT_START = 001 << 12, LOHA_FT_END = 017 << 12 } |
| enum | { LU_TIME_FIND_LOOKUP, LU_TIME_FIND_ALLOC, LU_TIME_FIND_INSERT, LU_TIME_NR } |
Functions | |
| int | lu_site_stats_print (const struct lu_site *s, char *page, int count) |
| Output site statistical counters into a buffer. | |
| int | lu_global_init (void) |
| Initialization of global lu_* data. | |
| void | lu_global_fini (void) |
| Dual to lu_global_init(). | |
| int | lu_kmem_init (struct lu_kmem_descr *caches) |
| Helper function to initialize a number of kmem slab caches at once. | |
| void | lu_kmem_fini (struct lu_kmem_descr *caches) |
| Helper function to finalize a number of kmem slab cached at once. | |
Variables | |
| lu_buf | LU_BUF_NULL |
| null buffer | |
| const char * | lu_time_names [LU_TIME_NR] |
Design goals:
Server side object is split into layers, one per device in the corresponding device stack. Individual layer is represented by struct lu_object. Compound layered object --- by struct lu_object_header. Most interface functions take lu_object as an argument and operate on the whole compound object. This decision was made due to the following reasons:
Generic code supports layering more complex than simple stacking, e.g., it is possible that at some layer object "spawns" multiple sub-objects on the lower layer.
Compound object is uniquely identified by its fid. Objects are indexed by their fids (hash table is used for index).
Object's life-time is controlled by reference counting. When reference count drops to 0, object is returned to cache. Cached objects still retain their identity (i.e., fid), and can be recovered from cache.
Objects are kept in the global LRU list, and lu_site_purge() function can be used to reclaim given number of unused objects from the tail of the LRU.
Generic code tries to replace recursion through layers by iterations where possible. Additionally to the end of reducing stack consumption, data, when practically possible, are allocated through lu_context_key interface rather than on stack.
| #define DECLARE_LU_CDEBUG_PRINT_INFO | ( | var, | |||
| mask | ) |
Value:
struct lu_cdebug_print_info var = { \
.lpi_subsys = DEBUG_SUBSYSTEM, \
.lpi_mask = (mask), \
.lpi_file = __FILE__, \
.lpi_fn = __FUNCTION__, \
.lpi_line = __LINE__ \
}
| #define LU_CONTEXT_KEY_DEFINE | ( | mod, | |||
| tags | ) |
Value:
struct lu_context_key mod##_thread_key = { \ .lct_tags = tags, \ .lct_init = mod##_key_init, \ .lct_fini = mod##_key_fini \ }
| #define LU_CONTEXT_KEY_INIT | ( | key | ) |
Value:
do { \ (key)->lct_owner = THIS_MODULE; \ } while (0)
| #define LU_KEY_FINI | ( | mod, | |||
| type | ) |
Value:
static void mod##_key_fini(const struct lu_context *ctx, \ struct lu_context_key *key, void* data) \ { \ type *info = data; \ \ OBD_FREE_PTR(info); \ } \ struct __##mod##__dummy_fini {;}
| #define LU_KEY_INIT | ( | mod, | |||
| type | ) |
Value:
static void* mod##_key_init(const struct lu_context *ctx, \ struct lu_context_key *key) \ { \ type *value; \ \ CLASSERT(CFS_PAGE_SIZE >= sizeof (*value)); \ \ OBD_ALLOC_PTR(value); \ if (value == NULL) \ value = ERR_PTR(-ENOMEM); \ \ return value; \ } \ struct __##mod##__dummy_init {;}
| #define LU_KEY_INIT_FINI | ( | mod, | |||
| type | ) |
Value:
LU_KEY_INIT(mod,type); \
LU_KEY_FINI(mod,type)
| #define LU_KEY_INIT_GENERIC | ( | mod | ) |
Value:
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_OBJECT_DEBUG | ( | mask, | |||
| env, | |||||
| object, | |||||
| format | ) |
Value:
do { \ static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask); \ \ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \ lu_object_print(env, &__info, lu_cdebug_printer, object); \ CDEBUG(mask, format , ## __VA_ARGS__); \ } \ } while (0)
| #define LU_OBJECT_HEADER | ( | mask, | |||
| env, | |||||
| object, | |||||
| format | ) |
Value:
do { \ static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask); \ \ if (cfs_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)
| #define LU_TYPE_FINI | ( | mod | ) |
Value:
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 | ( | mod | ) |
Value:
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_INIT_FINI | ( | mod | ) |
Value:
LU_TYPE_INIT(mod, __VA_ARGS__); \
LU_TYPE_FINI(mod, __VA_ARGS__); \
LU_TYPE_START(mod, __VA_ARGS__); \
LU_TYPE_STOP(mod, __VA_ARGS__)
| #define LU_TYPE_START | ( | mod | ) |
Value:
static void mod##_type_start(struct lu_device_type *t) \ { \ lu_context_key_revive_many(__VA_ARGS__, NULL); \ } \ struct __##mod##_dummy_type_start {;}
| #define LU_TYPE_STOP | ( | mod | ) |
Value:
static void mod##_type_stop(struct lu_device_type *t) \ { \ lu_context_key_quiesce_many(__VA_ARGS__, NULL); \ } \ struct __##mod##_dummy_type_stop {;}
| typedef int(*) lu_printer_t(const struct lu_env *env, void *cookie, const char *format,...) __attribute__((format(printf |
Type of "printer" function used by lu_object_operations::loo_object_print() method.
Printer function is needed to provide some flexibility in (semi-)debugging output: possible implementations: printk, CDEBUG, sysfs/seq_file
| enum lu_context_tag |
lu_context_key interface.
Similar to pthread_key.
| LCT_MD_THREAD | Thread on md server. |
| LCT_DT_THREAD | Thread on dt server. |
| LCT_TX_HANDLE | Context for transaction handle. |
| LCT_CL_THREAD | Thread on client. |
| LCT_SESSION | A per-request session on a server, and a per-system-call session on a client. |
| LCT_HAS_EXIT |
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_NOREF |
Don't add references for modules creating key values in that context.
This is only for contexts used internally by lu_object framework. |
| LCT_QUIESCENT | Key is being prepared for retiring, don't create new values for it. |
| LCT_REMEMBER | Context should be remembered. |
| LCT_SHRINKER | Contexts usable in cache shrinker thread. |
| enum lu_device_tag |
| enum lu_object_flags |
Flags for the object layers.
| LU_OBJECT_ALLOCATED |
this flags is set if lu_object_operations::loo_object_init() has been called for this layer.
Used by lu_object_alloc(). |
| void lu_context_fini | ( | struct lu_context * | ctx | ) |
Finalize context data-structure.
Destroy key values.
| int lu_context_init | ( | struct lu_context * | ctx, | |
| __u32 | tags | |||
| ) |
Initialize context data-structure.
Create values for all keys.
| void lu_context_key_degister_many | ( | struct lu_context_key * | k, | |
| ... | ||||
| ) |
De-register a number of keys.
This is a dual to lu_context_key_register_many().
| void lu_context_key_quiesce | ( | struct lu_context_key * | key | ) |
Destroy key in all remembered contexts.
This is used to destroy key values in "shared" contexts (like service threads), when a module owning the key is about to be unloaded.
| int lu_context_key_register_many | ( | struct lu_context_key * | k, | |
| ... | ||||
| ) |
Register a number of keys.
This has to be called after all keys have been initialized by a call to LU_CONTEXT_KEY_INIT().
| void lu_kmem_fini | ( | struct lu_kmem_descr * | caches | ) |
Helper function to finalize a number of kmem slab cached at once.
Dual to lu_kmem_init().
Add object o as a layer of compound object, going after before.
This is typically called by the ->ldo_object_alloc() method of before->lo_dev.
| void lu_object_add_top | ( | struct lu_object_header * | h, | |
| struct lu_object * | o | |||
| ) |
Add object o as first layer of compound object h.
This is typically called by the ->ldo_object_alloc() method of top-level device.
| struct lu_object* lu_object_find | ( | const struct lu_env * | env, | |
| struct lu_device * | dev, | |||
| const struct lu_fid * | f, | |||
| const struct lu_object_conf * | conf | |||
| ) |
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_at | ( | const struct lu_env * | env, | |
| struct lu_device * | dev, | |||
| const struct lu_fid * | f, | |||
| const struct lu_object_conf * | conf | |||
| ) |
Much like lu_object_find(), but top level device of object is specifically dev rather than top level device of the site.
This interface allows objects of different "stacking" to be created within the same site.
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.
| int lu_site_stats_print | ( | const struct lu_site * | s, | |
| char * | page, | |||
| int | count | |||
| ) |
Output site statistical counters into a buffer.
Suitable for lprocfs_rd_*()-style functions.
Finalize and free devices in the device stack.
Finalize device stack by purging object cache, and calling lu_device_type_operations::ldto_device_fini() and lu_device_type_operations::ldto_device_free() on all devices in the stack.