Whamcloud - gitweb
LU-8130 lu_object: convert lu_object cache to rhashtable
[fs/lustre-release.git] / lustre / include / lu_object.h
index 65180b2..187ecdd 100644 (file)
@@ -38,7 +38,9 @@
 #include <uapi/linux/lustre/lustre_idl.h>
 #include <lu_ref.h>
 #include <linux/percpu_counter.h>
+#include <linux/rhashtable.h>
 #include <linux/ctype.h>
+#include <obd_target.h>
 
 struct seq_file;
 struct proc_dir_entry;
@@ -101,6 +103,7 @@ struct lu_device;
 struct lu_object_header;
 struct lu_context;
 struct lu_env;
+struct lu_name;
 
 /**
  * Operations common for data and meta-data devices.
@@ -159,6 +162,26 @@ struct lu_device_operations {
                            struct lu_device *parent,
                            struct lu_device *dev);
 
+
+       /**
+        * Allocate new FID for file with @name under @parent
+        *
+        * \param[in] env       execution environment for this thread
+        * \param[in] dev       dt device
+        * \param[out] fid      new FID allocated
+        * \param[in] parent    parent object
+        * \param[in] name      lu_name
+        *
+        * \retval 0            0 FID allocated successfully.
+        * \retval 1            1 FID allocated successfully and new sequence
+        *                      requested from seq meta server
+        * \retval negative     negative errno if FID allocation failed.
+        */
+       int (*ldo_fid_alloc)(const struct lu_env *env,
+                            struct lu_device *dev,
+                            struct lu_fid *fid,
+                            struct lu_object *parent,
+                            const struct lu_name *name);
 };
 
 /**
@@ -298,12 +321,12 @@ struct lu_device_type_operations;
  * device types.
  */
 enum lu_device_tag {
-        /** this is meta-data device */
-        LU_DEVICE_MD = (1 << 0),
-        /** this is data device */
-        LU_DEVICE_DT = (1 << 1),
-        /** data device in the client stack */
-        LU_DEVICE_CL = (1 << 2)
+       /** this is meta-data device */
+       LU_DEVICE_MD = BIT(0),
+       /** this is data device */
+       LU_DEVICE_DT = BIT(1),
+       /** data device in the client stack */
+       LU_DEVICE_CL = BIT(2)
 };
 
 /**
@@ -396,39 +419,45 @@ struct lu_attr {
         *
         * \see enum la_valid
         */
-       __u64          la_valid;
+       __u64           la_valid;
         /** size in bytes */
-        __u64          la_size;
+       __u64           la_size;
        /** modification time in seconds since Epoch */
        s64             la_mtime;
        /** access time in seconds since Epoch */
        s64             la_atime;
        /** change time in seconds since Epoch */
        s64             la_ctime;
+       /** create time in seconds since Epoch */
+       s64             la_btime;
         /** 512-byte blocks allocated to object */
-        __u64          la_blocks;
+       __u64           la_blocks;
         /** permission bits and file type */
-        __u32          la_mode;
+       __u32           la_mode;
         /** owner id */
-        __u32          la_uid;
+       __u32           la_uid;
         /** group id */
-        __u32          la_gid;
+       __u32           la_gid;
         /** object flags */
-        __u32          la_flags;
+       __u32           la_flags;
         /** number of persistent references to this object */
-        __u32          la_nlink;
+       __u32           la_nlink;
         /** blk bits of the object*/
-        __u32          la_blkbits;
+       __u32           la_blkbits;
         /** blk size of the object*/
-        __u32          la_blksize;
+       __u32           la_blksize;
         /** real device */
-        __u32          la_rdev;
+       __u32           la_rdev;
        /** project id */
-       __u32          la_projid;
+       __u32           la_projid;
        /** set layout version to OST objects. */
        __u32           la_layout_version;
+       /** dirent count */
+       __u64           la_dirent_count;
 };
 
+#define LU_DIRENT_COUNT_UNSET  ~0ULL
+
 /**
  * Layer in the layered object.
  */
