summaryrefslogtreecommitdiffstats
path: root/super0.c
diff options
context:
space:
mode:
authorNeil Brown <neilb@suse.de>2006-04-28 14:10:38 +1000
committerNeil Brown <neilb@suse.de>2006-04-28 14:10:38 +1000
commitc4d831e164da10be75f915f9e06c529e90f55da9 (patch)
treeb3ebaa1dfbd810d7a5d0da1c19601646fdf01511 /super0.c
parent7fa42a0b5e4541b7178c848229fcb7e98696babe (diff)
downloadmdadm-c4d831e164da10be75f915f9e06c529e90f55da9.tar.gz
mdadm-c4d831e164da10be75f915f9e06c529e90f55da9.tar.xz
mdadm-c4d831e164da10be75f915f9e06c529e90f55da9.zip
[PATCH] Make sure update_super returns correct value.
For 'force' and 'assemble', update_super must return true if anything was changed. Also fix a bug with wonly handling in super0. Signed-off-by: Neil Brown <neilb@suse.de> ### Diffstat output ./super0.c | 18 ++++++++++++++---- ./super1.c | 7 +++++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff ./super0.c~current~ ./super0.c
Diffstat (limited to 'super0.c')
-rw-r--r--super0.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/super0.c b/super0.c
index a36b0a7..49474d0 100644
--- a/super0.c
+++ b/super0.c
@@ -317,6 +317,9 @@ static void getinfo_super0(struct mdinfo *info, void *sbv)
static int update_super0(struct mdinfo *info, void *sbv, char *update, char *devname, int verbose)
{
+ /* NOTE: for 'assemble' and 'force' we need to return non-zero if any change was made.
+ * For others, the return value is ignored.
+ */
int rv = 0;
mdp_super_t *sb = sbv;
if (strcmp(update, "sparc2.2")==0 ) {
@@ -367,18 +370,25 @@ static int update_super0(struct mdinfo *info, void *sbv, char *update, char *dev
sb->disks[i].state = 0;
}
if (strcmp(update, "force")==0) {
+ __u32 ehi = sb->events_hi, elo = sb->events_lo;
sb->events_hi = (info->events>>32) & 0xFFFFFFFF;
sb->events_lo = (info->events) & 0xFFFFFFFF;
- if (sb->level == 5 || sb->level == 4 || sb->level == 6)
+ if (sb->events_hi != ehi ||
+ sb->events_lo != elo)
+ rv = 1;
+ if ((sb->level == 5 || sb->level == 4 || sb->level == 6) &&
+ (sb->state & (1 << MD_SB_CLEAN)) == 0) {
/* need to force clean */
sb->state |= (1 << MD_SB_CLEAN);
+ rv = 1;
+ }
}
if (strcmp(update, "assemble")==0) {
int d = info->disk.number;
int wonly = sb->disks[d].state & (1<<MD_DISK_WRITEMOSTLY);
- sb->disks[d].state &= ~(1<<MD_DISK_WRITEMOSTLY);
- if (sb->disks[d].state != info->disk.state) {
- sb->disks[d].state = info->disk.state & wonly;
+ if ((sb->disks[d].state & ~(1<<MD_DISK_WRITEMOSTLY))
+ != info->disk.state) {
+ sb->disks[d].state = info->disk.state | wonly;
rv = 1;
}
}