]> Pileus Git - ~andy/linux/blobdiff - drivers/md/raid1.c
[PATCH] Kconfig fix (sparc32 drivers/char dependencies)
[~andy/linux] / drivers / md / raid1.c
index ff1dbec864af51d780e1135ae392c1f6962ae37c..51d9645ed09c5e8ff79aa9e7a6604e94dc274a54 100644 (file)
@@ -893,7 +893,6 @@ static int end_sync_read(struct bio *bio, unsigned int bytes_done, int error)
        if (!uptodate) {
                md_error(r1_bio->mddev,
                         conf->mirrors[r1_bio->read_disk].rdev);
-               set_bit(R1BIO_Degraded, &r1_bio->state);
        } else
                set_bit(R1BIO_Uptodate, &r1_bio->state);
        rdev_dec_pending(conf->mirrors[r1_bio->read_disk].rdev, conf->mddev);
@@ -918,10 +917,9 @@ static int end_sync_write(struct bio *bio, unsigned int bytes_done, int error)
                        mirror = i;
                        break;
                }
-       if (!uptodate) {
+       if (!uptodate)
                md_error(mddev, conf->mirrors[mirror].rdev);
-               set_bit(R1BIO_Degraded, &r1_bio->state);
-       }
+
        update_head_pos(mirror, r1_bio);
 
        if (atomic_dec_and_test(&r1_bio->remaining)) {
@@ -1109,6 +1107,7 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
        int i;
        int write_targets = 0;
        int sync_blocks;
+       int still_degraded = 0;
 
        if (!conf->r1buf_pool)
        {
@@ -1126,21 +1125,22 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                 * only be one in raid1 resync.
                 * We can find the current addess in mddev->curr_resync
                 */
-               if (!conf->fullsync) {
-                       if (mddev->curr_resync < max_sector)
-                               bitmap_end_sync(mddev->bitmap,
-                                               mddev->curr_resync,
+               if (mddev->curr_resync < max_sector) /* aborted */
+                       bitmap_end_sync(mddev->bitmap, mddev->curr_resync,
                                                &sync_blocks, 1);
-                       bitmap_close_sync(mddev->bitmap);
-               }
-               if (mddev->curr_resync >= max_sector)
+               else /* completed sync */
                        conf->fullsync = 0;
+
+               bitmap_close_sync(mddev->bitmap);
                close_sync(conf);
                return 0;
        }
 
-       if (!conf->fullsync &&
-           !bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks)) {
+       /* before building a request, check if we can skip these blocks..
+        * This call the bitmap_start_sync doesn't actually record anything
+        */
+       if (!bitmap_start_sync(mddev->bitmap, sector_nr, &sync_blocks, 1) &&
+           !conf->fullsync) {
                /* We can skip this block, and probably several more */
                *skipped = 1;
                return sync_blocks;
@@ -1205,24 +1205,23 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                if (i == disk) {
                        bio->bi_rw = READ;
                        bio->bi_end_io = end_sync_read;
-               } else if (conf->mirrors[i].rdev &&
-                          !conf->mirrors[i].rdev->faulty &&
-                          (!conf->mirrors[i].rdev->in_sync ||
-                           sector_nr + RESYNC_SECTORS > mddev->recovery_cp)) {
+               } else if (conf->mirrors[i].rdev == NULL ||
+                          conf->mirrors[i].rdev->faulty) {
+                       still_degraded = 1;
+                       continue;
+               } else if (!conf->mirrors[i].rdev->in_sync ||
+                          sector_nr + RESYNC_SECTORS > mddev->recovery_cp) {
                        bio->bi_rw = WRITE;
                        bio->bi_end_io = end_sync_write;
                        write_targets ++;
                } else
+                       /* no need to read or write here */
                        continue;
                bio->bi_sector = sector_nr + conf->mirrors[i].rdev->data_offset;
                bio->bi_bdev = conf->mirrors[i].rdev->bdev;
                bio->bi_private = r1_bio;
        }
 
-       if (write_targets + 1 < conf->raid_disks)
-               /* array degraded, can't clear bitmap */
-               set_bit(R1BIO_Degraded, &r1_bio->state);
-
        if (write_targets == 0) {
                /* There is nowhere to write, so all non-sync
                 * drives must be failed - so we are finished
@@ -1243,15 +1242,15 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                        len = (max_sector - sector_nr) << 9;
                if (len == 0)
                        break;
-               if (!conf->fullsync) {
-                       if (sync_blocks == 0) {
-                               if (!bitmap_start_sync(mddev->bitmap,
-                                                      sector_nr, &sync_blocks))
-                                       break;
-                               if (sync_blocks < (PAGE_SIZE>>9))
-                                       BUG();
-                               if (len > (sync_blocks<<9)) len = sync_blocks<<9;
-                       }
+               if (sync_blocks == 0) {
+                       if (!bitmap_start_sync(mddev->bitmap, sector_nr,
+                                       &sync_blocks, still_degraded) &&
+                                       !conf->fullsync)
+                               break;
+                       if (sync_blocks < (PAGE_SIZE>>9))
+                               BUG();
+                       if (len > (sync_blocks<<9))
+                               len = sync_blocks<<9;
                }
 
                for (i=0 ; i < conf->raid_disks; i++) {
@@ -1264,7 +1263,8 @@ static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, i
                                        while (i > 0) {
                                                i--;
                                                bio = r1_bio->bios[i];
-                                               if (bio->bi_end_io==NULL) continue;
+                                               if (bio->bi_end_io==NULL)
+                                                       continue;
                                                /* remove last page from this bio */
                                                bio->bi_vcnt--;
                                                bio->bi_size -= len;
@@ -1469,6 +1469,7 @@ static int raid1_resize(mddev_t *mddev, sector_t sectors)
                set_bit(MD_RECOVERY_NEEDED, &mddev->recovery);
        }
        mddev->size = mddev->array_size;
+       mddev->resync_max_sectors = sectors;
        return 0;
 }