@@ -471,17 +500,12 @@ enum lu_object_header_flags {
         * intialized yet, the object allocator will initialize it.
         */
        LU_OBJECT_INITED        = 2,
-       /**
-        * Object is being purged, so mustn't be returned by
-        * htable_lookup()
-        */
-       LU_OBJECT_PURGING       = 3,
 };
 
 enum lu_object_header_attr {
-       LOHA_EXISTS             = 1 << 0,
-       LOHA_REMOTE             = 1 << 1,
-       LOHA_HAS_AGENT_ENTRY    = 1 << 2,
+       LOHA_EXISTS             = BIT(0),
+       LOHA_REMOTE             = BIT(1),
+       LOHA_HAS_AGENT_ENTRY    = BIT(2),
        /**
         * UNIX file type is stored in S_IFMT bits.
         */
@@ -499,6 +523,8 @@ enum lu_object_header_attr {
  * it is created for things like not-yet-existing child created by mkdir or
  * create calls. lu_object_operations::loo_exists() can be used to check
  * whether object is backed by persistent storage entity.
+ * Any object containing this structre which might be placed in an
+ * rhashtable via loh_hash MUST be freed using call_rcu() or rcu_kfree().
  */
 struct lu_object_header {
        /**
@@ -520,9 +546,9 @@ struct lu_object_header {
         */
        __u32                   loh_attr;
        /**
-        * Linkage into per-site hash table. Protected by lu_site::ls_guard.
+        * Linkage into per-site hash table.
         */
-       struct hlist_node       loh_hash;
+       struct rhash_head       loh_hash;
        /**
         * Linkage into per-site LRU list. Protected by lu_site::ls_guard.
         */
@@ -568,7 +594,7 @@ struct lu_site {
         /**
          * objects hash table
          */
-       struct cfs_hash         *ls_obj_hash;
+       struct rhashtable       ls_obj_hash;
        /*
         * buckets for summary data
         */
@@ -648,7 +674,8 @@ int  lu_object_init       (struct lu_object *o,
 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);
-
+struct lu_object *lu_object_get_first(struct lu_object_header *h,
+                                     struct lu_device *dev);
 void lu_dev_add_linkage(struct lu_site *s, struct lu_device *d);
 void lu_dev_del_linkage(struct lu_site *s, struct lu_device *d);
 
@@ -706,8 +733,8 @@ static inline int lu_site_purge(const struct lu_env *env, struct lu_site *s,
        return lu_site_purge_objects(env, s, nr, 1);
 }
 
-void lu_site_print(const struct lu_env *env, struct lu_site *s, void *cookie,
-                   lu_printer_t printer);
+void lu_site_print(const struct lu_env *env, struct lu_site *s, atomic_t *ref,
+                  int msg_flags, lu_printer_t printer);
 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);
@@ -902,10 +929,10 @@ struct lu_rdpg {
 };
 
 enum lu_xattr_flags {
-       LU_XATTR_REPLACE = (1 << 0),
-       LU_XATTR_CREATE  = (1 << 1),
-       LU_XATTR_MERGE   = (1 << 2),
-       LU_XATTR_SPLIT   = (1 << 3),
+       LU_XATTR_REPLACE = BIT(0),
+       LU_XATTR_CREATE  = BIT(1),
+       LU_XATTR_MERGE   = BIT(2),
+       LU_XATTR_SPLIT   = BIT(3),
 };
 
 /** @} helpers */
@@ -988,62 +1015,62 @@ struct lu_context {
  */
 
 enum lu_context_tag {
-        /**
-         * Thread on md server
-         */
-        LCT_MD_THREAD = 1 << 0,
-        /**
-         * Thread on dt server
-         */
-        LCT_DT_THREAD = 1 << 1,
-        /**
-         * Thread on client
-         */
-        LCT_CL_THREAD = 1 << 3,
-        /**
-         * A per-request session on a server, and a per-system-call session on
-         * a client.
-         */
-        LCT_SESSION   = 1 << 4,
-        /**
-         * A per-request data on OSP device
-         */
-        LCT_OSP_THREAD = 1 << 5,
-        /**
-         * MGS device thread
-         */
-        LCT_MG_THREAD = 1 << 6,
-        /**
-         * Context for local operations
-         */
-       LCT_LOCAL = 1 << 7,
+       /**
+        * Thread on md server
+        */
+       LCT_MD_THREAD           = BIT(0),
+       /**
+        * Thread on dt server
+        */
+       LCT_DT_THREAD           = BIT(1),
+       /**
+        * Thread on client
+        */
+       LCT_CL_THREAD           = BIT(3),
+       /**
+        * A per-request session on a server, and a per-system-call session on
+        * a client.
+        */
+       LCT_SESSION             = BIT(4),
+       /**
+        * A per-request data on OSP device
+        */
+       LCT_OSP_THREAD          = BIT(5),
+       /**
+        * MGS device thread
+        */
+       LCT_MG_THREAD           = BIT(6),
+       /**
+        * Context for local operations
+        */
+       LCT_LOCAL               = BIT(7),
        /**
         * session for server thread
         **/
-       LCT_SERVER_SESSION = 1 << 8,
-        /**
-         * 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_HAS_EXIT  = 1 << 28,
-        /**
-         * Don't add references for modules creating key values in that context.
-         * This is only for contexts used internally by lu_object framework.
-         */
-        LCT_NOREF     = 1 << 29,
-        /**
-         * Key is being prepared for retiring, don't create new values for it.
-         */
-        LCT_QUIESCENT = 1 << 30,
-        /**
-         * Context should be remembered.
-         */
-        LCT_REMEMBER  = 1 << 31,
-        /**
-         * Contexts usable in cache shrinker thread.
-         */
-        LCT_SHRINKER  = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD|LCT_NOREF
+       LCT_SERVER_SESSION      = BIT(8),
+       /**
+        * 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_HAS_EXIT            = BIT(28),
+       /**
+        * Don't add references for modules creating key values in that context.
+        * This is only for contexts used internally by lu_object framework.
+        */
+       LCT_NOREF               = BIT(29),
+       /**
+        * Key is being prepared for retiring, don't create new values for it.
+        */
+       LCT_QUIESCENT           = BIT(30),
+       /**
+        * Context should be remembered.
+        */
+       LCT_REMEMBER            = BIT(31),
+       /**
+        * Contexts usable in cache shrinker thread.
+        */
+       LCT_SHRINKER    = LCT_MD_THREAD|LCT_DT_THREAD|LCT_CL_THREAD|LCT_NOREF,
 };
 
 /**
@@ -1292,6 +1319,7 @@ static inline void* lu_env_info(const struct lu_env *env,
 
 struct lu_env *lu_env_find(void);
 int lu_env_add(struct lu_env *env);
+int lu_env_add_task(struct lu_env *env, struct task_struct *task);
 void lu_env_remove(struct lu_env *env);
 
 /** @} lu_context */
@@ -1347,7 +1375,8 @@ static inline bool lu_name_is_temp_file(const char *name, int namelen,
         * About 0.07% of randomly-generated names will slip through,
         * but this avoids 99.93% of cross-MDT renames for those files.
         */
-       if (digit >= suffixlen - 2 || upper == suffixlen || lower == suffixlen)
+       if ((digit >= suffixlen - 1 && !isdigit(name[namelen - suffixlen])) ||
+           upper == suffixlen || lower == suffixlen)
                return false;
 
        return true;
@@ -1487,15 +1516,6 @@ static inline bool lu_object_is_cl(const struct lu_object *o)
        return lu_device_is_cl(o->lo_dev);
 }
 
-/* Generic subset of tgts */
-struct lu_tgt_pool {
-       __u32              *op_array;   /* array of index of
-                                        * lov_obd->lov_tgts */
-       unsigned int        op_count;   /* number of tgts in the array */
-       unsigned int        op_size;    /* allocated size of op_array */
-       struct rw_semaphore op_rw_sem;  /* to protect lu_tgt_pool use */
-};
-
 /* round-robin QoS data for LOD/LMV */
 struct lu_qos_rr {
        spinlock_t               lqr_alloc;     /* protect allocation index */