spin_lock_irqsave(&serial->serial_lock, flags); for (si = raid1_rb_iter_first(&serial->serial_rb, lo, hi);
si; si = raid1_rb_iter_next(si, lo, hi)) { if (si->start == lo && si->last == hi) {
raid1_rb_remove(si, &serial->serial_rb);
mempool_free(si, mddev->serial_info_pool);
found = 1; break;
}
} if (!found)
WARN(1, "The write IO is not recorded for serialization\n");
spin_unlock_irqrestore(&serial->serial_lock, flags);
wake_up(&serial->serial_io_wait);
}
for (i = 0; i < conf->raid_disks * 2; i++) { struct bio *bio = r1_bio->bios[i]; if (bio->bi_end_io)
rdev_dec_pending(conf->mirrors[i].rdev, r1_bio->mddev);
}
/* if nobody has done the final endio yet, do it now */ if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) {
pr_debug("raid1: sync end %s on sectors %llu-%llu\n",
(bio_data_dir(bio) == WRITE) ? "write" : "read",
(unsignedlonglong) bio->bi_iter.bi_sector,
(unsignedlonglong) bio_end_sector(bio) - 1);
/* it really is the end of this request */ if (test_bit(R1BIO_BehindIO, &r1_bio->state)) {
bio_free_pages(r1_bio->behind_master_bio);
bio_put(r1_bio->behind_master_bio);
r1_bio->behind_master_bio = NULL;
}
if (test_bit(R1BIO_BehindIO, &r1_bio->state))
mddev->bitmap_ops->end_behind_write(mddev);
md_write_end(mddev);
}
staticvoid r1_bio_write_done(struct r1bio *r1_bio)
{ if (!atomic_dec_and_test(&r1_bio->remaining)) return;
if (test_bit(R1BIO_WriteError, &r1_bio->state))
reschedule_retry(r1_bio); else {
close_write(r1_bio); if (test_bit(R1BIO_MadeGood, &r1_bio->state))
reschedule_retry(r1_bio); else
raid_end_bio_io(r1_bio);
}
}
staticvoid raid1_end_write_request(struct bio *bio)
{ struct r1bio *r1_bio = bio->bi_private; int behind = test_bit(R1BIO_BehindIO, &r1_bio->state); struct r1conf *conf = r1_bio->mddev->private; struct bio *to_put = NULL; int mirror = find_bio_disk(r1_bio, bio); struct md_rdev *rdev = conf->mirrors[mirror].rdev;
sector_t lo = r1_bio->sector;
sector_t hi = r1_bio->sector + r1_bio->sectors; bool ignore_error = !raid1_should_handle_error(bio) ||
(bio->bi_status && bio_op(bio) == REQ_OP_DISCARD);
/* *'onemirrorIOhasfinished'eventhandler:
*/ if (bio->bi_status && !ignore_error) {
set_bit(WriteErrorSeen, &rdev->flags); if (!test_and_set_bit(WantReplacement, &rdev->flags))
set_bit(MD_RECOVERY_NEEDED, &
conf->mddev->recovery);
if (test_bit(FailFast, &rdev->flags) &&
(bio->bi_opf & MD_FAILFAST) && /* We never try FailFast to WriteMostly devices */
!test_bit(WriteMostly, &rdev->flags)) {
md_error(r1_bio->mddev, rdev);
}
/* Maybe we can clear some bad blocks. */ if (rdev_has_badblock(rdev, r1_bio->sector, r1_bio->sectors) &&
!ignore_error) {
r1_bio->bios[mirror] = IO_MADE_GOOD;
set_bit(R1BIO_MadeGood, &r1_bio->state);
}
}
if (behind) { if (test_bit(CollisionCheck, &rdev->flags))
remove_serial(rdev, lo, hi); if (test_bit(WriteMostly, &rdev->flags))
atomic_dec(&r1_bio->behind_remaining);
/* *Inbehindmode,weACKthemasterbiooncetheI/O *hassafelyreachedallnon-writemostly *disks.SettingtheReturnedbitensuresthatthis *getsdoneonlyonce--wedon'teverwanttoreturn *-EIOhere,insteadwe'llwait
*/ if (atomic_read(&r1_bio->behind_remaining) >= (atomic_read(&r1_bio->remaining)-1) &&
test_bit(R1BIO_Uptodate, &r1_bio->state)) { /* Maybe we can return now */ if (!test_and_set_bit(R1BIO_Returned, &r1_bio->state)) { struct bio *mbio = r1_bio->master_bio;
pr_debug("raid1: behind end write sectors" " %llu-%llu\n",
(unsignedlonglong) mbio->bi_iter.bi_sector,
(unsignedlonglong) bio_end_sector(mbio) - 1);
call_bio_endio(r1_bio);
}
}
} elseif (rdev->mddev->serialize_policy)
remove_serial(rdev, lo, hi); if (r1_bio->bios[mirror] == NULL)
rdev_dec_pending(rdev, conf->mddev);
staticint choose_first_rdev(struct r1conf *conf, struct r1bio *r1_bio, int *max_sectors)
{
sector_t this_sector = r1_bio->sector; int len = r1_bio->sectors; int disk;
for (disk = 0 ; disk < conf->raid_disks * 2 ; disk++) { struct md_rdev *rdev; int read_len;
if (r1_bio->bios[disk] == IO_BLOCKED) continue;
rdev = conf->mirrors[disk].rdev; if (!rdev || test_bit(Faulty, &rdev->flags)) continue;
/* choose the first disk even if it has some bad blocks. */
read_len = raid1_check_read_range(rdev, this_sector, &len); if (read_len > 0) {
update_read_sectors(conf, disk, this_sector, read_len);
*max_sectors = read_len; return disk;
}
}
/* keep track of the disk with the most readable sectors. */
len = r1_bio->sectors;
read_len = raid1_check_read_range(rdev, this_sector, &len); if (read_len > best_len) {
best_disk = disk;
best_len = read_len;
}
}
/* there are no bad blocks, we can use this disk */
len = r1_bio->sectors;
read_len = raid1_check_read_range(rdev, this_sector, &len); if (read_len == r1_bio->sectors) {
*max_sectors = read_len;
update_read_sectors(conf, disk, this_sector, read_len); return disk;
}
/* don't read from slow disk unless have to */ if (test_bit(WriteMostly, &rdev->flags)) returnfalse;
/* don't split IO for bad blocks unless have to */ if (rdev_has_badblock(rdev, r1_bio->sector, r1_bio->sectors)) returnfalse;
returntrue;
}
struct read_balance_ctl {
sector_t closest_dist; int closest_dist_disk; int min_pending; int min_pending_disk; int sequential_disk; int readable_disks;
};
staticvoid wake_up_barrier(struct r1conf *conf)
{ if (wq_has_sleeper(&conf->wait_barrier))
wake_up(&conf->wait_barrier);
}
staticvoid flush_bio_list(struct r1conf *conf, struct bio *bio)
{ /* flush any pending bitmap writes to disk before proceeding w/ I/O */
raid1_prepare_flush_writes(conf->mddev);
wake_up_barrier(conf);
while (bio) { /* submit pending writes */ struct bio *next = bio->bi_next;
raid1_submit_write(bio);
bio = next;
cond_resched();
}
}
staticvoid flush_pending_writes(struct r1conf *conf)
{ /* Any writes that have been queued but are awaiting *bitmapupdatesgetflushedhere.
*/
spin_lock_irq(&conf->device_lock);
if (conf->pending_bio_list.head) { struct blk_plug plug; struct bio *bio;
bio = bio_list_get(&conf->pending_bio_list);
spin_unlock_irq(&conf->device_lock);
/* *Afterholdingconf->resync_lock,conf->nr_pending[idx] *shouldbedecreasedbeforewaitingforbarriertodrop. *Otherwise,wemayencounteraraceconditionbecause *raise_barrer()mightbewaitingforconf->nr_pending[idx] *tobe0atsametime.
*/
spin_lock_irq(&conf->resync_lock);
atomic_inc(&conf->nr_waiting[idx]);
atomic_dec(&conf->nr_pending[idx]); /* *Incasefreeze_array()iswaitingfor *get_unqueued_pending()==extra
*/
wake_up_barrier(conf); /* Wait for the barrier in same barrier unit bucket to drop. */
/* Return false when nowait flag is set */ if (nowait) {
ret = false;
} else {
wait_event_lock_irq(conf->wait_barrier,
!conf->array_frozen &&
!atomic_read(&conf->barrier[idx]),
conf->resync_lock);
atomic_inc(&conf->nr_pending[idx]);
}
spin_lock_irq(&conf->resync_lock);
atomic_inc(&conf->nr_waiting[idx]);
atomic_dec(&conf->nr_pending[idx]); /* *Incasefreeze_array()iswaitingfor *get_unqueued_pending()==extra
*/
wake_up_barrier(conf); /* Wait for array to be unfrozen */
/* Return false when nowait flag is set */ if (nowait) { /* Return false when nowait flag is set */
ret = false;
} else {
wait_event_lock_irq(conf->wait_barrier,
!conf->array_frozen,
conf->resync_lock);
atomic_inc(&conf->nr_pending[idx]);
}
/* conf->resync_lock should be held */ staticint get_unqueued_pending(struct r1conf *conf)
{ int idx, ret;
ret = atomic_read(&conf->nr_sync_pending); for (idx = 0; idx < BARRIER_BUCKETS_NR; idx++)
ret += atomic_read(&conf->nr_pending[idx]) -
atomic_read(&conf->nr_queued[idx]);
return ret;
}
staticvoid freeze_array(struct r1conf *conf, int extra)
{ /* Stop sync I/O and normal I/O and wait for everything to *goquiet. *Thisiscalledintwosituations: *1)managementcommandhandlers(reshape,removedisk,quiesce). *2)onenormalI/Orequestfailed.
/* *make_request()canaborttheoperationwhenread-aheadisbeing *usedandnoemptyrequestisavailable.
*/
rdisk = read_balance(conf, r1_bio, &max_sectors); if (rdisk < 0) { /* couldn't find anywhere to read from */ if (r1bio_existed)
pr_crit_ratelimited("md/raid1:%s: %pg: unrecoverable I/O read error for block %llu\n",
mdname(mddev),
conf->mirrors[r1_bio->read_disk].rdev->bdev,
r1_bio->sector);
raid_end_bio_io(r1_bio); return;
}
mirror = conf->mirrors + rdisk;
if (r1bio_existed)
pr_info_ratelimited("md/raid1:%s: redirecting sector %llu to other mirror: %pg\n",
mdname(mddev),
(unsignedlonglong)r1_bio->sector,
mirror->rdev->bdev);
staticbool wait_blocked_rdev(struct mddev *mddev, struct bio *bio)
{ struct r1conf *conf = mddev->private; int disks = conf->raid_disks * 2; int i;
retry: for (i = 0; i < disks; i++) { struct md_rdev *rdev = conf->mirrors[i].rdev;
if (!rdev) continue;
/* don't write here until the bad block is acknowledged */ if (test_bit(WriteErrorSeen, &rdev->flags) &&
rdev_has_badblock(rdev, bio->bi_iter.bi_sector,
bio_sectors(bio)) < 0)
set_bit(BlockedBadBlocks, &rdev->flags);
if (rdev_blocked(rdev)) { if (bio->bi_opf & REQ_NOWAIT) returnfalse;
/* In case raid1d snuck in to freeze_array */
wake_up_barrier(conf); return;
err_handle: for (k = 0; k < i; k++) { if (r1_bio->bios[k]) {
rdev_dec_pending(conf->mirrors[k].rdev, mddev);
r1_bio->bios[k] = NULL;
}
}
if (!rdev || test_bit(In_sync, &rdev->flags) ||
atomic_read(&rdev->nr_pending)) returnfalse;
/* Only remove non-faulty devices if recovery is not possible. */ if (!test_bit(Faulty, &rdev->flags) &&
rdev->mddev->recovery_disabled != conf->recovery_disabled &&
rdev->mddev->degraded < conf->raid_disks) returnfalse;
if (test_and_clear_bit(Nonrot, &rdev->flags))
WRITE_ONCE(conf->nonrot_disks, conf->nonrot_disks - 1);
WRITE_ONCE(info->rdev, NULL); returntrue;
}
staticint raid1_add_disk(struct mddev *mddev, struct md_rdev *rdev)
{ struct r1conf *conf = mddev->private; int err = -EEXIST; int mirror = 0, repl_slot = -1; struct raid1_info *p; int first = 0; int last = conf->raid_disks - 1;
if (mddev->recovery_disabled == conf->recovery_disabled) return -EBUSY;
if (rdev->raid_disk >= 0)
first = last = rdev->raid_disk;
/* *findthedisk...butpreferrdev->saved_raid_disk *ifpossible.
*/ if (rdev->saved_raid_disk >= 0 &&
rdev->saved_raid_disk >= first &&
rdev->saved_raid_disk < conf->raid_disks &&
conf->mirrors[rdev->saved_raid_disk].rdev == NULL)
first = last = rdev->saved_raid_disk;
for (mirror = first; mirror <= last; mirror++) {
p = conf->mirrors + mirror; if (!p->rdev) {
err = mddev_stack_new_rdev(mddev, rdev); if (err) return err;
raid1_add_conf(conf, rdev, mirror, false); /* As all devices are equivalent, we don't need a full recovery *ifthiswasrecentlyanydriveofthearray
*/ if (rdev->saved_raid_disk < 0)
conf->fullsync = 1; break;
} if (test_bit(WantReplacement, &p->rdev->flags) &&
p[conf->raid_disks].rdev == NULL && repl_slot < 0)
repl_slot = mirror;
}
if (err && repl_slot >= 0) { /* Add this device as a replacement */
clear_bit(In_sync, &rdev->flags);
set_bit(Replacement, &rdev->flags);
raid1_add_conf(conf, rdev, repl_slot, true);
err = 0;
conf->fullsync = 1;
}
print_conf(conf); return err;
}
staticint raid1_remove_disk(struct mddev *mddev, struct md_rdev *rdev)
{ struct r1conf *conf = mddev->private; int err = 0; int number = rdev->raid_disk; struct raid1_info *p = conf->mirrors + number;
if (unlikely(number >= conf->raid_disks)) goto abort;
if (rdev != p->rdev) {
number += conf->raid_disks;
p = conf->mirrors + number;
}
print_conf(conf); if (rdev == p->rdev) { if (!raid1_remove_conf(conf, number)) {
err = -EBUSY; goto abort;
}
if (number < conf->raid_disks &&
conf->mirrors[conf->raid_disks + number].rdev) { /* We just removed a device that is being replaced. *Movedownthereplacement.WedrainallIObefore *doingthistoavoidconfusion.
*/ struct md_rdev *repl =
conf->mirrors[conf->raid_disks + number].rdev;
freeze_array(conf, 0); if (atomic_read(&repl->nr_pending)) { /* It means that some queued IO of retry_list *holdrepl.Thus,wecannotsetreplacement *asNULL,avoidingrdevNULLpointer *dereferenceinsync_request_writeand *handle_write_finished.
*/
err = -EBUSY;
unfreeze_array(conf); goto abort;
}
clear_bit(Replacement, &repl->flags);
WRITE_ONCE(p->rdev, repl);
conf->mirrors[conf->raid_disks + number].rdev = NULL;
unfreeze_array(conf);
}
staticvoid end_sync_read(struct bio *bio)
{ struct r1bio *r1_bio = get_resync_r1bio(bio);
update_head_pos(r1_bio->read_disk, r1_bio);
/* *wehavereadablock,nowitneedstobere-written, *orre-readifthereadfailed. *Wedon'tdomuchhere,justschedulehandlingbyraid1d
*/ if (!bio->bi_status)
set_bit(R1BIO_Uptodate, &r1_bio->state);
if (atomic_dec_and_test(&r1_bio->remaining))
reschedule_retry(r1_bio);
}
staticvoid abort_sync_write(struct mddev *mddev, struct r1bio *r1_bio)
{
sector_t sync_blocks = 0;
sector_t s = r1_bio->sector; long sectors_to_go = r1_bio->sectors;
/* make sure these bits don't get cleared. */ do {
mddev->bitmap_ops->end_sync(mddev, s, &sync_blocks);
s += sync_blocks;
sectors_to_go -= sync_blocks;
} while (sectors_to_go > 0);
}
staticvoid put_sync_write_buf(struct r1bio *r1_bio, int uptodate)
{ if (atomic_dec_and_test(&r1_bio->remaining)) { struct mddev *mddev = r1_bio->mddev; int s = r1_bio->sectors;
staticint r1_sync_page_io(struct md_rdev *rdev, sector_t sector, int sectors, struct page *page, blk_opf_t rw)
{ if (sync_page_io(rdev, sector, sectors << 9, page, rw, false)) /* success */ return1; if (rw == REQ_OP_WRITE) {
set_bit(WriteErrorSeen, &rdev->flags); if (!test_and_set_bit(WantReplacement,
&rdev->flags))
set_bit(MD_RECOVERY_NEEDED, &
rdev->mddev->recovery);
} /* need to record an error - either for the block or the device */ if (!rdev_set_badblocks(rdev, sector, sectors, 0))
md_error(rdev->mddev, rdev); return0;
}
staticint fix_sync_read_error(struct r1bio *r1_bio)
{ /* Try some synchronous reads of other devices to get *gooddata,muchlikewithnormalreaderrors.Only *readintothepageswealreadyhavesowedon't *needtore-issuethereadrequest. *Wedon'tneedtofreezethearray,becausebeinginan *activesyncrequest,thereisnonormalIO,and *nooverlappingsyncs. *Wedon'tneedtocheckis_badblock()againaswe *madesurethatanythingwithabadblockinrange *willhavebi_end_ioclear.
*/ struct mddev *mddev = r1_bio->mddev; struct r1conf *conf = mddev->private; struct bio *bio = r1_bio->bios[r1_bio->read_disk]; struct page **pages = get_resync_pages(bio)->pages;
sector_t sect = r1_bio->sector; int sectors = r1_bio->sectors; int idx = 0; struct md_rdev *rdev;
rdev = conf->mirrors[r1_bio->read_disk].rdev; if (test_bit(FailFast, &rdev->flags)) { /* Don't try recovering from here - just fail it
* ... unless it is the last working device of course */
md_error(mddev, rdev); if (test_bit(Faulty, &rdev->flags)) /* Don't try to read from here, but make sure *put_bufdoesit'sthing
*/
bio->bi_end_io = end_sync_write;
}
while(sectors) { int s = sectors; int d = r1_bio->read_disk; int success = 0; int start;
if (s > (PAGE_SIZE>>9))
s = PAGE_SIZE >> 9; do { if (r1_bio->bios[d]->bi_end_io == end_sync_read) { /* No rcu protection needed here devices *canonlyberemovedwhennoresyncis *active,andresynciscurrentlyactive
*/
rdev = conf->mirrors[d].rdev; if (sync_page_io(rdev, sect, s<<9,
pages[idx],
REQ_OP_READ, false)) {
success = 1; break;
}
}
d++; if (d == conf->raid_disks * 2)
d = 0;
} while (!success && d != r1_bio->read_disk);
if (!success) { int abort = 0; /* Cannot read from anywhere, this block is lost. *Recordabadblockoneachdevice.Ifthatdoesn't *workjustdisableandinterrupttherecovery. *Don'tfaildevicesasthatwon'treallyhelp.
*/
pr_crit_ratelimited("md/raid1:%s: %pg: unrecoverable I/O read error for block %llu\n",
mdname(mddev), bio->bi_bdev,
(unsignedlonglong)r1_bio->sector); for (d = 0; d < conf->raid_disks * 2; d++) {
rdev = conf->mirrors[d].rdev; if (!rdev || test_bit(Faulty, &rdev->flags)) continue; if (!rdev_set_badblocks(rdev, sect, s, 0))
abort = 1;
} if (abort) return0;
start = d; /* write it back and re-read */ while (d != r1_bio->read_disk) { if (d == 0)
d = conf->raid_disks * 2;
d--; if (r1_bio->bios[d]->bi_end_io != end_sync_read) continue;
rdev = conf->mirrors[d].rdev; if (r1_sync_page_io(rdev, sect, s,
pages[idx],
REQ_OP_WRITE) == 0) {
r1_bio->bios[d]->bi_end_io = NULL;
rdev_dec_pending(rdev, mddev);
}
}
d = start; while (d != r1_bio->read_disk) { if (d == 0)
d = conf->raid_disks * 2;
d--; if (r1_bio->bios[d]->bi_end_io != end_sync_read) continue;
rdev = conf->mirrors[d].rdev; if (r1_sync_page_io(rdev, sect, s,
pages[idx],
REQ_OP_READ) != 0)
atomic_add(s, &rdev->corrected_errors);
}
sectors -= s;
sect += s;
idx ++;
}
set_bit(R1BIO_Uptodate, &r1_bio->state);
bio->bi_status = 0; return1;
}
staticvoid process_checks(struct r1bio *r1_bio)
{ /* We have read all readable devices. If we haven't *gottheblock,thenthereisnohopeleft. *Ifwehave,thenwewanttodoacomparison *andskipthewriteifeverythingisthesame. *Ifanyblocksfailedtoread,thenweneedto *attemptanover-write
*/ struct mddev *mddev = r1_bio->mddev; struct r1conf *conf = mddev->private; int primary; int i; int vcnt;
/* Fix variable parts of all bios */
vcnt = (r1_bio->sectors + PAGE_SIZE / 512 - 1) >> (PAGE_SHIFT - 9); for (i = 0; i < conf->raid_disks * 2; i++) {
blk_status_t status; struct bio *b = r1_bio->bios[i]; struct resync_pages *rp = get_resync_pages(b); if (b->bi_end_io != end_sync_read) continue; /* fixup the bio for reuse, but preserve errno */
status = b->bi_status;
bio_reset(b, conf->mirrors[i].rdev->bdev, REQ_OP_READ);
b->bi_status = status;
b->bi_iter.bi_sector = r1_bio->sector +
conf->mirrors[i].rdev->data_offset;
b->bi_end_io = end_sync_read;
rp->raid_bio = r1_bio;
b->bi_private = rp;
/* initialize bvec table again */
md_bio_reset_resync_pages(b, rp, r1_bio->sectors << 9);
} for (primary = 0; primary < conf->raid_disks * 2; primary++) if (r1_bio->bios[primary]->bi_end_io == end_sync_read &&
!r1_bio->bios[primary]->bi_status) {
r1_bio->bios[primary]->bi_end_io = NULL;
rdev_dec_pending(conf->mirrors[primary].rdev, mddev); break;
}
r1_bio->read_disk = primary; for (i = 0; i < conf->raid_disks * 2; i++) { int j = 0; struct bio *pbio = r1_bio->bios[primary]; struct bio *sbio = r1_bio->bios[i];
blk_status_t status = sbio->bi_status; struct page **ppages = get_resync_pages(pbio)->pages; struct page **spages = get_resync_pages(sbio)->pages; struct bio_vec *bi; int page_len[RESYNC_PAGES] = { 0 }; struct bvec_iter_all iter_all;
if (sbio->bi_end_io != end_sync_read) continue; /* Now we can 'fixup' the error value */
sbio->bi_status = 0;
/* bio has the data to be written to device 'i' where *wejustrecentlyhadawriteerror. *Werepeatedlyclonethebioandtrimdowntooneblock, *thentrythewrite.Wherethewritefailswerecord *abadblock. *Itisconceivablethatthebiodoesn'texactlyalignwith *blocks.Wemusthandlethissomehow. * *Wecurrentlyownareferenceontherdev.
*/
int block_sectors;
sector_t sector; int sectors; int sect_to_write = r1_bio->sectors; bool ok = true;
clear_bit(R1BIO_ReadError, &r1_bio->state); /* we got a read error. Maybe the drive is bad. Maybe just *theblockandwecanfixit. *WefreezeallotherIO,andtryreadingtheblockfrom *otherdevices.Whenwefindone,were-write *andcheckitthatfixesthereaderror. *Thisisalldonesynchronouslywhilethearrayis *frozen
*/
bio = r1_bio->bios[r1_bio->read_disk];
bio_put(bio);
r1_bio->bios[r1_bio->read_disk] = NULL;
rdev_dec_pending(rdev, conf->mddev);
sector = r1_bio->sector;
bio = r1_bio->master_bio;
/* Reuse the old r1_bio so that the IO_BLOCKED settings are preserved */
r1_bio->state = 0;
raid1_read_request(mddev, bio, r1_bio->sectors, r1_bio);
allow_barrier(conf, sector);
}
static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr,
sector_t max_sector, int *skipped)
{ struct r1conf *conf = mddev->private; struct r1bio *r1_bio; struct bio *bio;
sector_t nr_sectors; int disk = -1; int i; int wonly = -1; int write_targets = 0, read_targets = 0;
sector_t sync_blocks; bool still_degraded = false; int good_sectors = RESYNC_SECTORS; int min_bad = 0; /* number of sectors that are bad in all devices */ int idx = sector_to_idx(sector_nr); int page_idx = 0;
if (!mempool_initialized(&conf->r1buf_pool)) if (init_resync(conf)) return0;
if (sector_nr >= max_sector) { /* If we aborted, we need to abort the *synconthe'current'bitmapchunk(therewill *onlybeoneinraid1resync. *Wecanfindthecurrentaddessinmddev->curr_resync
*/ if (mddev->curr_resync < max_sector) /* aborted */
mddev->bitmap_ops->end_sync(mddev, mddev->curr_resync,
&sync_blocks); else/* completed sync */
conf->fullsync = 0;
if (mddev->bitmap == NULL &&
mddev->resync_offset == MaxSector &&
!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
conf->fullsync == 0) {
*skipped = 1; return max_sector - sector_nr;
} /* before building a request, check if we can skip these blocks.. *Thiscallthebitmap_start_syncdoesn'tactuallyrecordanything
*/ if (!mddev->bitmap_ops->start_sync(mddev, sector_nr, &sync_blocks, true) &&
!conf->fullsync && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) { /* We can skip this block, and probably several more */
*skipped = 1; return sync_blocks;
}
/* *Ifthereisnon-resyncactivitywaitingforaturn,thenletit *thoughbeforestartingonthisnewsyncrequest.
*/ if (atomic_read(&conf->nr_waiting[idx]))
schedule_timeout_uninterruptible(1);
/* we are incrementing sector_nr below. To be safe, we check against *sector_nr+twotimesRESYNC_SECTORS
*/
if (read_targets == 0 && min_bad > 0) { /* These sectors are bad on all InSync devices, so we *needtomarkthembadonallwritetargets
*/ int ok = 1; for (i = 0 ; i < conf->raid_disks * 2 ; i++) if (r1_bio->bios[i]->bi_end_io == end_sync_write) { struct md_rdev *rdev = conf->mirrors[i].rdev;
ok = rdev_set_badblocks(rdev, sector_nr,
min_bad, 0
) && ok;
}
set_bit(MD_SB_CHANGE_DEVS, &mddev->sb_flags);
*skipped = 1;
put_buf(r1_bio);
if (!ok) { /* Cannot record the badblocks, so need to *aborttheresync. *Iftherearemultiplereadtargets,couldjust *failthereallybadones???
*/
conf->recovery_disabled = mddev->recovery_disabled;
set_bit(MD_RECOVERY_INTR, &mddev->recovery); return0;
} else return min_bad;
} if (min_bad > 0 && min_bad < good_sectors) { /* only resync enough to reach the next bad->good
* transition */
good_sectors = min_bad;
}
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && read_targets > 0) /* extra read targets are also write targets */
write_targets += read_targets-1;
if (write_targets == 0 || read_targets == 0) { /* There is nowhere to write, so all non-sync *drivesmustbefailed-sowearefinished
*/
sector_t rv; if (min_bad > 0)
max_sector = sector_nr + min_bad;
rv = max_sector - sector_nr;
*skipped = 1;
put_buf(r1_bio); return rv;
}
if (max_sector > mddev->resync_max)
max_sector = mddev->resync_max; /* Don't do IO beyond here */ if (max_sector > sector_nr + good_sectors)
max_sector = sector_nr + good_sectors;
nr_sectors = 0;
sync_blocks = 0; do { struct page *page; int len = PAGE_SIZE; if (sector_nr + (len>>9) > max_sector)
len = (max_sector - sector_nr) << 9; if (len == 0) break; if (sync_blocks == 0) { if (!mddev->bitmap_ops->start_sync(mddev, sector_nr,
&sync_blocks, still_degraded) &&
!conf->fullsync &&
!test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) break; if ((len >> 9) > sync_blocks)
len = sync_blocks<<9;
}
for (i = 0 ; i < conf->raid_disks * 2; i++) { struct resync_pages *rp;
bio = r1_bio->bios[i];
rp = get_resync_pages(bio); if (bio->bi_end_io) {
page = resync_fetch_page(rp, page_idx);
/* For a user-requested sync, we read all readable devices and do a *compare
*/ if (test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery)) {
atomic_set(&r1_bio->remaining, read_targets); for (i = 0; i < conf->raid_disks * 2 && read_targets; i++) {
bio = r1_bio->bios[i]; if (bio->bi_end_io == end_sync_read) {
read_targets--; if (read_targets == 1)
bio->bi_opf &= ~MD_FAILFAST;
submit_bio_noacct(bio);
}
}
} else {
atomic_set(&r1_bio->remaining, 1);
bio = r1_bio->bios[r1_bio->read_disk]; if (read_targets == 1)
bio->bi_opf &= ~MD_FAILFAST;
submit_bio_noacct(bio);
} return nr_sectors;
}
static sector_t raid1_size(struct mddev *mddev, sector_t sectors, int raid_disks)
{ if (sectors) return sectors;
err = -EIO; for (i = 0; i < conf->raid_disks * 2; i++) {
disk = conf->mirrors + i;
if (i < conf->raid_disks &&
disk[conf->raid_disks].rdev) { /* This slot has a replacement. */ if (!disk->rdev) { /* No original, just make the replacement *arecoveringspare
*/
disk->rdev =
disk[conf->raid_disks].rdev;
disk[conf->raid_disks].rdev = NULL;
} elseif (!test_bit(In_sync, &disk->rdev->flags)) /* Original is not in_sync - bad */ goto abort;
}
if (!disk->rdev ||
!test_bit(In_sync, &disk->rdev->flags)) {
disk->head_position = 0; if (disk->rdev &&
(disk->rdev->saved_raid_disk < 0))
conf->fullsync = 1;
}
}
staticint raid1_run(struct mddev *mddev)
{ struct r1conf *conf; int i; int ret;
if (mddev->level != 1) {
pr_warn("md/raid1:%s: raid level not set to mirroring (%d)\n",
mdname(mddev), mddev->level); return -EIO;
} if (mddev->reshape_position != MaxSector) {
pr_warn("md/raid1:%s: reshape_position set but not supported\n",
mdname(mddev)); return -EIO;
}
if (!mddev_is_dm(mddev)) {
ret = raid1_set_limits(mddev); if (ret) { if (!mddev->private)
raid1_free(mddev, conf); return ret;
}
}
mddev->degraded = 0; for (i = 0; i < conf->raid_disks; i++) if (conf->mirrors[i].rdev == NULL ||
!test_bit(In_sync, &conf->mirrors[i].rdev->flags) ||
test_bit(Faulty, &conf->mirrors[i].rdev->flags))
mddev->degraded++; /* *RAID1needsatleastonediskinactive
*/ if (conf->raid_disks - mddev->degraded < 1) {
md_unregister_thread(mddev, &conf->thread); if (!mddev->private)
raid1_free(mddev, conf); return -EINVAL;
}
if (conf->raid_disks - mddev->degraded == 1)
mddev->resync_offset = MaxSector;
if (mddev->resync_offset != MaxSector)
pr_info("md/raid1:%s: not clean -- starting background reconstruction\n",
mdname(mddev));
pr_info("md/raid1:%s: active with %d out of %d mirrors\n",
mdname(mddev), mddev->raid_disks - mddev->degraded,
mddev->raid_disks);
staticint raid1_resize(struct mddev *mddev, sector_t sectors)
{ /* no resync is happening, and there is enough space *onalldevices,sowecanresize. *Weneedtomakesureresynccoversanynewspace. *Ifthearrayisshrinkingweshouldpossiblywaituntil *anyiointheremovedspacecompletes,butithardlyseems *worthit.
*/
sector_t newsize = raid1_size(mddev, sectors, 0); int ret;
if (mddev->external_size &&
mddev->array_sectors > newsize) return -EINVAL;
ret = mddev->bitmap_ops->resize(mddev, newsize, 0, false); if (ret) return ret;
if (raid_disks < conf->raid_disks) {
cnt=0; for (d= 0; d < conf->raid_disks; d++) if (conf->mirrors[d].rdev)
cnt++; if (cnt > raid_disks) return -EBUSY;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.