File: /usr/include/linux/raid/md_k.h

1     /*
2        md_k.h : kernel internal structure of the Linux MD driver
3               Copyright (C) 1996-98 Ingo Molnar, Gadi Oxman
4     	  
5        This program is free software; you can redistribute it and/or modify
6        it under the terms of the GNU General Public License as published by
7        the Free Software Foundation; either version 2, or (at your option)
8        any later version.
9        
10        You should have received a copy of the GNU General Public License
11        (for example /usr/src/linux/COPYING); if not, write to the Free
12        Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  
13     */
14     
15     #ifndef _MD_K_H
16     #define _MD_K_H
17     
18     #include <linux/kernel.h>	// for panic()
19     
20     #define MD_RESERVED       0UL
21     #define LINEAR            1UL
22     #define RAID0             2UL
23     #define RAID1             3UL
24     #define RAID5             4UL
25     #define TRANSLUCENT       5UL
26     #define HSM               6UL
27     #define MULTIPATH         7UL
28     #define MAX_PERSONALITY   8UL
29     
30     extern inline int pers_to_level (int pers)
31     {
32     	switch (pers) {
33     		case MULTIPATH:		return -4;
34     		case HSM:		return -3;
35     		case TRANSLUCENT:	return -2;
36     		case LINEAR:		return -1;
37     		case RAID0:		return 0;
38     		case RAID1:		return 1;
39     		case RAID5:		return 5;
40     	}
41     	panic("pers_to_level()");
42     	return 0;
43     }
44     
45     extern inline int level_to_pers (int level)
46     {
47     	switch (level) {
48     		case -4: return MULTIPATH;
49     		case -3: return HSM;
50     		case -2: return TRANSLUCENT;
51     		case -1: return LINEAR;
52     		case 0: return RAID0;
53     		case 1: return RAID1;
54     		case 4:
55     		case 5: return RAID5;
56     	}
57     	return MD_RESERVED;
58     }
59     
60     typedef struct mddev_s mddev_t;
61     typedef struct mdk_rdev_s mdk_rdev_t;
62     
63     #if (MINORBITS != 8)
64     #error MD doesnt handle bigger kdev yet
65     #endif
66     
67     #define MAX_MD_DEVS  (1<<MINORBITS)	/* Max number of md dev */
68     
69     /*
70      * Maps a kdev to an mddev/subdev. How 'data' is handled is up to
71      * the personality. (eg. HSM uses this to identify individual LVs)
72      */
73     typedef struct dev_mapping_s {
74     	mddev_t *mddev;
75     	void *data;
76     } dev_mapping_t;
77     
78     extern dev_mapping_t mddev_map [MAX_MD_DEVS];
79     
80     extern inline mddev_t * kdev_to_mddev (kdev_t dev)
81     {
82     	if (MAJOR(dev) != MD_MAJOR)
83     		BUG();
84             return mddev_map[MINOR(dev)].mddev;
85     }
86     
87     /*
88      * options passed in raidrun:
89      */
90     
91     #define MAX_CHUNK_SIZE (4096*1024)
92     
93     /*
94      * default readahead
95      */
96     #define MD_READAHEAD	MAX_READAHEAD
97     
98     extern inline int disk_faulty(mdp_disk_t * d)
99     {
100     	return d->state & (1 << MD_DISK_FAULTY);
101     }
102     
103     extern inline int disk_active(mdp_disk_t * d)
104     {
105     	return d->state & (1 << MD_DISK_ACTIVE);
106     }
107     
108     extern inline int disk_sync(mdp_disk_t * d)
109     {
110     	return d->state & (1 << MD_DISK_SYNC);
111     }
112     
113     extern inline int disk_spare(mdp_disk_t * d)
114     {
115     	return !disk_sync(d) && !disk_active(d) && !disk_faulty(d);
116     }
117     
118     extern inline int disk_removed(mdp_disk_t * d)
119     {
120     	return d->state & (1 << MD_DISK_REMOVED);
121     }
122     
123     extern inline void mark_disk_faulty(mdp_disk_t * d)
124     {
125     	d->state |= (1 << MD_DISK_FAULTY);
126     }
127     
128     extern inline void mark_disk_active(mdp_disk_t * d)
129     {
130     	d->state |= (1 << MD_DISK_ACTIVE);
131     }
132     
133     extern inline void mark_disk_sync(mdp_disk_t * d)
134     {
135     	d->state |= (1 << MD_DISK_SYNC);
136     }
137     
138     extern inline void mark_disk_spare(mdp_disk_t * d)
139     {
140     	d->state = 0;
141     }
142     
143     extern inline void mark_disk_removed(mdp_disk_t * d)
144     {
145     	d->state = (1 << MD_DISK_FAULTY) | (1 << MD_DISK_REMOVED);
146     }
147     
148     extern inline void mark_disk_inactive(mdp_disk_t * d)
149     {
150     	d->state &= ~(1 << MD_DISK_ACTIVE);
151     }
152     
153     extern inline void mark_disk_nonsync(mdp_disk_t * d)
154     {
155     	d->state &= ~(1 << MD_DISK_SYNC);
156     }
157     
158     /*
159      * MD's 'extended' device
160      */
161     struct mdk_rdev_s
162     {
163     	struct md_list_head same_set;	/* RAID devices within the same set */
164     	struct md_list_head all;	/* all RAID devices */
165     	struct md_list_head pending;	/* undetected RAID devices */
166     
167     	kdev_t dev;			/* Device number */
168     	kdev_t old_dev;			/*  "" when it was last imported */
169     	unsigned long size;		/* Device size (in blocks) */
170     	mddev_t *mddev;			/* RAID array if running */
171     	unsigned long last_events;	/* IO event timestamp */
172     
173     	struct block_device *bdev;	/* block device handle */
174     
175     	mdp_super_t *sb;
176     	unsigned long sb_offset;
177     
178     	int alias_device;		/* device alias to the same disk */
179     	int faulty;			/* if faulty do not issue IO requests */
180     	int desc_nr;			/* descriptor index in the superblock */
181     };
182     
183     
184     /*
185      * disk operations in a working array:
186      */
187     #define DISKOP_SPARE_INACTIVE	0
188     #define DISKOP_SPARE_WRITE	1
189     #define DISKOP_SPARE_ACTIVE	2
190     #define DISKOP_HOT_REMOVE_DISK	3
191     #define DISKOP_HOT_ADD_DISK	4
192     
193     typedef struct mdk_personality_s mdk_personality_t;
194     
195     struct mddev_s
196     {
197     	void				*private;
198     	mdk_personality_t		*pers;
199     	int				__minor;
200     	mdp_super_t			*sb;
201     	int				nb_dev;
202     	struct md_list_head 		disks;
203     	int				sb_dirty;
204     	mdu_param_t			param;
205     	int				ro;
206     	unsigned long			curr_resync;	/* blocks scheduled */
207     	unsigned long			resync_mark;	/* a recent timestamp */
208     	unsigned long			resync_mark_cnt;/* blocks written at resync_mark */
209     	char				*name;
210     	int				recovery_running;
211     	struct semaphore		reconfig_sem;
212     	struct semaphore		recovery_sem;
213     	struct semaphore		resync_sem;
214     	atomic_t			active;
215     
216     	atomic_t			recovery_active; /* blocks scheduled, but not written */
217     	md_wait_queue_head_t		recovery_wait;
218     
219     	struct md_list_head		all_mddevs;
220     };
221     
222     struct mdk_personality_s
223     {
224     	char *name;
225     	int (*make_request)(mddev_t *mddev, int rw, struct buffer_head * bh);
226     	int (*run)(mddev_t *mddev);
227     	int (*stop)(mddev_t *mddev);
228     	int (*status)(char *page, mddev_t *mddev);
229     	int (*error_handler)(mddev_t *mddev, kdev_t dev);
230     
231     /*
232      * Some personalities (RAID-1, RAID-5) can have disks hot-added and
233      * hot-removed. Hot removal is different from failure. (failure marks
234      * a disk inactive, but the disk is still part of the array) The interface
235      * to such operations is the 'pers->diskop()' function, can be NULL.
236      *
237      * the diskop function can change the pointer pointing to the incoming
238      * descriptor, but must do so very carefully. (currently only
239      * SPARE_ACTIVE expects such a change)
240      */
241     	int (*diskop) (mddev_t *mddev, mdp_disk_t **descriptor, int state);
242     
243     	int (*stop_resync)(mddev_t *mddev);
244     	int (*restart_resync)(mddev_t *mddev);
245     	int (*sync_request)(mddev_t *mddev, unsigned long block_nr);
246     };
247     
248     
249     /*
250      * Currently we index md_array directly, based on the minor
251      * number. This will have to change to dynamic allocation
252      * once we start supporting partitioning of md devices.
253      */
254     extern inline int mdidx (mddev_t * mddev)
255     {
256     	return mddev->__minor;
257     }
258     
259     extern inline kdev_t mddev_to_kdev(mddev_t * mddev)
260     {
261     	return MKDEV(MD_MAJOR, mdidx(mddev));
262     }
263     
264     extern mdk_rdev_t * find_rdev(mddev_t * mddev, kdev_t dev);
265     extern mdk_rdev_t * find_rdev_nr(mddev_t *mddev, int nr);
266     extern mdp_disk_t *get_spare(mddev_t *mddev);
267     
268     /*
269      * iterates through some rdev ringlist. It's safe to remove the
270      * current 'rdev'. Dont touch 'tmp' though.
271      */
272     #define ITERATE_RDEV_GENERIC(head,field,rdev,tmp)			\
273     									\
274     	for (tmp = head.next;						\
275     		rdev = md_list_entry(tmp, mdk_rdev_t, field),		\
276     			tmp = tmp->next, tmp->prev != &head		\
277     		; )
278     /*
279      * iterates through the 'same array disks' ringlist
280      */
281     #define ITERATE_RDEV(mddev,rdev,tmp)					\
282     	ITERATE_RDEV_GENERIC((mddev)->disks,same_set,rdev,tmp)
283     
284     /*
285      * Same as above, but assumes that the device has rdev->desc_nr numbered
286      * from 0 to mddev->nb_dev, and iterates through rdevs in ascending order.
287      */
288     #define ITERATE_RDEV_ORDERED(mddev,rdev,i)				\
289     	for (i = 0; rdev = find_rdev_nr(mddev, i), i < mddev->nb_dev; i++)
290     
291     
292     /*
293      * Iterates through all 'RAID managed disks'
294      */
295     #define ITERATE_RDEV_ALL(rdev,tmp)					\
296     	ITERATE_RDEV_GENERIC(all_raid_disks,all,rdev,tmp)
297     
298     /*
299      * Iterates through 'pending RAID disks'
300      */
301     #define ITERATE_RDEV_PENDING(rdev,tmp)					\
302     	ITERATE_RDEV_GENERIC(pending_raid_disks,pending,rdev,tmp)
303     
304     /*
305      * iterates through all used mddevs in the system.
306      */
307     #define ITERATE_MDDEV(mddev,tmp)					\
308     									\
309     	for (tmp = all_mddevs.next;					\
310     		mddev = md_list_entry(tmp, mddev_t, all_mddevs),	\
311     			tmp = tmp->next, tmp->prev != &all_mddevs	\
312     		; )
313     
314     extern inline int lock_mddev (mddev_t * mddev)
315     {
316     	return down_interruptible(&mddev->reconfig_sem);
317     }
318     
319     extern inline void unlock_mddev (mddev_t * mddev)
320     {
321     	up(&mddev->reconfig_sem);
322     }
323     
324     #define xchg_values(x,y) do { __typeof__(x) __tmp = x; \
325     				x = y; y = __tmp; } while (0)
326     
327     typedef struct mdk_thread_s {
328     	void			(*run) (void *data);
329     	void			*data;
330     	md_wait_queue_head_t	wqueue;
331     	unsigned long           flags;
332     	struct semaphore	*sem;
333     	struct task_struct	*tsk;
334     	const char		*name;
335     } mdk_thread_t;
336     
337     #define THREAD_WAKEUP  0
338     
339     #define MAX_DISKNAME_LEN 64
340     
341     typedef struct dev_name_s {
342     	struct md_list_head list;
343     	kdev_t dev;
344     	char namebuf [MAX_DISKNAME_LEN];
345     	char *name;
346     } dev_name_t;
347     
348     
349     #define __wait_event_lock_irq(wq, condition, lock) 			\
350     do {									\
351     	wait_queue_t __wait;						\
352     	init_waitqueue_entry(&__wait, current);				\
353     									\
354     	add_wait_queue(&wq, &__wait);					\
355     	for (;;) {							\
356     		set_current_state(TASK_UNINTERRUPTIBLE);		\
357     		if (condition)						\
358     			break;						\
359     		spin_unlock_irq(&lock);					\
360     		run_task_queue(&tq_disk);				\
361     		schedule();						\
362     		spin_lock_irq(&lock);					\
363     	}								\
364     	current->state = TASK_RUNNING;					\
365     	remove_wait_queue(&wq, &__wait);				\
366     } while (0)
367     
368     #define wait_event_lock_irq(wq, condition, lock) 			\
369     do {									\
370     	if (condition)	 						\
371     		break;							\
372     	__wait_event_lock_irq(wq, condition, lock);			\
373     } while (0)
374     
375     #endif 
376     
377