Date: Thu, 26 Feb 2004 10:47:32 +0100 From: "Poul-Henning Kamp" <phk@phk.freebsd.dk> To: Pawel Jakub Dawidek <pjd@freebsd.org> Cc: freebsd-geom@freebsd.org Subject: Re: GEOM stripe library. Message-ID: <886.1077788852@critter.freebsd.dk> In-Reply-To: Your message of "Wed, 25 Feb 2004 11:30:57 %2B0100." <20040225103057.GB5506@darkness.comp.waw.pl>
next in thread | previous in thread | raw e-mail | index | archive | help
In message <20040225103057.GB5506@darkness.comp.waw.pl>, Pawel Jakub Dawidek wr ites: > * This disk have two slice: > * > * d_slices[0].s_offset =3D 1024 > * d_slices[0].s_length =3D 2048 > * d_slices[0].s_virt_offset =3D 0 > * d_slices[0].s_virt_end =3D 2048 (s_virt_offset + s_length) I can't really see what we need s_virt_end for. If you need it for implementation, then please calculate it as part of setup so that the users of this library will not even see it. >/* > * Structure g_stripe_group describes group of disks that are used > * on given offset. This allows to create stripe on disks with different > * sizes. > * > * disk 0 disk 1 disk 2 START_DISK START_OFFSET > * +-------+ +-------+ +-------+ 0 0 > * |0000000| |0000000| |0000000| > * |0000000| |0000000| |0000000| > * + - - - + +-------+ + - - - + 1024 0 + 1024 * 3 =3D 3072 > * |1111111| |1111111| > * |1111111| |1111111| > * |1111111| |1111111| > * +-------+ + - - - + 2560 3072 + 1536 * 2 =3D 6144 > * |2222222| > * +-------+ 3072 6144 + 512 * 1 =3D 6656 > * > * sc_groups[0].g_ndisks =3D 3 > * sc_groups[0].g_disks =3D { 0, 1, 2 } > * sc_groups[0].g_start_offset =3D 0 > * sc_groups[0].g_end_offset =3D 3072 > * sc_groups[0].g_start_disk =3D 0 Where is the actual stripe-width ? Shouldn't that be a parameter here ? > * sc_groups[1].g_ndisks =3D 2 > * sc_groups[1].g_disks =3D { 0, 2 } > * sc_groups[1].g_start_offset =3D 3072 > * sc_groups[1].g_end_offset =3D 6144 > * sc_groups[1].g_start_disk =3D 2560 s/2560/1024/ ? > * sc_groups[2].g_ndisks =3D 1 > * sc_groups[2].g_disks =3D { 2 } > * sc_groups[2].g_start_offset =3D 6144 > * sc_groups[2].g_end_offset =3D 6656 > * sc_groups[2].g_start_disk =3D 3072 s/3072/2560/ ? I have been thinking a bit more about this, and I can see a number of in-use striping geometries you cannot handle with this, in particular non-uniform striping (64k from disk0, 128k from disk1, 64k from disk0, 128k from disk1, ...) There are also some underspecified parameters and some overspecified ones. I think it would be much more compact in the client code and just as efficient for the library code to describe just the actual layout: struct g_slicecomponent { off_t offset; off_t bite; /* private members for the library */ ... }; struct g_slicepart { off_t stripes; struct g_slicecomponent *components; /* private members for the library */ ... }; struct stripe { int nconsumer; struct g_consumer *consumer; int nparts; struct g_slicepart *slicepart; /* private members for the library */ ... }; Simply striping two 1 megabyte disks with 8k stripes, preserving the first 63 sectors for metadata would look like this in not-quite-C: struct stripe { .nconsumer = 2; .consumer = [ ptr1; ptr2; ]; .nparts = 1; .slicepart = [ { .stripes = (1M - 63*512) / 8192; .components = [ { .offset = 63; .bite = 8k / 2; }; { .offset = 63; .bite = 8k / 2; }; ] }; ] }; And setting this up in class code could look like this: struct stripe *sp; sp = g_stripe_new(/* consumers */ 2, /* parts */ 1); sp->consumer[0] = c0; sp->consumer[1] = c1; sp->slicepart[0].stripes = (size - magic) / stripewidth; sp->slicepart[0].components[0].offset = magic; sp->slicepart[0].components[0].bite = stripewidth / 2; sp->slicepart[0].components[1].offset = magic; sp->slicepart[0].components[1].bite = stripewidth / 2; error = g_stripe_calculate(sp); A geometry somewhat like yours and with all parameters filled in would then look like this in not-quite-C: struct stripe { .nconsumer = 3; .consumer = [ ptr1; ptr2; ptr3; ]; .nparts = 3; .slicepart = [ { .stripes = 1024; .components = [ { .offset = 1024; .bite = 1024; }; { .offset = 1024; .bite = 1024; }; { .offset = 1024; .bite = 1024; }; ] }; { .stripes = 3072; .components = [ { .offset = 1024 + 1024 * 1024; .bite = 512; }; { .offset = 0; .bite = 0; }; { .offset = 1024 + 1024 * 1024; .bite = 512; }; ] }; { .stripes = 256; .components = [ { .offset = 0; .bite = 0; }; { .offset = 0; .bite = 0; }; { .consumer = 2; .offset = 1024 + 1024 * 1024 + 3072 * 512; .bite = 2048; }; ] }; ] }; And would look like this in C code: struct stripe *sp; sp = g_stripe_new(/* consumers */ 3, /* parts */ 3); sp->consumer[0] = c0; sp->consumer[1] = c1; sp->consumer[2] = c2; sp->slicepart[0].stripes = 1024; for (i = 0; i < 3; i++) { sp->slicepart[0].components[i].offset = 1024; sp->slicepart[0].components[i].bite = 1024; } sp->slicepart[1].stripes = 3072; sp->slicepart[1].components[0].offset = -1; /* autocalculate */ sp->slicepart[1].components[0].bite = 512; sp->slicepart[1].components[2].offset = -1; /* autocalculate */ sp->slicepart[1].components[2].bite = 512; sp->slicepart[1].stripes = 256; sp->slicepart[1].components[2].offset = -1; /* autocalculate */ sp->slicepart[1].components[2].bite = 2048; error = g_stripe_calculate(sp); Setting offset to -1 means "continue wherever we got to". -- Poul-Henning Kamp | UNIX since Zilog Zeus 3.20 phk@FreeBSD.ORG | TCP/IP since RFC 956 FreeBSD committer | BSD since 4.3-tahoe Never attribute to malice what can adequately be explained by incompetence.
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?886.1077788852>