* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2011, 2012, Whamcloud, Inc.
*/
/*
* This file is part of Lustre, http://www.lustre.org/
/*
* struct lu_fid
*/
-#include <lustre/lustre_idl.h>
-
#include <libcfs/libcfs.h>
+#include <lustre/lustre_idl.h>
+
#include <lu_ref.h>
struct seq_file;
* 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,
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);
+
};
/**
+ * For lu_object_conf flags
+ */
+typedef enum {
+ /* Currently, only used for client-side object initialization. */
+ LOC_F_NEW = 0x1,
+} loc_flags_t;
+
+/**
* 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 {
+ /**
+ * Some hints for obj find and alloc.
+ */
+ loc_flags_t loc_flags;
};
/**
void *cookie, const char *format, ...)
__attribute__ ((format (printf, 3, 4)));
-/*
+/**
* Operations specific for particular lu_object.
*/
struct lu_object_operations {
*
* \todo XXX which means that atomic_t is probably too small.
*/
- atomic_t ld_ref;
+ cfs_atomic_t ld_ref;
/**
* Pointer to device type. Never modified once set.
*/
/**
* 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.
*/
struct lu_ref ld_reference;
+ /**
+ * Link the device to the site.
+ **/
+ cfs_list_t ld_linkage;
};
struct lu_device_type_operations;
/**
* 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.
*/
/**
* \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.
*/
*
* \see lu_device_types.
*/
- struct list_head ldt_linkage;
+ cfs_list_t ldt_linkage;
};
/**
/** size in bytes */
__u64 la_size;
/** modification time in seconds since Epoch */
- __u64 la_mtime;
+ obd_time la_mtime;
/** access time in seconds since Epoch */
- __u64 la_atime;
+ obd_time la_atime;
/** change time in seconds since Epoch */
- __u64 la_ctime;
+ obd_time la_ctime;
/** 512-byte blocks allocated to object */
__u64 la_blocks;
/** permission bits and file type */
LA_NLINK = 1 << 10,
LA_RDEV = 1 << 11,
LA_BLKSIZE = 1 << 12,
+ LA_KILL_SUID = 1 << 13,
+ LA_KILL_SGID = 1 << 14,
};
-/*
+/**
* 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;
- /*
+ cfs_list_t 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.
*/
};
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.
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 = 001 << 12, /**< S_IFIFO */
+ LOHA_FT_END = 017 << 12, /**< S_IFMT */
};
-/*
+/**
* "Compound" object, consisting of multiple layers.
*
* Compound object with given fid is unique with given lu_site.
* 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;
+ cfs_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;
+ cfs_hlist_node_t loh_hash;
/**
* Linkage into per-site LRU list. Protected by lu_site::ls_guard.
*/
- struct list_head loh_lru;
+ cfs_list_t 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;
+ cfs_list_t loh_layers;
/**
* A list of references to this object, for debugging.
*/
- struct lu_ref loh_reference;
+ struct lu_ref loh_reference;
};
struct fld;
+struct lu_site_bkt_data {
+ /**
+ * number of busy object on this bucket
+ */
+ long lsb_busy;
+ /**
+ * LRU list, updated on each access to object. Protected by
+ * bucket lock of lu_site::ls_obj_hash.
+ *
+ * "Cold" end of LRU is lu_site::ls_lru.next. Accessed object are
+ * moved to the lu_site::ls_lru.prev (this is due to the non-existence
+ * of list_for_each_entry_safe_reverse()).
+ */
+ cfs_list_t lsb_lru;
+ /**
+ * 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.
+ *
+ * \see htable_lookup().
+ */
+ cfs_waitq_t lsb_marche_funebre;
+};
+
+enum {
+ LU_SS_CREATED = 0,
+ LU_SS_CACHE_HIT,
+ LU_SS_CACHE_MISS,
+ LU_SS_CACHE_RACE,
+ LU_SS_CACHE_DEATH_RACE,
+ LU_SS_LRU_PURGED,
+ LU_SS_LAST_STAT
+};
+
/**
* lu_site is a "compartment" within which objects are unique, and LRU
* discipline is maintained.
*/
struct lu_site {
/**
- * Site-wide lock.
- *
- * lock protecting:
- *
- * - lu_site::ls_hash hash table (and its linkages in objects);
- *
- * - lu_site::ls_lru list (and its linkages in objects);
- *
- * - 0/1 transitions of object lu_object_header::loh_ref
- * reference count;
- *
- * yes, it's heavy.
+ * objects hash table
*/
- rwlock_t ls_guard;
+ cfs_hash_t *ls_obj_hash;
/**
- * Hash-table where objects are indexed by fid.
+ * index of bucket on hash table while purging
*/
- struct hlist_head *ls_hash;
+ int ls_purge_start;
/**
- * Bit-mask for hash-table size.
+ * Top-level device for this stack.
*/
- int ls_hash_mask;
+ struct lu_device *ls_top_dev;
/**
- * Order of hash-table.
+ * Linkage into global list of sites.
*/
- int ls_hash_bits;
+ cfs_list_t ls_linkage;
/**
- * Number of buckets in the hash-table.
- */
- int ls_hash_size;
+ * List for lu device for this site, protected
+ * by ls_ld_lock.
+ **/
+ cfs_list_t ls_ld_linkage;
+ cfs_spinlock_t ls_ld_lock;
/**
- * LRU list, updated on each access to object. Protected by
- * lu_site::ls_guard.
- *
- * "Cold" end of LRU is lu_site::ls_lru.next. Accessed object are
- * moved to the lu_site::ls_lru.prev (this is due to the non-existence
- * of list_for_each_entry_safe_reverse()).
- */
- struct list_head ls_lru;
- /**
- * Total number of objects in this site. Protected by
- * lu_site::ls_guard.
+ * lu_site stats
*/
- unsigned ls_total;
- /**
- * Total number of objects in this site with reference counter greater
- * than 0. Protected by lu_site::ls_guard.
- */
- unsigned ls_busy;
+ struct lprocfs_stats *ls_stats;
+ struct lprocfs_stats *ls_time_stats;
+};
- /**
- * 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
- */
- struct lu_client_seq *ls_client_seq;
-
- /* 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)
- *
- * is an average number of hash slots inspected during single
- * lookup.
- */
- __u32 s_cache_check;
- /** Races with cache insertions. */
- __u32 s_cache_race;
- /**
- * Races with object destruction.
- *
- * \see lu_site::ls_marche_funebre.
- */
- __u32 s_cache_death_race;
- __u32 s_lru_purged;
- } ls_stats;
+static inline struct lu_site_bkt_data *
+lu_site_bkt_from_fid(struct lu_site *site, struct lu_fid *fid)
+{
+ cfs_hash_bd_t bd;
- /**
- * Linkage into global list of sites.
- */
- struct list_head ls_linkage;
- struct lprocfs_stats *ls_time_stats;
-};
+ cfs_hash_bd_get(site->ls_obj_hash, fid, &bd);
+ return cfs_hash_bd_extra_get(site->ls_obj_hash, &bd);
+}
/** \name ctors
* Constructors/destructors.
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);
*/
static inline void lu_object_get(struct lu_object *o)
{
- LASSERT(atomic_read(&o->lo_header->loh_ref) > 0);
- atomic_inc(&o->lo_header->loh_ref);
+ LASSERT(cfs_atomic_read(&o->lo_header->loh_ref) > 0);
+ cfs_atomic_inc(&o->lo_header->loh_ref);
}
/**
*/
static inline int lu_object_is_dying(const struct lu_object_header *h)
{
- return test_bit(LU_OBJECT_HEARD_BANSHEE, &h->loh_flags);
+ return cfs_test_bit(LU_OBJECT_HEARD_BANSHEE, &h->loh_flags);
}
void lu_object_put(const struct lu_env *env, struct lu_object *o);
*/
static inline struct lu_object *lu_object_top(struct lu_object_header *h)
{
- LASSERT(!list_empty(&h->loh_layers));
+ LASSERT(!cfs_list_empty(&h->loh_layers));
return container_of0(h->loh_layers.next, struct lu_object, lo_linkage);
}
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);
-
-struct lu_cdebug_print_info {
- int lpi_subsys;
- int lpi_mask;
- const char *lpi_file;
- const char *lpi_fn;
- int lpi_line;
-};
+ const struct lu_device_type *dtype);
-/*
+/**
* Printer function emitting messages through libcfs_debug_msg().
*/
int lu_cdebug_printer(const struct lu_env *env,
void *cookie, const char *format, ...);
-#define DECLARE_LU_CDEBUG_PRINT_INFO(var, mask) \
- struct lu_cdebug_print_info var = { \
- .lpi_subsys = DEBUG_SUBSYSTEM, \
- .lpi_mask = (mask), \
- .lpi_file = __FILE__, \
- .lpi_fn = __FUNCTION__, \
- .lpi_line = __LINE__ \
- };
+/**
+ * Print object description followed by a user-supplied message.
+ */
+#define LU_OBJECT_DEBUG(mask, env, object, format, ...) \
+do { \
+ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \
+ \
+ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \
+ lu_object_print(env, &msgdata, lu_cdebug_printer, object);\
+ CDEBUG(mask, format , ## __VA_ARGS__); \
+ } \
+} while (0)
-/*
- * Print object description followed by user-supplied message.
+/**
+ * Print short object description followed by a user-supplied message.
*/
-#define LU_OBJECT_DEBUG(mask, env, object, format, ...) \
-({ \
- static DECLARE_LU_CDEBUG_PRINT_INFO(__info, mask); \
+#define LU_OBJECT_HEADER(mask, env, object, format, ...) \
+do { \
+ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \
\
- lu_object_print(env, &__info, lu_cdebug_printer, object); \
- CDEBUG(mask, format , ## __VA_ARGS__); \
-})
+ if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \
+ lu_object_header_print(env, &msgdata, lu_cdebug_printer,\
+ (object)->lo_header); \
+ lu_cdebug_printer(env, &msgdata, "\n"); \
+ CDEBUG(mask, format , ## __VA_ARGS__); \
+ } \
+} while (0)
-/*
- * Print human readable representation of the @o to the @f.
- */
-void lu_object_print(const struct lu_env *env, void *cookie,
- lu_printer_t printer, const struct lu_object *o);
+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.
+/**
+ * \retval 1 iff object \a o exists on stable storage,
+ * \retval 0 iff object \a o not exists on stable storage.
+ * \retval -1 iff object \a o is on remote server.
*/
static inline int lu_object_exists(const struct lu_object *o)
{
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 {
* `non-transient' contexts, i.e., ones created for service threads
* are placed here.
*/
- struct list_head lc_remember;
+ cfs_list_t 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;
};
/**
* Internal implementation detail: number of values created for this
* key.
*/
- atomic_t lct_used;
+ cfs_atomic_t lct_used;
/**
* Internal implementation detail: module for this key.
*/
- struct module *lct_owner;
+ cfs_module_t *lct_owner;
/**
* References to this key. For debugging.
*/
#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); \
+ 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); \
+ } while (key != NULL); \
+ va_end(args); \
}
-#define LU_TYPE_INIT(mod, ...) \
+#define LU_TYPE_INIT(mod, ...) \
LU_KEY_INIT_GENERIC(mod) \
- static int mod##_type_init(struct lu_device_type *t) \
- { \
+ 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, ...) \
- static void mod##_type_fini(struct lu_device_type *t) \
- { \
+#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_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 {;}
#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 {;}
-#define LU_TYPE_INIT_FINI(mod, ...) \
- LU_TYPE_INIT(mod, __VA_ARGS__); \
+#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__)
void lu_context_key_revive_many (struct lu_context_key *k, ...);
void lu_context_key_quiesce_many (struct lu_context_key *k, ...);
+/*
+ * update/clear ctx/ses tags.
+ */
+void lu_context_tags_update(__u32 tags);
+void lu_context_tags_clear(__u32 tags);
+void lu_session_tags_update(__u32 tags);
+void lu_session_tags_clear(__u32 tags);
+
/**
* Environment.
*/
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);
+int lu_env_refill_by_tags(struct lu_env *env, __u32 ctags, __u32 stags);
/** @} lu_context */
* 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;
};
/**
void lu_kmem_fini(struct lu_kmem_descr *caches);
/** @} lu */
-
#endif /* __LUSTRE_LU_OBJECT_H */