[PATCH 2/7] Enable create array with write cache (--write-cache DEVICE).

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Specify the write cache device with --write-cache DEVICE

./mdadm --create -f /dev/md0 --assume-clean -c 32 --raid-devices=4 --level=5 /dev/sd[c-f] --write-cache /dev/sdb1
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

Only one cache device is allowed. If multiple --write-cache
are given, mdadm will use the first and ignore others

./mdadm --create -f /dev/md0 --assume-clean -c 32 --raid-devices=4 --level=5 /dev/sd[c-f] --write-cache /dev/sdb1 --write-cache /dev/sdx
mdadm: Please specify only one cache device for the array.
mdadm: Ignoring --write-cache /dev/sdx...
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.

Signed-off-by: Song Liu <songliubraving@xxxxxx>
---
 Create.c | 21 +++++++++++++++------
 ReadMe.c |  1 +
 mdadm.c  | 19 +++++++++++++++++++
 mdadm.h  |  2 ++
 super1.c |  8 ++++++++
 5 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/Create.c b/Create.c
index ef28da0..0d2a591 100644
--- a/Create.c
+++ b/Create.c
@@ -87,7 +87,7 @@ int Create(struct supertype *st, char *mddev,
 	unsigned long long minsize=0, maxsize=0;
 	char *mindisc = NULL;
 	char *maxdisc = NULL;
-	int dnum;
+	int dnum, raid_disk_num;
 	struct mddev_dev *dv;
 	int fail=0, warn=0;
 	struct stat stb;
@@ -180,11 +180,11 @@ int Create(struct supertype *st, char *mddev,
 		pr_err("This metadata type does not support spare disks at create time\n");
 		return 1;
 	}
-	if (subdevs > s->raiddisks+s->sparedisks) {
+	if (subdevs > s->raiddisks+s->sparedisks+s->cachedisks) {
 		pr_err("You have listed more devices (%d) than are in the array(%d)!\n", subdevs, s->raiddisks+s->sparedisks);
 		return 1;
 	}
-	if (!have_container && subdevs < s->raiddisks+s->sparedisks) {
+	if (!have_container && subdevs < s->raiddisks+s->sparedisks+s->cachedisks) {
 		pr_err("You haven't given enough devices (real or missing) to create this array\n");
 		return 1;
 	}
@@ -397,6 +397,9 @@ int Create(struct supertype *st, char *mddev,
 			}
 		}
 
+		if (dv->disposition == 'c')
+			continue;  /* skip write cache for size check */
+
 		freesize /= 2; /* convert to K */
 		if (s->chunk && s->chunk != UnSet) {
 			/* round to chunk size */
@@ -834,7 +837,7 @@ int Create(struct supertype *st, char *mddev,
 	for (pass=1; pass <=2 ; pass++) {
 		struct mddev_dev *moved_disk = NULL; /* the disk that was moved out of the insert point */
 
-		for (dnum=0, dv = devlist ; dv ;
+		for (dnum=0, raid_disk_num=0, dv = devlist ; dv ;
 		     dv=(dv->next)?(dv->next):moved_disk, dnum++) {
 			int fd;
 			struct stat stb;
@@ -859,8 +862,13 @@ int Create(struct supertype *st, char *mddev,
 				*inf = info;
 
 				inf->disk.number = dnum;
-				inf->disk.raid_disk = dnum;
-				if (inf->disk.raid_disk < s->raiddisks)
+				inf->disk.raid_disk = raid_disk_num++;
+
+				if (dv->disposition == 'c') {
+					inf->disk.raid_disk = 0xfffd;
+					inf->disk.state = (1<<MD_DISK_WRITECACHE);
+					raid_disk_num--;
+				} else if (inf->disk.raid_disk < s->raiddisks)
 					inf->disk.state = (1<<MD_DISK_ACTIVE) |
 						(1<<MD_DISK_SYNC);
 				else
@@ -909,6 +917,7 @@ int Create(struct supertype *st, char *mddev,
 					inf->disk.major = major(stb.st_rdev);
 					inf->disk.minor = minor(stb.st_rdev);
 				}
+
 				break;
 			case 2:
 				inf->errors = 0;
diff --git a/ReadMe.c b/ReadMe.c
index 87a4916..74f7162 100644
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -140,6 +140,7 @@ struct option long_options[] = {
     {"homehost",  1, 0,  HomeHost},
     {"symlinks",  1, 0,  Symlinks},
     {"data-offset",1, 0, DataOffset},
+    {"write-cache",1, 0, WriteCache},
 
     /* For assemble */
     {"uuid",      1, 0, 'u'},
diff --git a/mdadm.c b/mdadm.c
index 3e8c49b..9a7048b 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -74,6 +74,7 @@ int main(int argc, char *argv[])
 		.require_homehost = 1,
 	};
 	struct shape s = {
+		.cachedisks	= 0,
 		.level		= UnSet,
 		.layout		= UnSet,
 		.bitmap_chunk	= UnSet,
@@ -1137,6 +1138,24 @@ int main(int argc, char *argv[])
 		case O(INCREMENTAL, IncrementalPath):
 			remove_path = optarg;
 			continue;
+		case O(CREATE, WriteCache):
+			if (s.cachedisks) {
+				pr_err("Please specify only one cache device for the array.\n");
+				pr_err("Ignoring --write-cache %s...\n", optarg);
+				continue;
+			}
+			dv = xmalloc(sizeof(*dv));
+			dv->devname = optarg;
+			dv->disposition = 'c';  /* WriteCache */
+			dv->writemostly = writemostly;
+			dv->used = 0;
+			dv->next = NULL;
+			*devlistend = dv;
+			devlistend = &dv->next;
+			devs_found++;
+
+			s.cachedisks = 1;
+			continue;
 		}
 		/* We have now processed all the valid options. Anything else is
 		 * an error
diff --git a/mdadm.h b/mdadm.h
index 141f963..d28caa0 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -344,6 +344,7 @@ enum special_options {
 	Dump,
 	Restore,
 	Action,
+	WriteCache,
 };
 
 enum prefix_standard {
@@ -423,6 +424,7 @@ struct context {
 struct shape {
 	int	raiddisks;
 	int	sparedisks;
+	int	cachedisks;
 	int	level;
 	int	layout;
 	char	*layout_str;
diff --git a/super1.c b/super1.c
index 7af0fd5..f8a55c6 100644
--- a/super1.c
+++ b/super1.c
@@ -977,6 +977,10 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
 	case 0xFFFE:
 		info->disk.state = 1; /* faulty */
 		break;
+	case 0xFFFD:
+		info->disk.state = (1 << MD_DISK_WRITECACHE); /* faulty */
+		info->disk.raid_disk = role;
+		break;
 	default:
 		info->disk.state = 6; /* active and in sync */
 		info->disk.raid_disk = role;
@@ -1096,6 +1100,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
 		int want;
 		if (info->disk.state & (1<<MD_DISK_ACTIVE))
 			want = info->disk.raid_disk;
+		else if (info->disk.state & (1<<MD_DISK_WRITECACHE))
+			want = 0xFFFD;
 		else
 			want = 0xFFFF;
 		if (sb->dev_roles[d] != __cpu_to_le16(want)) {
@@ -1422,6 +1428,8 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
 		*rp = __cpu_to_le16(dk->raid_disk);
 	else if ((dk->state & ~2) == 0) /* active or idle -> spare */
 		*rp = 0xffff;
+	else if (dk->state & (1<<MD_DISK_WRITECACHE))
+		*rp = 0xfffd;
 	else
 		*rp = 0xfffe;
 
-- 
1.8.1

--
To unsubscribe from this list: send the line "unsubscribe linux-raid" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Linux RAID Wiki]     [ATA RAID]     [Linux SCSI Target Infrastructure]     [Linux Block]     [Linux IDE]     [Linux SCSI]     [Linux Hams]     [Device Mapper]     [Device Mapper Cryptographics]     [Kernel]     [Linux Admin]     [Linux Net]     [GFS]     [RPM]     [git]     [Yosemite Forum]


  Powered by Linux