md/raid0: tidy up printk messages.
[safe/jmp/linux-2.6] / drivers / md / raid5.h
index 0c7375a..0f86f5e 100644 (file)
@@ -2,6 +2,7 @@
 #define _RAID5_H
 
 #include <linux/raid/xor.h>
+#include <linux/dmaengine.h>
 
 /*
  *
  */
 enum check_states {
        check_state_idle = 0,
-       check_state_run, /* parity check */
+       check_state_run, /* xor parity check */
+       check_state_run_q, /* q-parity check */
+       check_state_run_pq, /* pq dual parity check */
        check_state_check_result,
        check_state_compute_run, /* parity repair */
        check_state_compute_result,
@@ -198,9 +201,12 @@ struct stripe_head {
        struct hlist_node       hash;
        struct list_head        lru;          /* inactive_list or handle_list */
        struct raid5_private_data *raid_conf;
+       short                   generation;     /* increments with every
+                                                * reshape */
        sector_t                sector;         /* sector of this row */
        short                   pd_idx;         /* parity disk index */
        short                   qd_idx;         /* 'Q' disk index for raid6 */
+       short                   ddf_layout;/* use DDF ordering to calculate Q */
        unsigned long           state;          /* state flags */
        atomic_t                count;        /* nr of active thread/requests */
        spinlock_t              lock;
@@ -208,12 +214,20 @@ struct stripe_head {
        int                     disks;          /* disks in stripe */
        enum check_states       check_state;
        enum reconstruct_states reconstruct_state;
-       /* stripe_operations
+       /**
+        * struct stripe_operations
         * @target - STRIPE_OP_COMPUTE_BLK target
+        * @target2 - 2nd compute target in the raid6 case
+        * @zero_sum_result - P and Q verification flags
+        * @request - async service request flags for raid_run_ops
         */
        struct stripe_operations {
-               int                target;
-               u32                zero_sum_result;
+               int                  target, target2;
+               enum sum_check_flags zero_sum_result;
+               #ifdef CONFIG_MULTICORE_RAID456
+               unsigned long        request;
+               wait_queue_head_t    wait_for_ops;
+               #endif
        } ops;
        struct r5dev {
                struct bio      req;
@@ -238,7 +252,7 @@ struct stripe_head_state {
 
 /* r6_state - extra state data only relevant to r6 */
 struct r6_state {
-       int p_failed, q_failed, qd_idx, failed_num[2];
+       int p_failed, q_failed, failed_num[2];
 };
 
 /* Flags */
@@ -268,6 +282,8 @@ struct r6_state {
 #define READ_MODIFY_WRITE      2
 /* not a write method, but a compute_parity mode */
 #define        CHECK_PARITY            3
+/* Additional compute_parity mode -- updates the parity w/o LOCKING */
+#define UPDATE_PARITY          4
 
 /*
  * Stripe state
@@ -286,6 +302,8 @@ struct r6_state {
 #define        STRIPE_FULL_WRITE       13 /* all blocks are set to be overwritten */
 #define        STRIPE_BIOFILL_RUN      14
 #define        STRIPE_COMPUTE_RUN      15
+#define        STRIPE_OPS_REQ_PENDING  16
+
 /*
  * Operation request flags
  */
@@ -293,7 +311,7 @@ struct r6_state {
 #define STRIPE_OP_COMPUTE_BLK  1
 #define STRIPE_OP_PREXOR       2
 #define STRIPE_OP_BIODRAIN     3
-#define STRIPE_OP_POSTXOR      4
+#define STRIPE_OP_RECONSTRUCT  4
 #define STRIPE_OP_CHECK        5
 
 /*
@@ -329,17 +347,28 @@ struct raid5_private_data {
        struct hlist_head       *stripe_hashtbl;
        mddev_t                 *mddev;
        struct disk_info        *spare;
-       int                     chunk_size, level, algorithm;
+       int                     chunk_sectors;
+       int                     level, algorithm;
        int                     max_degraded;
        int                     raid_disks;
        int                     max_nr_stripes;
 
-       /* used during an expand */
-       sector_t                expand_progress;        /* MaxSector when no expand happening */
-       sector_t                expand_lo; /* from here up to expand_progress it out-of-bounds
-                                           * as we haven't flushed the metadata yet
-                                           */
+       /* reshape_progress is the leading edge of a 'reshape'
+        * It has value MaxSector when no reshape is happening
+        * If delta_disks < 0, it is the last sector we started work on,
+        * else is it the next sector to work on.
+        */
+       sector_t                reshape_progress;
+       /* reshape_safe is the trailing edge of a reshape.  We know that
+        * before (or after) this address, all reshape has completed.
+        */
+       sector_t                reshape_safe;
        int                     previous_raid_disks;
+       int                     prev_chunk_sectors;
+       int                     prev_algo;
+       short                   generation; /* increments with every reshape */
+       unsigned long           reshape_checkpoint; /* Time we last updated
+                                                    * metadata */
 
        struct list_head        handle_list; /* stripes needing handling */
        struct list_head        hold_list; /* preread ready stripes */
@@ -369,8 +398,21 @@ struct raid5_private_data {
                                            * (fresh device added).
                                            * Cleared when a sync completes.
                                            */
-
-       struct page             *spare_page; /* Used when checking P/Q in raid6 */
+       /* per cpu variables */
+       struct raid5_percpu {
+               struct page     *spare_page; /* Used when checking P/Q in raid6 */
+               void            *scribble;   /* space for constructing buffer
+                                             * lists and performing address
+                                             * conversions
+                                             */
+       } __percpu *percpu;
+       size_t                  scribble_len; /* size of scribble region must be
+                                              * associated with conf to handle
+                                              * cpu hotplug while reshaping
+                                              */
+#ifdef CONFIG_HOTPLUG_CPU
+       struct notifier_block   cpu_notify;
+#endif
 
        /*
         * Free stripes pool
@@ -385,18 +427,74 @@ struct raid5_private_data {
        int                     pool_size; /* number of disks in stripeheads in pool */
        spinlock_t              device_lock;
        struct disk_info        *disks;
+
+       /* When taking over an array from a different personality, we store
+        * the new thread here until we fully activate the array.
+        */
+       struct mdk_thread_s     *thread;
 };
 
 typedef struct raid5_private_data raid5_conf_t;
 
-#define mddev_to_conf(mddev) ((raid5_conf_t *) mddev->private)
-
 /*
  * Our supported algorithms
  */
-#define ALGORITHM_LEFT_ASYMMETRIC      0
-#define ALGORITHM_RIGHT_ASYMMETRIC     1
-#define ALGORITHM_LEFT_SYMMETRIC       2
-#define ALGORITHM_RIGHT_SYMMETRIC      3
+#define ALGORITHM_LEFT_ASYMMETRIC      0 /* Rotating Parity N with Data Restart */
+#define ALGORITHM_RIGHT_ASYMMETRIC     1 /* Rotating Parity 0 with Data Restart */
+#define ALGORITHM_LEFT_SYMMETRIC       2 /* Rotating Parity N with Data Continuation */
+#define ALGORITHM_RIGHT_SYMMETRIC      3 /* Rotating Parity 0 with Data Continuation */
+
+/* Define non-rotating (raid4) algorithms.  These allow
+ * conversion of raid4 to raid5.
+ */
+#define ALGORITHM_PARITY_0             4 /* P or P,Q are initial devices */
+#define ALGORITHM_PARITY_N             5 /* P or P,Q are final devices. */
+
+/* DDF RAID6 layouts differ from md/raid6 layouts in two ways.
+ * Firstly, the exact positioning of the parity block is slightly
+ * different between the 'LEFT_*' modes of md and the "_N_*" modes
+ * of DDF.
+ * Secondly, or order of datablocks over which the Q syndrome is computed
+ * is different.
+ * Consequently we have different layouts for DDF/raid6 than md/raid6.
+ * These layouts are from the DDFv1.2 spec.
+ * Interestingly DDFv1.2-Errata-A does not specify N_CONTINUE but
+ * leaves RLQ=3 as 'Vendor Specific'
+ */
+
+#define ALGORITHM_ROTATING_ZERO_RESTART        8 /* DDF PRL=6 RLQ=1 */
+#define ALGORITHM_ROTATING_N_RESTART   9 /* DDF PRL=6 RLQ=2 */
+#define ALGORITHM_ROTATING_N_CONTINUE  10 /*DDF PRL=6 RLQ=3 */
+
+
+/* For every RAID5 algorithm we define a RAID6 algorithm
+ * with exactly the same layout for data and parity, and
+ * with the Q block always on the last device (N-1).
+ * This allows trivial conversion from RAID5 to RAID6
+ */
+#define ALGORITHM_LEFT_ASYMMETRIC_6    16
+#define ALGORITHM_RIGHT_ASYMMETRIC_6   17
+#define ALGORITHM_LEFT_SYMMETRIC_6     18
+#define ALGORITHM_RIGHT_SYMMETRIC_6    19
+#define ALGORITHM_PARITY_0_6           20
+#define ALGORITHM_PARITY_N_6           ALGORITHM_PARITY_N
+
+static inline int algorithm_valid_raid5(int layout)
+{
+       return (layout >= 0) &&
+               (layout <= 5);
+}
+static inline int algorithm_valid_raid6(int layout)
+{
+       return (layout >= 0 && layout <= 5)
+               ||
+               (layout >= 8 && layout <= 10)
+               ||
+               (layout >= 16 && layout <= 20);
+}
 
+static inline int algorithm_is_DDF(int layout)
+{
+       return layout >= 8 && layout <= 10;
+}
 #endif