summaryrefslogtreecommitdiffstats
path: root/include/linux/raid
diff options
context:
space:
mode:
Diffstat (limited to 'include/linux/raid')
-rw-r--r--include/linux/raid/md.h2
-rw-r--r--include/linux/raid/md_k.h41
-rw-r--r--include/linux/raid/raid1.h79
-rw-r--r--include/linux/raid/raid5.h118
-rw-r--r--include/linux/raid/xor.h12
5 files changed, 245 insertions, 7 deletions
diff --git a/include/linux/raid/md.h b/include/linux/raid/md.h
index cabc0a8be..c2cabe19b 100644
--- a/include/linux/raid/md.h
+++ b/include/linux/raid/md.h
@@ -36,6 +36,7 @@
#include <net/checksum.h>
#include <linux/random.h>
#include <linux/locks.h>
+#include <linux/kernel_stat.h>
#include <asm/io.h>
#include <linux/raid/md_compatible.h>
@@ -74,6 +75,7 @@ extern void md_wakeup_thread(mdk_thread_t *thread);
extern void md_interrupt_thread (mdk_thread_t *thread);
extern int md_update_sb (mddev_t *mddev);
extern int md_do_sync(mddev_t *mddev, mdp_disk_t *spare);
+extern void md_done_sync(mddev_t *mddev, int blocks, int ok);
extern void md_recover_arrays (void);
extern int md_check_ordering (mddev_t *mddev);
extern void autodetect_raid(void);
diff --git a/include/linux/raid/md_k.h b/include/linux/raid/md_k.h
index e0fdda3fa..b62d63750 100644
--- a/include/linux/raid/md_k.h
+++ b/include/linux/raid/md_k.h
@@ -162,7 +162,7 @@ struct mdk_rdev_s
kdev_t dev; /* Device number */
kdev_t old_dev; /* "" when it was last imported */
- int size; /* Device size (in blocks) */
+ unsigned long size; /* Device size (in blocks) */
mddev_t *mddev; /* RAID array if running */
unsigned long last_events; /* IO event timestamp */
@@ -170,7 +170,7 @@ struct mdk_rdev_s
struct file filp; /* Lock file */
mdp_super_t *sb;
- int sb_offset;
+ unsigned long sb_offset;
int faulty; /* if faulty do not issue IO requests */
int desc_nr; /* descriptor index in the superblock */
@@ -199,13 +199,17 @@ struct mddev_s
int sb_dirty;
mdu_param_t param;
int ro;
- unsigned int curr_resync;
+ unsigned long curr_resync;
unsigned long resync_start;
char *name;
int recovery_running;
struct semaphore reconfig_sem;
struct semaphore recovery_sem;
struct semaphore resync_sem;
+
+ atomic_t recovery_active;
+ md_wait_queue_head_t recovery_wait;
+
struct md_list_head all_mddevs;
request_queue_t queue;
};
@@ -213,15 +217,11 @@ struct mddev_s
struct mdk_personality_s
{
char *name;
- int (*map)(mddev_t *mddev, kdev_t dev, kdev_t *rdev,
- unsigned long *rsector, unsigned long size);
int (*make_request)(request_queue_t *q, mddev_t *mddev, int rw, struct buffer_head * bh);
void (*end_request)(struct buffer_head * bh, int uptodate);
int (*run)(mddev_t *mddev);
int (*stop)(mddev_t *mddev);
int (*status)(char *page, mddev_t *mddev);
- int (*ioctl)(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg);
int max_invalid_dev;
int (*error_handler)(mddev_t *mddev, kdev_t dev);
@@ -239,6 +239,7 @@ struct mdk_personality_s
int (*stop_resync)(mddev_t *mddev);
int (*restart_resync)(mddev_t *mddev);
+ int (*sync_request)(mddev_t *mddev, unsigned long block_nr);
};
@@ -339,5 +340,31 @@ typedef struct dev_name_s {
char name [MAX_DISKNAME_LEN];
} dev_name_t;
+
+#define __wait_event_lock_irq(wq, condition, lock) \
+do { \
+ wait_queue_t __wait; \
+ init_waitqueue_entry(&__wait, current); \
+ \
+ add_wait_queue(&wq, &__wait); \
+ for (;;) { \
+ set_current_state(TASK_UNINTERRUPTIBLE); \
+ if (condition) \
+ break; \
+ spin_unlock_irq(&lock); \
+ schedule(); \
+ spin_lock_irq(&lock); \
+ } \
+ current->state = TASK_RUNNING; \
+ remove_wait_queue(&wq, &__wait); \
+} while (0)
+
+#define wait_event_lock_irq(wq, condition, lock) \
+do { \
+ if (condition) \
+ break; \
+ __wait_event_lock_irq(wq, condition, lock); \
+} while (0)
+
#endif _MD_K_H
diff --git a/include/linux/raid/raid1.h b/include/linux/raid/raid1.h
new file mode 100644
index 000000000..1016bdaa4
--- /dev/null
+++ b/include/linux/raid/raid1.h
@@ -0,0 +1,79 @@
+#ifndef _RAID1_H
+#define _RAID1_H
+
+#include <linux/raid/md.h>
+
+struct mirror_info {
+ int number;
+ int raid_disk;
+ kdev_t dev;
+ int next;
+ int sect_limit;
+
+ /*
+ * State bits:
+ */
+ int operational;
+ int write_only;
+ int spare;
+
+ int used_slot;
+};
+
+struct raid1_private_data {
+ mddev_t *mddev;
+ struct mirror_info mirrors[MD_SB_DISKS];
+ int nr_disks;
+ int raid_disks;
+ int working_disks;
+ int last_used;
+ unsigned long next_sect;
+ int sect_count;
+ mdk_thread_t *thread, *resync_thread;
+ int resync_mirrors;
+ struct mirror_info *spare;
+ md_spinlock_t device_lock;
+
+ /* for use when syncing mirrors: */
+ int start_active, start_ready,
+ start_pending, start_future;
+ int cnt_done, cnt_active, cnt_ready,
+ cnt_pending, cnt_future;
+ int phase;
+ int window;
+ md_wait_queue_head_t wait_done;
+ md_wait_queue_head_t wait_ready;
+ md_spinlock_t segment_lock;
+};
+
+typedef struct raid1_private_data raid1_conf_t;
+
+/*
+ * this is the only point in the RAID code where we violate
+ * C type safety. mddev->private is an 'opaque' pointer.
+ */
+#define mddev_to_conf(mddev) ((raid1_conf_t *) mddev->private)
+
+/*
+ * this is our 'private' 'collective' RAID1 buffer head.
+ * it contains information about what kind of IO operations were started
+ * for this RAID1 operation, and about their status:
+ */
+
+struct raid1_bh {
+ atomic_t remaining; /* 'have we finished' count,
+ * used from IRQ handlers
+ */
+ int cmd;
+ unsigned long state;
+ mddev_t *mddev;
+ struct buffer_head *master_bh;
+ struct buffer_head *mirror_bh [MD_SB_DISKS];
+ struct buffer_head bh_req;
+ struct buffer_head *next_retry;
+};
+/* bits for raid1_bh.state */
+#define R1BH_Uptodate 1
+#define R1BH_SyncPhase 2
+
+#endif
diff --git a/include/linux/raid/raid5.h b/include/linux/raid/raid5.h
new file mode 100644
index 000000000..ab839ea02
--- /dev/null
+++ b/include/linux/raid/raid5.h
@@ -0,0 +1,118 @@
+#ifndef _RAID5_H
+#define _RAID5_H
+
+#include <linux/raid/md.h>
+#include <linux/raid/xor.h>
+
+struct disk_info {
+ kdev_t dev;
+ int operational;
+ int number;
+ int raid_disk;
+ int write_only;
+ int spare;
+ int used_slot;
+};
+
+struct stripe_head {
+ md_spinlock_t stripe_lock;
+ struct stripe_head *hash_next, **hash_pprev; /* hash pointers */
+ struct stripe_head *free_next; /* pool of free sh's */
+ struct buffer_head *buffer_pool; /* pool of free buffers */
+ struct buffer_head *bh_pool; /* pool of free bh's */
+ struct raid5_private_data *raid_conf;
+ struct buffer_head *bh_old[MD_SB_DISKS]; /* disk image */
+ struct buffer_head *bh_new[MD_SB_DISKS]; /* buffers of the MD device (present in buffer cache) */
+ struct buffer_head *bh_copy[MD_SB_DISKS]; /* copy on write of bh_new (bh_new can change from under us) */
+ struct buffer_head *bh_req[MD_SB_DISKS]; /* copy of bh_new (only the buffer heads), queued to the lower levels */
+ int cmd_new[MD_SB_DISKS]; /* READ/WRITE for new */
+ int new[MD_SB_DISKS]; /* buffer added since the last handle_stripe() */
+ unsigned long sector; /* sector of this row */
+ int size; /* buffers size */
+ int pd_idx; /* parity disk index */
+ atomic_t nr_pending; /* nr of pending cmds */
+ unsigned long state; /* state flags */
+ int cmd; /* stripe cmd */
+ atomic_t count; /* nr of waiters */
+ int write_method; /* reconstruct-write / read-modify-write */
+ int phase; /* PHASE_BEGIN, ..., PHASE_COMPLETE */
+ md_wait_queue_head_t wait; /* processes waiting for this stripe */
+
+ int sync_redone;
+};
+
+/*
+ * Phase
+ */
+#define PHASE_BEGIN 0
+#define PHASE_READ_OLD 1
+#define PHASE_WRITE 2
+#define PHASE_READ 3
+#define PHASE_COMPLETE 4
+
+/*
+ * Write method
+ */
+#define METHOD_NONE 0
+#define RECONSTRUCT_WRITE 1
+#define READ_MODIFY_WRITE 2
+
+/*
+ * Stripe state
+ */
+#define STRIPE_LOCKED 0
+#define STRIPE_ERROR 1
+
+/*
+ * Stripe commands
+ */
+#define STRIPE_NONE 0
+#define STRIPE_WRITE 1
+#define STRIPE_READ 2
+#define STRIPE_SYNC 3
+
+struct raid5_private_data {
+ struct stripe_head **stripe_hashtbl;
+ mddev_t *mddev;
+ mdk_thread_t *thread, *resync_thread;
+ struct disk_info disks[MD_SB_DISKS];
+ struct disk_info *spare;
+ int buffer_size;
+ int chunk_size, level, algorithm;
+ int raid_disks, working_disks, failed_disks;
+ int sector_count;
+ unsigned long next_sector;
+ atomic_t nr_handle;
+ struct stripe_head *next_free_stripe;
+ atomic_t nr_stripes;
+ int resync_parity;
+ int max_nr_stripes;
+ int clock;
+ atomic_t nr_hashed_stripes;
+ atomic_t nr_locked_stripes;
+ atomic_t nr_pending_stripes;
+ atomic_t nr_cached_stripes;
+
+ /*
+ * Free stripes pool
+ */
+ atomic_t nr_free_sh;
+ struct stripe_head *free_sh_list;
+ md_wait_queue_head_t wait_for_stripe;
+
+ md_spinlock_t device_lock;
+};
+
+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
+
+#endif
diff --git a/include/linux/raid/xor.h b/include/linux/raid/xor.h
new file mode 100644
index 000000000..c8034b759
--- /dev/null
+++ b/include/linux/raid/xor.h
@@ -0,0 +1,12 @@
+#ifndef _XOR_H
+#define _XOR_H
+
+#include <linux/raid/md.h>
+
+#define MAX_XOR_BLOCKS 4
+
+extern void calibrate_xor_block(void);
+extern void (*xor_block)(unsigned int count,
+ struct buffer_head **bh_ptr);
+
+#endif