OSDN Git Service
(root)
/
uclinux-h8
/
linux.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Revert "dm mirror: use all available legs on multiple failures"
[uclinux-h8/linux.git]
/
drivers
/
md
/
dm-raid1.c
diff --git
a/drivers/md/dm-raid1.c
b/drivers/md/dm-raid1.c
index
a95cbb8
..
4da8858
100644
(file)
--- a/
drivers/md/dm-raid1.c
+++ b/
drivers/md/dm-raid1.c
@@
-145,6
+145,7
@@
static void dispatch_bios(void *context, struct bio_list *bio_list)
struct dm_raid1_bio_record {
struct mirror *m;
struct dm_raid1_bio_record {
struct mirror *m;
+ /* if details->bi_bdev == NULL, details were not saved */
struct dm_bio_details details;
region_t write_region;
};
struct dm_bio_details details;
region_t write_region;
};
@@
-260,7
+261,7
@@
static int mirror_flush(struct dm_target *ti)
struct mirror *m;
struct dm_io_request io_req = {
.bi_op = REQ_OP_WRITE,
struct mirror *m;
struct dm_io_request io_req = {
.bi_op = REQ_OP_WRITE,
- .bi_op_flags = REQ_PREFLUSH,
+ .bi_op_flags = REQ_PREFLUSH
| REQ_SYNC
,
.mem.type = DM_IO_KMEM,
.mem.ptr.addr = NULL,
.client = ms->io_client,
.mem.type = DM_IO_KMEM,
.mem.ptr.addr = NULL,
.client = ms->io_client,
@@
-1198,6
+1199,8
@@
static int mirror_map(struct dm_target *ti, struct bio *bio)
struct dm_raid1_bio_record *bio_record =
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
struct dm_raid1_bio_record *bio_record =
dm_per_bio_data(bio, sizeof(struct dm_raid1_bio_record));
+ bio_record->details.bi_bdev = NULL;
+
if (rw == WRITE) {
/* Save region for mirror_end_io() handler */
bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio);
if (rw == WRITE) {
/* Save region for mirror_end_io() handler */
bio_record->write_region = dm_rh_bio_to_region(ms->rh, bio);
@@
-1256,12
+1259,22
@@
static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
}
if (error == -EOPNOTSUPP)
}
if (error == -EOPNOTSUPP)
-
return error
;
+
goto out
;
if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD))
if ((error == -EWOULDBLOCK) && (bio->bi_opf & REQ_RAHEAD))
-
return error
;
+
goto out
;
if (unlikely(error)) {
if (unlikely(error)) {
+ if (!bio_record->details.bi_bdev) {
+ /*
+ * There wasn't enough memory to record necessary
+ * information for a retry or there was no other
+ * mirror in-sync.
+ */
+ DMERR_LIMIT("Mirror read failed.");
+ return -EIO;
+ }
+
m = bio_record->m;
DMERR("Mirror read failed from %s. Trying alternative device.",
m = bio_record->m;
DMERR("Mirror read failed from %s. Trying alternative device.",
@@
-1277,6
+1290,7
@@
static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
bd = &bio_record->details;
dm_bio_restore(bd, bio);
bd = &bio_record->details;
dm_bio_restore(bd, bio);
+ bio_record->details.bi_bdev = NULL;
bio->bi_error = 0;
queue_bio(ms, bio, rw);
bio->bi_error = 0;
queue_bio(ms, bio, rw);
@@
-1285,6
+1299,9
@@
static int mirror_end_io(struct dm_target *ti, struct bio *bio, int error)
DMERR("All replicated volumes dead, failing I/O");
}
DMERR("All replicated volumes dead, failing I/O");
}
+out:
+ bio_record->details.bi_bdev = NULL;
+
return error;
}
return error;
}