Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 30380
b: refs/heads/master
c: 4254376
h: refs/heads/master
v: v3
  • Loading branch information
NeilBrown authored and Linus Torvalds committed Jun 26, 2006
1 parent aa94ab8 commit b08a81a
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 9 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 07d84d109d8beedd68df9da2e4e9f25c8217e7fb
refs/heads/master: 42543769142d2375f2b5f8fc9cac999f84bd4c4c
65 changes: 57 additions & 8 deletions trunk/drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -1558,15 +1558,30 @@ static void md_print_devices(void)
}


static void sync_sbs(mddev_t * mddev)
static void sync_sbs(mddev_t * mddev, int nospares)
{
/* Update each superblock (in-memory image), but
* if we are allowed to, skip spares which already
* have the right event counter, or have one earlier
* (which would mean they aren't being marked as dirty
* with the rest of the array)
*/
mdk_rdev_t *rdev;
struct list_head *tmp;

ITERATE_RDEV(mddev,rdev,tmp) {
super_types[mddev->major_version].
sync_super(mddev, rdev);
rdev->sb_loaded = 1;
if (rdev->sb_events == mddev->events ||
(nospares &&
rdev->raid_disk < 0 &&
(rdev->sb_events&1)==0 &&
rdev->sb_events+1 == mddev->events)) {
/* Don't update this superblock */
rdev->sb_loaded = 2;
} else {
super_types[mddev->major_version].
sync_super(mddev, rdev);
rdev->sb_loaded = 1;
}
}
}

Expand All @@ -1576,12 +1591,42 @@ void md_update_sb(mddev_t * mddev)
struct list_head *tmp;
mdk_rdev_t *rdev;
int sync_req;
int nospares = 0;

repeat:
spin_lock_irq(&mddev->write_lock);
sync_req = mddev->in_sync;
mddev->utime = get_seconds();
mddev->events ++;
if (mddev->sb_dirty == 3)
/* just a clean<-> dirty transition, possibly leave spares alone,
* though if events isn't the right even/odd, we will have to do
* spares after all
*/
nospares = 1;

/* If this is just a dirty<->clean transition, and the array is clean
* and 'events' is odd, we can roll back to the previous clean state */
if (mddev->sb_dirty == 3
&& (mddev->in_sync && mddev->recovery_cp == MaxSector)
&& (mddev->events & 1))
mddev->events--;
else {
/* otherwise we have to go forward and ... */
mddev->events ++;
if (!mddev->in_sync || mddev->recovery_cp != MaxSector) { /* not clean */
/* .. if the array isn't clean, insist on an odd 'events' */
if ((mddev->events&1)==0) {
mddev->events++;
nospares = 0;
}
} else {
/* otherwise insist on an even 'events' (for clean states) */
if ((mddev->events&1)) {
mddev->events++;
nospares = 0;
}
}
}

if (!mddev->events) {
/*
Expand All @@ -1593,7 +1638,7 @@ void md_update_sb(mddev_t * mddev)
mddev->events --;
}
mddev->sb_dirty = 2;
sync_sbs(mddev);
sync_sbs(mddev, nospares);

/*
* do not write anything to disk if using
Expand All @@ -1615,6 +1660,8 @@ void md_update_sb(mddev_t * mddev)
ITERATE_RDEV(mddev,rdev,tmp) {
char b[BDEVNAME_SIZE];
dprintk(KERN_INFO "md: ");
if (rdev->sb_loaded != 1)
continue; /* no noise on spare devices */
if (test_bit(Faulty, &rdev->flags))
dprintk("(skipping faulty ");

Expand All @@ -1626,6 +1673,7 @@ void md_update_sb(mddev_t * mddev)
dprintk(KERN_INFO "(write) %s's sb offset: %llu\n",
bdevname(rdev->bdev,b),
(unsigned long long)rdev->sb_offset);
rdev->sb_events = mddev->events;

} else
dprintk(")\n");
Expand Down Expand Up @@ -1895,6 +1943,7 @@ static mdk_rdev_t *md_import_device(dev_t newdev, int super_format, int super_mi
rdev->desc_nr = -1;
rdev->flags = 0;
rdev->data_offset = 0;
rdev->sb_events = 0;
atomic_set(&rdev->nr_pending, 0);
atomic_set(&rdev->read_errors, 0);
atomic_set(&rdev->corrected_errors, 0);
Expand Down Expand Up @@ -4708,7 +4757,7 @@ void md_write_start(mddev_t *mddev, struct bio *bi)
spin_lock_irq(&mddev->write_lock);
if (mddev->in_sync) {
mddev->in_sync = 0;
mddev->sb_dirty = 1;
mddev->sb_dirty = 3;
md_wakeup_thread(mddev->thread);
}
spin_unlock_irq(&mddev->write_lock);
Expand Down Expand Up @@ -5055,7 +5104,7 @@ void md_check_recovery(mddev_t *mddev)
if (mddev->safemode && !atomic_read(&mddev->writes_pending) &&
!mddev->in_sync && mddev->recovery_cp == MaxSector) {
mddev->in_sync = 1;
mddev->sb_dirty = 1;
mddev->sb_dirty = 3;
}
if (mddev->safemode == 1)
mddev->safemode = 0;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/linux/raid/md_k.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ struct mdk_rdev_s

struct page *sb_page;
int sb_loaded;
__u64 sb_events;
sector_t data_offset; /* start of data in array */
sector_t sb_offset;
int sb_size; /* bytes in the superblock */
Expand Down

0 comments on commit b08a81a

Please sign in to comment.