* Device: a layer in the server side abstraction stacking.
*/
struct lu_device {
- /**
- * reference count. This is incremented, in particular, on each object
- * created at this layer.
- *
- * \todo XXX which means that atomic_t is probably too small.
- */
- cfs_atomic_t ld_ref;
- /**
- * Pointer to device type. Never modified once set.
- */
- struct lu_device_type *ld_type;
+ /**
+ * reference count. This is incremented, in particular, on each object
+ * created at this layer.
+ *
+ * \todo XXX which means that atomic_t is probably too small.
+ */
+ atomic_t ld_ref;
+ /**
+ * Pointer to device type. Never modified once set.
+ */
+ struct lu_device_type *ld_type;
/**
* Operation vector for this device.
*/
/**
* Link the device to the site.
**/
- cfs_list_t ld_linkage;
+ struct list_head ld_linkage;
};
struct lu_device_type_operations;
/**
* Number of existing device type instances.
*/
- unsigned ldt_device_nr;
- /**
- * Linkage into a global list of all device types.
- *
- * \see lu_device_types.
- */
- cfs_list_t ldt_linkage;
+ atomic_t ldt_device_nr;
+ /**
+ * Linkage into a global list of all device types.
+ *
+ * \see lu_device_types.
+ */
+ struct list_head ldt_linkage;
};
/**
/**
* Linkage into list of all layers.
*/
- cfs_list_t lo_linkage;
+ struct list_head lo_linkage;
/**
* Link to the device, for debugging.
*/
* whether object is backed by persistent storage entity.
*/
struct lu_object_header {
- /**
- * Object flags from enum lu_object_header_flags. Set and checked
- * atomically.
- */
- unsigned long loh_flags;
- /**
- * Object reference count. Protected by lu_site::ls_guard.
- */
- cfs_atomic_t loh_ref;
- /**
- * Fid, uniquely identifying this object.
- */
- struct lu_fid loh_fid;
- /**
- * Common object attributes, cached for efficiency. From enum
- * lu_object_header_attr.
- */
- __u32 loh_attr;
- /**
- * Linkage into per-site hash table. Protected by lu_site::ls_guard.
- */
- cfs_hlist_node_t loh_hash;
- /**
- * Linkage into per-site LRU list. Protected by lu_site::ls_guard.
- */
- cfs_list_t loh_lru;
- /**
- * Linkage into list of layers. Never modified once set (except lately
- * during object destruction). No locking is necessary.
- */
- cfs_list_t loh_layers;
- /**
- * A list of references to this object, for debugging.
- */
- struct lu_ref loh_reference;
+ /**
+ * Fid, uniquely identifying this object.
+ */
+ struct lu_fid loh_fid;
+ /**
+ * Object flags from enum lu_object_header_flags. Set and checked
+ * atomically.
+ */
+ unsigned long loh_flags;
+ /**
+ * Object reference count. Protected by lu_site::ls_guard.
+ */
+ atomic_t loh_ref;
+ /**
+ * Common object attributes, cached for efficiency. From enum
+ * lu_object_header_attr.
+ */
+ __u32 loh_attr;
+ /**
+ * Linkage into per-site hash table. Protected by lu_site::ls_guard.
+ */
+ struct hlist_node loh_hash;
+ /**
+ * Linkage into per-site LRU list. Protected by lu_site::ls_guard.
+ */
+ 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;
+ /**
+ * A list of references to this object, for debugging.
+ */
+ struct lu_ref loh_reference;
};
struct fld;
/**
* number of busy object on this bucket
*/
- long lsb_busy;
+ long lsb_busy;
/**
* LRU list, updated on each access to object. Protected by
* bucket lock of lu_site::ls_obj_hash.
* 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;
+ struct list_head 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
*
* \see htable_lookup().
*/
- wait_queue_head_t lsb_marche_funebre;
+ wait_queue_head_t lsb_marche_funebre;
};
enum {
/**
* objects hash table
*/
- cfs_hash_t *ls_obj_hash;
+ cfs_hash_t *ls_obj_hash;
/**
* index of bucket on hash table while purging
*/
- int ls_purge_start;
- /**
- * Top-level device for this stack.
- */
- struct lu_device *ls_top_dev;
+ int ls_purge_start;
+ /**
+ * Top-level device for this stack.
+ */
+ struct lu_device *ls_top_dev;
/**
* Bottom-level device for this stack
*/
struct lu_device *ls_bottom_dev;
- /**
- * Linkage into global list of sites.
- */
- cfs_list_t ls_linkage;
- /**
- * List for lu device for this site, protected
- * by ls_ld_lock.
- **/
- cfs_list_t ls_ld_linkage;
+ /**
+ * Linkage into global list of sites.
+ */
+ struct list_head ls_linkage;
+ /**
+ * List for lu device for this site, protected
+ * by ls_ld_lock.
+ **/
+ struct list_head ls_ld_linkage;
spinlock_t ls_ld_lock;
-
+ /**
+ * Lock to serialize site purge.
+ */
+ struct mutex ls_purge_mutex;
/**
* lu_site stats
*/
int lu_device_type_init(struct lu_device_type *ldt);
void lu_device_type_fini(struct lu_device_type *ldt);
-void lu_types_stop(void);
/** @} ctors */
*/
static inline void lu_object_get(struct lu_object *o)
{
- LASSERT(cfs_atomic_read(&o->lo_header->loh_ref) > 0);
- cfs_atomic_inc(&o->lo_header->loh_ref);
+ LASSERT(atomic_read(&o->lo_header->loh_ref) > 0);
+ atomic_inc(&o->lo_header->loh_ref);
}
/**
*/
static inline struct lu_object *lu_object_top(struct lu_object_header *h)
{
- LASSERT(!cfs_list_empty(&h->loh_layers));
- return container_of0(h->loh_layers.next, struct lu_object, lo_linkage);
+ LASSERT(!list_empty(&h->loh_layers));
+ return container_of0(h->loh_layers.next, struct lu_object, lo_linkage);
}
/**
*/
#define LU_OBJECT_DEBUG(mask, env, object, format, ...) \
do { \
- LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \
- \
if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \
+ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \
lu_object_print(env, &msgdata, lu_cdebug_printer, object);\
CDEBUG(mask, format , ## __VA_ARGS__); \
} \
*/
#define LU_OBJECT_HEADER(mask, env, object, format, ...) \
do { \
- LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \
- \
if (cfs_cdebug_show(mask, DEBUG_SUBSYSTEM)) { \
+ LIBCFS_DEBUG_MSG_DATA_DECL(msgdata, mask, NULL); \
lu_object_header_print(env, &msgdata, lu_cdebug_printer,\
(object)->lo_header); \
lu_cdebug_printer(env, &msgdata, "\n"); \
};
enum lu_xattr_flags {
- LU_XATTR_REPLACE = (1 << 0),
- LU_XATTR_CREATE = (1 << 1)
+ LU_XATTR_REPLACE = (1 << 0),
+ LU_XATTR_CREATE = (1 << 1)
};
/** @} helpers */
* Pointer to an array with key values. Internal implementation
* detail.
*/
- void **lc_value;
- /**
- * Linkage into a list of all remembered contexts. Only
- * `non-transient' contexts, i.e., ones created for service threads
- * are placed here.
- */
- cfs_list_t lc_remember;
- /**
- * Version counter used to skip calls to lu_context_refill() when no
- * keys were registered.
- */
- unsigned lc_version;
+ void **lc_value;
+ /**
+ * 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;
+ unsigned lc_cookie;
};
/**
*/
void (*lct_exit)(const struct lu_context *ctx,
struct lu_context_key *key, void *data);
- /**
- * 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.
- */
- cfs_atomic_t lct_used;
+ /**
+ * 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;
+ struct module *lct_owner;
/**
* References to this key. For debugging.
*/
- struct lu_ref lct_reference;
+ struct lu_ref lct_reference;
};
#define LU_KEY_INIT(mod, type) \
* Output site statistical counters into a buffer. Suitable for
* ll_rd_*()-style functions.
*/
+int lu_site_stats_seq_print(const struct lu_site *s, struct seq_file *m);
int lu_site_stats_print(const struct lu_site *s, char *page, int count);
/**
};
/**
+ * Validate names (path components)
+ *
+ * To be valid \a name must be non-empty, '\0' terminated of length \a
+ * name_len, and not contain '/'. The maximum length of a name (before
+ * say -ENAMETOOLONG will be returned) is really controlled by llite
+ * and the server. We only check for something insane coming from bad
+ * integer handling here.
+ */
+static inline bool lu_name_is_valid_2(const char *name, size_t name_len)
+{
+ return name != NULL &&
+ name_len > 0 &&
+ name_len < INT_MAX &&
+ name[name_len] == '\0' &&
+ strlen(name) == name_len &&
+ memchr(name, '/', name_len) == NULL;
+}
+
+static inline bool lu_name_is_valid(const struct lu_name *ln)
+{
+ return lu_name_is_valid_2(ln->ln_name, ln->ln_namelen);
+}
+
+#define DNAME "%.*s"
+#define PNAME(ln) \
+ (lu_name_is_valid(ln) ? (ln)->ln_namelen : 0), \
+ (lu_name_is_valid(ln) ? (ln)->ln_name : "")
+
+/**
* Common buffer structure to be passed around for various xattr_{s,g}et()
* methods.
*/