aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.h')
-rw-r--r--drivers/md/md.h48
1 files changed, 47 insertions, 1 deletions
diff --git a/drivers/md/md.h b/drivers/md/md.h
index 7d906a96477a..85af8433f8b8 100644
--- a/drivers/md/md.h
+++ b/drivers/md/md.h
@@ -29,6 +29,13 @@
29typedef struct mddev_s mddev_t; 29typedef struct mddev_s mddev_t;
30typedef struct mdk_rdev_s mdk_rdev_t; 30typedef struct mdk_rdev_s mdk_rdev_t;
31 31
32/* Bad block numbers are stored sorted in a single page.
33 * 64bits is used for each block or extent.
34 * 54 bits are sector number, 9 bits are extent size,
35 * 1 bit is an 'acknowledged' flag.
36 */
37#define MD_MAX_BADBLOCKS (PAGE_SIZE/8)
38
32/* 39/*
33 * MD's 'extended' device 40 * MD's 'extended' device
34 */ 41 */
@@ -111,8 +118,47 @@ struct mdk_rdev_s
111 118
112 struct sysfs_dirent *sysfs_state; /* handle for 'state' 119 struct sysfs_dirent *sysfs_state; /* handle for 'state'
113 * sysfs entry */ 120 * sysfs entry */
121
122 struct badblocks {
123 int count; /* count of bad blocks */
124 int shift; /* shift from sectors to block size
125 * a -ve shift means badblocks are
126 * disabled.*/
127 u64 *page; /* badblock list */
128 int changed;
129 seqlock_t lock;
130 } badblocks;
114}; 131};
115 132
133#define BB_LEN_MASK (0x00000000000001FFULL)
134#define BB_OFFSET_MASK (0x7FFFFFFFFFFFFE00ULL)
135#define BB_ACK_MASK (0x8000000000000000ULL)
136#define BB_MAX_LEN 512
137#define BB_OFFSET(x) (((x) & BB_OFFSET_MASK) >> 9)
138#define BB_LEN(x) (((x) & BB_LEN_MASK) + 1)
139#define BB_ACK(x) (!!((x) & BB_ACK_MASK))
140#define BB_MAKE(a, l, ack) (((a)<<9) | ((l)-1) | ((u64)(!!(ack)) << 63))
141
142extern int md_is_badblock(struct badblocks *bb, sector_t s, int sectors,
143 sector_t *first_bad, int *bad_sectors);
144static inline int is_badblock(mdk_rdev_t *rdev, sector_t s, int sectors,
145 sector_t *first_bad, int *bad_sectors)
146{
147 if (unlikely(rdev->badblocks.count)) {
148 int rv = md_is_badblock(&rdev->badblocks, rdev->data_offset + s,
149 sectors,
150 first_bad, bad_sectors);
151 if (rv)
152 *first_bad -= rdev->data_offset;
153 return rv;
154 }
155 return 0;
156}
157extern int rdev_set_badblocks(mdk_rdev_t *rdev, sector_t s, int sectors,
158 int acknowledged);
159extern int rdev_clear_badblocks(mdk_rdev_t *rdev, sector_t s, int sectors);
160extern void md_ack_all_badblocks(struct badblocks *bb);
161
116struct mddev_s 162struct mddev_s
117{ 163{
118 void *private; 164 void *private;
@@ -517,7 +563,7 @@ extern void mddev_init(mddev_t *mddev);
517extern int md_run(mddev_t *mddev); 563extern int md_run(mddev_t *mddev);
518extern void md_stop(mddev_t *mddev); 564extern void md_stop(mddev_t *mddev);
519extern void md_stop_writes(mddev_t *mddev); 565extern void md_stop_writes(mddev_t *mddev);
520extern void md_rdev_init(mdk_rdev_t *rdev); 566extern int md_rdev_init(mdk_rdev_t *rdev);
521 567
522extern void mddev_suspend(mddev_t *mddev); 568extern void mddev_suspend(mddev_t *mddev);
523extern void mddev_resume(mddev_t *mddev); 569extern void mddev_resume(mddev_t *mddev);