Upgrade to mdadm-3.2.4
Resolves: bz820534 (rawhide) bz820527 (f17) bz820531 (f16) bz820532 (f15) Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
This commit is contained in:
parent
252d3d6557
commit
76ff773cd6
@ -1,21 +1,5 @@
|
||||
--- mdadm-3.2.1/Makefile.static 2011-03-27 22:31:20.000000000 -0400
|
||||
+++ mdadm-3.2.1/Makefile 2011-03-28 10:16:55.277900184 -0400
|
||||
@@ -68,11 +68,11 @@ CONFFILEFLAGS = -DCONFFILE=\"$(CONFFILE)
|
||||
# pivotroot from early boot to late boot.
|
||||
# /dev is an odd place to put this, but it is the only directory that
|
||||
# meets the requirements.
|
||||
-MAP_DIR=/dev/.mdadm
|
||||
-MAP_FILE = map
|
||||
-MDMON_DIR = /dev/.mdadm
|
||||
+MAP_DIR=/dev/md
|
||||
+MAP_FILE = md-device-map
|
||||
+MDMON_DIR = /dev/md
|
||||
# place for autoreplace cookies
|
||||
-FAILED_SLOTS_DIR = /dev/.mdadm/failed-slots
|
||||
+FAILED_SLOTS_DIR = /dev/md/failed-slots
|
||||
DIRFLAGS = -DMAP_DIR=\"$(MAP_DIR)\" -DMAP_FILE=\"$(MAP_FILE)\"
|
||||
DIRFLAGS += -DMDMON_DIR=\"$(MDMON_DIR)\"
|
||||
DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\"
|
||||
@@ -238,16 +238,16 @@ install : mdadm mdmon install-man instal
|
||||
$(INSTALL) -D $(STRIP) -m 755 mdmon $(DESTDIR)$(BINDIR)/mdmon
|
||||
|
||||
|
@ -1,101 +0,0 @@
|
||||
From 08ca2adffffeb3bfda3cafababfc26706a60463b Mon Sep 17 00:00:00 2001
|
||||
From: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Date: Wed, 25 Jan 2012 15:18:02 +0100
|
||||
Subject: [PATCH 2/4] Add --offroot argument to mdadm
|
||||
|
||||
When --offroot is specified, mdadm will change the first character of
|
||||
argv[0] to '@'. This is used to signal to systemd that mdadm was
|
||||
launched from initramfs and should not be shut down before returning
|
||||
to the initramfs.
|
||||
|
||||
Acked-by: Doug Ledford <dledford@redhat.com>
|
||||
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
ReadMe.c | 5 +++++
|
||||
mdadm.8.in | 12 ++++++++++++
|
||||
mdadm.c | 9 +++++++++
|
||||
mdadm.h | 1 +
|
||||
4 files changed, 27 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/ReadMe.c b/ReadMe.c
|
||||
index 9aa798b..a60e11b 100644
|
||||
--- a/ReadMe.c
|
||||
+++ b/ReadMe.c
|
||||
@@ -111,6 +111,7 @@ struct option long_options[] = {
|
||||
{"kill-subarray", 1, 0, KillSubarray},
|
||||
{"update-subarray", 1, 0, UpdateSubarray},
|
||||
{"udev-rules", 2, 0, UdevRules},
|
||||
+ {"offroot", 0, 0, OffRootOpt},
|
||||
|
||||
/* synonyms */
|
||||
{"monitor", 0, 0, 'F'},
|
||||
@@ -268,6 +269,10 @@ char OptionHelp[] =
|
||||
" --query -Q : Display general information about how a\n"
|
||||
" device relates to the md driver\n"
|
||||
" --auto-detect : Start arrays auto-detected by the kernel\n"
|
||||
+" --offroot : Set first character of argv[0] to @ to indicate the\n"
|
||||
+" application was launched from initrd/initramfs and\n"
|
||||
+" should not be shutdown by systemd as part of the\n"
|
||||
+" regular shutdown process.\n"
|
||||
;
|
||||
/*
|
||||
"\n"
|
||||
diff --git a/mdadm.8.in b/mdadm.8.in
|
||||
index 27be110..4f06a88 100644
|
||||
--- a/mdadm.8.in
|
||||
+++ b/mdadm.8.in
|
||||
@@ -255,6 +255,18 @@ Avoid printing purely informative messages. With this,
|
||||
will be silent unless there is something really important to report.
|
||||
|
||||
.TP
|
||||
+.BR \-\-offroot
|
||||
+Set first character of argv[0] to @ to indicate mdadm was launched
|
||||
+from initrd/initramfs and should not be shutdown by systemd as part of
|
||||
+the regular shutdown process. This option is normally only used by
|
||||
+the system's initscripts. Please see here for more details on how
|
||||
+systemd handled argv[0]:
|
||||
+.IP
|
||||
+.B http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
|
||||
+.PP
|
||||
+
|
||||
+
|
||||
+.TP
|
||||
.BR \-f ", " \-\-force
|
||||
Be more forceful about certain operations. See the various modes for
|
||||
the exact meaning of this option in different contexts.
|
||||
diff --git a/mdadm.c b/mdadm.c
|
||||
index f07fac2..78f28d5 100644
|
||||
--- a/mdadm.c
|
||||
+++ b/mdadm.c
|
||||
@@ -174,6 +174,15 @@ int main(int argc, char *argv[])
|
||||
homehost = optarg;
|
||||
continue;
|
||||
|
||||
+ /*
|
||||
+ * --offroot sets first char of argv[0] to @. This is used
|
||||
+ * by systemd to signal that the tast was launched from
|
||||
+ * initrd/initramfs and should be preserved during shutdown
|
||||
+ */
|
||||
+ case OffRootOpt:
|
||||
+ argv[0][0] = '@';
|
||||
+ continue;
|
||||
+
|
||||
case ':':
|
||||
case '?':
|
||||
fputs(Usage, stderr);
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index 381ef86..fec93aa 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -321,6 +321,7 @@ enum special_options {
|
||||
UdevRules,
|
||||
FreezeReshape,
|
||||
Continue,
|
||||
+ OffRootOpt,
|
||||
};
|
||||
|
||||
/* structures read from config file */
|
||||
--
|
||||
1.7.8.4
|
||||
|
@ -1,79 +0,0 @@
|
||||
From da827518c1f062e7d49433691d33e103525f9d6a Mon Sep 17 00:00:00 2001
|
||||
From: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Date: Wed, 25 Jan 2012 15:18:03 +0100
|
||||
Subject: [PATCH 3/4] Add --offroot argument to mdmon
|
||||
|
||||
Acked-by: Doug Ledford <dledford@redhat.com>
|
||||
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
mdmon.8 | 12 +++++++++++-
|
||||
mdmon.c | 8 ++++++++
|
||||
2 files changed, 19 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/mdmon.8 b/mdmon.8
|
||||
index 8c1ce5f..a9178b6 100644
|
||||
--- a/mdmon.8
|
||||
+++ b/mdmon.8
|
||||
@@ -5,7 +5,7 @@ mdmon \- monitor MD external metadata arrays
|
||||
|
||||
.SH SYNOPSIS
|
||||
|
||||
-.BI mdmon " [--all] [--takeover] CONTAINER"
|
||||
+.BI mdmon " [--all] [--takeover] [--offroot] CONTAINER"
|
||||
|
||||
.SH OVERVIEW
|
||||
The 2.6.27 kernel brings the ability to support external metadata arrays.
|
||||
@@ -165,6 +165,16 @@ argument is over-written with the name of the container. To allow for
|
||||
containers with names longer than 5 characters, this argument can be
|
||||
arbitrarily extended, e.g. to
|
||||
.BR \-\-all-active-arrays .
|
||||
+.TP
|
||||
+.BR \-\-offroot
|
||||
+Set first character of argv[0] to @ to indicate mdmon was launched
|
||||
+from initrd/initramfs and should not be shutdown by systemd as part of
|
||||
+the regular shutdown process. This option is normally only used by
|
||||
+the system's initscripts. Please see here for more details on how
|
||||
+systemd handled argv[0]:
|
||||
+.IP
|
||||
+.B http://www.freedesktop.org/wiki/Software/systemd/RootStorageDaemons
|
||||
+.PP
|
||||
|
||||
.PP
|
||||
Note that
|
||||
diff --git a/mdmon.c b/mdmon.c
|
||||
index a65c4a4..2093476 100644
|
||||
--- a/mdmon.c
|
||||
+++ b/mdmon.c
|
||||
@@ -272,6 +272,10 @@ void usage(void)
|
||||
" --help -h : This message\n"
|
||||
" --all : All devices\n"
|
||||
" --takeover -t : Takeover container\n"
|
||||
+" --offroot : Set first character of argv[0] to @ to indicate the\n"
|
||||
+" application was launched from initrd/initramfs and\n"
|
||||
+" should not be shutdown by systemd as part of the\n"
|
||||
+" regular shutdown process.\n"
|
||||
);
|
||||
exit(2);
|
||||
}
|
||||
@@ -291,6 +295,7 @@ int main(int argc, char *argv[])
|
||||
{"all", 0, NULL, 'a'},
|
||||
{"takeover", 0, NULL, 't'},
|
||||
{"help", 0, NULL, 'h'},
|
||||
+ {"offroot", 0, NULL, OffRootOpt},
|
||||
{NULL, 0, NULL, 0}
|
||||
};
|
||||
|
||||
@@ -304,6 +309,9 @@ int main(int argc, char *argv[])
|
||||
container_name = optarg;
|
||||
takeover = 1;
|
||||
break;
|
||||
+ case OffRootOpt:
|
||||
+ argv[0][0] = '@';
|
||||
+ break;
|
||||
case 'h':
|
||||
default:
|
||||
usage();
|
||||
--
|
||||
1.7.8.4
|
||||
|
@ -1,66 +0,0 @@
|
||||
From fbdef49811c9e2b54e2064d9af68cfffa77c6e77 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Wed, 4 Apr 2012 14:00:42 +1000
|
||||
Subject: [PATCH] Bitmap_offset is a signed number
|
||||
|
||||
As the bitmap can be before the superblock, bitmap_offset is signed.
|
||||
But some of the code didn't honour that :-(
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
mdadm.h | 2 +-
|
||||
super1.c | 4 ++--
|
||||
sysfs.c | 2 +-
|
||||
3 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index 941cffa..9f58800 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -211,7 +211,7 @@ struct mdinfo {
|
||||
unsigned long long recovery_start; /* per-device rebuild position */
|
||||
#define MaxSector (~0ULL) /* resync/recovery complete position */
|
||||
};
|
||||
- unsigned long bitmap_offset; /* 0 == none, 1 == a file */
|
||||
+ long bitmap_offset; /* 0 == none, 1 == a file */
|
||||
unsigned long safe_mode_delay; /* ms delay to mark clean */
|
||||
int new_level, delta_disks, new_layout, new_chunk;
|
||||
int errors;
|
||||
diff --git a/super1.c b/super1.c
|
||||
index 20f4c86..2770a7f 100644
|
||||
--- a/super1.c
|
||||
+++ b/super1.c
|
||||
@@ -620,7 +620,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
|
||||
info->data_offset = __le64_to_cpu(sb->data_offset);
|
||||
info->component_size = __le64_to_cpu(sb->size);
|
||||
if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET))
|
||||
- info->bitmap_offset = __le32_to_cpu(sb->bitmap_offset);
|
||||
+ info->bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset);
|
||||
|
||||
info->disk.major = 0;
|
||||
info->disk.minor = 0;
|
||||
@@ -1636,7 +1636,7 @@ add_internal_bitmap1(struct supertype *st,
|
||||
offset = -room;
|
||||
}
|
||||
|
||||
- sb->bitmap_offset = __cpu_to_le32(offset);
|
||||
+ sb->bitmap_offset = (long)__cpu_to_le32(offset);
|
||||
|
||||
sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map)
|
||||
| MD_FEATURE_BITMAP_OFFSET);
|
||||
diff --git a/sysfs.c b/sysfs.c
|
||||
index cddabae..a1007cf 100644
|
||||
--- a/sysfs.c
|
||||
+++ b/sysfs.c
|
||||
@@ -226,7 +226,7 @@ struct mdinfo *sysfs_read(int fd, int devnum, unsigned long options)
|
||||
else if (strncmp(buf, "none", 4) == 0)
|
||||
sra->bitmap_offset = 0;
|
||||
else if (buf[0] == '+')
|
||||
- sra->bitmap_offset = strtoul(buf+1, NULL, 10);
|
||||
+ sra->bitmap_offset = strtol(buf+1, NULL, 10);
|
||||
else
|
||||
goto abort;
|
||||
}
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 111e9fdaa8a5084bd329819a0906a685b2271c0d Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Tue, 7 Feb 2012 15:03:19 +0100
|
||||
Subject: [PATCH 03/12] FIX: Array is not run when expansion disks are added
|
||||
|
||||
When added disk is disk added by expansion and this is last disk added
|
||||
to array, assemble_container_content() will not even try to run such array.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Assemble.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/Assemble.c b/Assemble.c
|
||||
index ad4eb9c..13adfc3 100644
|
||||
--- a/Assemble.c
|
||||
+++ b/Assemble.c
|
||||
@@ -1557,7 +1557,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||
working++;
|
||||
} else if (errno == EEXIST)
|
||||
preexist++;
|
||||
- if (working == 0)
|
||||
+ if (working + expansion == 0)
|
||||
return 1;/* Nothing new, don't try to start */
|
||||
|
||||
map_update(&map, fd2devnum(mdfd),
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,85 +0,0 @@
|
||||
From 4aecb54a211a77aa0589aa2abb8acd992ae8795a Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:08 +0200
|
||||
Subject: [PATCH 14/14] FIX: Assembled second array is in read only state
|
||||
during reshape
|
||||
|
||||
When arrays using external metadata are assembled, and one of array
|
||||
in container is under reshape, second array will remain in read only
|
||||
state (not auto read only). It is caused by array fact that array
|
||||
is frozen and mdmon doesn't has opportunity to switch array in r/w mode.
|
||||
|
||||
Freezing not reshaped array just after it is being assembled allows mdmon
|
||||
to enable it for writing.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Assemble.c | 29 +++++++++++++++++++++--------
|
||||
1 files changed, 21 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/Assemble.c b/Assemble.c
|
||||
index 23695e7..080993d 100644
|
||||
--- a/Assemble.c
|
||||
+++ b/Assemble.c
|
||||
@@ -1558,6 +1558,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||
int expansion = 0;
|
||||
struct map_ent *map = NULL;
|
||||
int old_raid_disks;
|
||||
+ int start_reshape;
|
||||
|
||||
sysfs_init(content, mdfd, 0);
|
||||
|
||||
@@ -1569,7 +1570,17 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||
return 1;
|
||||
}
|
||||
|
||||
- if (st->ss->external && content->recovery_blocked)
|
||||
+ /* There are two types of reshape: container wide or sub-array specific
|
||||
+ * Check if metadata requests blocking container wide reshapes
|
||||
+ */
|
||||
+ start_reshape = (content->reshape_active &&
|
||||
+ !((content->reshape_active == CONTAINER_RESHAPE) &&
|
||||
+ (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))));
|
||||
+
|
||||
+ /* Block subarray here if it is under reshape now
|
||||
+ * Do not allow for any changes in this array
|
||||
+ */
|
||||
+ if (st->ss->external && content->recovery_blocked && start_reshape)
|
||||
block_subarray(content);
|
||||
|
||||
if (sra)
|
||||
@@ -1595,14 +1606,7 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||
(working + preexist + expansion) >=
|
||||
content->array.working_disks) {
|
||||
int err;
|
||||
- int start_reshape;
|
||||
|
||||
- /* There are two types of reshape: container wide or sub-array specific
|
||||
- * Check if metadata requests blocking container wide reshapes
|
||||
- */
|
||||
- start_reshape = (content->reshape_active &&
|
||||
- !((content->reshape_active == CONTAINER_RESHAPE) &&
|
||||
- (content->array.state & (1<<MD_SB_BLOCK_CONTAINER_RESHAPE))));
|
||||
if (start_reshape) {
|
||||
int spare = content->array.raid_disks + expansion;
|
||||
if (restore_backup(st, content,
|
||||
@@ -1646,6 +1650,15 @@ int assemble_container_content(struct supertype *st, int mdfd,
|
||||
}
|
||||
if (!err)
|
||||
sysfs_set_safemode(content, content->safe_mode_delay);
|
||||
+
|
||||
+ /* Block subarray here if it is not reshaped now
|
||||
+ * It has be blocked a little later to allow mdmon to switch in
|
||||
+ * in to R/W state
|
||||
+ */
|
||||
+ if (st->ss->external && content->recovery_blocked &&
|
||||
+ !start_reshape)
|
||||
+ block_subarray(content);
|
||||
+
|
||||
if (verbose >= 0) {
|
||||
if (err)
|
||||
fprintf(stderr, Name
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,63 +0,0 @@
|
||||
From d7592845d4a9b885af7121f8ff6ba4f77610cd32 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Thu, 16 Feb 2012 14:16:04 +0100
|
||||
Subject: [PATCH 15/15] FIX: Changes in '0' case for reshape position
|
||||
verification
|
||||
|
||||
Reading sysfs entry that is '0' long should cause an error.
|
||||
Reshape position cannot be empty.
|
||||
|
||||
Absence of reshape position should be ignored. It is possible
|
||||
that we are about raid0 reshape continuation and it is before takeover.
|
||||
This means that according metadata (changed by mdmon) it should be reshaped
|
||||
but md knows nothing about it at this moment. Reshape continuation
|
||||
in reshape_array() will change it to raid4 and reshape position appears
|
||||
in sysfs.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
---
|
||||
Grow.c | 12 ++++++++++--
|
||||
1 files changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 53a7cad..239b50d 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1876,9 +1876,12 @@ static int verify_reshape_position(struct mdinfo *info, int level)
|
||||
{
|
||||
int ret_val = 0;
|
||||
char buf[40];
|
||||
+ int rv;
|
||||
|
||||
/* read sync_max, failure can mean raid0 array */
|
||||
- if (sysfs_get_str(info, NULL, "sync_max", buf, 40) > 0) {
|
||||
+ rv = sysfs_get_str(info, NULL, "sync_max", buf, 40);
|
||||
+
|
||||
+ if (rv > 0) {
|
||||
char *ep;
|
||||
unsigned long long position = strtoull(buf, &ep, 0);
|
||||
|
||||
@@ -1906,6 +1909,11 @@ static int verify_reshape_position(struct mdinfo *info, int level)
|
||||
ret_val = 1;
|
||||
}
|
||||
}
|
||||
+ } else if (rv == 0) {
|
||||
+ /* for valid sysfs entry, 0-length content
|
||||
+ * should be indicated as error
|
||||
+ */
|
||||
+ ret_val = -1;
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
@@ -3975,7 +3983,7 @@ int Grow_continue_command(char *devname, int fd,
|
||||
* correct position
|
||||
*/
|
||||
if (verify_reshape_position(content,
|
||||
- map_name(pers, mdstat->level)) <= 0) {
|
||||
+ map_name(pers, mdstat->level)) < 0) {
|
||||
ret_val = 1;
|
||||
goto Grow_continue_command_exit;
|
||||
}
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,62 +0,0 @@
|
||||
From 65a9798b58b4e4de0157043e2b30a738c27eff43 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:03 +0200
|
||||
Subject: [PATCH 09/14] FIX: Detect error and rollback metadata
|
||||
|
||||
Some setting size error cases were not detected.
|
||||
When error occurs, stop setting new size action and rollback metadata
|
||||
changes.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 13 +++++++++++--
|
||||
1 files changed, 11 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 86d1020..1b45199 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1665,9 +1665,12 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
* understands '0' to mean 'max'.
|
||||
*/
|
||||
min_csize = 0;
|
||||
+ rv = 0;
|
||||
for (mdi = sra->devs; mdi; mdi = mdi->next) {
|
||||
- if (sysfs_set_num(sra, mdi, "size", size) < 0)
|
||||
+ if (sysfs_set_num(sra, mdi, "size", size) < 0) {
|
||||
+ rv = 1;
|
||||
break;
|
||||
+ }
|
||||
if (array.not_persistent == 0 &&
|
||||
array.major_version == 0 &&
|
||||
get_linux_version() < 3001000) {
|
||||
@@ -1682,11 +1685,16 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
}
|
||||
}
|
||||
}
|
||||
+ if (rv) {
|
||||
+ fprintf(stderr, Name ": Cannot set size on "
|
||||
+ "array members.\n");
|
||||
+ goto size_change_error;
|
||||
+ }
|
||||
if (min_csize && size > min_csize) {
|
||||
fprintf(stderr, Name ": Cannot safely make this array "
|
||||
"use more than 2TB per device on this kernel.\n");
|
||||
rv = 1;
|
||||
- goto release;
|
||||
+ goto size_change_error;
|
||||
}
|
||||
if (min_csize && size == 0) {
|
||||
/* Don't let the kernel choose a size - it will get
|
||||
@@ -1748,6 +1756,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
ioctl(fd, GET_ARRAY_INFO, &array);
|
||||
}
|
||||
|
||||
+size_change_error:
|
||||
if (rv != 0) {
|
||||
int err = errno;
|
||||
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 1ca90aa6484a6f5d4fdd6122ad1d2015209bd8e0 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Thu, 9 Feb 2012 12:38:15 +1100
|
||||
Subject: [PATCH 12/12] FIX: Do not try to (continue) reshape using inactive
|
||||
array
|
||||
|
||||
When one of arrays is inactive, do not try to continue reshape
|
||||
on this array. Just skip it.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 14 ++++++++++++++
|
||||
1 files changed, 14 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 61adefa..53a7cad 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -2626,6 +2626,13 @@ int reshape_container(char *container, char *devname,
|
||||
devname2devnum(container));
|
||||
if (!mdstat)
|
||||
continue;
|
||||
+ if (mdstat->active == 0) {
|
||||
+ fprintf(stderr, Name ": Skipping inactive "
|
||||
+ "array md%i.\n", mdstat->devnum);
|
||||
+ free_mdstat(mdstat);
|
||||
+ mdstat = NULL;
|
||||
+ continue;
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
if (!content)
|
||||
@@ -3922,6 +3929,13 @@ int Grow_continue_command(char *devname, int fd,
|
||||
mdstat = mdstat_by_subdev(array, container_dev);
|
||||
if (!mdstat)
|
||||
continue;
|
||||
+ if (mdstat->active == 0) {
|
||||
+ fprintf(stderr, Name ": Skipping inactive "
|
||||
+ "array md%i.\n", mdstat->devnum);
|
||||
+ free_mdstat(mdstat);
|
||||
+ mdstat = NULL;
|
||||
+ continue;
|
||||
+ }
|
||||
break;
|
||||
}
|
||||
if (!content) {
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,84 +0,0 @@
|
||||
From 44f6f18113b1764a9d1234d3ff9a6bac968b03b8 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:01 +0200
|
||||
Subject: [PATCH 07/14] FIX: Extend size of raid0 array
|
||||
|
||||
For raid0, takeover operation is required for size change.
|
||||
Add takeover to degraded raid4 before size change and back to raid0 after.
|
||||
Array information has to be read again from md after takeover.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 35 +++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 35 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 8c7bafc..e8f6554 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1626,6 +1626,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
long long orig_size = get_component_size(fd)/2;
|
||||
long long min_csize;
|
||||
struct mdinfo *mdi;
|
||||
+ int raid0_takeover = 0;
|
||||
|
||||
if (orig_size == 0)
|
||||
orig_size = array.size;
|
||||
@@ -1674,6 +1675,28 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
"2TB per device\n");
|
||||
size = min_csize;
|
||||
}
|
||||
+ if (st->ss->external) {
|
||||
+ if (sra->array.level == 0) {
|
||||
+ rv = sysfs_set_str(sra, NULL, "level",
|
||||
+ "raid5");
|
||||
+ if (!rv) {
|
||||
+ raid0_takeover = 1;
|
||||
+ /* get array parametes after takeover
|
||||
+ * to chane one parameter at time only
|
||||
+ */
|
||||
+ rv = ioctl(fd, GET_ARRAY_INFO, &array);
|
||||
+ }
|
||||
+ }
|
||||
+ /* make sure mdmon is
|
||||
+ * aware of the new level */
|
||||
+ if (!mdmon_running(st->container_dev))
|
||||
+ start_mdmon(st->container_dev);
|
||||
+ ping_monitor(container);
|
||||
+ if (mdmon_running(st->container_dev) &&
|
||||
+ st->update_tail == NULL)
|
||||
+ st->update_tail = &st->updates;
|
||||
+ }
|
||||
+
|
||||
array.size = size;
|
||||
if (array.size != size) {
|
||||
/* got truncated to 32bit, write to
|
||||
@@ -1686,12 +1709,24 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
rv = -1;
|
||||
} else {
|
||||
rv = ioctl(fd, SET_ARRAY_INFO, &array);
|
||||
+
|
||||
/* manage array size when it is managed externally
|
||||
*/
|
||||
if ((rv == 0) && st->ss->external)
|
||||
rv = set_array_size(st, sra, sra->text_version);
|
||||
}
|
||||
|
||||
+ if (raid0_takeover) {
|
||||
+ /* do not recync non-existing parity,
|
||||
+ * we will drop it anyway
|
||||
+ */
|
||||
+ sysfs_set_str(sra, NULL, "sync_action", "idle");
|
||||
+ /* go back to raid0, drop parity disk
|
||||
+ */
|
||||
+ sysfs_set_str(sra, NULL, "level", "raid0");
|
||||
+ ioctl(fd, GET_ARRAY_INFO, &array);
|
||||
+ }
|
||||
+
|
||||
if (rv != 0) {
|
||||
int err = errno;
|
||||
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,35 +0,0 @@
|
||||
From 5d1c7cdaca575d8a32a7a82517d88e2099f6a213 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Thu, 12 Jan 2012 08:12:39 +0100
|
||||
Subject: [PATCH] FIX: External metadata sometimes is not updated
|
||||
|
||||
External metadata sometimes is not updated.
|
||||
It can be observed during 2 raid0 arrays Capacity Expansion.
|
||||
New array size is not set, because metadata is not updated and on the reshape
|
||||
end mdadm doesn't read new array size from metadata.
|
||||
This happens when mdmon finishes his work (due to takeover to raid0),
|
||||
before all metadata updates are processed.
|
||||
|
||||
Make sure that all updates are flushed to disk before executing takeover.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index b2c1360..89f563c 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -2396,6 +2396,7 @@ started:
|
||||
/* Re-load the metadata as much could have changed */
|
||||
int cfd = open_dev(st->container_dev);
|
||||
if (cfd >= 0) {
|
||||
+ ping_manager(container);
|
||||
ping_monitor(container);
|
||||
st->ss->free_super(st);
|
||||
st->ss->load_container(st, cfd, container);
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,38 +0,0 @@
|
||||
From 92d49ecfaabcd015cf9957a0863996eaa5755747 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Tue, 7 Feb 2012 15:03:03 +0100
|
||||
Subject: [PATCH 01/12] FIX: NULL pointer to strdup() can be passed
|
||||
|
||||
When result from strchr() is NULL and it is assigned to subarray,
|
||||
NULL pointer can be passed to strdup() function and coredump file
|
||||
is generated.
|
||||
|
||||
Subarray is checked for NULL pointer, so it is assumed that it can
|
||||
be NULL at this moment.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
util.c | 5 +++--
|
||||
1 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/util.c b/util.c
|
||||
index e5f7a20..7abbff7 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -966,9 +966,10 @@ struct supertype *super_by_fd(int fd, char **subarrayp)
|
||||
char *dev = verstr+1;
|
||||
|
||||
subarray = strchr(dev, '/');
|
||||
- if (subarray)
|
||||
+ if (subarray) {
|
||||
*subarray++ = '\0';
|
||||
- subarray = strdup(subarray);
|
||||
+ subarray = strdup(subarray);
|
||||
+ }
|
||||
container = devname2devnum(dev);
|
||||
if (sra)
|
||||
sysfs_free(sra);
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,50 +0,0 @@
|
||||
From 7e7e9a4d72323fe0298c9f5741245b0f11165a31 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:02 +0200
|
||||
Subject: [PATCH 08/14] FIX: Respect metadata size limitations
|
||||
|
||||
When reshape_super() updates metadata with new size, due to some metadata
|
||||
limitations saved value can be different than requested value by user.
|
||||
Update size (read it from metadata) for setting it in md.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 21 +++++++++++++++++++++
|
||||
1 files changed, 21 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index e8f6554..86d1020 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1637,6 +1637,27 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
goto release;
|
||||
}
|
||||
sync_metadata(st);
|
||||
+ if (st->ss->external) {
|
||||
+ /* metadata can have size limitation
|
||||
+ * update size value according to metadata information
|
||||
+ */
|
||||
+ struct mdinfo *sizeinfo =
|
||||
+ st->ss->container_content(st, subarray);
|
||||
+ if (sizeinfo) {
|
||||
+ unsigned long long new_size =
|
||||
+ sizeinfo->custom_array_size/2;
|
||||
+ int data_disks = get_data_disks(
|
||||
+ sizeinfo->array.level,
|
||||
+ sizeinfo->array.layout,
|
||||
+ sizeinfo->array.raid_disks);
|
||||
+ new_size /= data_disks;
|
||||
+ dprintf("Metadata size correction from %llu to "
|
||||
+ "%llu (%llu)\n", orig_size, new_size,
|
||||
+ new_size * data_disks);
|
||||
+ size = new_size;
|
||||
+ sysfs_free(sizeinfo);
|
||||
+ }
|
||||
+ }
|
||||
|
||||
/* Update the size of each member device in case
|
||||
* they have been resized. This will never reduce
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 58d26a2a81c4ad93ccce88865f2c4ac2588bec69 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:07 +0200
|
||||
Subject: [PATCH 13/14] FIX: Size change is possible as standalone change only
|
||||
|
||||
Size change is possible as standalone change only. To make sure size change
|
||||
is not requested pass '-1' as size parameter.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 1b45199..389992e 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1973,7 +1973,7 @@ size_change_error:
|
||||
/* Impose these changes on a single array. First
|
||||
* check that the metadata is OK with the change. */
|
||||
|
||||
- if (reshape_super(st, info.component_size, info.new_level,
|
||||
+ if (reshape_super(st, -1, info.new_level,
|
||||
info.new_layout, info.new_chunk,
|
||||
info.array.raid_disks, info.delta_disks,
|
||||
backup_file, devname, APPLY_METADATA_CHANGES,
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,118 +0,0 @@
|
||||
From 016e00f54635138ce34b9e4ba18d37e182288bd1 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:51:59 +0200
|
||||
Subject: [PATCH 05/14] FIX: Support metadata changes rollback
|
||||
|
||||
Function reshape_super() guards metadata changes.
|
||||
It is used to apply changes rollback in error case also.
|
||||
As change (apply and rollback) can be not bi-directional reshape_super()
|
||||
has to know if current action is metadata change that should be guarded
|
||||
using metadata restrictions, or this is metadata rollback change
|
||||
executed due to error occurrence.
|
||||
|
||||
In second case change has to be unconditional.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 16 ++++++++++------
|
||||
mdadm.h | 4 ++++
|
||||
super-intel.c | 2 +-
|
||||
3 files changed, 15 insertions(+), 7 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 5fd44aa..8c7bafc 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -650,7 +650,7 @@ static void wait_reshape(struct mdinfo *sra)
|
||||
static int reshape_super(struct supertype *st, long long size, int level,
|
||||
int layout, int chunksize, int raid_disks,
|
||||
int delta_disks, char *backup_file, char *dev,
|
||||
- int verbose)
|
||||
+ int direction, int verbose)
|
||||
{
|
||||
/* nothing extra to check in the native case */
|
||||
if (!st->ss->external)
|
||||
@@ -664,7 +664,7 @@ static int reshape_super(struct supertype *st, long long size, int level,
|
||||
|
||||
return st->ss->reshape_super(st, size, level, layout, chunksize,
|
||||
raid_disks, delta_disks, backup_file, dev,
|
||||
- verbose);
|
||||
+ direction, verbose);
|
||||
}
|
||||
|
||||
static void sync_metadata(struct supertype *st)
|
||||
@@ -1631,7 +1631,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
orig_size = array.size;
|
||||
|
||||
if (reshape_super(st, size, UnSet, UnSet, 0, 0, UnSet, NULL,
|
||||
- devname, !quiet)) {
|
||||
+ devname, APPLY_METADATA_CHANGES, !quiet)) {
|
||||
rv = 1;
|
||||
goto release;
|
||||
}
|
||||
@@ -1697,7 +1697,9 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
|
||||
/* restore metadata */
|
||||
if (reshape_super(st, orig_size, UnSet, UnSet, 0, 0,
|
||||
- UnSet, NULL, devname, !quiet) == 0)
|
||||
+ UnSet, NULL, devname,
|
||||
+ ROLLBACK_METADATA_CHANGES,
|
||||
+ !quiet) == 0)
|
||||
sync_metadata(st);
|
||||
fprintf(stderr, Name ": Cannot set device size for %s: %s\n",
|
||||
devname, strerror(err));
|
||||
@@ -1909,7 +1911,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
if (reshape_super(st, info.component_size, info.new_level,
|
||||
info.new_layout, info.new_chunk,
|
||||
info.array.raid_disks, info.delta_disks,
|
||||
- backup_file, devname, quiet)) {
|
||||
+ backup_file, devname, APPLY_METADATA_CHANGES,
|
||||
+ quiet)) {
|
||||
rv = 1;
|
||||
goto release;
|
||||
}
|
||||
@@ -2608,7 +2611,8 @@ int reshape_container(char *container, char *devname,
|
||||
reshape_super(st, -1, info->new_level,
|
||||
info->new_layout, info->new_chunk,
|
||||
info->array.raid_disks, info->delta_disks,
|
||||
- backup_file, devname, quiet)) {
|
||||
+ backup_file, devname, APPLY_METADATA_CHANGES,
|
||||
+ quiet)) {
|
||||
unfreeze(st);
|
||||
return 1;
|
||||
}
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index 9f58800..686d4b4 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -740,9 +740,13 @@ extern struct superswitch {
|
||||
* initialized to indicate if reshape is being performed at the
|
||||
* container or subarray level
|
||||
*/
|
||||
+#define APPLY_METADATA_CHANGES 1
|
||||
+#define ROLLBACK_METADATA_CHANGES 0
|
||||
+
|
||||
int (*reshape_super)(struct supertype *st, long long size, int level,
|
||||
int layout, int chunksize, int raid_disks,
|
||||
int delta_disks, char *backup, char *dev,
|
||||
+ int direction,
|
||||
int verbose); /* optional */
|
||||
int (*manage_reshape)( /* optional */
|
||||
int afd, struct mdinfo *sra, struct reshape *reshape,
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index ac8922f..32a53d1 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -10018,7 +10018,7 @@ int imsm_takeover(struct supertype *st, struct geo_params *geo)
|
||||
static int imsm_reshape_super(struct supertype *st, long long size, int level,
|
||||
int layout, int chunksize, int raid_disks,
|
||||
int delta_disks, char *backup, char *dev,
|
||||
- int verbose)
|
||||
+ int direction, int verbose)
|
||||
{
|
||||
int ret_val = 1;
|
||||
struct geo_params geo;
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,39 +0,0 @@
|
||||
From 3c20f9899bc95b35f5b9544c6741b4fccd616326 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Thu, 12 Jan 2012 08:12:47 +0100
|
||||
Subject: [PATCH] FIX: mdmon check in reshape_container() can cause a problem
|
||||
|
||||
When raid0 reshape is executed mdmon can dissappear due to raid level
|
||||
takeover operation. If this happen before mdmon check, mdadm would treat
|
||||
it as error condition. It is not true for this case.
|
||||
|
||||
Remove mdmon check from reshape_container() function.
|
||||
Error condition check will remain using reshape_array() reentry test
|
||||
for the same array (line 2577).
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 6 ------
|
||||
1 files changed, 0 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 89f563c..c1bc1ca 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -2608,12 +2608,6 @@ int reshape_container(char *container, char *devname,
|
||||
restart = 0;
|
||||
if (rv)
|
||||
break;
|
||||
- rv = !mdmon_running(devname2devnum(container));
|
||||
- if (rv) {
|
||||
- printf(Name ": Mdmon is not found. "
|
||||
- "Cannot continue container reshape.\n");
|
||||
- break;
|
||||
- }
|
||||
}
|
||||
if (!rv)
|
||||
unfreeze(st);
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,45 +0,0 @@
|
||||
From e1dd332a09c66ef0df68229cc633b8f2521e5db4 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Thu, 9 Feb 2012 12:37:40 +1100
|
||||
Subject: [PATCH 11/12] FIX: restart reshape when reshape process is stopped
|
||||
just between 2 reshapes
|
||||
|
||||
When reshape is restarted from '0', very begin of array
|
||||
it is possible that for external metadata reshape and array
|
||||
configuration doesn't happen.
|
||||
Check if md has the same opinion, and reshape is restarted
|
||||
from 0. If so, this is regular reshape start after reshape
|
||||
switch in metadata to next array only.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 12 ++++++++++++
|
||||
1 files changed, 12 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 6b1380a..61adefa 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1980,6 +1980,18 @@ static int reshape_array(char *container, int fd, char *devname,
|
||||
goto release;
|
||||
}
|
||||
|
||||
+ if (st->ss->external && restart && (info->reshape_progress == 0)) {
|
||||
+ /* When reshape is restarted from '0', very begin of array
|
||||
+ * it is possible that for external metadata reshape and array
|
||||
+ * configuration doesn't happen.
|
||||
+ * Check if md has the same opinion, and reshape is restarted
|
||||
+ * from 0. If so, this is regular reshape start after reshape
|
||||
+ * switch in metadata to next array only.
|
||||
+ */
|
||||
+ if ((verify_reshape_position(info, reshape.level) >= 0) &&
|
||||
+ (info->reshape_progress == 0))
|
||||
+ restart = 0;
|
||||
+ }
|
||||
if (restart) {
|
||||
/* reshape already started. just skip to monitoring the reshape */
|
||||
if (reshape.backup_blocks == 0)
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,139 +0,0 @@
|
||||
From f93346ef078fde20e46849901efa16dd1b05ec33 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Thu, 9 Feb 2012 12:36:41 +1100
|
||||
Subject: [PATCH 08/12] FIX: use md position to reshape restart
|
||||
|
||||
When reshape is broken, it can occur that metadata is not saved properly.
|
||||
This can cause that reshape process is farther in md than metadata states.
|
||||
|
||||
On reshape restart use md position as start position, if it is farther than
|
||||
position specified in metadata. Opposite situation treat as error.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 86 ++++++++++++++++++++++++++++++++++++++++++++-------------------
|
||||
1 files changed, 60 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 70bdee1..6b1380a 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1862,6 +1862,55 @@ release:
|
||||
return rv;
|
||||
}
|
||||
|
||||
+/* verify_reshape_position()
|
||||
+ * Function checks if reshape position in metadata is not farther
|
||||
+ * than position in md.
|
||||
+ * Return value:
|
||||
+ * 0 : not valid sysfs entry
|
||||
+ * it can be caused by not started reshape, it should be started
|
||||
+ * by reshape array or raid0 array is before takeover
|
||||
+ * -1 : error, reshape position is obviously wrong
|
||||
+ * 1 : success, reshape progress correct or updated
|
||||
+*/
|
||||
+static int verify_reshape_position(struct mdinfo *info, int level)
|
||||
+{
|
||||
+ int ret_val = 0;
|
||||
+ char buf[40];
|
||||
+
|
||||
+ /* read sync_max, failure can mean raid0 array */
|
||||
+ if (sysfs_get_str(info, NULL, "sync_max", buf, 40) > 0) {
|
||||
+ char *ep;
|
||||
+ unsigned long long position = strtoull(buf, &ep, 0);
|
||||
+
|
||||
+ dprintf(Name": Read sync_max sysfs entry is: %s\n", buf);
|
||||
+ if (!(ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' '))) {
|
||||
+ position *= get_data_disks(level,
|
||||
+ info->new_layout,
|
||||
+ info->array.raid_disks);
|
||||
+ if (info->reshape_progress < position) {
|
||||
+ dprintf("Corrected reshape progress (%llu) to "
|
||||
+ "md position (%llu)\n",
|
||||
+ info->reshape_progress, position);
|
||||
+ info->reshape_progress = position;
|
||||
+ ret_val = 1;
|
||||
+ } else if (info->reshape_progress > position) {
|
||||
+ fprintf(stderr, Name ": Fatal error: array "
|
||||
+ "reshape was not properly frozen "
|
||||
+ "(expected reshape position is %llu, "
|
||||
+ "but reshape progress is %llu.\n",
|
||||
+ position, info->reshape_progress);
|
||||
+ ret_val = -1;
|
||||
+ } else {
|
||||
+ dprintf("Reshape position in md and metadata "
|
||||
+ "are the same;");
|
||||
+ ret_val = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret_val;
|
||||
+}
|
||||
+
|
||||
static int reshape_array(char *container, int fd, char *devname,
|
||||
struct supertype *st, struct mdinfo *info,
|
||||
int force, struct mddev_dev *devlist,
|
||||
@@ -2251,9 +2300,16 @@ started:
|
||||
|
||||
sra->new_chunk = info->new_chunk;
|
||||
|
||||
- if (restart)
|
||||
+ if (restart) {
|
||||
+ /* for external metadata checkpoint saved by mdmon can be lost
|
||||
+ * or missed /due to e.g. crash/. Check if md is not during
|
||||
+ * restart farther than metadata points to.
|
||||
+ * If so, this means metadata information is obsolete.
|
||||
+ */
|
||||
+ if (st->ss->external)
|
||||
+ verify_reshape_position(info, reshape.level);
|
||||
sra->reshape_progress = info->reshape_progress;
|
||||
- else {
|
||||
+ } else {
|
||||
sra->reshape_progress = 0;
|
||||
if (reshape.after.data_disks < reshape.before.data_disks)
|
||||
/* start from the end of the new array */
|
||||
@@ -3765,8 +3821,6 @@ int Grow_continue_command(char *devname, int fd,
|
||||
char buf[40];
|
||||
int cfd = -1;
|
||||
int fd2 = -1;
|
||||
- char *ep;
|
||||
- unsigned long long position;
|
||||
|
||||
dprintf("Grow continue from command line called for %s\n",
|
||||
devname);
|
||||
@@ -3894,28 +3948,8 @@ int Grow_continue_command(char *devname, int fd,
|
||||
/* verify that array under reshape is started from
|
||||
* correct position
|
||||
*/
|
||||
- ret_val = sysfs_get_str(content, NULL, "sync_max", buf, 40);
|
||||
- if (ret_val <= 0) {
|
||||
- fprintf(stderr, Name
|
||||
- ": cannot open verify reshape progress for %s (%i)\n",
|
||||
- content->sys_name, ret_val);
|
||||
- ret_val = 1;
|
||||
- goto Grow_continue_command_exit;
|
||||
- }
|
||||
- dprintf(Name ": Read sync_max sysfs entry is: %s\n", buf);
|
||||
- position = strtoull(buf, &ep, 0);
|
||||
- if (ep == buf || (*ep != 0 && *ep != '\n' && *ep != ' ')) {
|
||||
- fprintf(stderr, Name ": Fatal error: array reshape was"
|
||||
- " not properly frozen\n");
|
||||
- ret_val = 1;
|
||||
- goto Grow_continue_command_exit;
|
||||
- }
|
||||
- position *= get_data_disks(map_name(pers, mdstat->level),
|
||||
- content->new_layout,
|
||||
- content->array.raid_disks);
|
||||
- if (position != content->reshape_progress) {
|
||||
- fprintf(stderr, Name ": Fatal error: array reshape was"
|
||||
- " not properly frozen.\n");
|
||||
+ if (verify_reshape_position(content,
|
||||
+ map_name(pers, mdstat->level)) <= 0) {
|
||||
ret_val = 1;
|
||||
goto Grow_continue_command_exit;
|
||||
}
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,46 +0,0 @@
|
||||
From 50927b1323a4cfcbf3729ff552c496695d6199eb Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Tue, 7 Feb 2012 15:03:35 +0100
|
||||
Subject: [PATCH 05/12] Fix: Sometimes mdmon throws core dump during reshape
|
||||
|
||||
Problem was found during reshaping 2 volumes /raid0 and raid5/ in container.
|
||||
Sometimes mdmon throws core dump due to NULL pointer exception.
|
||||
|
||||
Problem occurs in scenario:
|
||||
- managemon: is about spare activation (degraded raid4 volume == raid0 under takeover)
|
||||
- managemon: detect level change and signals monitor (manage_member() calls replace_array())
|
||||
- monitor: detects transition raid4/5->raid0 and sets a->container to NULL
|
||||
to indicate array deactivation
|
||||
- managemon : continues his work and tries to activate spare (a->check_degraded is set).
|
||||
NULL pointer is passed to metadata handler activate_spare()
|
||||
Core dump is generated.
|
||||
|
||||
To resolve this situation managemon (after monitor kick) checks again
|
||||
a->container pointer to learn if current array is not to be deactivated.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
managemon.c | 6 ++++++
|
||||
1 files changed, 6 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/managemon.c b/managemon.c
|
||||
index cde0d8b..6c21ecb 100644
|
||||
--- a/managemon.c
|
||||
+++ b/managemon.c
|
||||
@@ -486,6 +486,12 @@ static void manage_member(struct mdstat_ent *mdstat,
|
||||
}
|
||||
}
|
||||
|
||||
+ /* we are after monitor kick,
|
||||
+ * so container field can be cleared - check it again
|
||||
+ */
|
||||
+ if (a->container == NULL)
|
||||
+ return;
|
||||
+
|
||||
/* We don't check the array while any update is pending, as it
|
||||
* might container a change (such as a spare assignment) which
|
||||
* could affect our decisions.
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,40 +0,0 @@
|
||||
From 119374a0ac7d6a73cd296134b0151aa213bbee42 Mon Sep 17 00:00:00 2001
|
||||
From: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Date: Thu, 26 Apr 2012 16:55:10 +0200
|
||||
Subject: [PATCH 1/2] Fix sign extension of bitmap_offset in super1.c
|
||||
|
||||
fbdef49811c9e2b54e2064d9af68cfffa77c6e77 incorrectly tried to fix sign
|
||||
extension of the bitmap offset. However mdinfo->bitmap_offset is a u32
|
||||
and needs to be converted to a 32 bit signed integer before the sign
|
||||
extension.
|
||||
|
||||
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
---
|
||||
super1.c | 4 ++--
|
||||
1 files changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/super1.c b/super1.c
|
||||
index 36369d8..be77c33 100644
|
||||
--- a/super1.c
|
||||
+++ b/super1.c
|
||||
@@ -620,7 +620,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
|
||||
info->data_offset = __le64_to_cpu(sb->data_offset);
|
||||
info->component_size = __le64_to_cpu(sb->size);
|
||||
if (sb->feature_map & __le32_to_cpu(MD_FEATURE_BITMAP_OFFSET))
|
||||
- info->bitmap_offset = (long)__le32_to_cpu(sb->bitmap_offset);
|
||||
+ info->bitmap_offset = (int32_t)__le32_to_cpu(sb->bitmap_offset);
|
||||
|
||||
info->disk.major = 0;
|
||||
info->disk.minor = 0;
|
||||
@@ -1651,7 +1651,7 @@ add_internal_bitmap1(struct supertype *st,
|
||||
offset = -room;
|
||||
}
|
||||
|
||||
- sb->bitmap_offset = (long)__cpu_to_le32(offset);
|
||||
+ sb->bitmap_offset = (int32_t)__cpu_to_le32(offset);
|
||||
|
||||
sb->feature_map = __cpu_to_le32(__le32_to_cpu(sb->feature_map)
|
||||
| MD_FEATURE_BITMAP_OFFSET);
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,96 +0,0 @@
|
||||
From 78340e26a54db960de238b511f5cdc74aebe4453 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Tue, 7 Feb 2012 15:03:43 +0100
|
||||
Subject: [PATCH 06/12] Flush mdmon before next reshape step during container
|
||||
operation
|
||||
|
||||
Using takeover operation for grow purposes, mdadm has to be sure
|
||||
that mdmon processes all updates, and if necessary it will be closed
|
||||
at takeover to raid0 operation. If mdmon is late, next array in container
|
||||
is processed and due to race condition mdmon closes itself instead to monitor
|
||||
next reshape operation.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 12 ++++++++++--
|
||||
msg.c | 10 ++++++++++
|
||||
msg.h | 1 +
|
||||
3 files changed, 21 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 36a1de7..70bdee1 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -2003,6 +2003,9 @@ static int reshape_array(char *container, int fd, char *devname,
|
||||
|
||||
if (reshape.level > 0 && st->ss->external) {
|
||||
/* make sure mdmon is aware of the new level */
|
||||
+ if (mdmon_running(st->container_dev))
|
||||
+ flush_mdmon(container);
|
||||
+
|
||||
if (!mdmon_running(st->container_dev))
|
||||
start_mdmon(st->container_dev);
|
||||
ping_monitor(container);
|
||||
@@ -2396,8 +2399,7 @@ started:
|
||||
/* Re-load the metadata as much could have changed */
|
||||
int cfd = open_dev(st->container_dev);
|
||||
if (cfd >= 0) {
|
||||
- ping_manager(container);
|
||||
- ping_monitor(container);
|
||||
+ flush_mdmon(container);
|
||||
st->ss->free_super(st);
|
||||
st->ss->load_container(st, cfd, container);
|
||||
close(cfd);
|
||||
@@ -2594,6 +2596,9 @@ int reshape_container(char *container, char *devname,
|
||||
|
||||
sysfs_init(content, fd, mdstat->devnum);
|
||||
|
||||
+ if (mdmon_running(devname2devnum(container)))
|
||||
+ flush_mdmon(container);
|
||||
+
|
||||
rv = reshape_array(container, fd, adev, st,
|
||||
content, force, NULL,
|
||||
backup_file, quiet, 1, restart,
|
||||
@@ -2608,6 +2613,9 @@ int reshape_container(char *container, char *devname,
|
||||
restart = 0;
|
||||
if (rv)
|
||||
break;
|
||||
+
|
||||
+ if (mdmon_running(devname2devnum(container)))
|
||||
+ flush_mdmon(container);
|
||||
}
|
||||
if (!rv)
|
||||
unfreeze(st);
|
||||
diff --git a/msg.c b/msg.c
|
||||
index dc780b3..44aad1f 100644
|
||||
--- a/msg.c
|
||||
+++ b/msg.c
|
||||
@@ -487,3 +487,13 @@ int ping_manager(char *devname)
|
||||
close(sfd);
|
||||
return err;
|
||||
}
|
||||
+
|
||||
+/* using takeover operation for grow purposes, mdadm has to be sure
|
||||
+ * that mdmon processes all updates, and if necessary it will be closed
|
||||
+ * at takeover to raid0 operation
|
||||
+ */
|
||||
+void flush_mdmon(char *container)
|
||||
+{
|
||||
+ ping_manager(container);
|
||||
+ ping_monitor(container);
|
||||
+}
|
||||
diff --git a/msg.h b/msg.h
|
||||
index c6d037d..eefa649 100644
|
||||
--- a/msg.h
|
||||
+++ b/msg.h
|
||||
@@ -34,5 +34,6 @@ extern int block_monitor(char *container, const int freeze);
|
||||
extern void unblock_monitor(char *container, const int unfreeze);
|
||||
extern int fping_monitor(int sock);
|
||||
extern int ping_manager(char *devname);
|
||||
+extern void flush_mdmon(char *container);
|
||||
|
||||
#define MSG_MAX_LEN (4*1024*1024)
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,49 +0,0 @@
|
||||
From 69fe207ed68e560d76a592fd86af32a9d1deca25 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Thu, 22 Mar 2012 15:53:53 +1100
|
||||
Subject: [PATCH] Incremental: fix adding devices with --incremental
|
||||
|
||||
We should use 'info' here, not 'info2'.
|
||||
info2 refers to some other device (There may not even be one).l
|
||||
info is *this* disk.
|
||||
|
||||
This is particularly important for getting info.disk.state
|
||||
correct, which the kernel depends on to get 're-add' functionality
|
||||
correct.
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Incremental.c | 8 ++++----
|
||||
1 files changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Incremental.c b/Incremental.c
|
||||
index 836a6f1..a61f453 100644
|
||||
--- a/Incremental.c
|
||||
+++ b/Incremental.c
|
||||
@@ -414,19 +414,19 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||
goto out_unlock;
|
||||
}
|
||||
}
|
||||
- info2.disk.major = major(stb.st_rdev);
|
||||
- info2.disk.minor = minor(stb.st_rdev);
|
||||
+ info.disk.major = major(stb.st_rdev);
|
||||
+ info.disk.minor = minor(stb.st_rdev);
|
||||
/* add disk needs to know about containers */
|
||||
if (st->ss->external)
|
||||
sra->array.level = LEVEL_CONTAINER;
|
||||
- err = add_disk(mdfd, st, sra, &info2);
|
||||
+ err = add_disk(mdfd, st, sra, &info);
|
||||
if (err < 0 && errno == EBUSY) {
|
||||
/* could be another device present with the same
|
||||
* disk.number. Find and reject any such
|
||||
*/
|
||||
find_reject(mdfd, st, sra, info.disk.number,
|
||||
info.events, verbose, chosen_name);
|
||||
- err = add_disk(mdfd, st, sra, &info2);
|
||||
+ err = add_disk(mdfd, st, sra, &info);
|
||||
}
|
||||
if (err < 0) {
|
||||
fprintf(stderr, Name ": failed to add %s to %s: %s.\n",
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,68 +0,0 @@
|
||||
From 7b5ec34bb072781c0efbba8b21a941fff4d6ae7f Mon Sep 17 00:00:00 2001
|
||||
From: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Date: Thu, 26 Apr 2012 17:05:22 +0200
|
||||
Subject: [PATCH 2/2] Introduce sysfs_set_num_signed() and use it to set
|
||||
bitmap/offset
|
||||
|
||||
mdinfo->bitmap_offset is a signed long and needs to be treated as
|
||||
such when passed to the kernel.
|
||||
|
||||
This resolves the problem with adding internal bitmaps to a 1.0 array.
|
||||
|
||||
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
---
|
||||
Grow.c | 4 ++--
|
||||
mdadm.h | 2 ++
|
||||
sysfs.c | 8 ++++++++
|
||||
3 files changed, 12 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index b4b9ff2..0b0d718 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -424,8 +424,8 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
|
||||
if (offset_setable) {
|
||||
st->ss->getinfo_super(st, mdi, NULL);
|
||||
sysfs_init(mdi, fd, -1);
|
||||
- rv = sysfs_set_num(mdi, NULL, "bitmap/location",
|
||||
- mdi->bitmap_offset);
|
||||
+ rv = sysfs_set_num_signed(mdi, NULL, "bitmap/location",
|
||||
+ mdi->bitmap_offset);
|
||||
} else {
|
||||
array.state |= (1<<MD_SB_BITMAP_PRESENT);
|
||||
rv = ioctl(fd, SET_ARRAY_INFO, &array);
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index e60a706..0c91a34 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -473,6 +473,8 @@ extern int sysfs_set_str(struct mdinfo *sra, struct mdinfo *dev,
|
||||
char *name, char *val);
|
||||
extern int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
|
||||
char *name, unsigned long long val);
|
||||
+extern int sysfs_set_num_signed(struct mdinfo *sra, struct mdinfo *dev,
|
||||
+ char *name, long long val);
|
||||
extern int sysfs_uevent(struct mdinfo *sra, char *event);
|
||||
extern int sysfs_get_fd(struct mdinfo *sra, struct mdinfo *dev,
|
||||
char *name);
|
||||
diff --git a/sysfs.c b/sysfs.c
|
||||
index a1007cf..8e9d0c5 100644
|
||||
--- a/sysfs.c
|
||||
+++ b/sysfs.c
|
||||
@@ -428,6 +428,14 @@ int sysfs_set_num(struct mdinfo *sra, struct mdinfo *dev,
|
||||
return sysfs_set_str(sra, dev, name, valstr);
|
||||
}
|
||||
|
||||
+int sysfs_set_num_signed(struct mdinfo *sra, struct mdinfo *dev,
|
||||
+ char *name, long long val)
|
||||
+{
|
||||
+ char valstr[50];
|
||||
+ sprintf(valstr, "%lli", val);
|
||||
+ return sysfs_set_str(sra, dev, name, valstr);
|
||||
+}
|
||||
+
|
||||
int sysfs_uevent(struct mdinfo *sra, char *event)
|
||||
{
|
||||
char fname[50];
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,66 +0,0 @@
|
||||
From c69ffac0d6a068823a1365c3b155ff72f8c4686f Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Wed, 7 Mar 2012 15:25:57 +1100
|
||||
Subject: [PATCH] Manage: allow --re-add to failed array.
|
||||
|
||||
If both "legs" of a RAID1 (or equivalent in RAID10) fail, then one
|
||||
of the becomes available again it maybe appropriate to re-add the
|
||||
failed device(s).
|
||||
So remove the restriction that an array must has 'enough' devices
|
||||
before being re-added, and if there is no-where to read a superblock
|
||||
from for matching, then assume the kernel will do necessary checks.
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Manage.c | 16 +++++++++++++---
|
||||
1 files changed, 13 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/Manage.c b/Manage.c
|
||||
index d9775de..4cf6e58 100644
|
||||
--- a/Manage.c
|
||||
+++ b/Manage.c
|
||||
@@ -723,7 +723,13 @@ int Manage_subdevs(char *devname, int fd,
|
||||
break;
|
||||
}
|
||||
/* FIXME this is a bad test to be using */
|
||||
- if (!tst->sb) {
|
||||
+ if (!tst->sb &&
|
||||
+ dv->re_add) {
|
||||
+ /* we are re-adding a device to a
|
||||
+ * completely dead array - have to depend
|
||||
+ * on kernel to check
|
||||
+ */
|
||||
+ } else if (!tst->sb) {
|
||||
close(tfd);
|
||||
st->ss->free_super(st);
|
||||
fprintf(stderr, Name ": cannot load array metadata from %s\n", devname);
|
||||
@@ -747,12 +753,16 @@ int Manage_subdevs(char *devname, int fd,
|
||||
* and was temporarily removed, and is now being re-added.
|
||||
* If so, we can simply re-add it.
|
||||
*/
|
||||
- tst->ss->uuid_from_super(tst, duuid);
|
||||
|
||||
if (st->sb) {
|
||||
struct mdinfo mdi;
|
||||
st->ss->getinfo_super(st, &mdi, NULL);
|
||||
st->ss->uuid_from_super(st, ouuid);
|
||||
+ if (tst->sb)
|
||||
+ tst->ss->uuid_from_super(tst, duuid);
|
||||
+ else
|
||||
+ /* Assume uuid matches: kernel will check */
|
||||
+ memcpy(duuid, ouuid, sizeof(ouuid));
|
||||
if ((mdi.disk.state & (1<<MD_DISK_ACTIVE)) &&
|
||||
!(mdi.disk.state & (1<<MD_DISK_FAULTY)) &&
|
||||
memcmp(duuid, ouuid, sizeof(ouuid))==0) {
|
||||
@@ -768,7 +778,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
disc.number = mdi.disk.number;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disc) != 0
|
||||
|| disc.major != 0 || disc.minor != 0
|
||||
- || !enough_fd(fd))
|
||||
+ )
|
||||
goto skip_re_add;
|
||||
disc.major = major(stb.st_rdev);
|
||||
disc.minor = minor(stb.st_rdev);
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,66 +0,0 @@
|
||||
From 9f58469128c99c0d7f434d28657f86789334f253 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Thu, 22 Mar 2012 16:15:03 +1100
|
||||
Subject: [PATCH 3/3] Manage: freeze recovery while adding multiple devices.
|
||||
|
||||
If the kernel supports it, freeze recovery over multiple adds,
|
||||
so that they can all be added to the array at the same time and
|
||||
be recovered in parallel.
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Manage.c | 13 +++++++++++++
|
||||
1 files changed, 13 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/Manage.c b/Manage.c
|
||||
index f53fe27..7deba3a 100644
|
||||
--- a/Manage.c
|
||||
+++ b/Manage.c
|
||||
@@ -416,12 +416,15 @@ int Manage_subdevs(char *devname, int fd,
|
||||
int lfd = -1;
|
||||
int sysfd = -1;
|
||||
int count = 0; /* number of actions taken */
|
||||
+ struct mdinfo info;
|
||||
+ int frozen = 0;
|
||||
|
||||
if (ioctl(fd, GET_ARRAY_INFO, &array)) {
|
||||
fprintf(stderr, Name ": cannot get array info for %s\n",
|
||||
devname);
|
||||
goto abort;
|
||||
}
|
||||
+ sysfs_init(&info, fd, 0);
|
||||
|
||||
/* array.size is only 32 bit and may be truncated.
|
||||
* So read from sysfs if possible, and record number of sectors
|
||||
@@ -629,6 +632,12 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname, strerror(errno));
|
||||
goto abort;
|
||||
}
|
||||
+ if (!frozen) {
|
||||
+ if (sysfs_freeze_array(&info) == 1)
|
||||
+ frozen = 1;
|
||||
+ else
|
||||
+ frozen = -1;
|
||||
+ }
|
||||
|
||||
st = dup_super(tst);
|
||||
|
||||
@@ -1166,11 +1175,15 @@ int Manage_subdevs(char *devname, int fd,
|
||||
break;
|
||||
}
|
||||
}
|
||||
+ if (frozen > 0)
|
||||
+ sysfs_set_str(&info, NULL, "sync_action","idle");
|
||||
if (test && count == 0)
|
||||
return 2;
|
||||
return 0;
|
||||
|
||||
abort:
|
||||
+ if (frozen > 0)
|
||||
+ sysfs_set_str(&info, NULL, "sync_action","idle");
|
||||
return 1;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,347 +0,0 @@
|
||||
From bcbb3112d2801594358153956191e4cff6021de3 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Thu, 22 Mar 2012 16:07:02 +1100
|
||||
Subject: [PATCH 2/3] Manage: replace 'return 1' with 'goto abort'.
|
||||
|
||||
This will allow exit processing in next patch
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Manage.c | 75 ++++++++++++++++++++++++++++++++-----------------------------
|
||||
1 files changed, 39 insertions(+), 36 deletions(-)
|
||||
|
||||
diff --git a/Manage.c b/Manage.c
|
||||
index 4cf6e58..f53fe27 100644
|
||||
--- a/Manage.c
|
||||
+++ b/Manage.c
|
||||
@@ -420,7 +420,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (ioctl(fd, GET_ARRAY_INFO, &array)) {
|
||||
fprintf(stderr, Name ": cannot get array info for %s\n",
|
||||
devname);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
/* array.size is only 32 bit and may be truncated.
|
||||
@@ -435,7 +435,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (!tst) {
|
||||
fprintf(stderr, Name ": unsupport array - version %d.%d\n",
|
||||
array.major_version, array.minor_version);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
stb.st_rdev = 0;
|
||||
@@ -457,7 +457,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
fprintf(stderr, Name ": %s only meaningful "
|
||||
"with -r, not -%c\n",
|
||||
dv->devname, dv->disposition);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
for (; j < 1024 && remaining_disks > 0; j++) {
|
||||
unsigned dev;
|
||||
@@ -490,7 +490,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
fprintf(stderr, Name ": %s only meaningful "
|
||||
"with -r of -f, not -%c\n",
|
||||
dv->devname, dv->disposition);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
for (; j < 1024 && remaining_disks > 0; j++) {
|
||||
int sfd;
|
||||
@@ -530,7 +530,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (dv->disposition != 'a' || dv->re_add == 0) {
|
||||
fprintf(stderr, Name ": 'missing' only meaningful "
|
||||
"with --re-add\n");
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
if (add_devlist == NULL)
|
||||
add_devlist = conf_get_devs();
|
||||
@@ -554,7 +554,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
fprintf(stderr, Name ": %s only meaningful "
|
||||
"with -r or -f, not -%c\n",
|
||||
dv->devname, dv->disposition);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
sprintf(dname, "dev-%s", dv->devname);
|
||||
@@ -576,7 +576,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
fprintf(stderr, Name ": %s does not appear "
|
||||
"to be a component of %s\n",
|
||||
dv->devname, devname);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -595,7 +595,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname, strerror(errno));
|
||||
if (tfd >= 0)
|
||||
close(tfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
close(tfd);
|
||||
tfd = -1;
|
||||
@@ -604,21 +604,21 @@ int Manage_subdevs(char *devname, int fd,
|
||||
fprintf(stderr, Name ": %s is not a "
|
||||
"block device.\n",
|
||||
dv->devname);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
}
|
||||
switch(dv->disposition){
|
||||
default:
|
||||
fprintf(stderr, Name ": internal error - devmode[%s]=%d\n",
|
||||
dv->devname, dv->disposition);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
case 'a':
|
||||
/* add the device */
|
||||
if (subarray) {
|
||||
fprintf(stderr, Name ": Cannot add disks to a"
|
||||
" \'member\' array, perform this"
|
||||
" operation on the parent container\n");
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
/* Make sure it isn't in use (in 2.6 or later) */
|
||||
tfd = dev_open(add_dev, O_RDONLY|O_EXCL|O_DIRECT);
|
||||
@@ -627,7 +627,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (tfd < 0) {
|
||||
fprintf(stderr, Name ": Cannot open %s: %s\n",
|
||||
dv->devname, strerror(errno));
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
st = dup_super(tst);
|
||||
@@ -639,7 +639,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (!get_dev_size(tfd, dv->devname, &ldsize)) {
|
||||
st->ss->free_super(st);
|
||||
close(tfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
} else if (!get_dev_size(tfd, NULL, &ldsize)) {
|
||||
st->ss->free_super(st);
|
||||
@@ -661,7 +661,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
add_dev, devname);
|
||||
st->ss->free_super(st);
|
||||
close(tfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
fprintf(stderr, Name
|
||||
": %s is larger than %s can "
|
||||
@@ -686,7 +686,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
|
||||
fprintf(stderr, Name ": hot add failed for %s: %s\n",
|
||||
add_dev, strerror(errno));
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
if (array.not_persistent == 0 || tst->ss->external) {
|
||||
@@ -733,7 +733,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
close(tfd);
|
||||
st->ss->free_super(st);
|
||||
fprintf(stderr, Name ": cannot load array metadata from %s\n", devname);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
/* Make sure device is large enough */
|
||||
@@ -746,7 +746,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
continue;
|
||||
fprintf(stderr, Name ": %s not large enough to join array\n",
|
||||
dv->devname);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
/* Possibly this device was recently part of the array
|
||||
@@ -799,7 +799,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
fprintf(stderr, Name ": failed to open %s for"
|
||||
" superblock update during re-add\n", dv->devname);
|
||||
st->ss->free_super(st);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
if (dv->writemostly == 1)
|
||||
@@ -822,7 +822,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
fprintf(stderr, Name ": failed to update"
|
||||
" superblock during re-add\n");
|
||||
st->ss->free_super(st);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
}
|
||||
/* don't even try if disk is marked as faulty */
|
||||
@@ -840,7 +840,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
st->ss->free_super(st);
|
||||
if (add_dev != dv->devname)
|
||||
continue;
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
skip_re_add:
|
||||
re_add_failed = 1;
|
||||
@@ -864,7 +864,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
fprintf(stderr, Name
|
||||
": --re-add for %s to %s is not possible\n",
|
||||
dv->devname, devname);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
if (re_add_failed) {
|
||||
fprintf(stderr, Name ": %s reports being an active member for %s, but a --re-add fails.\n",
|
||||
@@ -875,7 +875,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname);
|
||||
if (tfd >= 0)
|
||||
close(tfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
} else {
|
||||
/* non-persistent. Must ensure that new drive
|
||||
@@ -886,7 +886,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname);
|
||||
if (tfd >= 0)
|
||||
close(tfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
}
|
||||
/* committed to really trying this device now*/
|
||||
@@ -921,11 +921,11 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (tst->ss->add_to_super(tst, &disc, dfd,
|
||||
dv->devname)) {
|
||||
close(dfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
if (tst->ss->write_init_super(tst)) {
|
||||
close(dfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
} else if (dv->re_add) {
|
||||
/* this had better be raid1.
|
||||
@@ -974,7 +974,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
" could not get exclusive access to container\n",
|
||||
dv->devname);
|
||||
tst->ss->free_super(tst);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
|
||||
@@ -984,7 +984,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname)) {
|
||||
close(dfd);
|
||||
close(container_fd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
if (tst->update_tail)
|
||||
flush_metadata_updates(tst);
|
||||
@@ -997,7 +997,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname);
|
||||
close(container_fd);
|
||||
tst->ss->free_super(tst);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
sra->array.level = LEVEL_CONTAINER;
|
||||
/* Need to set data_offset and component_size */
|
||||
@@ -1013,7 +1013,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
" failed for %s\n", dv->devname);
|
||||
close(container_fd);
|
||||
sysfs_free(sra);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
ping_monitor_by_id(devnum);
|
||||
sysfs_free(sra);
|
||||
@@ -1023,7 +1023,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (ioctl(fd, ADD_NEW_DISK, &disc)) {
|
||||
fprintf(stderr, Name ": add new device failed for %s as %d: %s\n",
|
||||
dv->devname, j, strerror(errno));
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
}
|
||||
if (verbose >= 0)
|
||||
@@ -1038,7 +1038,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
" operation on the parent container\n");
|
||||
if (sysfd >= 0)
|
||||
close(sysfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
if (tst->ss->external) {
|
||||
/* To remove a device from a container, we must
|
||||
@@ -1058,7 +1058,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
" to container - odd\n");
|
||||
if (sysfd >= 0)
|
||||
close(sysfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
/* in the detached case it is not possible to
|
||||
* check if we are the unique holder, so just
|
||||
@@ -1075,7 +1075,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
errno == EEXIST ? "still in use":
|
||||
"not a member");
|
||||
close(lfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
}
|
||||
/* FIXME check that it is a current member */
|
||||
@@ -1118,7 +1118,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
strerror(errno));
|
||||
if (lfd >= 0)
|
||||
close(lfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
if (tst->ss->external) {
|
||||
/*
|
||||
@@ -1131,7 +1131,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
|
||||
if (!name) {
|
||||
fprintf(stderr, Name ": unable to get container name\n");
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
|
||||
ping_manager(name);
|
||||
@@ -1154,7 +1154,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dnprintable, strerror(errno));
|
||||
if (sysfd >= 0)
|
||||
close(sysfd);
|
||||
- return 1;
|
||||
+ goto abort;
|
||||
}
|
||||
if (sysfd >= 0)
|
||||
close(sysfd);
|
||||
@@ -1169,6 +1169,9 @@ int Manage_subdevs(char *devname, int fd,
|
||||
if (test && count == 0)
|
||||
return 2;
|
||||
return 0;
|
||||
+
|
||||
+abort:
|
||||
+ return 1;
|
||||
}
|
||||
|
||||
int autodetect(void)
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,94 +0,0 @@
|
||||
From 4011421332681ba733a2fc90de7ac94da8593418 Mon Sep 17 00:00:00 2001
|
||||
From: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Date: Thu, 23 Feb 2012 08:55:19 +1100
|
||||
Subject: [PATCH 2/2] Print error message if failing to write super for 1.x
|
||||
metadata
|
||||
|
||||
In addition remove attempt to print an error message if
|
||||
write_init_super() fails, as this is handled in the various
|
||||
write_init_super() functions. This avoids a segfault on error.
|
||||
|
||||
Reported by Jim Meyering in
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=795461
|
||||
|
||||
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Create.c | 3 ---
|
||||
super1.c | 25 ++++++++++++++++---------
|
||||
2 files changed, 16 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/Create.c b/Create.c
|
||||
index 90ff3ed..e5c6b05 100644
|
||||
--- a/Create.c
|
||||
+++ b/Create.c
|
||||
@@ -924,9 +924,6 @@ int Create(struct supertype *st, char *mddev,
|
||||
}
|
||||
|
||||
if (st->ss->write_init_super(st)) {
|
||||
- fprintf(stderr,
|
||||
- Name ": Failed to write metadata to %s\n",
|
||||
- dv->devname);
|
||||
st->ss->free_super(st);
|
||||
goto abort_locked;
|
||||
}
|
||||
diff --git a/super1.c b/super1.c
|
||||
index a18952a..341ad53 100644
|
||||
--- a/super1.c
|
||||
+++ b/super1.c
|
||||
@@ -1106,13 +1106,16 @@ static int write_init_super1(struct supertype *st)
|
||||
}
|
||||
free(refst);
|
||||
|
||||
- if (!get_dev_size(di->fd, NULL, &dsize))
|
||||
- return 1;
|
||||
+ if (!get_dev_size(di->fd, NULL, &dsize)) {
|
||||
+ rv = 1;
|
||||
+ goto error_out;
|
||||
+ }
|
||||
dsize >>= 9;
|
||||
|
||||
if (dsize < 24) {
|
||||
close(di->fd);
|
||||
- return 2;
|
||||
+ rv = 2;
|
||||
+ goto error_out;
|
||||
}
|
||||
|
||||
|
||||
@@ -1176,22 +1179,26 @@ static int write_init_super1(struct supertype *st)
|
||||
sb->data_size = __cpu_to_le64(dsize - reserved);
|
||||
break;
|
||||
default:
|
||||
- return -EINVAL;
|
||||
+ fprintf(stderr, Name ": Failed to write invalid "
|
||||
+ "metadata format 1.%i to %s\n",
|
||||
+ st->minor_version, di->devname);
|
||||
+ rv = -EINVAL;
|
||||
+ goto out;
|
||||
}
|
||||
|
||||
|
||||
sb->sb_csum = calc_sb_1_csum(sb);
|
||||
rv = store_super1(st, di->fd);
|
||||
- if (rv)
|
||||
- fprintf(stderr,
|
||||
- Name ": failed to write superblock to %s\n",
|
||||
- di->devname);
|
||||
-
|
||||
if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1))
|
||||
rv = st->ss->write_bitmap(st, di->fd);
|
||||
close(di->fd);
|
||||
di->fd = -1;
|
||||
}
|
||||
+error_out:
|
||||
+ if (rv)
|
||||
+ fprintf(stderr, Name ": Failed to write metadata to %s\n",
|
||||
+ di->devname);
|
||||
+out:
|
||||
return rv;
|
||||
}
|
||||
#endif
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,81 +0,0 @@
|
||||
From 480f3566411675ec41f18e5f6e15429f891e144c Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Wed, 18 Apr 2012 09:06:02 +1000
|
||||
Subject: [PATCH] Raid limit of 1024 when scanning for devices.
|
||||
|
||||
When we can for devices using GET_DISK_INFO we currently
|
||||
limit to 1024. But some arrays can have more than this.
|
||||
So raise it to 4096 and make the constant a #define.
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Manage.c | 4 ++--
|
||||
mdadm.h | 8 ++++++++
|
||||
util.c | 4 ++--
|
||||
3 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/Manage.c b/Manage.c
|
||||
index 102c013..3767f01 100644
|
||||
--- a/Manage.c
|
||||
+++ b/Manage.c
|
||||
@@ -462,7 +462,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname, dv->disposition);
|
||||
goto abort;
|
||||
}
|
||||
- for (; j < 1024 && remaining_disks > 0; j++) {
|
||||
+ for (; j < MAX_DISKS && remaining_disks > 0; j++) {
|
||||
unsigned dev;
|
||||
disc.number = j;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disc))
|
||||
@@ -495,7 +495,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname, dv->disposition);
|
||||
goto abort;
|
||||
}
|
||||
- for (; j < 1024 && remaining_disks > 0; j++) {
|
||||
+ for (; j < MAX_DISKS && remaining_disks > 0; j++) {
|
||||
int sfd;
|
||||
unsigned dev;
|
||||
disc.number = j;
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index 686d4b4..71cef38 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -1388,4 +1388,13 @@ static inline int xasprintf(char **strp, const char *fmt, ...) {
|
||||
#define PROCESS_DELAYED -2
|
||||
#define PROCESS_PENDING -3
|
||||
|
||||
extern int __offroot;
|
||||
+
|
||||
+/* When using "GET_DISK_INFO" it isn't certain how high
|
||||
+ * we need to check. So we impose an absolute limit of
|
||||
+ * MAX_DISKS. This needs to be much more than the largest
|
||||
+ * number of devices any metadata can support. Currently
|
||||
+ * v1.x can support 1920
|
||||
+ */
|
||||
+#define MAX_DISKS 4096
|
||||
+
|
||||
diff --git a/util.c b/util.c
|
||||
index b942058..ac0f78c 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -378,7 +378,7 @@ int enough_fd(int fd)
|
||||
array.raid_disks <= 0)
|
||||
return 0;
|
||||
avail = calloc(array.raid_disks, 1);
|
||||
- for (i=0; i < 1024 && array.nr_disks > 0; i++) {
|
||||
+ for (i=0; i < MAX_DISKS && array.nr_disks > 0; i++) {
|
||||
disk.number = i;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
|
||||
continue;
|
||||
@@ -1275,7 +1275,7 @@ void get_one_disk(int mdfd, mdu_array_info_t *ainf, mdu_disk_info_t *disk)
|
||||
int d;
|
||||
|
||||
ioctl(mdfd, GET_ARRAY_INFO, ainf);
|
||||
- for (d = 0 ; d < 1024 ; d++) {
|
||||
+ for (d = 0 ; d < MAX_DISKS ; d++) {
|
||||
if (ioctl(mdfd, GET_DISK_INFO, disk) == 0 &&
|
||||
(disk->major || disk->minor))
|
||||
return;
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,85 +0,0 @@
|
||||
From 0a999759b54f94fd63ac0ee298a549acef6f7d6f Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Wed, 18 Apr 2012 14:19:49 +1000
|
||||
Subject: [PATCH 1/3] Relax restrictions on when --add is permitted.
|
||||
|
||||
The restriction that --add was not allowed on a device which
|
||||
looked like a recent member of an array was overly harsh.
|
||||
|
||||
The real requirement was to avoid using --add when the array had
|
||||
failed, and the device being added might contain necessary
|
||||
information which can only be incorporated by stopping and
|
||||
re-assembling with --force.
|
||||
|
||||
So change the test to reflect the need.
|
||||
|
||||
Reported-by: Doug Ledford <dledford@redhat.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Manage.c | 35 ++++++++++++++++++++++++++---------
|
||||
1 files changed, 26 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/Manage.c b/Manage.c
|
||||
index 3767f01..95aa270 100644
|
||||
--- a/Manage.c
|
||||
+++ b/Manage.c
|
||||
@@ -448,7 +448,7 @@ int Manage_subdevs(char *devname, int fd,
|
||||
char *dnprintable = dv->devname;
|
||||
char *add_dev = dv->devname;
|
||||
int err;
|
||||
- int re_add_failed = 0;
|
||||
+ int array_failed;
|
||||
|
||||
next = dv->next;
|
||||
jnext = 0;
|
||||
@@ -851,9 +851,8 @@ int Manage_subdevs(char *devname, int fd,
|
||||
continue;
|
||||
goto abort;
|
||||
}
|
||||
- skip_re_add:
|
||||
- re_add_failed = 1;
|
||||
}
|
||||
+ skip_re_add:
|
||||
st->ss->free_super(st);
|
||||
}
|
||||
if (add_dev != dv->devname) {
|
||||
@@ -875,12 +874,30 @@ int Manage_subdevs(char *devname, int fd,
|
||||
dv->devname, devname);
|
||||
goto abort;
|
||||
}
|
||||
- if (re_add_failed) {
|
||||
- fprintf(stderr, Name ": %s reports being an active member for %s, but a --re-add fails.\n",
|
||||
- dv->devname, devname);
|
||||
- fprintf(stderr, Name ": not performing --add as that would convert %s in to a spare.\n",
|
||||
- dv->devname);
|
||||
- fprintf(stderr, Name ": To make this a spare, use \"mdadm --zero-superblock %s\" first.\n",
|
||||
+ if (array.active_disks < array.raid_disks) {
|
||||
+ char *avail = calloc(array.raid_disks, 1);
|
||||
+ int d;
|
||||
+ int found = 0;
|
||||
+
|
||||
+ for (d = 0; d < MAX_DISKS && found < array.active_disks; d++) {
|
||||
+ disc.number = d;
|
||||
+ if (ioctl(fd, GET_DISK_INFO, &disc))
|
||||
+ continue;
|
||||
+ if (disc.major == 0 && disc.minor == 0)
|
||||
+ continue;
|
||||
+ if (!(disc.state & (1<<MD_DISK_SYNC)))
|
||||
+ continue;
|
||||
+ avail[disc.raid_disk] = 1;
|
||||
+ found++;
|
||||
+ }
|
||||
+ array_failed = !enough(array.level, array.raid_disks,
|
||||
+ array.layout, 1, avail);
|
||||
+ } else
|
||||
+ array_failed = 0;
|
||||
+ if (array_failed) {
|
||||
+ fprintf(stderr, Name ": %s has failed so using --add cannot work and might destroy\n",
|
||||
+ devname);
|
||||
+ fprintf(stderr, Name ": data on %s. You should stop the array and re-assemble it.\n",
|
||||
dv->devname);
|
||||
if (tfd >= 0)
|
||||
close(tfd);
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,171 +0,0 @@
|
||||
From de5a472ea32867d002558bac0d2d2b4faf45c7c4 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Tue, 7 Feb 2012 14:04:47 +1100
|
||||
Subject: [PATCH] Remove avail_disks arg from 'enough'.
|
||||
|
||||
It can easily be calculated from 'avail' and 'raid_disks', and we
|
||||
will soon have a case where we don't have it easily available to pass
|
||||
in.
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Assemble.c | 16 ++++++++--------
|
||||
Detail.c | 4 ++--
|
||||
Incremental.c | 2 +-
|
||||
mdadm.h | 2 +-
|
||||
util.c | 11 ++++++++---
|
||||
5 files changed, 20 insertions(+), 15 deletions(-)
|
||||
|
||||
diff --git a/Assemble.c b/Assemble.c
|
||||
index fd94461..972398e 100644
|
||||
--- a/Assemble.c
|
||||
+++ b/Assemble.c
|
||||
@@ -934,7 +934,7 @@ int Assemble(struct supertype *st, char *mddev,
|
||||
}
|
||||
continue;
|
||||
}
|
||||
- /* If this devices thinks that 'most_recent' has failed, then
|
||||
+ /* If this device thinks that 'most_recent' has failed, then
|
||||
* we must reject this device.
|
||||
*/
|
||||
if (j != most_recent &&
|
||||
@@ -965,7 +965,7 @@ int Assemble(struct supertype *st, char *mddev,
|
||||
free(devmap);
|
||||
while (force && !enough(content->array.level, content->array.raid_disks,
|
||||
content->array.layout, 1,
|
||||
- avail, okcnt)) {
|
||||
+ avail)) {
|
||||
/* Choose the newest best drive which is
|
||||
* not up-to-date, update the superblock
|
||||
* and add it.
|
||||
@@ -1132,7 +1132,7 @@ int Assemble(struct supertype *st, char *mddev,
|
||||
if (force && !clean &&
|
||||
!enough(content->array.level, content->array.raid_disks,
|
||||
content->array.layout, clean,
|
||||
- avail, okcnt)) {
|
||||
+ avail)) {
|
||||
change += st->ss->update_super(st, content, "force-array",
|
||||
devices[chosen_drive].devname, verbose,
|
||||
0, NULL);
|
||||
@@ -1331,7 +1331,7 @@ int Assemble(struct supertype *st, char *mddev,
|
||||
if (runstop == 1 ||
|
||||
(runstop <= 0 &&
|
||||
( enough(content->array.level, content->array.raid_disks,
|
||||
- content->array.layout, clean, avail, okcnt) &&
|
||||
+ content->array.layout, clean, avail) &&
|
||||
(okcnt + rebuilding_cnt >= req_cnt || start_partial_ok)
|
||||
))) {
|
||||
/* This array is good-to-go.
|
||||
@@ -1437,13 +1437,13 @@ int Assemble(struct supertype *st, char *mddev,
|
||||
mddev, strerror(errno));
|
||||
|
||||
if (!enough(content->array.level, content->array.raid_disks,
|
||||
- content->array.layout, 1, avail, okcnt))
|
||||
+ content->array.layout, 1, avail))
|
||||
fprintf(stderr, Name ": Not enough devices to "
|
||||
"start the array.\n");
|
||||
else if (!enough(content->array.level,
|
||||
content->array.raid_disks,
|
||||
content->array.layout, clean,
|
||||
- avail, okcnt))
|
||||
+ avail))
|
||||
fprintf(stderr, Name ": Not enough devices to "
|
||||
"start the array while not clean "
|
||||
"- consider --force.\n");
|
||||
@@ -1471,12 +1471,12 @@ int Assemble(struct supertype *st, char *mddev,
|
||||
if (sparecnt)
|
||||
fprintf(stderr, " and %d spare%s", sparecnt, sparecnt==1?"":"s");
|
||||
if (!enough(content->array.level, content->array.raid_disks,
|
||||
- content->array.layout, 1, avail, okcnt))
|
||||
+ content->array.layout, 1, avail))
|
||||
fprintf(stderr, " - not enough to start the array.\n");
|
||||
else if (!enough(content->array.level,
|
||||
content->array.raid_disks,
|
||||
content->array.layout, clean,
|
||||
- avail, okcnt))
|
||||
+ avail))
|
||||
fprintf(stderr, " - not enough to start the "
|
||||
"array while not clean - consider "
|
||||
"--force.\n");
|
||||
diff --git a/Detail.c b/Detail.c
|
||||
index e7d1681..1d7e3a1 100644
|
||||
--- a/Detail.c
|
||||
+++ b/Detail.c
|
||||
@@ -367,7 +367,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
|
||||
if (avail_disks == array.raid_disks)
|
||||
st = "";
|
||||
else if (!enough(array.level, array.raid_disks,
|
||||
- array.layout, 1, avail, avail_disks))
|
||||
+ array.layout, 1, avail))
|
||||
st = ", FAILED";
|
||||
else
|
||||
st = ", degraded";
|
||||
@@ -580,7 +580,7 @@ This is pretty boring
|
||||
if (brief) printf("\n");
|
||||
if (test &&
|
||||
!enough(array.level, array.raid_disks, array.layout,
|
||||
- 1, avail, avail_disks))
|
||||
+ 1, avail))
|
||||
rv = 2;
|
||||
|
||||
free(disks);
|
||||
diff --git a/Incremental.c b/Incremental.c
|
||||
index 60175af..b457bf3 100644
|
||||
--- a/Incremental.c
|
||||
+++ b/Incremental.c
|
||||
@@ -486,7 +486,7 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||
active_disks = count_active(st, sra, mdfd, &avail, &info);
|
||||
if (enough(info.array.level, info.array.raid_disks,
|
||||
info.array.layout, info.array.state & 1,
|
||||
- avail, active_disks) == 0) {
|
||||
+ avail) == 0) {
|
||||
if (verbose >= 0)
|
||||
fprintf(stderr, Name
|
||||
": %s attached to %s, not enough to start (%d).\n",
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index d862b3e..45198bb 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -1164,7 +1164,7 @@ extern char *fname_from_uuid(struct supertype *st,
|
||||
struct mdinfo *info, char *buf, char sep);
|
||||
extern unsigned long calc_csum(void *super, int bytes);
|
||||
extern int enough(int level, int raid_disks, int layout, int clean,
|
||||
- char *avail, int avail_disks);
|
||||
+ char *avail);
|
||||
extern int enough_fd(int fd);
|
||||
extern int ask(char *mesg);
|
||||
extern unsigned long long get_component_size(int fd);
|
||||
diff --git a/util.c b/util.c
|
||||
index 4ba44e6..e5f7a20 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -311,10 +311,15 @@ int test_partition_from_id(dev_t id)
|
||||
return rv;
|
||||
}
|
||||
|
||||
-int enough(int level, int raid_disks, int layout, int clean,
|
||||
- char *avail, int avail_disks)
|
||||
+int enough(int level, int raid_disks, int layout, int clean, char *avail)
|
||||
{
|
||||
int copies, first;
|
||||
+ int i;
|
||||
+ int avail_disks = 0;
|
||||
+
|
||||
+ for (i = 0; i < raid_disks; i++)
|
||||
+ avail_disks += !!avail[i];
|
||||
+
|
||||
switch (level) {
|
||||
case 10:
|
||||
/* This is the tricky one - we need to check
|
||||
@@ -389,7 +394,7 @@ int enough_fd(int fd)
|
||||
}
|
||||
/* This is used on an active array, so assume it is clean */
|
||||
rv = enough(array.level, array.raid_disks, array.layout,
|
||||
- 1, avail, avail_disks);
|
||||
+ 1, avail);
|
||||
free(avail);
|
||||
return rv;
|
||||
}
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,32 +0,0 @@
|
||||
From 52f07f57195229809c7b6d71ca81d2182d303058 Mon Sep 17 00:00:00 2001
|
||||
From: "Czarnowska, Anna" <anna.czarnowska@intel.com>
|
||||
Date: Wed, 7 Mar 2012 12:51:30 +0000
|
||||
Subject: [PATCH] Reset bad flag on map update
|
||||
|
||||
Map file may miss an entry if bad flag is not cleared on update.
|
||||
|
||||
This happens for example when an old entry exists in map that
|
||||
has no mdstat counterpart and we create a new array with the same devnum.
|
||||
Newly created array will not appear in map if update doesnt clear bad flag.
|
||||
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
mapfile.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/mapfile.c b/mapfile.c
|
||||
index 0bfecd0..9e2c893 100644
|
||||
--- a/mapfile.c
|
||||
+++ b/mapfile.c
|
||||
@@ -246,6 +246,7 @@ int map_update(struct map_ent **mpp, int devnum, char *metadata,
|
||||
memcpy(mp->uuid, uuid, 16);
|
||||
free(mp->path);
|
||||
mp->path = path ? strdup(path) : NULL;
|
||||
+ mp->bad = 0;
|
||||
break;
|
||||
}
|
||||
if (!mp)
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,75 +0,0 @@
|
||||
From a0963a86e12a55d501f421048bd7c09cf4d78b93 Mon Sep 17 00:00:00 2001
|
||||
From: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Date: Wed, 25 Jan 2012 15:18:04 +0100
|
||||
Subject: [PATCH 4/4] Spawn mdmon with --offroot if mdadm was launched with
|
||||
--offroot
|
||||
|
||||
Acked-by: Doug Ledford <dledford@redhat.com>
|
||||
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
mdadm.c | 1 +
|
||||
mdadm.h | 2 ++
|
||||
util.c | 17 +++++++++++++----
|
||||
3 files changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/mdadm.c b/mdadm.c
|
||||
index 78f28d5..1efa3e8 100644
|
||||
--- a/mdadm.c
|
||||
+++ b/mdadm.c
|
||||
@@ -181,6 +181,7 @@ int main(int argc, char *argv[])
|
||||
*/
|
||||
case OffRootOpt:
|
||||
argv[0][0] = '@';
|
||||
+ __offroot = 1;
|
||||
continue;
|
||||
|
||||
case ':':
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index fec93aa..d862b3e 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -1383,3 +1383,5 @@ static inline int xasprintf(char **strp, const char *fmt, ...) {
|
||||
|
||||
#define PROCESS_DELAYED -2
|
||||
#define PROCESS_PENDING -3
|
||||
+
|
||||
+extern int __offroot;
|
||||
diff --git a/util.c b/util.c
|
||||
index 6985a70..4ba44e6 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -32,6 +32,8 @@
|
||||
#include <dirent.h>
|
||||
#include <signal.h>
|
||||
|
||||
+int __offroot;
|
||||
+
|
||||
/*
|
||||
* following taken from linux/blkpg.h because they aren't
|
||||
* anywhere else and it isn't safe to #include linux/ * stuff.
|
||||
@@ -1622,10 +1624,17 @@ int start_mdmon(int devnum)
|
||||
skipped = 0;
|
||||
|
||||
for (i=0; paths[i]; i++)
|
||||
- if (paths[i][0])
|
||||
- execl(paths[i], "mdmon",
|
||||
- devnum2devname(devnum),
|
||||
- NULL);
|
||||
+ if (paths[i][0]) {
|
||||
+ if (__offroot) {
|
||||
+ execl(paths[i], "mdmon", "--offroot",
|
||||
+ devnum2devname(devnum),
|
||||
+ NULL);
|
||||
+ } else {
|
||||
+ execl(paths[i], "mdmon",
|
||||
+ devnum2devname(devnum),
|
||||
+ NULL);
|
||||
+ }
|
||||
+ }
|
||||
exit(1);
|
||||
case -1: fprintf(stderr, Name ": cannot run mdmon. "
|
||||
"Array remains readonly\n");
|
||||
--
|
||||
1.7.8.4
|
||||
|
@ -1,122 +0,0 @@
|
||||
From b89b2007a01f60386fb53107b883eed85319281c Mon Sep 17 00:00:00 2001
|
||||
From: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Date: Thu, 5 Jan 2012 12:09:45 +0100
|
||||
Subject: [PATCH 1/1] Work around gcc-4.7's strict aliasing checks
|
||||
|
||||
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
---
|
||||
sha1.c | 8 +++++---
|
||||
super-ddf.c | 22 ++++++++++++++--------
|
||||
2 files changed, 19 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/sha1.c b/sha1.c
|
||||
index 556d9ca..0258515 100644
|
||||
--- a/sha1.c
|
||||
+++ b/sha1.c
|
||||
@@ -101,6 +101,7 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
|
||||
/* Take yet unprocessed bytes into account. */
|
||||
md5_uint32 bytes = ctx->buflen;
|
||||
size_t pad;
|
||||
+ md5_uint32 *ptr;
|
||||
|
||||
/* Now count remaining bytes. */
|
||||
ctx->total[0] += bytes;
|
||||
@@ -111,9 +112,10 @@ sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
|
||||
memcpy (&ctx->buffer[bytes], fillbuf, pad);
|
||||
|
||||
/* Put the 64-bit file length in *bits* at the end of the buffer. */
|
||||
- *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3);
|
||||
- *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) |
|
||||
- (ctx->total[0] >> 29));
|
||||
+ ptr = (md5_uint32 *) &ctx->buffer[bytes + pad + 4];
|
||||
+ *ptr = SWAP (ctx->total[0] << 3);
|
||||
+ ptr = (md5_uint32 *) &ctx->buffer[bytes + pad];
|
||||
+ *ptr = SWAP ((ctx->total[1] << 3) | (ctx->total[0] >> 29));
|
||||
|
||||
/* Process last bytes. */
|
||||
sha1_process_block (ctx->buffer, bytes + pad + 8, ctx);
|
||||
diff --git a/super-ddf.c b/super-ddf.c
|
||||
index b5b0b42..abd6793 100644
|
||||
--- a/super-ddf.c
|
||||
+++ b/super-ddf.c
|
||||
@@ -1336,6 +1336,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
|
||||
{
|
||||
struct ddf_super *ddf = st->sb;
|
||||
int map_disks = info->array.raid_disks;
|
||||
+ __u32 *cptr;
|
||||
|
||||
if (ddf->currentconf) {
|
||||
getinfo_super_ddf_bvd(st, info, map);
|
||||
@@ -1347,8 +1348,9 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
|
||||
info->array.level = LEVEL_CONTAINER;
|
||||
info->array.layout = 0;
|
||||
info->array.md_minor = -1;
|
||||
- info->array.ctime = DECADE + __be32_to_cpu(*(__u32*)
|
||||
- (ddf->anchor.guid+16));
|
||||
+ cptr = (__u32 *)(ddf->anchor.guid + 16);
|
||||
+ info->array.ctime = DECADE + __be32_to_cpu(*cptr);
|
||||
+
|
||||
info->array.utime = 0;
|
||||
info->array.chunk_size = 0;
|
||||
info->container_enough = 1;
|
||||
@@ -1407,6 +1409,7 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
|
||||
int j;
|
||||
struct dl *dl;
|
||||
int map_disks = info->array.raid_disks;
|
||||
+ __u32 *cptr;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
/* FIXME this returns BVD info - what if we want SVD ?? */
|
||||
@@ -1416,8 +1419,8 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
|
||||
info->array.layout = rlq_to_layout(vc->conf.rlq, vc->conf.prl,
|
||||
info->array.raid_disks);
|
||||
info->array.md_minor = -1;
|
||||
- info->array.ctime = DECADE +
|
||||
- __be32_to_cpu(*(__u32*)(vc->conf.guid+16));
|
||||
+ cptr = (__u32 *)(vc->conf.guid + 16);
|
||||
+ info->array.ctime = DECADE + __be32_to_cpu(*cptr);
|
||||
info->array.utime = DECADE + __be32_to_cpu(vc->conf.timestamp);
|
||||
info->array.chunk_size = 512 << vc->conf.chunk_shift;
|
||||
info->custom_array_size = 0;
|
||||
@@ -2192,6 +2195,7 @@ static int add_to_super_ddf(struct supertype *st,
|
||||
struct phys_disk_entry *pde;
|
||||
unsigned int n, i;
|
||||
struct stat stb;
|
||||
+ __u32 *tptr;
|
||||
|
||||
if (ddf->currentconf) {
|
||||
add_to_super_ddf_bvd(st, dk, fd, devname);
|
||||
@@ -2220,8 +2224,9 @@ static int add_to_super_ddf(struct supertype *st,
|
||||
tm = localtime(&now);
|
||||
sprintf(dd->disk.guid, "%8s%04d%02d%02d",
|
||||
T10, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
|
||||
- *(__u32*)(dd->disk.guid + 16) = random32();
|
||||
- *(__u32*)(dd->disk.guid + 20) = random32();
|
||||
+ tptr = (__u32 *)(dd->disk.guid + 16);
|
||||
+ *tptr++ = random32();
|
||||
+ *tptr = random32();
|
||||
|
||||
do {
|
||||
/* Cannot be bothered finding a CRC of some irrelevant details*/
|
||||
@@ -2967,6 +2972,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
|
||||
unsigned int j;
|
||||
struct mdinfo *this;
|
||||
char *ep;
|
||||
+ __u32 *cptr;
|
||||
|
||||
if (subarray &&
|
||||
(strtoul(subarray, &ep, 10) != vc->vcnum ||
|
||||
@@ -2986,8 +2992,8 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
|
||||
this->array.md_minor = -1;
|
||||
this->array.major_version = -1;
|
||||
this->array.minor_version = -2;
|
||||
- this->array.ctime = DECADE +
|
||||
- __be32_to_cpu(*(__u32*)(vc->conf.guid+16));
|
||||
+ cptr = (__u32 *)(vc->conf.guid + 16);
|
||||
+ this->array.ctime = DECADE + __be32_to_cpu(*cptr);
|
||||
this->array.utime = DECADE +
|
||||
__be32_to_cpu(vc->conf.timestamp);
|
||||
this->array.chunk_size = 512 << vc->conf.chunk_shift;
|
||||
--
|
||||
1.7.8.2
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 9200d418d049aff77b3d0ad8f30f1a16adc56030 Mon Sep 17 00:00:00 2001
|
||||
From: Jim Meyering <jim@meyering.net>
|
||||
Date: Tue, 21 Feb 2012 13:02:22 +0100
|
||||
Subject: [PATCH 1/2] avoid double-free upon "old buggy kernel" sysfs_read
|
||||
failure
|
||||
|
||||
* Incremental.c (Incremental): On sysfs_read failure, don't call
|
||||
sysfs_free(sra) just before "goto out_unlock", since that very
|
||||
same "sra" is freed the same way by the clean-up code below.
|
||||
|
||||
Signed-off-by: Jim Meyering <meyering@redhat.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Incremental.c | 1 -
|
||||
1 files changed, 0 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/Incremental.c b/Incremental.c
|
||||
index b457bf3..836a6f1 100644
|
||||
--- a/Incremental.c
|
||||
+++ b/Incremental.c
|
||||
@@ -325,7 +325,6 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||
fprintf(stderr, Name
|
||||
": You have an old buggy kernel which cannot support\n"
|
||||
" --incremental reliably. Aborting.\n");
|
||||
- sysfs_free(sra);
|
||||
rv = 2;
|
||||
goto out_unlock;
|
||||
}
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,52 +0,0 @@
|
||||
From 9126b9a816b1576f58718dbb71bcaff2bfc274e3 Mon Sep 17 00:00:00 2001
|
||||
From: "Czarnowska, Anna" <anna.czarnowska@intel.com>
|
||||
Date: Mon, 2 Apr 2012 10:18:37 +1000
|
||||
Subject: [PATCH 6/7] check that no disk over 2TB is used to create container
|
||||
when no support
|
||||
|
||||
Creation of a container using disks over 2TB should be allowed only when orom supports large disks
|
||||
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 24 ++++++++++++++++--------
|
||||
1 files changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 7803a2e..1bc9e9c 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -5331,14 +5331,22 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
|
||||
return 0;
|
||||
}
|
||||
close(fd);
|
||||
- if (super->orom && raiddisks > super->orom->tds) {
|
||||
- if (verbose)
|
||||
- fprintf(stderr, Name ": %d exceeds maximum number of"
|
||||
- " platform supported disks: %d\n",
|
||||
- raiddisks, super->orom->tds);
|
||||
-
|
||||
- free_imsm(super);
|
||||
- return 0;
|
||||
+ if (super->orom) {
|
||||
+ if (raiddisks > super->orom->tds) {
|
||||
+ if (verbose)
|
||||
+ fprintf(stderr, Name ": %d exceeds maximum number of"
|
||||
+ " platform supported disks: %d\n",
|
||||
+ raiddisks, super->orom->tds);
|
||||
+ free_imsm(super);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ if ((super->orom->attr & IMSM_OROM_ATTR_2TB_DISK) == 0 &&
|
||||
+ (ldsize >> 9) >> 32 > 0) {
|
||||
+ if (verbose)
|
||||
+ fprintf(stderr, Name ": %s exceeds maximum platform supported size\n", dev);
|
||||
+ free_imsm(super);
|
||||
+ return 0;
|
||||
+ }
|
||||
}
|
||||
|
||||
*freesize = avail_size_imsm(st, ldsize >> 9);
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,69 +0,0 @@
|
||||
From 2cc699afbf0a05baf02d26309eb4ad0e4e81c5d5 Mon Sep 17 00:00:00 2001
|
||||
From: "Czarnowska, Anna" <anna.czarnowska@intel.com>
|
||||
Date: Mon, 2 Apr 2012 10:17:55 +1000
|
||||
Subject: [PATCH 5/7] check volume size in validate_geometry_imsm_orom
|
||||
|
||||
When orom does not support volumes over 2TB the creation should be disallowed
|
||||
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 14 ++++++++++----
|
||||
1 files changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 0c38b45..7803a2e 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -5860,7 +5860,7 @@ static int imsm_default_chunk(const struct imsm_orom *orom)
|
||||
|
||||
static int
|
||||
validate_geometry_imsm_orom(struct intel_super *super, int level, int layout,
|
||||
- int raiddisks, int *chunk, int verbose)
|
||||
+ int raiddisks, int *chunk, unsigned long long size, int verbose)
|
||||
{
|
||||
/* check/set platform and metadata limits/defaults */
|
||||
if (super->orom && raiddisks > super->orom->dpa) {
|
||||
@@ -5895,6 +5895,12 @@ validate_geometry_imsm_orom(struct intel_super *super, int level, int layout,
|
||||
layout, level);
|
||||
return 0;
|
||||
}
|
||||
+
|
||||
+ if (super->orom && (super->orom->attr & IMSM_OROM_ATTR_2TB) == 0 && chunk &&
|
||||
+ (calc_array_size(level, raiddisks, layout, *chunk, size) >> 32) > 0) {
|
||||
+ pr_vrb(": platform does not support a volume size over 2TB\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5922,7 +5928,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
||||
|
||||
mpb = super->anchor;
|
||||
|
||||
- if (!validate_geometry_imsm_orom(super, level, layout, raiddisks, chunk, verbose)) {
|
||||
+ if (!validate_geometry_imsm_orom(super, level, layout, raiddisks, chunk, size, verbose)) {
|
||||
fprintf(stderr, Name ": RAID gemetry validation failed. "
|
||||
"Cannot proceed with the action(s).\n");
|
||||
return 0;
|
||||
@@ -6187,7 +6193,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
if (st->sb) {
|
||||
struct intel_super *super = st->sb;
|
||||
if (!validate_geometry_imsm_orom(st->sb, level, layout,
|
||||
- raiddisks, chunk,
|
||||
+ raiddisks, chunk, size,
|
||||
verbose))
|
||||
return 0;
|
||||
/* we are being asked to automatically layout a
|
||||
@@ -6598,7 +6604,7 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
||||
get_imsm_raid_level(map), /* RAID level */
|
||||
imsm_level_to_layout(get_imsm_raid_level(map)),
|
||||
map->num_members, /* raid disks */
|
||||
- &chunk,
|
||||
+ &chunk, join_u32(dev->size_low, dev->size_high),
|
||||
1 /* verbose */)) {
|
||||
fprintf(stderr, Name ": IMSM RAID geometry validation"
|
||||
" failed. Array %s activation is blocked.\n",
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,72 +0,0 @@
|
||||
From 97f81ee2635d8c1283ef857bc46d7314acffa1c3 Mon Sep 17 00:00:00 2001
|
||||
From: "Czarnowska, Anna" <anna.czarnowska@intel.com>
|
||||
Date: Mon, 2 Apr 2012 10:15:08 +1000
|
||||
Subject: [PATCH 2/7] clear hi bits if not used after loading metadata from
|
||||
disk
|
||||
|
||||
Functions retrieving sizes from metadata do not need to check
|
||||
2TB attribute only when we can guarantee the hi bits are always
|
||||
clear when the MPB_ATTR_2TB_DISK attribute is not set.
|
||||
|
||||
Therefore the following fields are cleared on metadata load
|
||||
when not in use according to attribute:
|
||||
struct imsm_disk.total_blocks_hi
|
||||
struct imsm_map.pba_of_lba0_hi
|
||||
struct imsm_map.blocks_per_member_hi
|
||||
struct imsm_map.num_data_stripes_hi
|
||||
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 28 +++++++++++++++++++++++++++-
|
||||
1 files changed, 27 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index c65d39b..480b379 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -3590,6 +3590,32 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
|
||||
|
||||
static int read_imsm_migr_rec(int fd, struct intel_super *super);
|
||||
|
||||
+/* clears hi bits in metadata if MPB_ATTRIB_2TB_DISK not set */
|
||||
+static void clear_hi(struct intel_super *super)
|
||||
+{
|
||||
+ struct imsm_super *mpb = super->anchor;
|
||||
+ int i, n;
|
||||
+ if (mpb->attributes & MPB_ATTRIB_2TB_DISK)
|
||||
+ return;
|
||||
+ for (i = 0; i < mpb->num_disks; ++i) {
|
||||
+ struct imsm_disk *disk = &mpb->disk[i];
|
||||
+ disk->total_blocks_hi = 0;
|
||||
+ }
|
||||
+ for (i = 0; i < mpb->num_raid_devs; ++i) {
|
||||
+ struct imsm_dev *dev = get_imsm_dev(super, i);
|
||||
+ if (!dev)
|
||||
+ return;
|
||||
+ for (n = 0; n < 2; ++n) {
|
||||
+ struct imsm_map *map = get_imsm_map(dev, n);
|
||||
+ if (!map)
|
||||
+ continue;
|
||||
+ map->pba_of_lba0_hi = 0;
|
||||
+ map->blocks_per_member_hi = 0;
|
||||
+ map->num_data_stripes_hi = 0;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static int
|
||||
load_and_parse_mpb(int fd, struct intel_super *super, char *devname, int keep_fd)
|
||||
{
|
||||
@@ -3602,7 +3628,7 @@ load_and_parse_mpb(int fd, struct intel_super *super, char *devname, int keep_fd
|
||||
if (err)
|
||||
return err;
|
||||
err = parse_raid_devices(super);
|
||||
-
|
||||
+ clear_hi(super);
|
||||
return err;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 8453f8d0df0111cfd25e984afb7a64153b04bc27 Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
Date: Thu, 12 Jan 2012 10:40:00 +1100
|
||||
Subject: [PATCH] fix: Monitor sometimes crashes
|
||||
|
||||
The "char cnt [40]" buffer is sometimes too small to hold all message
|
||||
- in such case monitor crashes.
|
||||
The buffer must be larger to be able to hold all message.
|
||||
|
||||
Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Monitor.c | 5 +++--
|
||||
1 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Monitor.c b/Monitor.c
|
||||
index 8bc8824..77f22aa 100644
|
||||
--- a/Monitor.c
|
||||
+++ b/Monitor.c
|
||||
@@ -563,8 +563,9 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
||||
struct mdinfo *sra =
|
||||
sysfs_read(-1, st->devnum, GET_MISMATCH);
|
||||
if (sra && sra->mismatch_cnt > 0) {
|
||||
- char cnt[40];
|
||||
- sprintf(cnt, " mismatches found: %d (on raid level %d)",
|
||||
+ char cnt[80];
|
||||
+ snprintf(cnt, sizeof(cnt),
|
||||
+ " mismatches found: %d (on raid level %d)",
|
||||
sra->mismatch_cnt, array.level);
|
||||
alert("RebuildFinished", dev, cnt, ainfo);
|
||||
} else
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,34 +0,0 @@
|
||||
From 0c4304ca8b3328132537922fed8ee9e3bbb8a0fa Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
Date: Thu, 12 Jan 2012 10:57:20 +1100
|
||||
Subject: [PATCH] fix: container creation with --incremental used.
|
||||
|
||||
If there is no name provided for a container by the metadata it is
|
||||
always appropriate to use the metadata version name. create_mddev
|
||||
will still add a uniquifying digit to the end so there is little risk
|
||||
of confusion.
|
||||
This makes the --incremental code behave the same as the --assemble code.
|
||||
|
||||
Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Incremental.c | 3 +--
|
||||
1 files changed, 1 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/Incremental.c b/Incremental.c
|
||||
index 78c9712..60175af 100644
|
||||
--- a/Incremental.c
|
||||
+++ b/Incremental.c
|
||||
@@ -259,8 +259,7 @@ int Incremental(char *devname, int verbose, int runstop,
|
||||
|
||||
name_to_use = info.name;
|
||||
if (name_to_use[0] == 0 &&
|
||||
- info.array.level == LEVEL_CONTAINER &&
|
||||
- trustworthy == LOCAL) {
|
||||
+ info.array.level == LEVEL_CONTAINER) {
|
||||
name_to_use = info.text_version;
|
||||
trustworthy = METADATA;
|
||||
}
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,31 +0,0 @@
|
||||
From b51702b82767b726e34d205c9e00a4f61d3044a7 Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
Date: Fri, 20 Apr 2012 11:00:25 +0200
|
||||
Subject: [PATCH 3/3] fix: correct extending size of raid0 array
|
||||
|
||||
Setting "sync_action" to "idle" while extending size of raid0 array
|
||||
is racy and sometimes fails.
|
||||
"sync_action" should be set to "frozen" instead.
|
||||
|
||||
Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 2 +-
|
||||
1 files changed, 1 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index 389992e..b4b9ff2 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1749,7 +1749,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
/* do not recync non-existing parity,
|
||||
* we will drop it anyway
|
||||
*/
|
||||
- sysfs_set_str(sra, NULL, "sync_action", "idle");
|
||||
+ sysfs_set_str(sra, NULL, "sync_action", "frozen");
|
||||
/* go back to raid0, drop parity disk
|
||||
*/
|
||||
sysfs_set_str(sra, NULL, "level", "raid0");
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,63 +0,0 @@
|
||||
From 13bcac9059b6aef7bf9e828fbdea285cf6adcbd2 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:04 +0200
|
||||
Subject: [PATCH 10/14] imsm: Add function imsm_get_free_size()
|
||||
|
||||
Add function imsm_imsm_get_free_size() using part of code from function
|
||||
reserve_space().
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 25 ++++++++++++++++++++++++-
|
||||
1 files changed, 24 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 49e383f..7cc0ed5 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -6108,7 +6108,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
||||
return 1;
|
||||
}
|
||||
|
||||
-static int reserve_space(struct supertype *st, int raiddisks,
|
||||
+static int imsm_get_free_size(struct supertype *st, int raiddisks,
|
||||
unsigned long long size, int chunk,
|
||||
unsigned long long *freesize)
|
||||
{
|
||||
@@ -6186,9 +6186,32 @@ static int reserve_space(struct supertype *st, int raiddisks,
|
||||
|
||||
*freesize = size;
|
||||
|
||||
+ dprintf("imsm: imsm_get_free_size() returns : %llu\n", size);
|
||||
+
|
||||
return 1;
|
||||
}
|
||||
|
||||
+static int reserve_space(struct supertype *st, int raiddisks,
|
||||
+ unsigned long long size, int chunk,
|
||||
+ unsigned long long *freesize)
|
||||
+{
|
||||
+ struct intel_super *super = st->sb;
|
||||
+ struct dl *dl;
|
||||
+ int cnt;
|
||||
+ int rv = 0;
|
||||
+
|
||||
+ rv = imsm_get_free_size(st, raiddisks, size, chunk, freesize);
|
||||
+ if (rv) {
|
||||
+ cnt = 0;
|
||||
+ for (dl = super->disks; dl; dl = dl->next)
|
||||
+ if (dl->e)
|
||||
+ dl->raiddisk = cnt++;
|
||||
+ rv = 1;
|
||||
+ }
|
||||
+
|
||||
+ return rv;
|
||||
+}
|
||||
+
|
||||
static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
int raiddisks, int *chunk, unsigned long long size,
|
||||
char *dev, unsigned long long *freesize,
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,238 +0,0 @@
|
||||
From f3871fdc6841a0505d3a987f4ea1cfb16f6cc201 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:51:57 +0200
|
||||
Subject: [PATCH 03/14] imsm: Add new metadata update for volume size
|
||||
expansion
|
||||
|
||||
Add new meatdata update type imsm_update_size_change, and update metadata
|
||||
for volume size expansion operation.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
|
||||
1 files changed, 124 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 2e6a899..ac8922f 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -419,6 +419,7 @@ enum imsm_update_type {
|
||||
update_reshape_migration,
|
||||
update_takeover,
|
||||
update_general_migration_checkpoint,
|
||||
+ update_size_change,
|
||||
};
|
||||
|
||||
struct imsm_update_activate_spare {
|
||||
@@ -471,6 +472,12 @@ struct imsm_update_reshape_migration {
|
||||
int new_disks[1]; /* new_raid_disks - old_raid_disks makedev number */
|
||||
};
|
||||
|
||||
+struct imsm_update_size_change {
|
||||
+ enum imsm_update_type type;
|
||||
+ int subdev;
|
||||
+ long long new_size;
|
||||
+};
|
||||
+
|
||||
struct imsm_update_general_migration_checkpoint {
|
||||
enum imsm_update_type type;
|
||||
__u32 curr_migr_unit;
|
||||
@@ -6974,7 +6981,8 @@ static void handle_missing(struct intel_super *super, struct imsm_dev *dev)
|
||||
super->updates_pending++;
|
||||
}
|
||||
|
||||
-static unsigned long long imsm_set_array_size(struct imsm_dev *dev)
|
||||
+static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
|
||||
+ long long new_size)
|
||||
{
|
||||
int used_disks = imsm_num_data_members(dev, MAP_0);
|
||||
unsigned long long array_blocks;
|
||||
@@ -6993,8 +7001,17 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev)
|
||||
|
||||
/* set array size in metadata
|
||||
*/
|
||||
- map = get_imsm_map(dev, MAP_0);
|
||||
- array_blocks = blocks_per_member(map) * used_disks;
|
||||
+ if (new_size <= 0) {
|
||||
+ /* OLCE size change is caused by added disks
|
||||
+ */
|
||||
+ map = get_imsm_map(dev, MAP_0);
|
||||
+ array_blocks = blocks_per_member(map) * used_disks;
|
||||
+ } else {
|
||||
+ /* Online Volume Size Change
|
||||
+ * Using available free space
|
||||
+ */
|
||||
+ array_blocks = new_size;
|
||||
+ }
|
||||
|
||||
/* round array size down to closest MB
|
||||
*/
|
||||
@@ -7051,7 +7068,7 @@ static void imsm_progress_container_reshape(struct intel_super *super)
|
||||
memcpy(map2, map, copy_map_size);
|
||||
map2->num_members = prev_num_members;
|
||||
|
||||
- imsm_set_array_size(dev);
|
||||
+ imsm_set_array_size(dev, -1);
|
||||
super->clean_migration_record_by_mdmon = 1;
|
||||
super->updates_pending++;
|
||||
}
|
||||
@@ -7941,7 +7958,7 @@ skip_disk_add:
|
||||
*tofree = *space_list;
|
||||
/* calculate new size
|
||||
*/
|
||||
- imsm_set_array_size(new_dev);
|
||||
+ imsm_set_array_size(new_dev, -1);
|
||||
|
||||
ret_val = 1;
|
||||
}
|
||||
@@ -7956,6 +7973,44 @@ error_disk_add:
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
+static int apply_size_change_update(struct imsm_update_size_change *u,
|
||||
+ struct intel_super *super)
|
||||
+{
|
||||
+ struct intel_dev *id;
|
||||
+ int ret_val = 0;
|
||||
+
|
||||
+ dprintf("apply_size_change_update()\n");
|
||||
+ if ((u->subdev < 0) ||
|
||||
+ (u->subdev > 1)) {
|
||||
+ dprintf("imsm: Error: Wrong subdev: %i\n", u->subdev);
|
||||
+ return ret_val;
|
||||
+ }
|
||||
+
|
||||
+ for (id = super->devlist ; id; id = id->next) {
|
||||
+ if (id->index == (unsigned)u->subdev) {
|
||||
+ struct imsm_dev *dev = get_imsm_dev(super, u->subdev);
|
||||
+ struct imsm_map *map = get_imsm_map(dev, MAP_0);
|
||||
+ int used_disks = imsm_num_data_members(dev, MAP_0);
|
||||
+ unsigned long long blocks_per_member;
|
||||
+
|
||||
+ /* calculate new size
|
||||
+ */
|
||||
+ blocks_per_member = u->new_size / used_disks;
|
||||
+ dprintf("imsm: apply_size_change_update(size: %llu, "
|
||||
+ "blocks per member: %llu)\n",
|
||||
+ u->new_size, blocks_per_member);
|
||||
+ set_blocks_per_member(map, blocks_per_member);
|
||||
+ imsm_set_array_size(dev, u->new_size);
|
||||
+
|
||||
+ ret_val = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return ret_val;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static int apply_update_activate_spare(struct imsm_update_activate_spare *u,
|
||||
struct intel_super *super,
|
||||
struct active_array *active_array)
|
||||
@@ -8155,7 +8210,7 @@ static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
|
||||
newmap = get_imsm_map(newdev, MAP_1);
|
||||
memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
|
||||
|
||||
- imsm_set_array_size(newdev);
|
||||
+ imsm_set_array_size(newdev, -1);
|
||||
}
|
||||
|
||||
sp = (void **)id->dev;
|
||||
@@ -8363,6 +8418,12 @@ static void imsm_process_update(struct supertype *st,
|
||||
super->updates_pending++;
|
||||
break;
|
||||
}
|
||||
+ case update_size_change: {
|
||||
+ struct imsm_update_size_change *u = (void *)update->buf;
|
||||
+ if (apply_size_change_update(u, super))
|
||||
+ super->updates_pending++;
|
||||
+ break;
|
||||
+ }
|
||||
case update_activate_spare: {
|
||||
struct imsm_update_activate_spare *u = (void *) update->buf;
|
||||
if (apply_update_activate_spare(u, super, st->arrays))
|
||||
@@ -8757,6 +8818,9 @@ static void imsm_prepare_update(struct supertype *st,
|
||||
dprintf("New anchor length is %llu\n", (unsigned long long)len);
|
||||
break;
|
||||
}
|
||||
+ case update_size_change: {
|
||||
+ break;
|
||||
+ }
|
||||
case update_create_array: {
|
||||
struct imsm_update_create_array *u = (void *) update->buf;
|
||||
struct intel_dev *dv;
|
||||
@@ -9614,6 +9678,43 @@ abort:
|
||||
return 0;
|
||||
}
|
||||
|
||||
+
|
||||
+/******************************************************************************
|
||||
+ * function: imsm_create_metadata_update_for_size_change()
|
||||
+ * Creates update for IMSM array for array size change.
|
||||
+ *
|
||||
+ ******************************************************************************/
|
||||
+static int imsm_create_metadata_update_for_size_change(
|
||||
+ struct supertype *st,
|
||||
+ struct geo_params *geo,
|
||||
+ struct imsm_update_size_change **updatep)
|
||||
+{
|
||||
+ struct intel_super *super = st->sb;
|
||||
+ int update_memory_size = 0;
|
||||
+ struct imsm_update_size_change *u = NULL;
|
||||
+
|
||||
+ dprintf("imsm_create_metadata_update_for_size_change(enter)"
|
||||
+ " New size = %llu\n", geo->size);
|
||||
+
|
||||
+ /* size of all update data without anchor */
|
||||
+ update_memory_size = sizeof(struct imsm_update_size_change);
|
||||
+
|
||||
+ u = calloc(1, update_memory_size);
|
||||
+ if (u == NULL) {
|
||||
+ dprintf("error: cannot get memory for "
|
||||
+ "imsm_create_metadata_update_for_size_change\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ u->type = update_size_change;
|
||||
+ u->subdev = super->current_vol;
|
||||
+ u->new_size = geo->size;
|
||||
+
|
||||
+ dprintf("imsm: reshape update preparation : OK\n");
|
||||
+ *updatep = u;
|
||||
+
|
||||
+ return update_memory_size;
|
||||
+}
|
||||
+
|
||||
/******************************************************************************
|
||||
* function: imsm_create_metadata_update_for_migration()
|
||||
* Creates update for IMSM array.
|
||||
@@ -10023,8 +10124,23 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
|
||||
}
|
||||
break;
|
||||
case CH_ARRAY_SIZE: {
|
||||
- /* ToDo: Prepare metadata update here
|
||||
- */
|
||||
+ struct imsm_update_size_change *u = NULL;
|
||||
+ int len =
|
||||
+ imsm_create_metadata_update_for_size_change(
|
||||
+ st, &geo, &u);
|
||||
+ if (len < 1) {
|
||||
+ dprintf("imsm: "
|
||||
+ "Cannot prepare update\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ ret_val = 0;
|
||||
+ /* update metadata locally */
|
||||
+ imsm_update_metadata_locally(st, u, len);
|
||||
+ /* and possibly remotely */
|
||||
+ if (st->update_tail)
|
||||
+ append_metadata_update(st, u, len);
|
||||
+ else
|
||||
+ free(u);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,129 +0,0 @@
|
||||
From 54397ed97af065b1e3a12d6beab09bc05a07a9d0 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:51:58 +0200
|
||||
Subject: [PATCH 04/14] imsm: Execute size change for external metatdata
|
||||
|
||||
For external metatdata ioctl doesn't set new size. Set new size using sysfs.
|
||||
Put code for size change in to function to re-use the same code as during
|
||||
On-line Capacity Expansion
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
Grow.c | 78 ++++++++++++++++++++++++++++++++++++++-------------------------
|
||||
1 files changed, 47 insertions(+), 31 deletions(-)
|
||||
|
||||
diff --git a/Grow.c b/Grow.c
|
||||
index e3ef8d4..5fd44aa 100644
|
||||
--- a/Grow.c
|
||||
+++ b/Grow.c
|
||||
@@ -1386,6 +1386,44 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+static int set_array_size(struct supertype *st, struct mdinfo *sra,
|
||||
+ char *text_version)
|
||||
+{
|
||||
+ struct mdinfo *info;
|
||||
+ char *subarray;
|
||||
+ int ret_val = -1;
|
||||
+
|
||||
+ if ((st == NULL) || (sra == NULL))
|
||||
+ return ret_val;
|
||||
+
|
||||
+ if (text_version == NULL)
|
||||
+ text_version = sra->text_version;
|
||||
+ subarray = strchr(text_version+1, '/')+1;
|
||||
+ info = st->ss->container_content(st, subarray);
|
||||
+ if (info) {
|
||||
+ unsigned long long current_size = 0;
|
||||
+ unsigned long long new_size =
|
||||
+ info->custom_array_size/2;
|
||||
+
|
||||
+ if (sysfs_get_ll(sra, NULL, "array_size", ¤t_size) == 0 &&
|
||||
+ new_size > current_size) {
|
||||
+ if (sysfs_set_num(sra, NULL, "array_size", new_size)
|
||||
+ < 0)
|
||||
+ dprintf("Error: Cannot set array size");
|
||||
+ else {
|
||||
+ ret_val = 0;
|
||||
+ dprintf("Array size changed");
|
||||
+ }
|
||||
+ dprintf(" from %llu to %llu.\n",
|
||||
+ current_size, new_size);
|
||||
+ }
|
||||
+ sysfs_free(info);
|
||||
+ } else
|
||||
+ dprintf("Error: set_array_size(): info pointer in NULL\n");
|
||||
+
|
||||
+ return ret_val;
|
||||
+}
|
||||
+
|
||||
static int reshape_array(char *container, int fd, char *devname,
|
||||
struct supertype *st, struct mdinfo *info,
|
||||
int force, struct mddev_dev *devlist,
|
||||
@@ -1636,7 +1674,6 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
"2TB per device\n");
|
||||
size = min_csize;
|
||||
}
|
||||
-
|
||||
array.size = size;
|
||||
if (array.size != size) {
|
||||
/* got truncated to 32bit, write to
|
||||
@@ -1647,8 +1684,14 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
|
||||
"component_size", size);
|
||||
else
|
||||
rv = -1;
|
||||
- } else
|
||||
+ } else {
|
||||
rv = ioctl(fd, SET_ARRAY_INFO, &array);
|
||||
+ /* manage array size when it is managed externally
|
||||
+ */
|
||||
+ if ((rv == 0) && st->ss->external)
|
||||
+ rv = set_array_size(st, sra, sra->text_version);
|
||||
+ }
|
||||
+
|
||||
if (rv != 0) {
|
||||
int err = errno;
|
||||
|
||||
@@ -2507,35 +2550,8 @@ started:
|
||||
*/
|
||||
if (reshape.before.data_disks !=
|
||||
reshape.after.data_disks &&
|
||||
- info->custom_array_size) {
|
||||
- struct mdinfo *info2;
|
||||
- char *subarray = strchr(info->text_version+1, '/')+1;
|
||||
-
|
||||
- info2 = st->ss->container_content(st, subarray);
|
||||
- if (info2) {
|
||||
- unsigned long long current_size = 0;
|
||||
- unsigned long long new_size =
|
||||
- info2->custom_array_size/2;
|
||||
-
|
||||
- if (sysfs_get_ll(sra,
|
||||
- NULL,
|
||||
- "array_size",
|
||||
- ¤t_size) == 0 &&
|
||||
- new_size > current_size) {
|
||||
- if (sysfs_set_num(sra, NULL,
|
||||
- "array_size", new_size)
|
||||
- < 0)
|
||||
- dprintf("Error: Cannot"
|
||||
- " set array size");
|
||||
- else
|
||||
- dprintf("Array size "
|
||||
- "changed");
|
||||
- dprintf(" from %llu to %llu.\n",
|
||||
- current_size, new_size);
|
||||
- }
|
||||
- sysfs_free(info2);
|
||||
- }
|
||||
- }
|
||||
+ info->custom_array_size)
|
||||
+ set_array_size(st, info, info->text_version);
|
||||
|
||||
if (info->new_level != reshape.level) {
|
||||
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,103 +0,0 @@
|
||||
From 7abc98717c32d08a2aab366e79c12a91573fb538 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:51:56 +0200
|
||||
Subject: [PATCH 02/14] imsm: FIX: Add volume size expand support to
|
||||
imsm_analyze_change()
|
||||
|
||||
Patch adds ability to function imsm_analyze_change() for:
|
||||
1. Detect size change request for volume operation.
|
||||
2. Check and correct size for change.
|
||||
3. Set new change kind to CH_ARRAY_SIZE
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 files changed, 51 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 5f86539..2e6a899 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -405,6 +405,7 @@ struct extent {
|
||||
enum imsm_reshape_type {
|
||||
CH_TAKEOVER,
|
||||
CH_MIGRATION,
|
||||
+ CH_ARRAY_SIZE,
|
||||
};
|
||||
|
||||
/* definition of messages passed to imsm_process_update */
|
||||
@@ -9726,6 +9727,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
int devNumChange = 0;
|
||||
/* imsm compatible layout value for array geometry verification */
|
||||
int imsm_layout = -1;
|
||||
+ int data_disks;
|
||||
+ struct imsm_dev *dev;
|
||||
+ struct intel_super *super;
|
||||
+ long long current_size;
|
||||
|
||||
getinfo_super_imsm_volume(st, &info, NULL);
|
||||
if ((geo->level != info.array.level) &&
|
||||
@@ -9807,6 +9812,47 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
geo->chunksize = info.array.chunk_size;
|
||||
|
||||
chunk = geo->chunksize / 1024;
|
||||
+
|
||||
+ super = st->sb;
|
||||
+ dev = get_imsm_dev(super, super->current_vol);
|
||||
+ data_disks = imsm_num_data_members(dev , MAP_0);
|
||||
+ /* compute current size in K per disk member
|
||||
+ */
|
||||
+ current_size = info.custom_array_size / 2 / data_disks;
|
||||
+
|
||||
+ if ((current_size != geo->size) && (geo->size > 0)) {
|
||||
+ if (change != -1) {
|
||||
+ fprintf(stderr,
|
||||
+ Name " Error. Size change should be the only "
|
||||
+ "one at a time.\n");
|
||||
+ change = -1;
|
||||
+ goto analyse_change_exit;
|
||||
+ }
|
||||
+ if ((super->current_vol + 1) != super->anchor->num_raid_devs) {
|
||||
+ fprintf(stderr,
|
||||
+ Name " Error. The last volume in container "
|
||||
+ "can be expanded only (%i/%i).\n",
|
||||
+ super->current_vol, st->devnum);
|
||||
+ goto analyse_change_exit;
|
||||
+ }
|
||||
+ geo->size *= 2;
|
||||
+ /* round size due to metadata compatibility
|
||||
+ */
|
||||
+ geo->size = (geo->size >> SECT_PER_MB_SHIFT)
|
||||
+ << SECT_PER_MB_SHIFT;
|
||||
+ dprintf("Prepare update for size change to %llu\n", geo->size );
|
||||
+ if (current_size >= geo->size) {
|
||||
+ fprintf(stderr,
|
||||
+ Name " Error. Size expanssion is supported only"
|
||||
+ " (current size is %llu, requested size "
|
||||
+ "/rounded/ is %llu).\n",
|
||||
+ current_size, geo->size);
|
||||
+ goto analyse_change_exit;
|
||||
+ }
|
||||
+ geo->size *= data_disks;
|
||||
+ geo->raid_disks = dev->vol.map->num_members;
|
||||
+ change = CH_ARRAY_SIZE;
|
||||
+ }
|
||||
if (!validate_geometry_imsm(st,
|
||||
geo->level,
|
||||
imsm_layout,
|
||||
@@ -9976,6 +10022,11 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
|
||||
free(u);
|
||||
}
|
||||
break;
|
||||
+ case CH_ARRAY_SIZE: {
|
||||
+ /* ToDo: Prepare metadata update here
|
||||
+ */
|
||||
+ }
|
||||
+ break;
|
||||
default:
|
||||
ret_val = 1;
|
||||
}
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,32 +0,0 @@
|
||||
From e1742195ff3dba97929f81af6b7633481a23397a Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Tue, 7 Feb 2012 15:03:51 +0100
|
||||
Subject: [PATCH 07/12] imsm: FIX: Chunk size migration problem
|
||||
|
||||
When chunk size migration occurs (e.g. 128k->4k) first checkpoint cannot
|
||||
be set in md due to too small step. Correct migration record initialization
|
||||
to allow whole copy area usage and increase migration checkpoint step.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 3 ++-
|
||||
1 files changed, 2 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 19a2c84..f5762d8 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -8913,7 +8913,8 @@ void init_migr_record_imsm(struct supertype *st, struct imsm_dev *dev,
|
||||
|
||||
migr_rec->dest_depth_per_unit = GEN_MIGR_AREA_SIZE /
|
||||
max(map_dest->blocks_per_strip, map_src->blocks_per_strip);
|
||||
- migr_rec->dest_depth_per_unit *= map_dest->blocks_per_strip;
|
||||
+ migr_rec->dest_depth_per_unit *=
|
||||
+ max(map_dest->blocks_per_strip, map_src->blocks_per_strip);
|
||||
new_data_disks = imsm_num_data_members(dev, MAP_0);
|
||||
migr_rec->blocks_per_unit =
|
||||
__cpu_to_le32(migr_rec->dest_depth_per_unit * new_data_disks);
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,88 +0,0 @@
|
||||
From 51d83f5d119f9b727cc715b22b1625332bd0130b Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Thu, 9 Feb 2012 12:37:04 +1100
|
||||
Subject: [PATCH 10/12] imsm: FIX: Clear migration record when migration
|
||||
switches to next volume.
|
||||
|
||||
When OLCE is in progress, checkpoint steps are getting bigger due to added space during process.
|
||||
When mdadm fails after saving "max" to sync_max, mdmon will monitor process
|
||||
and switch reshape to next array. At this moment we have got information
|
||||
inconsistency between metadata and migration record.
|
||||
To avoid this, clear migration record by mdmon /exception from the rule
|
||||
that migration record is maintained by mdadm/ when reshape switches
|
||||
to next array.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 19 ++++++++++++++++---
|
||||
1 files changed, 16 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 5f451f3..958edb5 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -353,6 +353,9 @@ struct intel_super {
|
||||
void *migr_rec_buf; /* buffer for I/O operations */
|
||||
struct migr_record *migr_rec; /* migration record */
|
||||
};
|
||||
+ int clean_migration_record_by_mdmon; /* when reshape is switched to next
|
||||
+ array, it indicates that mdmon is allowed to clean migration
|
||||
+ record */
|
||||
size_t len; /* size of the 'buf' allocation */
|
||||
void *next_buf; /* for realloc'ing buf from the manager */
|
||||
size_t next_len;
|
||||
@@ -3465,6 +3468,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
|
||||
free(super->buf);
|
||||
return 2;
|
||||
}
|
||||
+ super->clean_migration_record_by_mdmon = 0;
|
||||
|
||||
if (!sectors) {
|
||||
check_sum = __gen_imsm_checksum(super->anchor);
|
||||
@@ -5029,6 +5033,10 @@ static int write_super_imsm(struct supertype *st, int doclose)
|
||||
sum = __gen_imsm_checksum(mpb);
|
||||
mpb->check_sum = __cpu_to_le32(sum);
|
||||
|
||||
+ if (super->clean_migration_record_by_mdmon) {
|
||||
+ clear_migration_record = 1;
|
||||
+ super->clean_migration_record_by_mdmon = 0;
|
||||
+ }
|
||||
if (clear_migration_record)
|
||||
memset(super->migr_rec_buf, 0, MIGR_REC_BUF_SIZE);
|
||||
|
||||
@@ -5036,9 +5044,6 @@ static int write_super_imsm(struct supertype *st, int doclose)
|
||||
for (d = super->disks; d ; d = d->next) {
|
||||
if (d->index < 0 || is_failed(&d->disk))
|
||||
continue;
|
||||
- if (store_imsm_mpb(d->fd, mpb))
|
||||
- fprintf(stderr, "%s: failed for device %d:%d (fd: %d)%s\n",
|
||||
- __func__, d->major, d->minor, d->fd, strerror(errno));
|
||||
|
||||
if (clear_migration_record) {
|
||||
unsigned long long dsize;
|
||||
@@ -5050,6 +5055,13 @@ static int write_super_imsm(struct supertype *st, int doclose)
|
||||
perror("Write migr_rec failed");
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (store_imsm_mpb(d->fd, mpb))
|
||||
+ fprintf(stderr,
|
||||
+ "%s: failed for device %d:%d (fd: %d)%s\n",
|
||||
+ __func__, d->major, d->minor,
|
||||
+ d->fd, strerror(errno));
|
||||
+
|
||||
if (doclose) {
|
||||
close(d->fd);
|
||||
d->fd = -1;
|
||||
@@ -6928,6 +6940,7 @@ static void imsm_progress_container_reshape(struct intel_super *super)
|
||||
map2->num_members = prev_num_members;
|
||||
|
||||
imsm_set_array_size(dev);
|
||||
+ super->clean_migration_record_by_mdmon = 1;
|
||||
super->updates_pending++;
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,126 +0,0 @@
|
||||
From c41e00b2e68aed0ab9d41f70a3e119d86a92cf29 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:06 +0200
|
||||
Subject: [PATCH 12/14] imsm: FIX: Component size alignment check
|
||||
|
||||
Put currently existing code for alignment correction in to function
|
||||
imsm_component_size_aligment_check() and use it for align component size
|
||||
to chunk size during volume size expansion operation.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 68 ++++++++++++++++++++++++++++++++++++++++----------------
|
||||
1 files changed, 48 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 1f47234..9685726 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -2454,6 +2454,32 @@ int imsm_reshape_blocks_arrays_changes(struct intel_super *super)
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
+static unsigned long long imsm_component_size_aligment_check(int level,
|
||||
+ int chunk_size,
|
||||
+ unsigned long long component_size)
|
||||
+{
|
||||
+ unsigned int component_size_alligment;
|
||||
+
|
||||
+ /* check component size aligment
|
||||
+ */
|
||||
+ component_size_alligment = component_size % (chunk_size/512);
|
||||
+
|
||||
+ dprintf("imsm_component_size_aligment_check(Level: %i, "
|
||||
+ "chunk_size = %i, component_size = %llu), "
|
||||
+ "component_size_alligment = %u\n",
|
||||
+ level, chunk_size, component_size,
|
||||
+ component_size_alligment);
|
||||
+
|
||||
+ if (component_size_alligment && (level != 1) && (level != UnSet)) {
|
||||
+ dprintf("imsm: reported component size alligned from %llu ",
|
||||
+ component_size);
|
||||
+ component_size -= component_size_alligment;
|
||||
+ dprintf("to %llu (%i).\n",
|
||||
+ component_size, component_size_alligment);
|
||||
+ }
|
||||
+
|
||||
+ return component_size;
|
||||
+}
|
||||
|
||||
static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info, char *dmap)
|
||||
{
|
||||
@@ -2465,7 +2491,6 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
|
||||
struct imsm_map *map_to_analyse = map;
|
||||
struct dl *dl;
|
||||
char *devname;
|
||||
- unsigned int component_size_alligment;
|
||||
int map_disks = info->array.raid_disks;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
@@ -2548,19 +2573,10 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
|
||||
info->data_offset = pba_of_lba0(map_to_analyse);
|
||||
info->component_size = blocks_per_member(map_to_analyse);
|
||||
|
||||
- /* check component size aligment
|
||||
- */
|
||||
- component_size_alligment =
|
||||
- info->component_size % (info->array.chunk_size/512);
|
||||
-
|
||||
- if (component_size_alligment &&
|
||||
- (info->array.level != 1) && (info->array.level != UnSet)) {
|
||||
- dprintf("imsm: reported component size alligned from %llu ",
|
||||
- info->component_size);
|
||||
- info->component_size -= component_size_alligment;
|
||||
- dprintf("to %llu (%i).\n",
|
||||
- info->component_size, component_size_alligment);
|
||||
- }
|
||||
+ info->component_size = imsm_component_size_aligment_check(
|
||||
+ info->array.level,
|
||||
+ info->array.chunk_size,
|
||||
+ info->component_size);
|
||||
|
||||
memset(info->uuid, 0, sizeof(info->uuid));
|
||||
info->recovery_start = MaxSector;
|
||||
@@ -9949,9 +9965,18 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
super = st->sb;
|
||||
dev = get_imsm_dev(super, super->current_vol);
|
||||
data_disks = imsm_num_data_members(dev , MAP_0);
|
||||
- /* compute current size in K per disk member
|
||||
+ /* compute current size per disk member
|
||||
*/
|
||||
- current_size = info.custom_array_size / 2 / data_disks;
|
||||
+ current_size = info.custom_array_size / data_disks;
|
||||
+
|
||||
+ if (geo->size > 0) {
|
||||
+ /* align component size
|
||||
+ */
|
||||
+ geo->size = imsm_component_size_aligment_check(
|
||||
+ get_imsm_raid_level(dev->vol.map),
|
||||
+ chunk * 1024,
|
||||
+ geo->size * 2);
|
||||
+ }
|
||||
|
||||
if ((current_size != geo->size) && (geo->size >= 0)) {
|
||||
if (change != -1) {
|
||||
@@ -9984,10 +10009,13 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
}
|
||||
geo->size = freesize + current_size;
|
||||
|
||||
- /* round to chunk size */
|
||||
- geo->size &= ~(chunk-1);
|
||||
- } else
|
||||
- geo->size *= 2;
|
||||
+ /* align component size
|
||||
+ */
|
||||
+ geo->size = imsm_component_size_aligment_check(
|
||||
+ get_imsm_raid_level(dev->vol.map),
|
||||
+ chunk * 1024,
|
||||
+ geo->size);
|
||||
+ }
|
||||
|
||||
if ((direction == ROLLBACK_METADATA_CHANGES)) {
|
||||
/* accept size for rollback only
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,44 +0,0 @@
|
||||
From d2bde6d3aa9468ddf0965f09907a666b92186e42 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Tue, 7 Feb 2012 15:03:11 +0100
|
||||
Subject: [PATCH 02/12] imsm: FIX: No new missing disks are allowed during
|
||||
general migration
|
||||
|
||||
When during incremental assembly general migration is in progress,
|
||||
starting degraded array causes that no more disks (even present)
|
||||
can be added later as array is already started.
|
||||
|
||||
Request all previously present disks during general migration for assembly.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 12 +++++++++++-
|
||||
1 files changed, 11 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index eba11d6..17034bb 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -2683,7 +2683,17 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
|
||||
enough = 0;
|
||||
else /* we're normal, or already degraded */
|
||||
enough = 1;
|
||||
-
|
||||
+ if (is_gen_migration(dev) && missing) {
|
||||
+ /* during general migration we need all disks
|
||||
+ * that process is running on.
|
||||
+ * No new missing disk is allowed.
|
||||
+ */
|
||||
+ max_enough = -1;
|
||||
+ enough = -1;
|
||||
+ /* no more checks necessary
|
||||
+ */
|
||||
+ break;
|
||||
+ }
|
||||
/* in the missing/failed disk case check to see
|
||||
* if at least one array is runnable
|
||||
*/
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,130 +0,0 @@
|
||||
From fbf3d20214537e5e4bf6fb04f191418a58e88463 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:00 +0200
|
||||
Subject: [PATCH 06/14] imsm: FIX: Support metadata changes rollback
|
||||
|
||||
Add metadata rollback specific code for imsm.
|
||||
Let reshape_super() ability to differentiate metadata apply and rollback
|
||||
actions.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 56 ++++++++++++++++++++++++++++++++++++++------------------
|
||||
1 files changed, 38 insertions(+), 18 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 32a53d1..49e383f 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -9470,7 +9470,8 @@ static int imsm_find_array_minor_by_subdev(int subdev, int container, int *minor
|
||||
|
||||
static int imsm_reshape_is_allowed_on_container(struct supertype *st,
|
||||
struct geo_params *geo,
|
||||
- int *old_raid_disks)
|
||||
+ int *old_raid_disks,
|
||||
+ int direction)
|
||||
{
|
||||
/* currently we only support increasing the number of devices
|
||||
* for a container. This increases the number of device for each
|
||||
@@ -9494,6 +9495,12 @@ static int imsm_reshape_is_allowed_on_container(struct supertype *st,
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
+ if (direction == ROLLBACK_METADATA_CHANGES) {
|
||||
+ dprintf("imsm: Metadata changes rollback is not supported for "
|
||||
+ "container operation.\n");
|
||||
+ return ret_val;
|
||||
+ }
|
||||
+
|
||||
info = container_content_imsm(st, NULL);
|
||||
for (member = info; member; member = member->next) {
|
||||
int result;
|
||||
@@ -9814,11 +9821,13 @@ static void imsm_update_metadata_locally(struct supertype *st,
|
||||
* Function: imsm_analyze_change
|
||||
* Description: Function analyze change for single volume
|
||||
* and validate if transition is supported
|
||||
-* Parameters: Geometry parameters, supertype structure
|
||||
+* Parameters: Geometry parameters, supertype structure,
|
||||
+* metadata change direction (apply/rollback)
|
||||
* Returns: Operation type code on success, -1 if fail
|
||||
****************************************************************************/
|
||||
enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
- struct geo_params *geo)
|
||||
+ struct geo_params *geo,
|
||||
+ int direction)
|
||||
{
|
||||
struct mdinfo info;
|
||||
int change = -1;
|
||||
@@ -9937,18 +9946,24 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
goto analyse_change_exit;
|
||||
}
|
||||
geo->size *= 2;
|
||||
- /* round size due to metadata compatibility
|
||||
- */
|
||||
- geo->size = (geo->size >> SECT_PER_MB_SHIFT)
|
||||
- << SECT_PER_MB_SHIFT;
|
||||
- dprintf("Prepare update for size change to %llu\n", geo->size );
|
||||
- if (current_size >= geo->size) {
|
||||
- fprintf(stderr,
|
||||
- Name " Error. Size expanssion is supported only"
|
||||
- " (current size is %llu, requested size "
|
||||
- "/rounded/ is %llu).\n",
|
||||
- current_size, geo->size);
|
||||
- goto analyse_change_exit;
|
||||
+ if ((direction == ROLLBACK_METADATA_CHANGES)) {
|
||||
+ /* accept size for rollback only
|
||||
+ */
|
||||
+ } else {
|
||||
+ /* round size due to metadata compatibility
|
||||
+ */
|
||||
+ geo->size = (geo->size >> SECT_PER_MB_SHIFT)
|
||||
+ << SECT_PER_MB_SHIFT;
|
||||
+ dprintf("Prepare update for size change to %llu\n",
|
||||
+ geo->size );
|
||||
+ if (current_size >= geo->size) {
|
||||
+ fprintf(stderr,
|
||||
+ Name " Error. Size expanssion is "
|
||||
+ "supported only (current size is %llu, "
|
||||
+ "requested size /rounded/ is %llu).\n",
|
||||
+ current_size, geo->size);
|
||||
+ goto analyse_change_exit;
|
||||
+ }
|
||||
}
|
||||
geo->size *= data_disks;
|
||||
geo->raid_disks = dev->vol.map->num_members;
|
||||
@@ -9978,7 +9993,12 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
}
|
||||
|
||||
analyse_change_exit:
|
||||
-
|
||||
+ if ((direction == ROLLBACK_METADATA_CHANGES) &&
|
||||
+ ((change == CH_MIGRATION) || (change == CH_TAKEOVER))) {
|
||||
+ dprintf("imsm: Metadata changes rollback is not supported for "
|
||||
+ "migration and takeover operations.\n");
|
||||
+ change = -1;
|
||||
+ }
|
||||
return change;
|
||||
}
|
||||
|
||||
@@ -10049,7 +10069,7 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
|
||||
int old_raid_disks = 0;
|
||||
|
||||
if (imsm_reshape_is_allowed_on_container(
|
||||
- st, &geo, &old_raid_disks)) {
|
||||
+ st, &geo, &old_raid_disks, direction)) {
|
||||
struct imsm_update_reshape *u = NULL;
|
||||
int len;
|
||||
|
||||
@@ -10098,7 +10118,7 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
|
||||
goto exit_imsm_reshape_super;
|
||||
}
|
||||
super->current_vol = dev->index;
|
||||
- change = imsm_analyze_change(st, &geo);
|
||||
+ change = imsm_analyze_change(st, &geo, direction);
|
||||
switch (change) {
|
||||
case CH_TAKEOVER:
|
||||
ret_val = imsm_takeover(st, &geo);
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,36 +0,0 @@
|
||||
From 36fd8ccc0e755042e3983a2bd02523461b5f8307 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:51:55 +0200
|
||||
Subject: [PATCH 01/14] imsm: FIX: Update function imsm_num_data_members() for
|
||||
Raid1/10
|
||||
|
||||
Function imsm_num_data_members() returns wrong value for raid 1 and 10.
|
||||
It returns all data member but it should return number of unique data
|
||||
members (excluding mirror devices)
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 4 +++-
|
||||
1 files changed, 3 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 088e6bc..5f86539 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -2032,9 +2032,11 @@ static __u8 imsm_num_data_members(struct imsm_dev *dev, int second_map)
|
||||
|
||||
switch (get_imsm_raid_level(map)) {
|
||||
case 0:
|
||||
+ return map->num_members;
|
||||
+ break;
|
||||
case 1:
|
||||
case 10:
|
||||
- return map->num_members;
|
||||
+ return map->num_members/2;
|
||||
case 5:
|
||||
return map->num_members - 1;
|
||||
default:
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,29 +0,0 @@
|
||||
From bf5cf7c705f292a070746c83f9dd00d7662f458d Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Tue, 7 Feb 2012 15:03:27 +0100
|
||||
Subject: [PATCH 04/12] imsm: FIX: imsm_get_allowed_degradation() doesn't
|
||||
count degradation for raid1
|
||||
|
||||
Missing case raid1 added to function.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 1 +
|
||||
1 files changed, 1 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 17034bb..19a2c84 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -8771,6 +8771,7 @@ static int imsm_get_allowed_degradation(int level, int raid_disks,
|
||||
struct imsm_dev *dev)
|
||||
{
|
||||
switch (level) {
|
||||
+ case 1:
|
||||
case 10:{
|
||||
int ret_val = 0;
|
||||
struct imsm_map *map;
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,43 +0,0 @@
|
||||
From 6a75c8ca79b4cf89a5d1ac24b484b75e8a7e9fb4 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Thu, 9 Feb 2012 12:36:42 +1100
|
||||
Subject: [PATCH 09/12] imsm: FIX: use md position to reshape restart
|
||||
|
||||
When reshape is broken it can occur that metadata is not saved properly.
|
||||
This can cause that reshape process is farther in md than metadata states.
|
||||
|
||||
On restart save checkpoint to store current position /probably farther/
|
||||
that can be read from md.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 12 ++++++++++++
|
||||
1 files changed, 12 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index f5762d8..5f451f3 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -10067,6 +10067,18 @@ static int imsm_manage_reshape(
|
||||
"are present in copy area.\n");
|
||||
goto abort;
|
||||
}
|
||||
+ /* Save checkpoint to update migration record for current
|
||||
+ * reshape position (in md). It can be farther than current
|
||||
+ * reshape position in metadata.
|
||||
+ */
|
||||
+ if (save_checkpoint_imsm(st, sra, UNIT_SRC_NORMAL) == 1) {
|
||||
+ /* ignore error == 2, this can mean end of reshape here
|
||||
+ */
|
||||
+ dprintf("imsm: Cannot write checkpoint to "
|
||||
+ "migration record (UNIT_SRC_NORMAL, "
|
||||
+ "initial save)\n");
|
||||
+ goto abort;
|
||||
+ }
|
||||
}
|
||||
|
||||
/* size for data */
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,60 +0,0 @@
|
||||
From b130333f39734eed08d38d6c36025fa4d618bc52 Mon Sep 17 00:00:00 2001
|
||||
From: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Date: Fri, 13 Apr 2012 16:52:05 +0200
|
||||
Subject: [PATCH 11/14] imsm: Support setting max size for size change
|
||||
operation
|
||||
|
||||
Add support for setting max size for size change operation using
|
||||
imsm_get_free_size() function for computing maximum available space.
|
||||
|
||||
Signed-off-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 24 ++++++++++++++++++++++--
|
||||
1 files changed, 22 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 7cc0ed5..1f47234 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -9953,7 +9953,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
*/
|
||||
current_size = info.custom_array_size / 2 / data_disks;
|
||||
|
||||
- if ((current_size != geo->size) && (geo->size > 0)) {
|
||||
+ if ((current_size != geo->size) && (geo->size >= 0)) {
|
||||
if (change != -1) {
|
||||
fprintf(stderr,
|
||||
Name " Error. Size change should be the only "
|
||||
@@ -9968,7 +9968,27 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
|
||||
super->current_vol, st->devnum);
|
||||
goto analyse_change_exit;
|
||||
}
|
||||
- geo->size *= 2;
|
||||
+ if (geo->size == 0) {
|
||||
+ /* requested size change to the maximum available size
|
||||
+ */
|
||||
+ unsigned long long freesize;
|
||||
+ int rv;
|
||||
+
|
||||
+ rv = imsm_get_free_size(st, dev->vol.map->num_members,
|
||||
+ 0, chunk, &freesize);
|
||||
+ if (rv == 0) {
|
||||
+ fprintf(stderr, Name " Error. Cannot find "
|
||||
+ "maximum available space.\n");
|
||||
+ change = -1;
|
||||
+ goto analyse_change_exit;
|
||||
+ }
|
||||
+ geo->size = freesize + current_size;
|
||||
+
|
||||
+ /* round to chunk size */
|
||||
+ geo->size &= ~(chunk-1);
|
||||
+ } else
|
||||
+ geo->size *= 2;
|
||||
+
|
||||
if ((direction == ROLLBACK_METADATA_CHANGES)) {
|
||||
/* accept size for rollback only
|
||||
*/
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,484 +0,0 @@
|
||||
From 5551b113dc18a6275fb04c7e7e3b76c656926e0a Mon Sep 17 00:00:00 2001
|
||||
From: "Czarnowska, Anna" <anna.czarnowska@intel.com>
|
||||
Date: Mon, 2 Apr 2012 10:15:03 +1000
|
||||
Subject: [PATCH 1/7] imsm: avoid overflows for disks over 1TB
|
||||
|
||||
Calculating array_blocks using info->size causes error on activation of
|
||||
volume using disks over 1 TB. unsigned long long size parameter
|
||||
is used instead.
|
||||
|
||||
total_blocks, pba_of_lba0, blocks_per_member and num_data_stripes overflow
|
||||
when using disks over 2TB.
|
||||
|
||||
Part of fillers in metadata is used to contain hi bits of the numbers
|
||||
that are likely to go over 32 bit limit.
|
||||
Functions are added to get and set such fields as the hi bits are not
|
||||
adjacent with low bits in the structures.
|
||||
|
||||
Acked-by: Dan Williams <dan.j.williams@intel.com>
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 198 +++++++++++++++++++++++++++++++++++++-------------------
|
||||
1 files changed, 131 insertions(+), 67 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index a351b60..c65d39b 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -95,15 +95,16 @@
|
||||
#define IMSM_MAX_DEVICES 255
|
||||
struct imsm_disk {
|
||||
__u8 serial[MAX_RAID_SERIAL_LEN];/* 0xD8 - 0xE7 ascii serial number */
|
||||
- __u32 total_blocks; /* 0xE8 - 0xEB total blocks */
|
||||
+ __u32 total_blocks_lo; /* 0xE8 - 0xEB total blocks lo */
|
||||
__u32 scsi_id; /* 0xEC - 0xEF scsi ID */
|
||||
#define SPARE_DISK __cpu_to_le32(0x01) /* Spare */
|
||||
#define CONFIGURED_DISK __cpu_to_le32(0x02) /* Member of some RaidDev */
|
||||
#define FAILED_DISK __cpu_to_le32(0x04) /* Permanent failure */
|
||||
__u32 status; /* 0xF0 - 0xF3 */
|
||||
__u32 owner_cfg_num; /* which config 0,1,2... owns this disk */
|
||||
-#define IMSM_DISK_FILLERS 4
|
||||
- __u32 filler[IMSM_DISK_FILLERS]; /* 0xF4 - 0x107 MPB_DISK_FILLERS for future expansion */
|
||||
+ __u32 total_blocks_hi; /* 0xF4 - 0xF5 total blocks hi */
|
||||
+#define IMSM_DISK_FILLERS 3
|
||||
+ __u32 filler[IMSM_DISK_FILLERS]; /* 0xF5 - 0x107 MPB_DISK_FILLERS for future expansion */
|
||||
};
|
||||
|
||||
/* map selector for map managment
|
||||
@@ -114,9 +115,9 @@ struct imsm_disk {
|
||||
|
||||
/* RAID map configuration infos. */
|
||||
struct imsm_map {
|
||||
- __u32 pba_of_lba0; /* start address of partition */
|
||||
- __u32 blocks_per_member;/* blocks per member */
|
||||
- __u32 num_data_stripes; /* number of data stripes */
|
||||
+ __u32 pba_of_lba0_lo; /* start address of partition */
|
||||
+ __u32 blocks_per_member_lo;/* blocks per member */
|
||||
+ __u32 num_data_stripes_lo; /* number of data stripes */
|
||||
__u16 blocks_per_strip;
|
||||
__u8 map_state; /* Normal, Uninitialized, Degraded, Failed */
|
||||
#define IMSM_T_STATE_NORMAL 0
|
||||
@@ -131,7 +132,10 @@ struct imsm_map {
|
||||
__u8 num_domains; /* number of parity domains */
|
||||
__u8 failed_disk_num; /* valid only when state is degraded */
|
||||
__u8 ddf;
|
||||
- __u32 filler[7]; /* expansion area */
|
||||
+ __u32 pba_of_lba0_hi;
|
||||
+ __u32 blocks_per_member_hi;
|
||||
+ __u32 num_data_stripes_hi;
|
||||
+ __u32 filler[4]; /* expansion area */
|
||||
#define IMSM_ORD_REBUILD (1 << 24)
|
||||
__u32 disk_ord_tbl[1]; /* disk_ord_tbl[num_members],
|
||||
* top byte contains some flags
|
||||
@@ -361,7 +365,7 @@ struct intel_super {
|
||||
size_t next_len;
|
||||
int updates_pending; /* count of pending updates for mdmon */
|
||||
int current_vol; /* index of raid device undergoing creation */
|
||||
- __u32 create_offset; /* common start for 'current_vol' */
|
||||
+ unsigned long long create_offset; /* common start for 'current_vol' */
|
||||
__u32 random; /* random data for seeding new family numbers */
|
||||
struct intel_dev *devlist;
|
||||
struct dl {
|
||||
@@ -870,6 +874,69 @@ static int count_memberships(struct dl *dl, struct intel_super *super)
|
||||
|
||||
static __u32 imsm_min_reserved_sectors(struct intel_super *super);
|
||||
|
||||
+static int split_ull(unsigned long long n, __u32 *lo, __u32 *hi)
|
||||
+{
|
||||
+ if (lo == 0 || hi == 0)
|
||||
+ return 1;
|
||||
+ *lo = __le32_to_cpu((unsigned)n);
|
||||
+ *hi = __le32_to_cpu((unsigned)(n >> 32));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static unsigned long long join_u32(__u32 lo, __u32 hi)
|
||||
+{
|
||||
+ return (unsigned long long)__le32_to_cpu(lo) |
|
||||
+ (((unsigned long long)__le32_to_cpu(hi)) << 32);
|
||||
+}
|
||||
+
|
||||
+static unsigned long long total_blocks(struct imsm_disk *disk)
|
||||
+{
|
||||
+ if (disk == NULL)
|
||||
+ return 0;
|
||||
+ return join_u32(disk->total_blocks_lo, disk->total_blocks_hi);
|
||||
+}
|
||||
+
|
||||
+static unsigned long long pba_of_lba0(struct imsm_map *map)
|
||||
+{
|
||||
+ if (map == NULL)
|
||||
+ return 0;
|
||||
+ return join_u32(map->pba_of_lba0_lo, map->pba_of_lba0_hi);
|
||||
+}
|
||||
+
|
||||
+static unsigned long long blocks_per_member(struct imsm_map *map)
|
||||
+{
|
||||
+ if (map == NULL)
|
||||
+ return 0;
|
||||
+ return join_u32(map->blocks_per_member_lo, map->blocks_per_member_hi);
|
||||
+}
|
||||
+
|
||||
+static unsigned long long num_data_stripes(struct imsm_map *map)
|
||||
+{
|
||||
+ if (map == NULL)
|
||||
+ return 0;
|
||||
+ return join_u32(map->num_data_stripes_lo, map->num_data_stripes_hi);
|
||||
+}
|
||||
+
|
||||
+static void set_total_blocks(struct imsm_disk *disk, unsigned long long n)
|
||||
+{
|
||||
+ split_ull(n, &disk->total_blocks_lo, &disk->total_blocks_hi);
|
||||
+}
|
||||
+
|
||||
+static void set_pba_of_lba0(struct imsm_map *map, unsigned long long n)
|
||||
+{
|
||||
+ split_ull(n, &map->pba_of_lba0_lo, &map->pba_of_lba0_hi);
|
||||
+}
|
||||
+
|
||||
+static void set_blocks_per_member(struct imsm_map *map, unsigned long long n)
|
||||
+{
|
||||
+ split_ull(n, &map->blocks_per_member_lo, &map->blocks_per_member_hi);
|
||||
+}
|
||||
+
|
||||
+static void set_num_data_stripes(struct imsm_map *map, unsigned long long n)
|
||||
+{
|
||||
+ split_ull(n, &map->num_data_stripes_lo, &map->num_data_stripes_hi);
|
||||
+}
|
||||
+
|
||||
static struct extent *get_extents(struct intel_super *super, struct dl *dl)
|
||||
{
|
||||
/* find a list of used extents on the given physical device */
|
||||
@@ -897,8 +964,8 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl)
|
||||
struct imsm_map *map = get_imsm_map(dev, MAP_0);
|
||||
|
||||
if (get_imsm_disk_slot(map, dl->index) >= 0) {
|
||||
- e->start = __le32_to_cpu(map->pba_of_lba0);
|
||||
- e->size = __le32_to_cpu(map->blocks_per_member);
|
||||
+ e->start = pba_of_lba0(map);
|
||||
+ e->size = blocks_per_member(map);
|
||||
e++;
|
||||
}
|
||||
}
|
||||
@@ -911,10 +978,9 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl)
|
||||
*/
|
||||
if (memberships) {
|
||||
struct extent *last = &rv[memberships - 1];
|
||||
- __u32 remainder;
|
||||
+ unsigned long long remainder;
|
||||
|
||||
- remainder = __le32_to_cpu(dl->disk.total_blocks) -
|
||||
- (last->start + last->size);
|
||||
+ remainder = total_blocks(&dl->disk) - (last->start + last->size);
|
||||
/* round down to 1k block to satisfy precision of the kernel
|
||||
* 'size' interface
|
||||
*/
|
||||
@@ -925,7 +991,7 @@ static struct extent *get_extents(struct intel_super *super, struct dl *dl)
|
||||
if (reservation > remainder)
|
||||
reservation = remainder;
|
||||
}
|
||||
- e->start = __le32_to_cpu(dl->disk.total_blocks) - reservation;
|
||||
+ e->start = total_blocks(&dl->disk) - reservation;
|
||||
e->size = 0;
|
||||
return rv;
|
||||
}
|
||||
@@ -954,7 +1020,7 @@ static __u32 imsm_reserved_sectors(struct intel_super *super, struct dl *dl)
|
||||
for (i = 0; e[i].size; i++)
|
||||
continue;
|
||||
|
||||
- rv = __le32_to_cpu(dl->disk.total_blocks) - e[i].start;
|
||||
+ rv = total_blocks(&dl->disk) - e[i].start;
|
||||
|
||||
free(e);
|
||||
|
||||
@@ -984,7 +1050,8 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super)
|
||||
{
|
||||
struct extent *e;
|
||||
int i;
|
||||
- __u32 min_active, remainder;
|
||||
+ unsigned long long min_active;
|
||||
+ __u32 remainder;
|
||||
__u32 rv = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
|
||||
struct dl *dl, *dl_min = NULL;
|
||||
|
||||
@@ -995,9 +1062,10 @@ static __u32 imsm_min_reserved_sectors(struct intel_super *super)
|
||||
for (dl = super->disks; dl; dl = dl->next) {
|
||||
if (dl->index < 0)
|
||||
continue;
|
||||
- if (dl->disk.total_blocks < min_active || min_active == 0) {
|
||||
+ unsigned long long blocks = total_blocks(&dl->disk);
|
||||
+ if (blocks < min_active || min_active == 0) {
|
||||
dl_min = dl;
|
||||
- min_active = dl->disk.total_blocks;
|
||||
+ min_active = blocks;
|
||||
}
|
||||
}
|
||||
if (!dl_min)
|
||||
@@ -1115,13 +1183,13 @@ static void print_imsm_dev(struct intel_super *super,
|
||||
sz += __le32_to_cpu(dev->size_low);
|
||||
printf(" Array Size : %llu%s\n", (unsigned long long)sz,
|
||||
human_size(sz * 512));
|
||||
- sz = __le32_to_cpu(map->blocks_per_member);
|
||||
+ sz = blocks_per_member(map);
|
||||
printf(" Per Dev Size : %llu%s\n", (unsigned long long)sz,
|
||||
human_size(sz * 512));
|
||||
- printf(" Sector Offset : %u\n",
|
||||
- __le32_to_cpu(map->pba_of_lba0));
|
||||
- printf(" Num Stripes : %u\n",
|
||||
- __le32_to_cpu(map->num_data_stripes));
|
||||
+ printf(" Sector Offset : %llu\n",
|
||||
+ pba_of_lba0(map));
|
||||
+ printf(" Num Stripes : %llu\n",
|
||||
+ num_data_stripes(map));
|
||||
printf(" Chunk Size : %u KiB",
|
||||
__le16_to_cpu(map->blocks_per_strip) / 2);
|
||||
if (map2)
|
||||
@@ -1182,7 +1250,7 @@ static void print_imsm_disk(struct imsm_disk *disk, int index, __u32 reserved)
|
||||
is_configured(disk) ? " active" : "",
|
||||
is_failed(disk) ? " failed" : "");
|
||||
printf(" Id : %08x\n", __le32_to_cpu(disk->scsi_id));
|
||||
- sz = __le32_to_cpu(disk->total_blocks) - reserved;
|
||||
+ sz = total_blocks(disk) - reserved;
|
||||
printf(" Usable Size : %llu%s\n", (unsigned long long)sz,
|
||||
human_size(sz * 512));
|
||||
}
|
||||
@@ -2462,9 +2530,8 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
|
||||
dl->index);
|
||||
}
|
||||
|
||||
- info->data_offset = __le32_to_cpu(map_to_analyse->pba_of_lba0);
|
||||
- info->component_size =
|
||||
- __le32_to_cpu(map_to_analyse->blocks_per_member);
|
||||
+ info->data_offset = pba_of_lba0(map_to_analyse);
|
||||
+ info->component_size = blocks_per_member(map_to_analyse);
|
||||
|
||||
/* check component size aligment
|
||||
*/
|
||||
@@ -2525,7 +2592,7 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info,
|
||||
|
||||
used_disks = imsm_num_data_members(dev, MAP_1);
|
||||
if (used_disks > 0) {
|
||||
- array_blocks = map->blocks_per_member *
|
||||
+ array_blocks = blocks_per_member(map) *
|
||||
used_disks;
|
||||
/* round array size down to closest MB
|
||||
*/
|
||||
@@ -2709,7 +2776,7 @@ static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info, char *
|
||||
__u32 reserved = imsm_reserved_sectors(super, super->disks);
|
||||
|
||||
disk = &super->disks->disk;
|
||||
- info->data_offset = __le32_to_cpu(disk->total_blocks) - reserved;
|
||||
+ info->data_offset = total_blocks(&super->disks->disk) - reserved;
|
||||
info->component_size = reserved;
|
||||
info->disk.state = is_configured(disk) ? (1 << MD_DISK_ACTIVE) : 0;
|
||||
/* we don't change info->disk.raid_disk here because
|
||||
@@ -3377,7 +3444,7 @@ int check_mpb_migr_compatibility(struct intel_super *super)
|
||||
/* This device is migrating */
|
||||
map0 = get_imsm_map(dev_iter, MAP_0);
|
||||
map1 = get_imsm_map(dev_iter, MAP_1);
|
||||
- if (map0->pba_of_lba0 != map1->pba_of_lba0)
|
||||
+ if (pba_of_lba0(map0) != pba_of_lba0(map1))
|
||||
/* migration optimization area was used */
|
||||
return -1;
|
||||
if (migr_rec->ascending_migr == 0
|
||||
@@ -3626,7 +3693,7 @@ static struct intel_super *alloc_super(void)
|
||||
if (super) {
|
||||
memset(super, 0, sizeof(*super));
|
||||
super->current_vol = -1;
|
||||
- super->create_offset = ~((__u32 ) 0);
|
||||
+ super->create_offset = ~((unsigned long long) 0);
|
||||
}
|
||||
return super;
|
||||
}
|
||||
@@ -4346,22 +4413,13 @@ static __u16 info_to_blocks_per_strip(mdu_array_info_t *info)
|
||||
return info->chunk_size >> 9;
|
||||
}
|
||||
|
||||
-static __u32 info_to_num_data_stripes(mdu_array_info_t *info, int num_domains)
|
||||
-{
|
||||
- __u32 num_stripes;
|
||||
-
|
||||
- num_stripes = (info->size * 2) / info_to_blocks_per_strip(info);
|
||||
- num_stripes /= num_domains;
|
||||
-
|
||||
- return num_stripes;
|
||||
-}
|
||||
-
|
||||
-static __u32 info_to_blocks_per_member(mdu_array_info_t *info)
|
||||
+static unsigned long long info_to_blocks_per_member(mdu_array_info_t *info,
|
||||
+ unsigned long long size)
|
||||
{
|
||||
if (info->level == 1)
|
||||
- return info->size * 2;
|
||||
+ return size * 2;
|
||||
else
|
||||
- return (info->size * 2) & ~(info_to_blocks_per_strip(info) - 1);
|
||||
+ return (size * 2) & ~(info_to_blocks_per_strip(info) - 1);
|
||||
}
|
||||
|
||||
static void imsm_update_version_info(struct intel_super *super)
|
||||
@@ -4452,7 +4510,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||
int i;
|
||||
unsigned long long array_blocks;
|
||||
size_t size_old, size_new;
|
||||
- __u32 num_data_stripes;
|
||||
+ unsigned long long num_data_stripes;
|
||||
|
||||
if (super->orom && mpb->num_raid_devs >= super->orom->vpa) {
|
||||
fprintf(stderr, Name": This imsm-container already has the "
|
||||
@@ -4540,11 +4598,11 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||
|
||||
strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
|
||||
if (info->level == 1)
|
||||
- array_blocks = info_to_blocks_per_member(info);
|
||||
+ array_blocks = info_to_blocks_per_member(info, size);
|
||||
else
|
||||
array_blocks = calc_array_size(info->level, info->raid_disks,
|
||||
info->layout, info->chunk_size,
|
||||
- info->size*2);
|
||||
+ size * 2);
|
||||
/* round array size down to closest MB */
|
||||
array_blocks = (array_blocks >> SECT_PER_MB_SHIFT) << SECT_PER_MB_SHIFT;
|
||||
|
||||
@@ -4557,8 +4615,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||
vol->dirty = !info->state;
|
||||
vol->curr_migr_unit = 0;
|
||||
map = get_imsm_map(dev, MAP_0);
|
||||
- map->pba_of_lba0 = __cpu_to_le32(super->create_offset);
|
||||
- map->blocks_per_member = __cpu_to_le32(info_to_blocks_per_member(info));
|
||||
+ set_pba_of_lba0(map, super->create_offset);
|
||||
+ set_blocks_per_member(map, info_to_blocks_per_member(info, size));
|
||||
map->blocks_per_strip = __cpu_to_le16(info_to_blocks_per_strip(info));
|
||||
map->failed_disk_num = ~0;
|
||||
if (info->level > 0)
|
||||
@@ -4585,8 +4643,10 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||
else
|
||||
map->num_domains = 1;
|
||||
|
||||
- num_data_stripes = info_to_num_data_stripes(info, map->num_domains);
|
||||
- map->num_data_stripes = __cpu_to_le32(num_data_stripes);
|
||||
+ /* info->size is only int so use the 'size' parameter instead */
|
||||
+ num_data_stripes = (size * 2) / info_to_blocks_per_strip(info);
|
||||
+ num_data_stripes /= map->num_domains;
|
||||
+ set_num_data_stripes(map, num_data_stripes);
|
||||
|
||||
map->num_members = info->raid_disks;
|
||||
for (i = 0; i < map->num_members; i++) {
|
||||
@@ -4729,8 +4789,8 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
|
||||
*/
|
||||
if (super->current_vol == 0) {
|
||||
for (df = super->missing; df; df = df->next) {
|
||||
- if (dl->disk.total_blocks > df->disk.total_blocks)
|
||||
- df->disk.total_blocks = dl->disk.total_blocks;
|
||||
+ if (total_blocks(&dl->disk) > total_blocks(&df->disk))
|
||||
+ set_total_blocks(&df->disk, total_blocks(&dl->disk));
|
||||
_disk = __get_imsm_disk(mpb, df->index);
|
||||
*_disk = df->disk;
|
||||
}
|
||||
@@ -4869,7 +4929,11 @@ static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
|
||||
get_dev_size(fd, NULL, &size);
|
||||
size /= 512;
|
||||
serialcpy(dd->disk.serial, dd->serial);
|
||||
- dd->disk.total_blocks = __cpu_to_le32(size);
|
||||
+ set_total_blocks(&dd->disk, size);
|
||||
+ if (__le32_to_cpu(dd->disk.total_blocks_hi) > 0) {
|
||||
+ struct imsm_super *mpb = super->anchor;
|
||||
+ mpb->attributes |= MPB_ATTRIB_2TB_DISK;
|
||||
+ }
|
||||
mark_spare(dd);
|
||||
if (sysfs_disk_to_scsi_id(fd, &id) == 0)
|
||||
dd->disk.scsi_id = __cpu_to_le32(id);
|
||||
@@ -5356,7 +5420,7 @@ static unsigned long long merge_extents(struct intel_super *super, int sum_exten
|
||||
if (maxsize < reserve)
|
||||
return 0;
|
||||
|
||||
- super->create_offset = ~((__u32) 0);
|
||||
+ super->create_offset = ~((unsigned long long) 0);
|
||||
if (start + reserve > super->create_offset)
|
||||
return 0; /* start overflows create_offset */
|
||||
super->create_offset = start + reserve;
|
||||
@@ -6597,8 +6661,8 @@ static struct mdinfo *container_content_imsm(struct supertype *st, char *subarra
|
||||
this->array.working_disks++;
|
||||
|
||||
info_d->events = __le32_to_cpu(mpb->generation_num);
|
||||
- info_d->data_offset = __le32_to_cpu(map->pba_of_lba0);
|
||||
- info_d->component_size = __le32_to_cpu(map->blocks_per_member);
|
||||
+ info_d->data_offset = pba_of_lba0(map);
|
||||
+ info_d->component_size = blocks_per_member(map);
|
||||
}
|
||||
/* now that the disk list is up-to-date fixup recovery_start */
|
||||
update_recovery_start(super, dev, this);
|
||||
@@ -6882,7 +6946,7 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev)
|
||||
/* set array size in metadata
|
||||
*/
|
||||
map = get_imsm_map(dev, MAP_0);
|
||||
- array_blocks = map->blocks_per_member * used_disks;
|
||||
+ array_blocks = blocks_per_member(map) * used_disks;
|
||||
|
||||
/* round array size down to closest MB
|
||||
*/
|
||||
@@ -6997,7 +7061,7 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
|
||||
used_disks = imsm_num_data_members(dev, MAP_0);
|
||||
if (used_disks > 0) {
|
||||
array_blocks =
|
||||
- map->blocks_per_member *
|
||||
+ blocks_per_member(map) *
|
||||
used_disks;
|
||||
/* round array size down to closest MB
|
||||
*/
|
||||
@@ -7364,9 +7428,9 @@ static struct dl *imsm_add_spare(struct intel_super *super, int slot,
|
||||
found = 0;
|
||||
j = 0;
|
||||
pos = 0;
|
||||
- array_start = __le32_to_cpu(map->pba_of_lba0);
|
||||
+ array_start = pba_of_lba0(map);
|
||||
array_end = array_start +
|
||||
- __le32_to_cpu(map->blocks_per_member) - 1;
|
||||
+ blocks_per_member(map) - 1;
|
||||
|
||||
do {
|
||||
/* check that we can start at pba_of_lba0 with
|
||||
@@ -7566,7 +7630,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a,
|
||||
di->disk.minor = dl->minor;
|
||||
di->disk.state = 0;
|
||||
di->recovery_start = 0;
|
||||
- di->data_offset = __le32_to_cpu(map->pba_of_lba0);
|
||||
+ di->data_offset = pba_of_lba0(map);
|
||||
di->component_size = a->info.component_size;
|
||||
di->container_member = inst;
|
||||
super->random = random32();
|
||||
@@ -8292,8 +8356,8 @@ static void imsm_process_update(struct supertype *st,
|
||||
}
|
||||
|
||||
new_map = get_imsm_map(&u->dev, MAP_0);
|
||||
- new_start = __le32_to_cpu(new_map->pba_of_lba0);
|
||||
- new_end = new_start + __le32_to_cpu(new_map->blocks_per_member);
|
||||
+ new_start = pba_of_lba0(new_map);
|
||||
+ new_end = new_start + blocks_per_member(new_map);
|
||||
inf = get_disk_info(u);
|
||||
|
||||
/* handle activate_spare versus create race:
|
||||
@@ -8303,8 +8367,8 @@ static void imsm_process_update(struct supertype *st,
|
||||
for (i = 0; i < mpb->num_raid_devs; i++) {
|
||||
dev = get_imsm_dev(super, i);
|
||||
map = get_imsm_map(dev, MAP_0);
|
||||
- start = __le32_to_cpu(map->pba_of_lba0);
|
||||
- end = start + __le32_to_cpu(map->blocks_per_member);
|
||||
+ start = pba_of_lba0(map);
|
||||
+ end = start + blocks_per_member(map);
|
||||
if ((new_start >= start && new_start <= end) ||
|
||||
(start >= new_start && start <= new_end))
|
||||
/* overlap */;
|
||||
@@ -9165,7 +9229,7 @@ int recover_backup_imsm(struct supertype *st, struct mdinfo *info)
|
||||
|
||||
write_offset = ((unsigned long long)
|
||||
__le32_to_cpu(migr_rec->dest_1st_member_lba) +
|
||||
- __le32_to_cpu(map_dest->pba_of_lba0)) * 512;
|
||||
+ pba_of_lba0(map_dest)) * 512;
|
||||
|
||||
unit_len = __le32_to_cpu(migr_rec->dest_depth_per_unit) * 512;
|
||||
if (posix_memalign((void **)&buf, 512, unit_len) != 0)
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 30602f533f151c24fe1345f495f02c30f98895f1 Mon Sep 17 00:00:00 2001
|
||||
From: Labun, Marcin <Marcin.Labun@intel.com>
|
||||
Date: Mon, 30 Jan 2012 12:00:43 +1100
|
||||
Subject: [PATCH] imsm: display fd in error trace when when store_imsm_mpb
|
||||
failes
|
||||
|
||||
Signed-off-by: Marcin Labun <marcin.labun@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 5 +++--
|
||||
1 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 7db5177..8d67a14 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -5027,8 +5027,9 @@ static int write_super_imsm(struct supertype *st, int doclose)
|
||||
if (d->index < 0 || is_failed(&d->disk))
|
||||
continue;
|
||||
if (store_imsm_mpb(d->fd, mpb))
|
||||
- fprintf(stderr, "%s: failed for device %d:%d %s\n",
|
||||
- __func__, d->major, d->minor, strerror(errno));
|
||||
+ fprintf(stderr, "%s: failed for device %d:%d (fd: %d)%s\n",
|
||||
+ __func__, d->major, d->minor, d->fd, strerror(errno));
|
||||
+
|
||||
if (clear_migration_record) {
|
||||
unsigned long long dsize;
|
||||
|
||||
--
|
||||
1.7.4.4
|
||||
|
@ -1,29 +0,0 @@
|
||||
From 4ff46bbc34aca294afe2127536b620672486598e Mon Sep 17 00:00:00 2001
|
||||
From: Marcin Labun <Marcin.Labun@intel.com>
|
||||
Date: Wed, 14 Dec 2011 15:02:49 +0100
|
||||
Subject: [PATCH 1/6] imsm: display maximum volumes per controller in --detail-platform command
|
||||
|
||||
Signed-off-by: Marcin Labun <marcin.labun@intel.com>
|
||||
---
|
||||
super-intel.c | 5 +++--
|
||||
1 files changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index b64aa7a..1c22aff 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -1663,8 +1663,9 @@ static void print_imsm_capability(const struct imsm_orom *orom)
|
||||
imsm_orom_has_chunk(orom, 1024*16) ? " 16M" : "",
|
||||
imsm_orom_has_chunk(orom, 1024*32) ? " 32M" : "",
|
||||
imsm_orom_has_chunk(orom, 1024*64) ? " 64M" : "");
|
||||
- printf(" Max Disks : %d\n", orom->tds);
|
||||
- printf(" Max Volumes : %d\n", orom->vpa);
|
||||
+ printf(" Max Disks : %d\n", orom->tds);
|
||||
+ printf(" Max Volumes per array : %d\n", orom->vpa);
|
||||
+ printf(" Max Volumes per controller: %d\n", orom->vphba);
|
||||
return;
|
||||
}
|
||||
|
||||
--
|
||||
1.7.1
|
||||
|
@ -1,62 +0,0 @@
|
||||
From 7ce05701813496571e1f7f79c726aa6e4868bd5f Mon Sep 17 00:00:00 2001
|
||||
From: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
Date: Fri, 20 Apr 2012 13:45:02 +0200
|
||||
Subject: [PATCH 2/3] imsm: fix: rebuild does not continue after reboot
|
||||
|
||||
If system is rebooted during rebuild, md driver changes sync_action
|
||||
from 'recover' to 'idle' (during stopping all md devices).
|
||||
If mdmon is still running then, it detects the change of sync_action state,
|
||||
finishes rebuild and writes metadata to disks. After computer's restart
|
||||
the RAID volume is in Normal state in OROM and rebuild seems to be finished.
|
||||
After system's start-up RAID volume is in auto-read-only state
|
||||
and metadata is in Dirty state. Rebuild seems to be finished but it is not.
|
||||
Data is inconsistent (out-of-sync).
|
||||
|
||||
When mdmon detects the change of sync_action from 'recover' to 'idle',
|
||||
it has to check if rebuild is really finished. Appropriate test was added.
|
||||
Now mdmon examines each volume's member if it is being rebuilt.
|
||||
|
||||
Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 17 +++++++++++++++++
|
||||
1 files changed, 17 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index e405d97..1ad5e47 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -7273,6 +7273,8 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
|
||||
struct imsm_dev *dev = get_imsm_dev(super, inst);
|
||||
struct imsm_map *map = get_imsm_map(dev, MAP_0);
|
||||
struct imsm_disk *disk;
|
||||
+ struct mdinfo *mdi;
|
||||
+ int recovery_not_finished = 0;
|
||||
int failed;
|
||||
__u32 ord;
|
||||
__u8 map_state;
|
||||
@@ -7313,6 +7315,21 @@ static void imsm_set_disk(struct active_array *a, int n, int state)
|
||||
dprintf("normal: ");
|
||||
if (is_rebuilding(dev)) {
|
||||
dprintf("while rebuilding");
|
||||
+ /* check if recovery is really finished */
|
||||
+ for (mdi = a->info.devs; mdi ; mdi = mdi->next)
|
||||
+ if (mdi->recovery_start != MaxSector) {
|
||||
+ recovery_not_finished = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ if (recovery_not_finished) {
|
||||
+ dprintf("\nimsm: Rebuild has not finished yet, "
|
||||
+ "state not changed");
|
||||
+ if (a->last_checkpoint < mdi->recovery_start) {
|
||||
+ a->last_checkpoint = mdi->recovery_start;
|
||||
+ super->updates_pending++;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
end_migration(dev, super, map_state);
|
||||
map = get_imsm_map(dev, MAP_0);
|
||||
map->failed_disk_num = ~0;
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,40 +0,0 @@
|
||||
From f878b24226953f06912ebceb2c811edf36818d2f Mon Sep 17 00:00:00 2001
|
||||
From: "Labun, Marcin" <Marcin.Labun@intel.com>
|
||||
Date: Fri, 27 Jan 2012 15:28:36 +0000
|
||||
Subject: [PATCH] imsm: fix, the second array need to have the whole available
|
||||
space on devices
|
||||
|
||||
Fix the case with creating an array with given container in command line
|
||||
instead of real devices:
|
||||
mdadm -CR /dev/md/raid0 -l 0 -n 2 -z5G /dev/md/imsm
|
||||
|
||||
Signed-off-by: Marcin Labun <marcin.labun@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 9 ++++++++-
|
||||
1 files changed, 8 insertions(+), 1 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 8d67a14..eba11d6 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -6029,8 +6029,15 @@ static int reserve_space(struct supertype *st, int raiddisks,
|
||||
size /= 2 * chunk;
|
||||
size *= 2 * chunk;
|
||||
}
|
||||
+ maxsize = size;
|
||||
+ }
|
||||
+ if (!check_env("IMSM_NO_PLATFORM") &&
|
||||
+ mpb->num_raid_devs > 0 && size && size != maxsize) {
|
||||
+ fprintf(stderr, Name ": attempting to create a second "
|
||||
+ "volume with size less then remaining space. "
|
||||
+ "Aborting...\n");
|
||||
+ return 0;
|
||||
}
|
||||
-
|
||||
cnt = 0;
|
||||
for (dl = super->disks; dl; dl = dl->next)
|
||||
if (dl->e)
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,33 +0,0 @@
|
||||
From 86130b7a213485f1aeb078c6f32c901648e2f679 Mon Sep 17 00:00:00 2001
|
||||
From: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Date: Mon, 2 Apr 2012 22:42:51 +0200
|
||||
Subject: [PATCH] imsm: fix: thunderdome may drop 2tb attribute
|
||||
|
||||
Spare superblock doesn't depend on other spares in container.
|
||||
When loading container metadata thunderdome
|
||||
may pick a small disk for the champion. This will result in incorrect
|
||||
interpretation of sizes of other disks in container when joint superblock
|
||||
is returned. If any disk in container has the 2TB attribute set, the result
|
||||
must have it set too.
|
||||
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
---
|
||||
super-intel.c | 2 ++
|
||||
1 files changed, 2 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index ed13542..869a39c 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -4079,6 +4079,8 @@ imsm_thunderdome(struct intel_super **super_list, int len)
|
||||
if (s == champion)
|
||||
continue;
|
||||
|
||||
+ mpb->attributes |= s->anchor->attributes & MPB_ATTRIB_2TB_DISK;
|
||||
+
|
||||
for (i = 0; i < mpb->num_disks; i++) {
|
||||
struct imsm_disk *disk;
|
||||
|
||||
--
|
||||
1.6.4.2
|
||||
|
@ -1,157 +0,0 @@
|
||||
From ec50f7b6bb3a5218b51e1a953d530ef6b446bcd4 Mon Sep 17 00:00:00 2001
|
||||
From: "Labun, Marcin" <Marcin.Labun@intel.com>
|
||||
Date: Mon, 30 Jan 2012 11:57:23 +1100
|
||||
Subject: [PATCH 2/3] imsm: load_imsm_super_all supports loading metadata from
|
||||
the device list
|
||||
|
||||
This option is going to be used to load and analyse the metadata from
|
||||
devices. This is needed to count the number of volumes on devcies attached
|
||||
to particular Intel controller (SATA or SAS). It shall be done without
|
||||
activation of container and volumes on the devices.
|
||||
|
||||
Signed-off-by: Marcin Labun <marcin.labun@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 79 ++++++++++++++++++++++++++++++++++++++++++++++++++++----
|
||||
1 files changed, 73 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 733d089..1cf8716 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -277,6 +277,22 @@ struct migr_record {
|
||||
* (for recovered migrations) */
|
||||
} __attribute__ ((__packed__));
|
||||
|
||||
+struct md_list {
|
||||
+ /* usage marker:
|
||||
+ * 1: load metadata
|
||||
+ * 2: metadata does not match
|
||||
+ * 4: already checked
|
||||
+ */
|
||||
+ int used;
|
||||
+ char *devname;
|
||||
+ int found;
|
||||
+ int container;
|
||||
+ dev_t st_rdev;
|
||||
+ struct md_list *next;
|
||||
+};
|
||||
+
|
||||
+#define pr_vrb(fmt, arg...) (void) (verbose && fprintf(stderr, Name fmt, ##arg))
|
||||
+
|
||||
static __u8 migr_type(struct imsm_dev *dev)
|
||||
{
|
||||
if (dev->vol.migr_type == MIGR_VERIFY &&
|
||||
@@ -4012,12 +4028,16 @@ imsm_thunderdome(struct intel_super **super_list, int len)
|
||||
|
||||
static int
|
||||
get_sra_super_block(int fd, struct intel_super **super_list, char *devname, int *max, int keep_fd);
|
||||
-
|
||||
static int get_super_block(struct intel_super **super_list, int devnum, char *devname,
|
||||
int major, int minor, int keep_fd);
|
||||
+static int
|
||||
+get_devlist_super_block(struct md_list *devlist, struct intel_super **super_list,
|
||||
+ int *max, int keep_fd);
|
||||
+
|
||||
|
||||
static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
||||
- char *devname, int keep_fd)
|
||||
+ char *devname, struct md_list *devlist,
|
||||
+ int keep_fd)
|
||||
{
|
||||
struct intel_super *super_list = NULL;
|
||||
struct intel_super *super = NULL;
|
||||
@@ -4028,7 +4048,8 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
||||
/* 'fd' is an opened container */
|
||||
err = get_sra_super_block(fd, &super_list, devname, &i, keep_fd);
|
||||
else
|
||||
- return 1;
|
||||
+ /* get super block from devlist devices */
|
||||
+ err = get_devlist_super_block(devlist, &super_list, &i, keep_fd);
|
||||
if (err)
|
||||
goto error;
|
||||
/* all mpbs enter, maybe one leaves */
|
||||
@@ -4094,7 +4115,54 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
||||
}
|
||||
|
||||
|
||||
+static int
|
||||
+get_devlist_super_block(struct md_list *devlist, struct intel_super **super_list,
|
||||
+ int *max, int keep_fd)
|
||||
+{
|
||||
+ struct md_list *tmpdev;
|
||||
+ int err = 0;
|
||||
+ int i = 0;
|
||||
+ int lmax = 0;
|
||||
|
||||
+ for (i = 0, tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
|
||||
+ if (tmpdev->used != 1)
|
||||
+ continue;
|
||||
+ if (tmpdev->container == 1) {
|
||||
+ int fd = dev_open(tmpdev->devname, O_RDONLY|O_EXCL);
|
||||
+ if (fd < 0) {
|
||||
+ fprintf(stderr, Name ": cannot open device %s: %s\n",
|
||||
+ tmpdev->devname, strerror(errno));
|
||||
+ err = 8;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ err = get_sra_super_block(fd, super_list,
|
||||
+ tmpdev->devname, &lmax,
|
||||
+ keep_fd);
|
||||
+ i += lmax;
|
||||
+ close(fd);
|
||||
+ if (err) {
|
||||
+ err = 7;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ } else {
|
||||
+ int major = major(tmpdev->st_rdev);
|
||||
+ int minor = minor(tmpdev->st_rdev);
|
||||
+ err = get_super_block(super_list,
|
||||
+ -1,
|
||||
+ tmpdev->devname,
|
||||
+ major, minor,
|
||||
+ keep_fd);
|
||||
+ i++;
|
||||
+ if (err) {
|
||||
+ err = 6;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ error:
|
||||
+ *max = i;
|
||||
+ return err;
|
||||
+}
|
||||
|
||||
static int get_super_block(struct intel_super **super_list, int devnum, char *devname,
|
||||
int major, int minor, int keep_fd)
|
||||
@@ -4187,7 +4255,7 @@ get_sra_super_block(int fd, struct intel_super **super_list, char *devname, int
|
||||
|
||||
static int load_container_imsm(struct supertype *st, int fd, char *devname)
|
||||
{
|
||||
- return load_super_imsm_all(st, fd, &st->sb, devname, 1);
|
||||
+ return load_super_imsm_all(st, fd, &st->sb, devname, NULL, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5305,7 +5373,6 @@ static int imsm_default_chunk(const struct imsm_orom *orom)
|
||||
return min(512, (1 << fs));
|
||||
}
|
||||
|
||||
-#define pr_vrb(fmt, arg...) (void) (verbose && fprintf(stderr, Name fmt, ##arg))
|
||||
static int
|
||||
validate_geometry_imsm_orom(struct intel_super *super, int level, int layout,
|
||||
int raiddisks, int *chunk, int verbose)
|
||||
@@ -5678,7 +5745,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
*/
|
||||
struct intel_super *super;
|
||||
|
||||
- if (load_super_imsm_all(st, cfd, (void **) &super, NULL, 1) == 0) {
|
||||
+ if (load_super_imsm_all(st, cfd, (void **) &super, NULL, NULL, 1) == 0) {
|
||||
st->sb = super;
|
||||
st->container_dev = fd2devnum(cfd);
|
||||
close(cfd);
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,261 +0,0 @@
|
||||
From 9587c3739b6d6edc7abfa4a655b9ab46926abdbf Mon Sep 17 00:00:00 2001
|
||||
From: "Labun, Marcin" <Marcin.Labun@intel.com>
|
||||
Date: Mon, 30 Jan 2012 11:56:58 +1100
|
||||
Subject: [PATCH 1/3] imsm: load_super_imsm_all function refactoring
|
||||
|
||||
Prepare function for subsequent changes related to
|
||||
loading metadata from devices list.
|
||||
|
||||
Signed-off-by: Marcin Labun <marcin.labun@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 176 +++++++++++++++++++++++++++++++++++++-------------------
|
||||
1 files changed, 116 insertions(+), 60 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 0e9269f..733d089 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -2985,7 +2985,7 @@ static void fd2devname(int fd, char *name)
|
||||
rv = readlink(path, dname, sizeof(dname)-1);
|
||||
if (rv <= 0)
|
||||
return;
|
||||
-
|
||||
+
|
||||
dname[rv] = '\0';
|
||||
nm = strrchr(dname, '/');
|
||||
if (nm) {
|
||||
@@ -4009,67 +4009,28 @@ imsm_thunderdome(struct intel_super **super_list, int len)
|
||||
return champion;
|
||||
}
|
||||
|
||||
+
|
||||
+static int
|
||||
+get_sra_super_block(int fd, struct intel_super **super_list, char *devname, int *max, int keep_fd);
|
||||
+
|
||||
+static int get_super_block(struct intel_super **super_list, int devnum, char *devname,
|
||||
+ int major, int minor, int keep_fd);
|
||||
+
|
||||
static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
||||
- char *devname)
|
||||
+ char *devname, int keep_fd)
|
||||
{
|
||||
- struct mdinfo *sra;
|
||||
struct intel_super *super_list = NULL;
|
||||
struct intel_super *super = NULL;
|
||||
- int devnum = fd2devnum(fd);
|
||||
- struct mdinfo *sd;
|
||||
- int retry;
|
||||
int err = 0;
|
||||
- int i;
|
||||
+ int i = 0;
|
||||
|
||||
- /* check if 'fd' an opened container */
|
||||
- sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
|
||||
- if (!sra)
|
||||
+ if (fd >= 0)
|
||||
+ /* 'fd' is an opened container */
|
||||
+ err = get_sra_super_block(fd, &super_list, devname, &i, keep_fd);
|
||||
+ else
|
||||
return 1;
|
||||
-
|
||||
- if (sra->array.major_version != -1 ||
|
||||
- sra->array.minor_version != -2 ||
|
||||
- strcmp(sra->text_version, "imsm") != 0) {
|
||||
- err = 1;
|
||||
+ if (err)
|
||||
goto error;
|
||||
- }
|
||||
- /* load all mpbs */
|
||||
- for (sd = sra->devs, i = 0; sd; sd = sd->next, i++) {
|
||||
- struct intel_super *s = alloc_super();
|
||||
- char nm[32];
|
||||
- int dfd;
|
||||
- int rv;
|
||||
-
|
||||
- err = 1;
|
||||
- if (!s)
|
||||
- goto error;
|
||||
- s->next = super_list;
|
||||
- super_list = s;
|
||||
-
|
||||
- err = 2;
|
||||
- sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
|
||||
- dfd = dev_open(nm, O_RDWR);
|
||||
- if (dfd < 0)
|
||||
- goto error;
|
||||
-
|
||||
- rv = find_intel_hba_capability(dfd, s, devname);
|
||||
- /* no orom/efi or non-intel hba of the disk */
|
||||
- if (rv != 0)
|
||||
- goto error;
|
||||
-
|
||||
- err = load_and_parse_mpb(dfd, s, NULL, 1);
|
||||
-
|
||||
- /* retry the load if we might have raced against mdmon */
|
||||
- if (err == 3 && mdmon_running(devnum))
|
||||
- for (retry = 0; retry < 3; retry++) {
|
||||
- usleep(3000);
|
||||
- err = load_and_parse_mpb(dfd, s, NULL, 1);
|
||||
- if (err != 3)
|
||||
- break;
|
||||
- }
|
||||
- if (err)
|
||||
- goto error;
|
||||
- }
|
||||
-
|
||||
/* all mpbs enter, maybe one leaves */
|
||||
super = imsm_thunderdome(&super_list, i);
|
||||
if (!super) {
|
||||
@@ -4114,13 +4075,16 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
||||
super_list = super_list->next;
|
||||
free_imsm(s);
|
||||
}
|
||||
- sysfs_free(sra);
|
||||
+
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
*sbp = super;
|
||||
- st->container_dev = devnum;
|
||||
+ if (fd >= 0)
|
||||
+ st->container_dev = fd2devnum(fd);
|
||||
+ else
|
||||
+ st->container_dev = NoMdDev;
|
||||
if (err == 0 && st->ss == NULL) {
|
||||
st->ss = &super_imsm;
|
||||
st->minor_version = 0;
|
||||
@@ -4129,9 +4093,101 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+
|
||||
+
|
||||
+
|
||||
+static int get_super_block(struct intel_super **super_list, int devnum, char *devname,
|
||||
+ int major, int minor, int keep_fd)
|
||||
+{
|
||||
+ struct intel_super*s = NULL;
|
||||
+ char nm[32];
|
||||
+ int dfd = -1;
|
||||
+ int rv;
|
||||
+ int err = 0;
|
||||
+ int retry;
|
||||
+
|
||||
+ s = alloc_super();
|
||||
+ if (!s) {
|
||||
+ err = 1;
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ sprintf(nm, "%d:%d", major, minor);
|
||||
+ dfd = dev_open(nm, O_RDWR);
|
||||
+ if (dfd < 0) {
|
||||
+ err = 2;
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ rv = find_intel_hba_capability(dfd, s, devname);
|
||||
+ /* no orom/efi or non-intel hba of the disk */
|
||||
+ if (rv != 0) {
|
||||
+ err = 4;
|
||||
+ goto error;
|
||||
+ }
|
||||
+
|
||||
+ err = load_and_parse_mpb(dfd, s, NULL, keep_fd);
|
||||
+
|
||||
+ /* retry the load if we might have raced against mdmon */
|
||||
+ if (err == 3 && (devnum != -1) && mdmon_running(devnum))
|
||||
+ for (retry = 0; retry < 3; retry++) {
|
||||
+ usleep(3000);
|
||||
+ err = load_and_parse_mpb(dfd, s, NULL, keep_fd);
|
||||
+ if (err != 3)
|
||||
+ break;
|
||||
+ }
|
||||
+ error:
|
||||
+ if (!err) {
|
||||
+ s->next = *super_list;
|
||||
+ *super_list = s;
|
||||
+ } else {
|
||||
+ if (s)
|
||||
+ free(s);
|
||||
+ if (dfd)
|
||||
+ close(dfd);
|
||||
+ }
|
||||
+ if ((dfd >= 0) && (!keep_fd))
|
||||
+ close(dfd);
|
||||
+ return err;
|
||||
+
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+get_sra_super_block(int fd, struct intel_super **super_list, char *devname, int *max, int keep_fd)
|
||||
+{
|
||||
+ struct mdinfo *sra;
|
||||
+ int devnum;
|
||||
+ struct mdinfo *sd;
|
||||
+ int err = 0;
|
||||
+ int i = 0;
|
||||
+ sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
|
||||
+ if (!sra)
|
||||
+ return 1;
|
||||
+
|
||||
+ if (sra->array.major_version != -1 ||
|
||||
+ sra->array.minor_version != -2 ||
|
||||
+ strcmp(sra->text_version, "imsm") != 0) {
|
||||
+ err = 1;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ /* load all mpbs */
|
||||
+ devnum = fd2devnum(fd);
|
||||
+ for (sd = sra->devs, i = 0; sd; sd = sd->next, i++) {
|
||||
+ if (get_super_block(super_list, devnum, devname,
|
||||
+ sd->disk.major, sd->disk.minor, keep_fd) != 0) {
|
||||
+ err = 7;
|
||||
+ goto error;
|
||||
+ }
|
||||
+ }
|
||||
+ error:
|
||||
+ sysfs_free(sra);
|
||||
+ *max = i;
|
||||
+ return err;
|
||||
+}
|
||||
+
|
||||
static int load_container_imsm(struct supertype *st, int fd, char *devname)
|
||||
{
|
||||
- return load_super_imsm_all(st, fd, &st->sb, devname);
|
||||
+ return load_super_imsm_all(st, fd, &st->sb, devname, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5558,7 +5614,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
dev, freesize,
|
||||
verbose);
|
||||
}
|
||||
-
|
||||
+
|
||||
if (!dev) {
|
||||
if (st->sb) {
|
||||
if (!validate_geometry_imsm_orom(st->sb, level, layout,
|
||||
@@ -5622,7 +5678,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
*/
|
||||
struct intel_super *super;
|
||||
|
||||
- if (load_super_imsm_all(st, cfd, (void **) &super, NULL) == 0) {
|
||||
+ if (load_super_imsm_all(st, cfd, (void **) &super, NULL, 1) == 0) {
|
||||
st->sb = super;
|
||||
st->container_dev = fd2devnum(cfd);
|
||||
close(cfd);
|
||||
@@ -6198,7 +6254,7 @@ static int imsm_open_new(struct supertype *c, struct active_array *a,
|
||||
{
|
||||
struct intel_super *super = c->sb;
|
||||
struct imsm_super *mpb = super->anchor;
|
||||
-
|
||||
+
|
||||
if (atoi(inst) >= mpb->num_raid_devs) {
|
||||
fprintf(stderr, "%s: subarry index %d, out of range\n",
|
||||
__func__, atoi(inst));
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,30 +0,0 @@
|
||||
From 027c374fd946824704291da933300da78c32a189 Mon Sep 17 00:00:00 2001
|
||||
From: "Czarnowska, Anna" <anna.czarnowska@intel.com>
|
||||
Date: Mon, 2 Apr 2012 10:19:04 +1000
|
||||
Subject: [PATCH 7/7] imsm: set 2tb disk attribute for spare
|
||||
|
||||
This patch ensures metadata attribute is set correctly also for spares.
|
||||
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 3 +++
|
||||
1 files changed, 3 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 1bc9e9c..dad4c4d 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -5048,6 +5048,9 @@ static int write_super_imsm_spares(struct intel_super *super, int doclose)
|
||||
continue;
|
||||
|
||||
spare->disk[0] = d->disk;
|
||||
+ if (__le32_to_cpu(d->disk.total_blocks_hi) > 0)
|
||||
+ spare->attributes |= MPB_ATTRIB_2TB_DISK;
|
||||
+
|
||||
sum = __gen_imsm_checksum(spare);
|
||||
spare->family_num = __cpu_to_le32(sum);
|
||||
spare->orig_family_num = 0;
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,497 +0,0 @@
|
||||
From ca9de185a3b96720adcc5120f6a34c5f9bb98b3f Mon Sep 17 00:00:00 2001
|
||||
From: "Labun, Marcin" <Marcin.Labun@intel.com>
|
||||
Date: Mon, 30 Jan 2012 12:00:10 +1100
|
||||
Subject: [PATCH 3/3] imsm: validate the number of imsm volumes per controller
|
||||
|
||||
IMSM OROM limits number of volumes per controller. Volumes
|
||||
above the limit are blocked in OROM. mdadm should follow OROM limitations
|
||||
in this area. Therefore we need to count number of volumes on the devices
|
||||
attached to SATA (ahci driver) or SAS (isci) controller. Adding a new volume
|
||||
must be blocked if the number of volumes on devices attached to the given
|
||||
controller is exceeded.
|
||||
|
||||
Signed-off-by: Marcin Labun <marcin.labun@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 404 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 files changed, 399 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 1cf8716..7db5177 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -3285,7 +3285,7 @@ static int parse_raid_devices(struct intel_super *super)
|
||||
len_migr = sizeof_imsm_dev(dev_iter, 1);
|
||||
if (len_migr > len)
|
||||
space_needed += len_migr - len;
|
||||
-
|
||||
+
|
||||
dv = malloc(sizeof(*dv));
|
||||
if (!dv)
|
||||
return 1;
|
||||
@@ -3321,7 +3321,7 @@ static int parse_raid_devices(struct intel_super *super)
|
||||
super->buf = buf;
|
||||
super->len = len;
|
||||
}
|
||||
-
|
||||
+
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -4122,12 +4122,12 @@ get_devlist_super_block(struct md_list *devlist, struct intel_super **super_list
|
||||
struct md_list *tmpdev;
|
||||
int err = 0;
|
||||
int i = 0;
|
||||
- int lmax = 0;
|
||||
|
||||
for (i = 0, tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
|
||||
if (tmpdev->used != 1)
|
||||
continue;
|
||||
if (tmpdev->container == 1) {
|
||||
+ int lmax = 0;
|
||||
int fd = dev_open(tmpdev->devname, O_RDONLY|O_EXCL);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, Name ": cannot open device %s: %s\n",
|
||||
@@ -5363,6 +5363,377 @@ static int is_raid_level_supported(const struct imsm_orom *orom, int level, int
|
||||
return 0;
|
||||
}
|
||||
|
||||
+
|
||||
+static int
|
||||
+active_arrays_by_format(char *name, char* hba, struct md_list **devlist,
|
||||
+ int dpa, int verbose)
|
||||
+{
|
||||
+ struct mdstat_ent *mdstat = mdstat_read(0, 0);
|
||||
+ struct mdstat_ent *memb = NULL;
|
||||
+ int count = 0;
|
||||
+ int num = 0;
|
||||
+ struct md_list *dv = NULL;
|
||||
+ int found;
|
||||
+
|
||||
+ for (memb = mdstat ; memb ; memb = memb->next) {
|
||||
+ if (memb->metadata_version &&
|
||||
+ (strncmp(memb->metadata_version, "external:", 9) == 0) &&
|
||||
+ (strcmp(&memb->metadata_version[9], name) == 0) &&
|
||||
+ !is_subarray(memb->metadata_version+9) &&
|
||||
+ memb->members) {
|
||||
+ struct dev_member *dev = memb->members;
|
||||
+ int fd = -1;
|
||||
+ while(dev && (fd < 0)) {
|
||||
+ char *path = malloc(strlen(dev->name) + strlen("/dev/") + 1);
|
||||
+ if (path) {
|
||||
+ num = sprintf(path, "%s%s", "/dev/", dev->name);
|
||||
+ if (num > 0)
|
||||
+ fd = open(path, O_RDONLY, 0);
|
||||
+ if ((num <= 0) || (fd < 0)) {
|
||||
+ pr_vrb(": Cannot open %s: %s\n",
|
||||
+ dev->name, strerror(errno));
|
||||
+ }
|
||||
+ free(path);
|
||||
+ }
|
||||
+ dev = dev->next;
|
||||
+ }
|
||||
+ found = 0;
|
||||
+ if ((fd >= 0) && disk_attached_to_hba(fd, hba)) {
|
||||
+ struct mdstat_ent *vol;
|
||||
+ for (vol = mdstat ; vol ; vol = vol->next) {
|
||||
+ if ((vol->active > 0) &&
|
||||
+ vol->metadata_version &&
|
||||
+ is_container_member(vol, memb->dev)) {
|
||||
+ found++;
|
||||
+ count++;
|
||||
+ }
|
||||
+ }
|
||||
+ if (*devlist && (found < dpa)) {
|
||||
+ dv = calloc(1, sizeof(*dv));
|
||||
+ if (dv == NULL)
|
||||
+ fprintf(stderr, Name ": calloc failed\n");
|
||||
+ else {
|
||||
+ dv->devname = malloc(strlen(memb->dev) + strlen("/dev/") + 1);
|
||||
+ if (dv->devname != NULL) {
|
||||
+ sprintf(dv->devname, "%s%s", "/dev/", memb->dev);
|
||||
+ dv->found = found;
|
||||
+ dv->used = 0;
|
||||
+ dv->next = *devlist;
|
||||
+ *devlist = dv;
|
||||
+ } else
|
||||
+ free(dv);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ if (fd >= 0)
|
||||
+ close(fd);
|
||||
+ }
|
||||
+ }
|
||||
+ free_mdstat(mdstat);
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+#ifdef DEBUG_LOOP
|
||||
+static struct md_list*
|
||||
+get_loop_devices(void)
|
||||
+{
|
||||
+ int i;
|
||||
+ struct md_list *devlist = NULL;
|
||||
+ struct md_list *dv = NULL;
|
||||
+
|
||||
+ for(i = 0; i < 12; i++) {
|
||||
+ dv = calloc(1, sizeof(*dv));
|
||||
+ if (dv == NULL) {
|
||||
+ fprintf(stderr, Name ": calloc failed\n");
|
||||
+ break;
|
||||
+ }
|
||||
+ dv->devname = malloc(40);
|
||||
+ if (dv->devname == NULL) {
|
||||
+ fprintf(stderr, Name ": malloc failed\n");
|
||||
+ free(dv);
|
||||
+ break;
|
||||
+ }
|
||||
+ sprintf(dv->devname, "/dev/loop%d", i);
|
||||
+ dv->next = devlist;
|
||||
+ devlist = dv;
|
||||
+ }
|
||||
+ return devlist;
|
||||
+}
|
||||
+#endif
|
||||
+
|
||||
+static struct md_list*
|
||||
+get_devices(const char *hba_path)
|
||||
+{
|
||||
+ struct md_list *devlist = NULL;
|
||||
+ struct md_list *dv = NULL;
|
||||
+ struct dirent *ent;
|
||||
+ DIR *dir;
|
||||
+ int err = 0;
|
||||
+
|
||||
+#if DEBUG_LOOP
|
||||
+ devlist = get_loop_devices();
|
||||
+ return devlist;
|
||||
+#endif
|
||||
+ /* scroll through /sys/dev/block looking for devices attached to
|
||||
+ * this hba
|
||||
+ */
|
||||
+ dir = opendir("/sys/dev/block");
|
||||
+ for (ent = dir ? readdir(dir) : NULL; ent; ent = readdir(dir)) {
|
||||
+ int fd;
|
||||
+ char buf[1024];
|
||||
+ int major, minor;
|
||||
+ char *path = NULL;
|
||||
+ if (sscanf(ent->d_name, "%d:%d", &major, &minor) != 2)
|
||||
+ continue;
|
||||
+ path = devt_to_devpath(makedev(major, minor));
|
||||
+ if (!path)
|
||||
+ continue;
|
||||
+ if (!path_attached_to_hba(path, hba_path)) {
|
||||
+ free(path);
|
||||
+ path = NULL;
|
||||
+ continue;
|
||||
+ }
|
||||
+ free(path);
|
||||
+ path = NULL;
|
||||
+ fd = dev_open(ent->d_name, O_RDONLY);
|
||||
+ if (fd >= 0) {
|
||||
+ fd2devname(fd, buf);
|
||||
+ close(fd);
|
||||
+ } else {
|
||||
+ fprintf(stderr, Name ": cannot open device: %s\n",
|
||||
+ ent->d_name);
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ dv = calloc(1, sizeof(*dv));
|
||||
+ if (dv == NULL) {
|
||||
+ fprintf(stderr, Name ": malloc failed\n");
|
||||
+ err = 1;
|
||||
+ break;
|
||||
+ }
|
||||
+ dv->devname = strdup(buf);
|
||||
+ if (dv->devname == NULL) {
|
||||
+ fprintf(stderr, Name ": malloc failed\n");
|
||||
+ err = 1;
|
||||
+ free(dv);
|
||||
+ break;
|
||||
+ }
|
||||
+ dv->next = devlist;
|
||||
+ devlist = dv;
|
||||
+ }
|
||||
+ if (err) {
|
||||
+ while(devlist) {
|
||||
+ dv = devlist;
|
||||
+ devlist = devlist->next;
|
||||
+ free(dv->devname);
|
||||
+ free(dv);
|
||||
+ }
|
||||
+ }
|
||||
+ return devlist;
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+count_volumes_list(struct md_list *devlist, char *homehost,
|
||||
+ int verbose, int *found)
|
||||
+{
|
||||
+ struct md_list *tmpdev;
|
||||
+ int count = 0;
|
||||
+ struct supertype *st = NULL;
|
||||
+
|
||||
+ /* first walk the list of devices to find a consistent set
|
||||
+ * that match the criterea, if that is possible.
|
||||
+ * We flag the ones we like with 'used'.
|
||||
+ */
|
||||
+ *found = 0;
|
||||
+ st = match_metadata_desc_imsm("imsm");
|
||||
+ if (st == NULL) {
|
||||
+ pr_vrb(": cannot allocate memory for imsm supertype\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
|
||||
+ char *devname = tmpdev->devname;
|
||||
+ struct stat stb;
|
||||
+ struct supertype *tst;
|
||||
+ int dfd;
|
||||
+ if (tmpdev->used > 1)
|
||||
+ continue;
|
||||
+ tst = dup_super(st);
|
||||
+ if (tst == NULL) {
|
||||
+ pr_vrb(": cannot allocate memory for imsm supertype\n");
|
||||
+ goto err_1;
|
||||
+ }
|
||||
+ tmpdev->container = 0;
|
||||
+ dfd = dev_open(devname, O_RDONLY|O_EXCL);
|
||||
+ if (dfd < 0) {
|
||||
+ dprintf(": cannot open device %s: %s\n",
|
||||
+ devname, strerror(errno));
|
||||
+ tmpdev->used = 2;
|
||||
+ } else if (fstat(dfd, &stb)< 0) {
|
||||
+ /* Impossible! */
|
||||
+ dprintf(": fstat failed for %s: %s\n",
|
||||
+ devname, strerror(errno));
|
||||
+ tmpdev->used = 2;
|
||||
+ } else if ((stb.st_mode & S_IFMT) != S_IFBLK) {
|
||||
+ dprintf(": %s is not a block device.\n",
|
||||
+ devname);
|
||||
+ tmpdev->used = 2;
|
||||
+ } else if (must_be_container(dfd)) {
|
||||
+ struct supertype *cst;
|
||||
+ cst = super_by_fd(dfd, NULL);
|
||||
+ if (cst == NULL) {
|
||||
+ dprintf(": cannot recognize container type %s\n",
|
||||
+ devname);
|
||||
+ tmpdev->used = 2;
|
||||
+ } else if (tst->ss != st->ss) {
|
||||
+ dprintf(": non-imsm container - ignore it: %s\n",
|
||||
+ devname);
|
||||
+ tmpdev->used = 2;
|
||||
+ } else if (!tst->ss->load_container ||
|
||||
+ tst->ss->load_container(tst, dfd, NULL))
|
||||
+ tmpdev->used = 2;
|
||||
+ else {
|
||||
+ tmpdev->container = 1;
|
||||
+ }
|
||||
+ if (cst)
|
||||
+ cst->ss->free_super(cst);
|
||||
+ } else {
|
||||
+ tmpdev->st_rdev = stb.st_rdev;
|
||||
+ if (tst->ss->load_super(tst,dfd, NULL)) {
|
||||
+ dprintf(": no RAID superblock on %s\n",
|
||||
+ devname);
|
||||
+ tmpdev->used = 2;
|
||||
+ } else if (tst->ss->compare_super == NULL) {
|
||||
+ dprintf(": Cannot assemble %s metadata on %s\n",
|
||||
+ tst->ss->name, devname);
|
||||
+ tmpdev->used = 2;
|
||||
+ }
|
||||
+ }
|
||||
+ if (dfd >= 0)
|
||||
+ close(dfd);
|
||||
+ if (tmpdev->used == 2 || tmpdev->used == 4) {
|
||||
+ /* Ignore unrecognised devices during auto-assembly */
|
||||
+ goto loop;
|
||||
+ }
|
||||
+ else {
|
||||
+ struct mdinfo info;
|
||||
+ tst->ss->getinfo_super(tst, &info, NULL);
|
||||
+
|
||||
+ if (st->minor_version == -1)
|
||||
+ st->minor_version = tst->minor_version;
|
||||
+
|
||||
+ if (memcmp(info.uuid, uuid_zero,
|
||||
+ sizeof(int[4])) == 0) {
|
||||
+ /* this is a floating spare. It cannot define
|
||||
+ * an array unless there are no more arrays of
|
||||
+ * this type to be found. It can be included
|
||||
+ * in an array of this type though.
|
||||
+ */
|
||||
+ tmpdev->used = 3;
|
||||
+ goto loop;
|
||||
+ }
|
||||
+
|
||||
+ if (st->ss != tst->ss ||
|
||||
+ st->minor_version != tst->minor_version ||
|
||||
+ st->ss->compare_super(st, tst) != 0) {
|
||||
+ /* Some mismatch. If exactly one array matches this host,
|
||||
+ * we can resolve on that one.
|
||||
+ * Or, if we are auto assembling, we just ignore the second
|
||||
+ * for now.
|
||||
+ */
|
||||
+ dprintf(": superblock on %s doesn't match others - assembly aborted\n",
|
||||
+ devname);
|
||||
+ goto loop;
|
||||
+ }
|
||||
+ tmpdev->used = 1;
|
||||
+ *found = 1;
|
||||
+ dprintf("found: devname: %s\n", devname);
|
||||
+ }
|
||||
+ loop:
|
||||
+ if (tst)
|
||||
+ tst->ss->free_super(tst);
|
||||
+ }
|
||||
+ if (*found != 0) {
|
||||
+ int err;
|
||||
+ if ((err = load_super_imsm_all(st, -1, &st->sb, NULL, devlist, 0)) == 0) {
|
||||
+ struct mdinfo *iter, *head = st->ss->container_content(st, NULL);
|
||||
+ for (iter = head; iter; iter = iter->next) {
|
||||
+ dprintf("content->text_version: %s vol\n",
|
||||
+ iter->text_version);
|
||||
+ if (iter->array.state & (1<<MD_SB_BLOCK_VOLUME)) {
|
||||
+ /* do not assemble arrays with unsupported
|
||||
+ configurations */
|
||||
+ dprintf(": Cannot activate member %s.\n",
|
||||
+ iter->text_version);
|
||||
+ } else
|
||||
+ count++;
|
||||
+ }
|
||||
+ sysfs_free(head);
|
||||
+
|
||||
+ } else {
|
||||
+ dprintf(" no valid super block on device list: err: %d %p\n",
|
||||
+ err, st->sb);
|
||||
+ }
|
||||
+ } else {
|
||||
+ dprintf(" no more devices to examin\n");
|
||||
+ }
|
||||
+
|
||||
+ for (tmpdev = devlist; tmpdev; tmpdev = tmpdev->next) {
|
||||
+ if ((tmpdev->used == 1) && (tmpdev->found)) {
|
||||
+ if (count) {
|
||||
+ if (count < tmpdev->found)
|
||||
+ count = 0;
|
||||
+ else
|
||||
+ count -= tmpdev->found;
|
||||
+ }
|
||||
+ }
|
||||
+ if (tmpdev->used == 1)
|
||||
+ tmpdev->used = 4;
|
||||
+ }
|
||||
+ err_1:
|
||||
+ if (st)
|
||||
+ st->ss->free_super(st);
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+static int
|
||||
+count_volumes(char *hba, int dpa, int verbose)
|
||||
+{
|
||||
+ struct md_list *devlist = NULL;
|
||||
+ int count = 0;
|
||||
+ int found = 0;;
|
||||
+
|
||||
+ devlist = get_devices(hba);
|
||||
+ /* if no intel devices return zero volumes */
|
||||
+ if (devlist == NULL)
|
||||
+ return 0;
|
||||
+
|
||||
+ count = active_arrays_by_format("imsm", hba, &devlist, dpa, verbose);
|
||||
+ dprintf(" path: %s active arrays: %d\n", hba, count);
|
||||
+ if (devlist == NULL)
|
||||
+ return 0;
|
||||
+ do {
|
||||
+ found = 0;
|
||||
+ count += count_volumes_list(devlist,
|
||||
+ NULL,
|
||||
+ verbose,
|
||||
+ &found);
|
||||
+ dprintf("found %d count: %d\n", found, count);
|
||||
+ } while (found);
|
||||
+
|
||||
+ dprintf("path: %s total number of volumes: %d\n", hba, count);
|
||||
+
|
||||
+ while(devlist) {
|
||||
+ struct md_list *dv = devlist;
|
||||
+ devlist = devlist->next;
|
||||
+ free(dv->devname);
|
||||
+ free(dv);
|
||||
+ }
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
static int imsm_default_chunk(const struct imsm_orom *orom)
|
||||
{
|
||||
/* up to 512 if the plaform supports it, otherwise the platform max.
|
||||
@@ -5583,6 +5954,15 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
||||
|
||||
*freesize = maxsize;
|
||||
|
||||
+ if (super->orom) {
|
||||
+ int count = count_volumes(super->hba->path,
|
||||
+ super->orom->dpa, verbose);
|
||||
+ if (super->orom->vphba <= count) {
|
||||
+ pr_vrb(": platform does not support more then %d raid volumes.\n",
|
||||
+ super->orom->vphba);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -5684,6 +6064,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
|
||||
if (!dev) {
|
||||
if (st->sb) {
|
||||
+ struct intel_super *super = st->sb;
|
||||
if (!validate_geometry_imsm_orom(st->sb, level, layout,
|
||||
raiddisks, chunk,
|
||||
verbose))
|
||||
@@ -5696,6 +6077,19 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
* created. add_to_super and getinfo_super
|
||||
* detect when autolayout is in progress.
|
||||
*/
|
||||
+ /* assuming that freesize is always given when array is
|
||||
+ created */
|
||||
+ if (super->orom && freesize) {
|
||||
+ int count;
|
||||
+ count = count_volumes(super->hba->path,
|
||||
+ super->orom->dpa, verbose);
|
||||
+ if (super->orom->vphba <= count) {
|
||||
+ pr_vrb(": platform does not support more"
|
||||
+ "then %d raid volumes.\n",
|
||||
+ super->orom->vphba);
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
if (freesize)
|
||||
return reserve_space(st, raiddisks, size,
|
||||
chunk?*chunk:0, freesize);
|
||||
@@ -7176,7 +7570,7 @@ static struct mdinfo *imsm_activate_spare(struct active_array *a,
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
-
|
||||
+
|
||||
mu->space = NULL;
|
||||
mu->space_list = NULL;
|
||||
mu->len = sizeof(struct imsm_update_activate_spare) * num_spares;
|
||||
@@ -7420,7 +7814,7 @@ error_disk_add:
|
||||
}
|
||||
|
||||
static int apply_update_activate_spare(struct imsm_update_activate_spare *u,
|
||||
- struct intel_super *super,
|
||||
+ struct intel_super *super,
|
||||
struct active_array *active_array)
|
||||
{
|
||||
struct imsm_super *mpb = super->anchor;
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,97 +0,0 @@
|
||||
From eb155f6de0986dc14c37dc9c4172bf0bcb8779fe Mon Sep 17 00:00:00 2001
|
||||
From: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Date: Wed, 25 Jan 2012 15:18:01 +0100
|
||||
Subject: [PATCH 1/4] mdmon: Use getopt_long() to parse command line options
|
||||
|
||||
This changes mdmon over to use getopt_long() for option parsing,
|
||||
making it easier to add new options. In addition this patch introduces
|
||||
a short version -t for --takeover and adds -h/--help.
|
||||
|
||||
Acked-by: Doug Ledford <dledford@redhat.com>
|
||||
Signed-off-by: Jes Sorensen <Jes.Sorensen@redhat.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
mdmon.c | 51 ++++++++++++++++++++++++++++++++++++++++-----------
|
||||
1 files changed, 40 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/mdmon.c b/mdmon.c
|
||||
index b6ae0e6..a65c4a4 100644
|
||||
--- a/mdmon.c
|
||||
+++ b/mdmon.c
|
||||
@@ -265,7 +265,14 @@ static int do_fork(void)
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
- fprintf(stderr, "Usage: mdmon [--all] [--takeover] CONTAINER\n");
|
||||
+ fprintf(stderr,
|
||||
+"Usage: mdmon [options] CONTAINER\n"
|
||||
+"\n"
|
||||
+"Options are:\n"
|
||||
+" --help -h : This message\n"
|
||||
+" --all : All devices\n"
|
||||
+" --takeover -t : Takeover container\n"
|
||||
+);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
@@ -277,25 +284,47 @@ int main(int argc, char *argv[])
|
||||
int devnum;
|
||||
char *devname;
|
||||
int status = 0;
|
||||
- int arg;
|
||||
+ int opt;
|
||||
int all = 0;
|
||||
int takeover = 0;
|
||||
-
|
||||
- for (arg = 1; arg < argc; arg++) {
|
||||
- if (strncmp(argv[arg], "--all",5) == 0 ||
|
||||
- strcmp(argv[arg], "/proc/mdstat") == 0) {
|
||||
- container_name = argv[arg];
|
||||
+ static struct option options[] = {
|
||||
+ {"all", 0, NULL, 'a'},
|
||||
+ {"takeover", 0, NULL, 't'},
|
||||
+ {"help", 0, NULL, 'h'},
|
||||
+ {NULL, 0, NULL, 0}
|
||||
+ };
|
||||
+
|
||||
+ while ((opt = getopt_long(argc, argv, "th", options, NULL)) != -1) {
|
||||
+ switch (opt) {
|
||||
+ case 'a':
|
||||
+ container_name = argv[optind-1];
|
||||
all = 1;
|
||||
- } else if (strcmp(argv[arg], "--takeover") == 0)
|
||||
+ break;
|
||||
+ case 't':
|
||||
+ container_name = optarg;
|
||||
takeover = 1;
|
||||
- else if (container_name == NULL)
|
||||
- container_name = argv[arg];
|
||||
- else
|
||||
+ break;
|
||||
+ case 'h':
|
||||
+ default:
|
||||
usage();
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ if (all == 0 && container_name == NULL) {
|
||||
+ if (argv[optind])
|
||||
+ container_name = argv[optind];
|
||||
+ }
|
||||
+
|
||||
if (container_name == NULL)
|
||||
usage();
|
||||
|
||||
+ if (argc - optind > 1)
|
||||
+ usage();
|
||||
+
|
||||
+ if (strcmp(container_name, "/proc/mdstat") == 0)
|
||||
+ all = 1;
|
||||
+
|
||||
if (all) {
|
||||
struct mdstat_ent *mdstat, *e;
|
||||
int container_len = strlen(container_name);
|
||||
--
|
||||
1.7.8.4
|
||||
|
@ -1,92 +0,0 @@
|
||||
From 68226a80812cd9fce63dbd14d2225ffdf16a781b Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Tue, 3 Jan 2012 00:36:23 +1100
|
||||
Subject: [PATCH 2/2] monitor: ensure we retry soon when 'remove' fails.
|
||||
|
||||
If a 'remove' fails there is no certainty that another event will
|
||||
happen soon, so make sure we retry soon anyway.
|
||||
|
||||
Reported-by: Adam Kwolek <adam.kwolek@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
mdadm.h | 1 +
|
||||
monitor.c | 16 ++++++++++------
|
||||
2 files changed, 11 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/mdadm.h b/mdadm.h
|
||||
index 3bcd052..381ef86 100644
|
||||
--- a/mdadm.h
|
||||
+++ b/mdadm.h
|
||||
@@ -867,6 +867,7 @@ struct supertype {
|
||||
* external:/md0/12
|
||||
*/
|
||||
int devcnt;
|
||||
+ int retry_soon;
|
||||
|
||||
struct mdinfo *devs;
|
||||
|
||||
diff --git a/monitor.c b/monitor.c
|
||||
index cfe4178..c987d10 100644
|
||||
--- a/monitor.c
|
||||
+++ b/monitor.c
|
||||
@@ -212,6 +212,7 @@ static void signal_manager(void)
|
||||
*/
|
||||
|
||||
#define ARRAY_DIRTY 1
|
||||
+#define ARRAY_BUSY 2
|
||||
static int read_and_act(struct active_array *a)
|
||||
{
|
||||
unsigned long long sync_completed;
|
||||
@@ -419,9 +420,9 @@ static int read_and_act(struct active_array *a)
|
||||
if ((mdi->next_state & DS_REMOVE) && mdi->state_fd >= 0) {
|
||||
int remove_result;
|
||||
|
||||
- /* the kernel may not be able to immediately remove the
|
||||
- * disk, we can simply wait until the next event to try
|
||||
- * again.
|
||||
+ /* The kernel may not be able to immediately remove the
|
||||
+ * disk. In that case we wait a little while and
|
||||
+ * try again.
|
||||
*/
|
||||
remove_result = write_attr("remove", mdi->state_fd);
|
||||
if (remove_result > 0) {
|
||||
@@ -429,7 +430,8 @@ static int read_and_act(struct active_array *a)
|
||||
close(mdi->state_fd);
|
||||
close(mdi->recovery_fd);
|
||||
mdi->state_fd = -1;
|
||||
- }
|
||||
+ } else
|
||||
+ ret |= ARRAY_BUSY;
|
||||
}
|
||||
if (mdi->next_state & DS_INSYNC) {
|
||||
write_attr("+in_sync", mdi->state_fd);
|
||||
@@ -597,7 +599,7 @@ static int wait_and_act(struct supertype *container, int nowait)
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 24*3600;
|
||||
ts.tv_nsec = 0;
|
||||
- if (*aap == NULL) {
|
||||
+ if (*aap == NULL || container->retry_soon) {
|
||||
/* just waiting to get O_EXCL access */
|
||||
ts.tv_sec = 0;
|
||||
ts.tv_nsec = 20000000ULL;
|
||||
@@ -612,7 +614,7 @@ static int wait_and_act(struct supertype *container, int nowait)
|
||||
#ifdef DEBUG
|
||||
dprint_wake_reasons(&rfds);
|
||||
#endif
|
||||
-
|
||||
+ container->retry_soon = 0;
|
||||
}
|
||||
|
||||
if (update_queue) {
|
||||
@@ -653,6 +655,8 @@ static int wait_and_act(struct supertype *container, int nowait)
|
||||
*/
|
||||
if (sigterm && !(ret & ARRAY_DIRTY))
|
||||
a->container = NULL; /* stop touching this array */
|
||||
+ if (ret & ARRAY_BUSY)
|
||||
+ container->retry_soon = 1;
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.7.8.2
|
||||
|
@ -1,109 +0,0 @@
|
||||
From 77b3ac8c6521d836dd3c6ef247c252293920fd52 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Tue, 3 Jan 2012 11:18:59 +1100
|
||||
Subject: [PATCH 1/2] monitor: make return from read_and_act more symbolic.
|
||||
|
||||
Rather than just a number, use a named flag.
|
||||
|
||||
This makes the code easier to understand and allows room for returning
|
||||
more flags later.
|
||||
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
monitor.c | 20 ++++++++++----------
|
||||
1 files changed, 10 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/monitor.c b/monitor.c
|
||||
index 29bde18..cfe4178 100644
|
||||
--- a/monitor.c
|
||||
+++ b/monitor.c
|
||||
@@ -211,6 +211,7 @@ static void signal_manager(void)
|
||||
*
|
||||
*/
|
||||
|
||||
+#define ARRAY_DIRTY 1
|
||||
static int read_and_act(struct active_array *a)
|
||||
{
|
||||
unsigned long long sync_completed;
|
||||
@@ -218,7 +219,7 @@ static int read_and_act(struct active_array *a)
|
||||
int check_reshape = 0;
|
||||
int deactivate = 0;
|
||||
struct mdinfo *mdi;
|
||||
- int dirty = 0;
|
||||
+ int ret = 0;
|
||||
int count = 0;
|
||||
|
||||
a->next_state = bad_word;
|
||||
@@ -254,14 +255,14 @@ static int read_and_act(struct active_array *a)
|
||||
if (a->curr_state == write_pending) {
|
||||
a->container->ss->set_array_state(a, 0);
|
||||
a->next_state = active;
|
||||
- dirty = 1;
|
||||
+ ret |= ARRAY_DIRTY;
|
||||
}
|
||||
if (a->curr_state == active_idle) {
|
||||
/* Set array to 'clean' FIRST, then mark clean
|
||||
* in the metadata
|
||||
*/
|
||||
a->next_state = clean;
|
||||
- dirty = 1;
|
||||
+ ret |= ARRAY_DIRTY;
|
||||
}
|
||||
if (a->curr_state == clean) {
|
||||
a->container->ss->set_array_state(a, 1);
|
||||
@@ -269,7 +270,7 @@ static int read_and_act(struct active_array *a)
|
||||
if (a->curr_state == active ||
|
||||
a->curr_state == suspended ||
|
||||
a->curr_state == bad_word)
|
||||
- dirty = 1;
|
||||
+ ret |= ARRAY_DIRTY;
|
||||
if (a->curr_state == readonly) {
|
||||
/* Well, I'm ready to handle things. If readonly
|
||||
* wasn't requested, transition to read-auto.
|
||||
@@ -284,7 +285,7 @@ static int read_and_act(struct active_array *a)
|
||||
a->next_state = read_auto; /* array is clean */
|
||||
else {
|
||||
a->next_state = active; /* Now active for recovery etc */
|
||||
- dirty = 1;
|
||||
+ ret |= ARRAY_DIRTY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -459,7 +460,7 @@ static int read_and_act(struct active_array *a)
|
||||
if (deactivate)
|
||||
a->container = NULL;
|
||||
|
||||
- return dirty;
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
static struct mdinfo *
|
||||
@@ -629,7 +630,6 @@ static int wait_and_act(struct supertype *container, int nowait)
|
||||
rv = 0;
|
||||
dirty_arrays = 0;
|
||||
for (a = *aap; a ; a = a->next) {
|
||||
- int is_dirty;
|
||||
|
||||
if (a->replaces && !discard_this) {
|
||||
struct active_array **ap;
|
||||
@@ -644,14 +644,14 @@ static int wait_and_act(struct supertype *container, int nowait)
|
||||
signal_manager();
|
||||
}
|
||||
if (a->container && !a->to_remove) {
|
||||
- is_dirty = read_and_act(a);
|
||||
+ int ret = read_and_act(a);
|
||||
rv |= 1;
|
||||
- dirty_arrays += is_dirty;
|
||||
+ dirty_arrays += !!(ret & ARRAY_DIRTY);
|
||||
/* when terminating stop manipulating the array after it
|
||||
* is clean, but make sure read_and_act() is given a
|
||||
* chance to handle 'active_idle'
|
||||
*/
|
||||
- if (sigterm && !is_dirty)
|
||||
+ if (sigterm && !(ret & ARRAY_DIRTY))
|
||||
a->container = NULL; /* stop touching this array */
|
||||
}
|
||||
}
|
||||
--
|
||||
1.7.8.2
|
||||
|
@ -1,39 +0,0 @@
|
||||
From 29cd0821bfe5acdeac0b8bb54b1de9e07a453323 Mon Sep 17 00:00:00 2001
|
||||
From: "Czarnowska, Anna" <anna.czarnowska@intel.com>
|
||||
Date: Mon, 2 Apr 2012 10:17:25 +1000
|
||||
Subject: [PATCH 4/7] show 2TB volumes/disks support in --detail-platform
|
||||
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
platform-intel.h | 1 +
|
||||
super-intel.c | 4 ++++
|
||||
2 files changed, 5 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/platform-intel.h b/platform-intel.h
|
||||
index c997f1b..94f2e81 100644
|
||||
--- a/platform-intel.h
|
||||
+++ b/platform-intel.h
|
||||
@@ -76,6 +76,7 @@ struct imsm_orom {
|
||||
#define IMSM_OROM_ATTR_RAID1E IMSM_OROM_RLC_RAID1E
|
||||
#define IMSM_OROM_ATTR_RAID5 IMSM_OROM_RLC_RAID5
|
||||
#define IMSM_OROM_ATTR_RAID_CNG IMSM_OROM_RLC_RAID_CNG
|
||||
+ #define IMSM_OROM_ATTR_2TB_DISK (1 << 26)
|
||||
#define IMSM_OROM_ATTR_2TB (1 << 29)
|
||||
#define IMSM_OROM_ATTR_PM (1 << 30)
|
||||
#define IMSM_OROM_ATTR_ChecksumVerify (1 << 31)
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 642ca26..0c38b45 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -1786,6 +1786,10 @@
|
||||
printf(" Max Disks : %d\n", orom->tds);
|
||||
printf(" Max Volumes per array : %d\n", orom->vpa);
|
||||
printf(" Max Volumes per controller: %d\n", orom->vphba);
|
||||
+ printf(" 2TB Volumes:%s supported\n",
|
||||
+ (orom->attr & IMSM_OROM_ATTR_2TB) ? "" : " not");
|
||||
+ printf(" 2TB Disks:%s supported\n",
|
||||
+ (orom->attr & IMSM_OROM_ATTR_2TB_DISK) ? "" : " not");
|
||||
return;
|
||||
}
|
||||
|
@ -1,47 +0,0 @@
|
||||
From e03640bda562df11b60ceaaa40a56425f358090e Mon Sep 17 00:00:00 2001
|
||||
From: "Czarnowska, Anna" <anna.czarnowska@intel.com>
|
||||
Date: Mon, 2 Apr 2012 10:16:04 +1000
|
||||
Subject: [PATCH 3/7] simplify calculating array_blocks
|
||||
|
||||
no point calling info_to_blocks_per_member when it just returns size*2 for level==1
|
||||
calc_array_size can be used for all levels
|
||||
|
||||
Signed-off-by: Anna Czarnowska <anna.czarnowska@intel.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super-intel.c | 5 +----
|
||||
util.c | 2 ++
|
||||
2 files changed, 3 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/super-intel.c b/super-intel.c
|
||||
index 480b379..642ca26 100644
|
||||
--- a/super-intel.c
|
||||
+++ b/super-intel.c
|
||||
@@ -4623,10 +4623,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||
}
|
||||
|
||||
strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
|
||||
- if (info->level == 1)
|
||||
- array_blocks = info_to_blocks_per_member(info, size);
|
||||
- else
|
||||
- array_blocks = calc_array_size(info->level, info->raid_disks,
|
||||
+ array_blocks = calc_array_size(info->level, info->raid_disks,
|
||||
info->layout, info->chunk_size,
|
||||
size * 2);
|
||||
/* round array size down to closest MB */
|
||||
diff --git a/util.c b/util.c
|
||||
index 7abbff7..d32e650 100644
|
||||
--- a/util.c
|
||||
+++ b/util.c
|
||||
@@ -711,6 +711,8 @@ void print_r10_layout(int layout)
|
||||
unsigned long long calc_array_size(int level, int raid_disks, int layout,
|
||||
int chunksize, unsigned long long devsize)
|
||||
{
|
||||
+ if (level == 1)
|
||||
+ return devsize;
|
||||
devsize &= ~(unsigned long long)((chunksize>>9)-1);
|
||||
return get_data_disks(level, layout, raid_disks) * devsize;
|
||||
}
|
||||
--
|
||||
1.7.7.6
|
||||
|
@ -1,88 +0,0 @@
|
||||
From 6ef89052d85b8137b8a7100f761d896ae6f61001 Mon Sep 17 00:00:00 2001
|
||||
From: NeilBrown <neilb@suse.de>
|
||||
Date: Tue, 7 Feb 2012 11:55:18 +1100
|
||||
Subject: [PATCH] super1: make aread/awrite always use an aligned buffer.
|
||||
|
||||
A recently change to write_bitmap1 meant awrite would sometimes
|
||||
write from a non-aligned buffer which of course break.
|
||||
|
||||
So change awrite (and aread) to always use their own aligned
|
||||
buffer to ensure safety.
|
||||
|
||||
Reported-by: Alexander Lyakas <alex.bolshoy@gmail.com>
|
||||
Signed-off-by: NeilBrown <neilb@suse.de>
|
||||
---
|
||||
super1.c | 39 +++++++++++++++++++++++----------------
|
||||
1 files changed, 23 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/super1.c b/super1.c
|
||||
index d23d6e8..cfa237a 100644
|
||||
--- a/super1.c
|
||||
+++ b/super1.c
|
||||
@@ -143,17 +143,19 @@ static int aread(int fd, void *buf, int len)
|
||||
* the full sector and copy relevant bits into
|
||||
* the buffer
|
||||
*/
|
||||
- int bsize;
|
||||
+ int bsize, iosize;
|
||||
char *b;
|
||||
int n;
|
||||
- if (ioctl(fd, BLKSSZGET, &bsize) != 0 ||
|
||||
- bsize <= len)
|
||||
- return read(fd, buf, len);
|
||||
- if (bsize > 4096)
|
||||
+ if (ioctl(fd, BLKSSZGET, &bsize) != 0)
|
||||
+ bsize = 512;
|
||||
+
|
||||
+ if (bsize > 4096 || len > 4096)
|
||||
return -1;
|
||||
b = (char*)(((long)(abuf+4096))&~4095UL);
|
||||
|
||||
- n = read(fd, b, bsize);
|
||||
+ for (iosize = 0; iosize < len; iosize += bsize)
|
||||
+ ;
|
||||
+ n = read(fd, b, iosize);
|
||||
if (n <= 0)
|
||||
return n;
|
||||
lseek(fd, len - n, 1);
|
||||
@@ -171,22 +173,27 @@ static int awrite(int fd, void *buf, int len)
|
||||
* than the write.
|
||||
* The address must be sector-aligned.
|
||||
*/
|
||||
- int bsize;
|
||||
+ int bsize, iosize;
|
||||
char *b;
|
||||
int n;
|
||||
- if (ioctl(fd, BLKSSZGET, &bsize) != 0 ||
|
||||
- bsize <= len)
|
||||
- return write(fd, buf, len);
|
||||
- if (bsize > 4096)
|
||||
+ if (ioctl(fd, BLKSSZGET, &bsize) != 0)
|
||||
+ bsize = 512;
|
||||
+ if (bsize > 4096 || len > 4096)
|
||||
return -1;
|
||||
b = (char*)(((long)(abuf+4096))&~4095UL);
|
||||
|
||||
- n = read(fd, b, bsize);
|
||||
- if (n <= 0)
|
||||
- return n;
|
||||
- lseek(fd, -n, 1);
|
||||
+ for (iosize = 0; iosize < len ; iosize += bsize)
|
||||
+ ;
|
||||
+
|
||||
+ if (len != iosize) {
|
||||
+ n = read(fd, b, iosize);
|
||||
+ if (n <= 0)
|
||||
+ return n;
|
||||
+ lseek(fd, -n, 1);
|
||||
+ }
|
||||
+
|
||||
memcpy(b, buf, len);
|
||||
- n = write(fd, b, bsize);
|
||||
+ n = write(fd, b, iosize);
|
||||
if (n <= 0)
|
||||
return n;
|
||||
lseek(fd, len - n, 1);
|
||||
--
|
||||
1.7.7.6
|
||||
|
18
mdadm-3.2.4-map-dir.patch
Normal file
18
mdadm-3.2.4-map-dir.patch
Normal file
@ -0,0 +1,18 @@
|
||||
--- mdadm-3.2.4/Makefile.map-dir 2012-05-10 12:29:09.687578525 +0200
|
||||
+++ mdadm-3.2.4/Makefile 2012-05-10 12:28:05.514380800 +0200
|
||||
@@ -67,12 +67,12 @@
|
||||
# Both MAP_DIR and MDMON_DIR should be somewhere that persists across the
|
||||
# pivotroot from early boot to late boot.
|
||||
# /run is best, but for distros that don't support that, /dev can work.
|
||||
-MAP_DIR=/run/mdadm
|
||||
-MAP_FILE = map
|
||||
+MAP_DIR=/dev/md
|
||||
+MAP_FILE = md-device-map
|
||||
MAP_PATH = $(MAP_DIR)/$(MAP_FILE)
|
||||
MDMON_DIR = $(MAP_DIR)
|
||||
# place for autoreplace cookies
|
||||
-FAILED_SLOTS_DIR = /run/mdadm/failed-slots
|
||||
+FAILED_SLOTS_DIR = $(MDMON_DIR)/failed-slots
|
||||
DIRFLAGS = -DMAP_DIR=\"$(MAP_DIR)\" -DMAP_FILE=\"$(MAP_FILE)\"
|
||||
DIRFLAGS += -DMDMON_DIR=\"$(MDMON_DIR)\"
|
||||
DIRFLAGS += -DFAILED_SLOTS_DIR=\"$(FAILED_SLOTS_DIR)\"
|
161
mdadm.spec
161
mdadm.spec
@ -1,8 +1,8 @@
|
||||
Summary: The mdadm program controls Linux md devices (software RAID arrays)
|
||||
Name: mdadm
|
||||
Version: 3.2.3
|
||||
Release: 9%{?dist}
|
||||
Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.bz2
|
||||
Version: 3.2.4
|
||||
Release: 1%{?dist}
|
||||
Source: http://www.kernel.org/pub/linux/utils/raid/mdadm/mdadm-%{version}.tar.xz
|
||||
Source1: mdmonitor.init
|
||||
Source2: raid-check
|
||||
Source3: mdadm.rules
|
||||
@ -11,78 +11,11 @@ Source5: mdadm-cron
|
||||
Source6: mdmonitor.service
|
||||
Source7: mdmonitor-takeover.service
|
||||
Source8: mdadm.conf
|
||||
Patch1: mdadm-3.2.3-Work-around-gcc-4.7-s-strict-aliasing-checks.patch
|
||||
Patch2: mdadm-3.2.3-monitor-make-return-from-read_and_act-more-symbolic.patch
|
||||
Patch3: mdadm-3.2.3-monitor-ensure-we-retry-soon-when-remove-fails.patch
|
||||
Patch4: mdadm-3.2.3-mdmon-Use-getopt_long-to-parse-command-line-options.patch
|
||||
Patch5: mdadm-3.2.3-Add-offroot-argument-to-mdadm.patch
|
||||
Patch6: mdadm-3.2.3-Add-offroot-argument-to-mdmon.patch
|
||||
Patch7: mdadm-3.2.3-Spawn-mdmon-with-offroot-if-mdadm-was-launched-with-.patch
|
||||
Patch8: mdadm-3.2.3-super1-make-aread-awrite-always-use-an-aligned-buffe.patch
|
||||
Patch9: mdadm-3.2.3-avoid-double-free-upon-old-buggy-kernel-sysfs_read-f.patch
|
||||
Patch10: mdadm-3.2.3-Print-error-message-if-failing-to-write-super-for-1..patch
|
||||
Patch11: mdadm-3.2.3-Incremental-fix-adding-devices-with-incremental.patch
|
||||
Patch12: mdadm-3.2.3-FIX-External-metadata-sometimes-is-not-updated.patch
|
||||
Patch13: mdadm-3.2.3-FIX-mdmon-check-in-reshape_container-can-cause-a-pro.patch
|
||||
Patch14: mdadm-3.2.3-imsm-display-fd-in-error-trace-when-when-store_imsm_.patch
|
||||
Patch15: mdadm-3.2.3-FIX-NULL-pointer-to-strdup-can-be-passed.patch
|
||||
Patch16: mdadm-3.2.3-imsm-FIX-No-new-missing-disks-are-allowed-during-gen.patch
|
||||
Patch17: mdadm-3.2.3-FIX-Array-is-not-run-when-expansion-disks-are-added.patch
|
||||
Patch18: mdadm-3.2.3-imsm-FIX-imsm_get_allowed_degradation-doesn-t-count-.patch
|
||||
Patch19: mdadm-3.2.3-Fix-Sometimes-mdmon-throws-core-dump-during-reshape.patch
|
||||
Patch20: mdadm-3.2.3-Flush-mdmon-before-next-reshape-step-during-containe.patch
|
||||
Patch21: mdadm-3.2.3-imsm-FIX-Chunk-size-migration-problem.patch
|
||||
Patch22: mdadm-3.2.3-FIX-use-md-position-to-reshape-restart.patch
|
||||
Patch23: mdadm-3.2.3-imsm-FIX-use-md-position-to-reshape-restart.patch
|
||||
Patch24: mdadm-3.2.3-imsm-FIX-Clear-migration-record-when-migration-switc.patch
|
||||
Patch25: mdadm-3.2.3-FIX-restart-reshape-when-reshape-process-is-stopped-.patch
|
||||
Patch26: mdadm-3.2.3-FIX-Do-not-try-to-continue-reshape-using-inactive-ar.patch
|
||||
Patch27: mdadm-3.2.3-FIX-Changes-in-0-case-for-reshape-position-verificat.patch
|
||||
Patch28: mdadm-3.2.3-fix-Monitor-sometimes-crashes.patch
|
||||
Patch29: mdadm-3.2.3-fix-container-creation-with-incremental-used.patch
|
||||
Patch30: mdadm-3.2.3-imsm-fix-the-second-array-need-to-have-the-whole-ava.patch
|
||||
Patch31: mdadm-3.2.3-imsm-load_super_imsm_all-function-refactoring.patch
|
||||
Patch32: mdadm-3.2.3-imsm-load_imsm_super_all-supports-loading-metadata-f.patch
|
||||
Patch33: mdadm-3.2.3-imsm-validate-the-number-of-imsm-volumes-per-control.patch
|
||||
Patch34: mdadm-3.2.3-imsm-display-maximum-volumes-per-controller-in-detai.patch
|
||||
Patch35: mdadm-3.2.3-imsm-avoid-overflows-for-disks-over-1TB.patch
|
||||
Patch36: mdadm-3.2.3-clear-hi-bits-if-not-used-after-loading-metadata-fro.patch
|
||||
Patch37: mdadm-3.2.3-simplify-calculating-array_blocks.patch
|
||||
Patch38: mdadm-3.2.3-show-2TB-volumes-disks-support-in-detail-platform.patch
|
||||
Patch39: mdadm-3.2.3-check-volume-size-in-validate_geometry_imsm_orom.patch
|
||||
Patch40: mdadm-3.2.3-check-that-no-disk-over-2TB-is-used-to-create-contai.patch
|
||||
Patch41: mdadm-3.2.3-imsm-set-2tb-disk-attribute-for-spare.patch
|
||||
Patch42: mdadm-3.2.3-imsm-fix-thunderdome-may-drop-2tb-attribute.patch
|
||||
Patch43: mdadm-3.2.3-imsm-FIX-Update-function-imsm_num_data_members-for-R.patch
|
||||
Patch44: mdadm-3.2.3-imsm-FIX-Add-volume-size-expand-support-to-imsm_anal.patch
|
||||
Patch45: mdadm-3.2.3-imsm-Add-new-metadata-update-for-volume-size-expansi.patch
|
||||
Patch46: mdadm-3.2.3-imsm-Execute-size-change-for-external-metatdata.patch
|
||||
Patch47: mdadm-3.2.3-FIX-Support-metadata-changes-rollback.patch
|
||||
Patch48: mdadm-3.2.3-imsm-FIX-Support-metadata-changes-rollback.patch
|
||||
Patch49: mdadm-3.2.3-FIX-Extend-size-of-raid0-array.patch
|
||||
Patch50: mdadm-3.2.3-FIX-Respect-metadata-size-limitations.patch
|
||||
Patch51: mdadm-3.2.3-FIX-Detect-error-and-rollback-metadata.patch
|
||||
Patch52: mdadm-3.2.3-imsm-Add-function-imsm_get_free_size.patch
|
||||
Patch53: mdadm-3.2.3-imsm-Support-setting-max-size-for-size-change-operat.patch
|
||||
Patch54: mdadm-3.2.3-imsm-FIX-Component-size-alignment-check.patch
|
||||
Patch55: mdadm-3.2.3-FIX-Size-change-is-possible-as-standalone-change-onl.patch
|
||||
Patch56: mdadm-3.2.3-FIX-Assembled-second-array-is-in-read-only-state-dur.patch
|
||||
Patch57: mdadm-3.2.3-fix-correct-extending-size-of-raid0-array.patch
|
||||
Patch58: mdadm-3.2.3-imsm-fix-rebuild-does-not-continue-after-reboot.patch
|
||||
Patch59: mdadm-3.2.3-Manage-allow-re-add-to-failed-array.patch
|
||||
Patch60: mdadm-3.2.3-Manage-replace-return-1-with-goto-abort.patch
|
||||
Patch61: mdadm-3.2.3-Manage-freeze-recovery-while-adding-multiple-devices.patch
|
||||
Patch62: mdadm-3.2.3-Relax-restrictions-on-when-add-is-permitted.patch
|
||||
Patch63: mdadm-3.2.3-Raid-limit-of-1024-when-scanning-for-devices.patch
|
||||
Patch64: mdadm-3.2.3-Remove-avail_disks-arg-from-enough.patch
|
||||
Patch65: mdadm-3.2.3-Reset-bad-flag-on-map-update.patch
|
||||
Patch66: mdadm-3.2.3-Bitmap_offset-is-a-signed-number.patch
|
||||
Patch67: mdadm-3.2.3-Fix-sign-extension-of-bitmap_offset-in-super1.c.patch
|
||||
Patch68: mdadm-3.2.3-Introduce-sysfs_set_num_signed-and-use-it-to-set-bit.patch
|
||||
|
||||
# Fedora customization patches
|
||||
Patch98: mdadm-3.2.3-udev.patch
|
||||
Patch99: mdadm-2.5.2-static.patch
|
||||
Patch97: mdadm-3.2.3-udev.patch
|
||||
Patch98: mdadm-2.5.2-static.patch
|
||||
# Fedora 15, 16, 17 - only
|
||||
Patch99: mdadm-3.2.4-map-dir.patch
|
||||
URL: http://www.kernel.org/pub/linux/utils/raid/mdadm/
|
||||
License: GPLv2+
|
||||
Group: System Environment/Base
|
||||
@ -115,78 +48,14 @@ is not used as the system init process.
|
||||
|
||||
%prep
|
||||
%setup -q
|
||||
%patch1 -p1 -b .gcc47
|
||||
%patch2 -p1 -b .read
|
||||
%patch3 -p1 -b .retry
|
||||
%patch4 -p1 -b .getopt
|
||||
%patch5 -p1 -b .offroot-mdadm
|
||||
%patch6 -p1 -b .offroot-mdmon
|
||||
%patch7 -p1 -b .offroot-spawn
|
||||
%patch8 -p1 -b .bitmap
|
||||
%patch9 -p1 -b .double
|
||||
%patch10 -p1 -b .print
|
||||
%patch11 -p1 -b .incremental
|
||||
%patch12 -p1 -b .update
|
||||
%patch13 -p1 -b .mdmon
|
||||
%patch14 -p1 -b .display
|
||||
%patch15 -p1 -b .strdup
|
||||
%patch16 -p1 -b .missing
|
||||
%patch17 -p1 -b .exp
|
||||
%patch18 -p1 -b .allowed
|
||||
%patch19 -p1 -b .core
|
||||
%patch20 -p1 -b .flush
|
||||
%patch21 -p1 -b .chunk
|
||||
%patch22 -p1 -b .position
|
||||
%patch23 -p1 -b .reshape
|
||||
%patch24 -p1 -b .record
|
||||
%patch25 -p1 -b .restart
|
||||
%patch26 -p1 -b .nocontinue
|
||||
%patch27 -p1 -b .0case
|
||||
%patch28 -p1 -b .monitor3
|
||||
%patch29 -p1 -b .container
|
||||
%patch30 -p1 -b .available
|
||||
%patch31 -p1 -b .validate-1
|
||||
%patch32 -p1 -b .validate-2
|
||||
%patch33 -p1 -b .validate-3
|
||||
%patch34 -p1 -b .validate-4
|
||||
%patch35 -p1 -b .2tb-1
|
||||
%patch36 -p1 -b .2tb-2
|
||||
%patch37 -p1 -b .2tb-3
|
||||
%patch38 -p1 -b .2tb-4
|
||||
%patch39 -p1 -b .2tb-5
|
||||
%patch40 -p1 -b .2tb-6
|
||||
%patch41 -p1 -b .2tb-7
|
||||
%patch42 -p1 -b .2tb-8
|
||||
%patch43 -p1 -b .expand-01
|
||||
%patch44 -p1 -b .expand-02
|
||||
%patch45 -p1 -b .expand-03
|
||||
%patch46 -p1 -b .expand-04
|
||||
%patch47 -p1 -b .expand-05
|
||||
%patch48 -p1 -b .expand-06
|
||||
%patch49 -p1 -b .expand-07
|
||||
%patch50 -p1 -b .expand-08
|
||||
%patch51 -p1 -b .expand-09
|
||||
%patch52 -p1 -b .expand-10
|
||||
%patch53 -p1 -b .expand-11
|
||||
%patch54 -p1 -b .expand-12
|
||||
%patch55 -p1 -b .expand-13
|
||||
%patch56 -p1 -b .expand-14
|
||||
%patch57 -p1 -b .expand-15
|
||||
%patch58 -p1 -b .rebuild-continue
|
||||
%patch59 -p1 -b .allow-re-add
|
||||
%patch60 -p1 -b .replace-return-1
|
||||
%patch61 -p1 -b .freeze-recovery
|
||||
%patch62 -p1 -b .make-add-work
|
||||
%patch63 -p1 -b .max-devices
|
||||
%patch64 -p1 -b .enough
|
||||
%patch65 -p1 -b .bad-flag
|
||||
%patch66 -p1 -b .bitmap-offset
|
||||
%patch67 -p1 -b .bitmap-offset2
|
||||
%patch68 -p1 -b .bitmap-offset3
|
||||
|
||||
# Fedora customization patches
|
||||
%patch98 -p1 -b .udev
|
||||
%patch99 -p1 -b .static
|
||||
%patch97 -p1 -b .udev
|
||||
%patch98 -p1 -b .static
|
||||
# Fedora 15, 16, 17 - only
|
||||
%if "%{fedora}" <= "17"
|
||||
%patch99 -p1 -b .map-dir
|
||||
%endif
|
||||
|
||||
%build
|
||||
make %{?_smp_mflags} CXFLAGS="$RPM_OPT_FLAGS" SYSCONFDIR="%{_sysconfdir}" mdadm mdmon
|
||||
@ -259,6 +128,10 @@ fi
|
||||
%{_initrddir}/*
|
||||
|
||||
%changelog
|
||||
* Thu May 10 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.4-1
|
||||
- Upgrade to mdadm-3.2.4
|
||||
- Resolves bz820534 (rawhide) bz820527 (f17) bz820531 (f16) bz820532 (f15)
|
||||
|
||||
* Mon Apr 30 2012 Jes Sorensen <Jes.Sorensen@redhat.com> - 3.2.3-9
|
||||
- Fix Monitor mode sometimes crashes when a resync completes
|
||||
- Fix missing symlink for mdadm container device when incremental creates
|
||||
|
Loading…
Reference in New Issue
Block a user