diff options
Diffstat (limited to 'include/linux/raid')
-rw-r--r-- | include/linux/raid/md.h | 2 | ||||
-rw-r--r-- | include/linux/raid/md_k.h | 41 | ||||
-rw-r--r-- | include/linux/raid/raid1.h | 79 | ||||
-rw-r--r-- | include/linux/raid/raid5.h | 118 | ||||
-rw-r--r-- | include/linux/raid/xor.h | 12 |
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 |