Whamcloud - gitweb
LU-5395 lfsck: deadlock between LFSCK and destroy
[fs/lustre-release.git] / lustre / include / lu_object.h
index 991d101..7c8c737 100644 (file)
@@ -169,6 +169,10 @@ typedef enum {
        /* This is a new object to be allocated, or the file
         * corresponding to the object does not exists. */
        LOC_F_NEW       = 0x00000001,
+
+       /* When find a dying object, just return -EAGAIN at once instead of
+        * blocking the thread. */
+       LOC_F_NOWAIT    = 0x00000002,
 } loc_flags_t;
 
 /**
@@ -258,17 +262,17 @@ struct lu_device_type;
  * 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.
          */
@@ -288,7 +292,7 @@ struct lu_device {
         /**
          * Link the device to the site.
          **/
-        cfs_list_t                         ld_linkage;
+       struct list_head                   ld_linkage;
 };
 
 struct lu_device_type_operations;
@@ -333,13 +337,13 @@ struct lu_device_type {
         /**
          * 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;
 };
 
 /**
@@ -473,7 +477,7 @@ struct lu_object {
         /**
          * Linkage into list of all layers.
          */
-        cfs_list_t                         lo_linkage;
+       struct list_head                   lo_linkage;
        /**
         * Link to the device, for debugging.
         */
@@ -515,41 +519,41 @@ enum lu_object_header_attr {
  * 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;
@@ -558,7 +562,7 @@ struct lu_site_bkt_data {
        /**
         * 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.
@@ -567,7 +571,7 @@ struct lu_site_bkt_data {
         * 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
@@ -576,7 +580,7 @@ struct lu_site_bkt_data {
         *
         * \see htable_lookup().
         */
-       wait_queue_head_t               lsb_marche_funebre;
+       wait_queue_head_t       lsb_marche_funebre;
 };
 
 enum {
@@ -603,30 +607,33 @@ struct lu_site {
         /**
          * 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
         */
@@ -681,7 +688,6 @@ void lu_dev_del_linkage(struct lu_site *s, struct lu_device *d);
 
 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 */
 
@@ -697,8 +703,8 @@ void lu_types_stop(void);
  */
 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);
 }
 
 /**
@@ -743,8 +749,8 @@ struct lu_object *lu_object_find_slice(const struct lu_env *env,
  */
 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);
 }
 
 /**
@@ -790,9 +796,8 @@ int lu_cdebug_printer(const struct lu_env *env,
  */
 #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__);                    \
         }                                                                 \
@@ -803,9 +808,8 @@ do {                                                                      \
  */
 #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");                 \
@@ -899,8 +903,8 @@ struct lu_rdpg {
 };
 
 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 */
@@ -959,22 +963,22 @@ struct lu_context {
          * 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;
 };
 
 /**
@@ -1105,24 +1109,24 @@ struct lu_context_key {
          */
         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)                                    \
@@ -1281,6 +1285,7 @@ int  lu_env_refill_by_tags(struct lu_env *env, __u32 ctags, __u32 stags);
  * 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);
 
 /**
@@ -1292,12 +1297,41 @@ struct lu_name {
 };
 
 /**
+ * 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.
  */
 struct lu_buf {
-        void   *lb_buf;
-        ssize_t lb_len;
+       void   *lb_buf;
+       size_t  lb_len;
 };
 
 #define DLUBUF "(%p %zu)"
@@ -1336,11 +1370,11 @@ struct lu_object *lu_object_anon(const struct lu_env *env,
 extern struct lu_buf LU_BUF_NULL;
 
 void lu_buf_free(struct lu_buf *buf);
-void lu_buf_alloc(struct lu_buf *buf, int size);
-void lu_buf_realloc(struct lu_buf *buf, int size);
+void lu_buf_alloc(struct lu_buf *buf, size_t size);
+void lu_buf_realloc(struct lu_buf *buf, size_t size);
 
-int lu_buf_check_and_grow(struct lu_buf *buf, int len);
-struct lu_buf *lu_buf_check_and_alloc(struct lu_buf *buf, int len);
+int lu_buf_check_and_grow(struct lu_buf *buf, size_t len);
+struct lu_buf *lu_buf_check_and_alloc(struct lu_buf *buf, size_t len);
 
 /** @} lu */
 #endif /* __LUSTRE_LU_OBJECT_H */