[Ocfs2-tools-devel] [PATCH 01/10] Ocfs2-tools: Define new corrupt code to make it compatible with fsck.ocfs2.
tristan.ye
tristan.ye at oracle.com
Sun Jun 7 18:49:01 PDT 2009
On Fri, 2009-06-05 at 12:57 -0700, Joel Becker wrote:
> On Fri, Jun 05, 2009 at 03:45:34PM +0800, Tristan Ye wrote:
> > In main.c, we redefine the corrupt_codes array to let it become FSCK_TYPE specific,
> > which can be provided as comma-separated-values string to fswreck binary.
> >
> > As our goal is to change the logic of corrupt operation as few as possible, their
> > associated handling funcs will still use former corrupt_* func family.
> >
> > Former CORRUPT_CODE enum will be abandoned as our new one will be more exact and
> > specific.
>
> Nice start! Some comments and improvements below.
> > /* remaining headers */
> > diff --git a/fswreck/main.c b/fswreck/main.c
> > index bc889d8..2690862 100644
> > --- a/fswreck/main.c
> > +++ b/fswreck/main.c
> > @@ -30,72 +30,531 @@ char *progname = NULL;
> > static char *device = NULL;
> > static uint16_t slotnum = UINT16_MAX;
> >
> > -struct corrupt_funcs {
> > - void (*func) (ocfs2_filesys *fs, int code, uint16_t slotnum);
> > - char *desc;
> > +static int corrupt[NUM_FSCK_TYPE];
> > +
> > +struct prompt_code {
> > +
> > + enum fsck_type type;
> > + char *str;
> > + void (*func)(ocfs2_filesys *fs, enum fsck_type code, uint16_t slotnum);
> > + char *desc;
> > };
>
> I like this structure.
>
> > +static struct prompt_code prompt_codes[NUM_FSCK_TYPE] = {
> > +
> > + { .type = EB_BLKNO,
> > + .str = "EB_BLKNO",
> > + .func = &corrupt_file,
> > + .desc = "Extent block error: EB_BLKNO",
> > + },
>
> And this array. But it's very verbose to type and read. I
> think you would be served by a macro that stringifies the type:
>
> #define define_prompt_code(_type, _func, _desc) \
> [_type] = { \
> .type = _type, \
> .str = #_type, \
> .func = _func, \
> .desc = _desc, \
> }
>
> This allows you to say:
>
> static struct prompt_code prompt_codes[NUM_FSCK_TYPE] = {
> define_prompt_code(EB_BLKNO, corrupt_file,
> "Corrupt an extent block's eb_blkno field"),
> define_prompt_code(...),
> ...,
> };
>
> You don't need the '&' on function pointers. The macro above
> uses c99 initializers to make sure that the structure for _type is at
> array index [_type], so they don't even need to be ordered properly
> (though they still should be). Finally, the description should be fully
> readable. Your code to print the description already prints ->str, so
> you don't need it as part of ->desc.
Thank you joel, Your suggestion sounds great as I also was tired of
typing such a long array definition...
>
> > + { .type = EB_GEN,
> > + .str = "EB_GEN",
> > + .func = &corrupt_file,
> > + .desc = "Extent block error: EB_GEN",
> > + },
>
> For example, this is easier to understand as:
>
> define_prompt_code(EB_GEN, corrupt_file,
> "Corrupt an extent blocks h_fs_generatoin field."),
>
> > + { .type = EB_GEN_FIX,
> > + .str = "EB_GEN_FIX",
> > + .func = &corrupt_file,
> > + .desc = "Extent block error: EB_GEN_FIX",
> > + },
>
> This one is a little more confusing. It comes from the same error as
> above, but it's all about triggering a fix of the extent block rather
> than the specific corruption. Perhaps:
>
> define_prompt_code(EB_GEN_FIX, corrupt_file,
> "Corrupt an extent blocks h_fs_generatoin "
> "field so that fsck.ocfs2 can fix it."),
>
> > + {
> > + .type = EXTENT_EB_INVALID,
> > + .str = "EXTENT_EB_INVALID",
> > + .func = &corrupt_file,
> > + .desc = "Extent block error: EXTENT_EB_INVALID",
> > + },
>
> Here I find an fswreck bug. The fswreck EXTENT_EB_INVALID
> corrupter actually does EB_GEN. But the wrong fsck choice can make this
> not exercise the EXTENT_EB_INVALID. The corrupter for EXTENT_EB_INVALID
> should instead have an extent record pointing to an unused block,
> perhaps block 0.
> Overall, do a quick pass with these descriptions. Don't work
> too hard figuring them all out. Once we've gotten the actual code
> worked out, we can both work on making the descriptions better.
Yes, I'll later make the descs much more readable and understandable.
>
> > @@ -110,8 +569,9 @@ static void usage (char *progname)
> > g_print (" -n <node slot number>\n");
> > g_print (" -c <corrupt code>\n");
> > g_print (" corrupt code description:\n");
> > - for (i = 0; i < MAX_CORRUPT; i++)
> > - g_print (" %02d - %s\n", i, cf[i].desc);
> > + for (i = 0; i < NUM_FSCK_TYPE; i++)
> > + g_print(" %s - %s\n", prompt_codes[i].str,
> > + prompt_codes[i].desc);
>
> See, you print str, desc. So there's no need including the code
> string in desc.
> Oh, can you change these to fprintf()? fswreck doesn't use glib
> anywhere else, and we can drop the dependency.
I meant to make the print function unchanged, Ok, that's fine to use
frprintf here.
>
> > +static int corrupt_code_match(const char *corrupt_codes)
> > +{
> > + int i;
> > +
> > + for (i = 0; i < NUM_FSCK_TYPE; i++)
> > + if (strcmp(corrupt_codes, prompt_codes[i].str) == 0)
> > + return i;
> > +
> > + return -1;
> > +}
>
> Make 'corrupt_codes' the singular 'corrupt_code'.
> parse_corrupt_codes() is passing a single code in to this function.
> Just makes it easier to read. You can even
> assert(!strchr(corrupt_code, ',')) if you like.
Nod:)
> All this is just organizational. The code looks very
> functional. Well done.
>
> Joel
>
More information about the Ocfs2-tools-devel
mailing list