Whamcloud - gitweb
LU-5395 lfsck: deadlock between LFSCK and destroy
[fs/lustre-release.git] / lustre / include / lu_object.h
index 702bc61..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;
 
 /**
@@ -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;
@@ -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.
         */
@@ -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
         */
@@ -742,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);
 }
 
 /**
@@ -956,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;
 };
 
 /**
@@ -1289,13 +1296,28 @@ struct lu_name {
         int            ln_namelen;
 };
 
+/**
+ * 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 ln->ln_name != NULL &&
-              ln->ln_namelen > 0 &&
-              ln->ln_name[ln->ln_namelen] == '\0' &&
-              strlen(ln->ln_name) == ln->ln_namelen &&
-              memchr(ln->ln_name, '/', ln->ln_namelen) == NULL;
+       return lu_name_is_valid_2(ln->ln_name, ln->ln_namelen);
 }
 
 #define DNAME "%.*s"
@@ -1308,8 +1330,8 @@ static inline bool lu_name_is_valid(const struct lu_name *ln)
  * methods.
  */
 struct lu_buf {
-        void   *lb_buf;
-        ssize_t lb_len;
+       void   *lb_buf;
+       size_t  lb_len;
 };
 
 #define DLUBUF "(%p %zu)"
@@ -1348,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 */