From 78826b67500c4fd4269822854ed0ee51be0898d3 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Sat, 2 Oct 2010 21:56:29 +1000 Subject: [PATCH] roll forward clean up More validation improved mem allocation general clean up Signed-off-by: NeilBrown --- roll.c | 100 +++++++++++++++++++++++++++++++-------------------------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/roll.c b/roll.c index ba986cb..a4dea4b 100644 --- a/roll.c +++ b/roll.c @@ -23,7 +23,18 @@ roll_valid(struct fs *fs, struct cluster_head *ch, unsigned long long addr) return 0; if (le64_to_cpu(ch->this_addr) != addr) return 0; - /* FIXME sanity check some values?? */ + switch (le16_to_cpu(ch->verify_type)) { + case VerifyNull: + case VerifyNext: + case VerifyNext2: + break; + default: + return 0; + } + if (ch->pad0 != 0) + return 0; + if (le16_to_cpu(ch->Clength) > fs->max_segment) + return 0; return 1; } @@ -36,18 +47,14 @@ roll_valid(struct fs *fs, struct cluster_head *ch, unsigned long long addr) static int roll_locate(struct fs *fs, u64 start, u64 *next, u64 *lastp, u64 *seqp, - int *maxp) + int *maxp, struct page *p) { - struct page *p = alloc_page(GFP_KERNEL); - struct cluster_head *ch; u64 this, prev, prev2, last; u64 seq = 0; int max = 0; int prevtype, prev2type; - if (!p) - return -ENOMEM; ch = (struct cluster_head *)page_address(p); this = start; prev = start; @@ -136,7 +143,7 @@ roll_locate(struct fs *fs, u64 start, if (le16_to_cpu(ch->Hlength) > max) max = le16_to_cpu(ch->Hlength); - if (prev2type == VerifyNext2 && start != this) { + if (prev2type == VerifyNext2) { start = prev; last = prev2; } if (prevtype == VerifyNext) { @@ -148,6 +155,10 @@ roll_locate(struct fs *fs, u64 start, prev2 = prev; prev2type = prevtype; prev = this ; prevtype = le16_to_cpu(ch->verify_type); this = le64_to_cpu(ch->next_addr); + if (prevtype == VerifyNull) { + start = this; + last = prev; + } seq++; } @@ -477,7 +488,6 @@ static int roll_forward(struct fs *fs) u64 first, next = 0, last = 0, seq = 0; int max = 0; struct page *p, *pg; - char *buf; int err; int blocksize = fs->blocksize; int dev; @@ -490,15 +500,21 @@ static int roll_forward(struct fs *fs) clear_bit(DelayYouth, &fs->fsstate); first = fs->checkpointcluster; - err = roll_locate(fs, first, &next, &last, &seq, &max); - if (err) - return err; - if (max > PAGE_SIZE) - return -EFBIG; - p = alloc_page(GFP_KERNEL); if (!p) return -ENOMEM; + + err = roll_locate(fs, first, &next, &last, &seq, &max, p); + + max = ((max + blocksize - 1) / blocksize) * blocksize; + + if (!err && max > PAGE_SIZE) + err = -EFBIG; + if (err) { + put_page(p); + return err; + } + pg = alloc_page(GFP_KERNEL); if (!pg) { put_page(p); @@ -513,42 +529,36 @@ static int roll_forward(struct fs *fs) lafs_cluster_init(fs, 1, 0, 0, 0); virttoseg(fs, first, &dev, &seg, &offset); - max = ((max + blocksize - 1) / blocksize) * blocksize; - dprintk("Max = %d\n", max); - buf = kmalloc(max, GFP_KERNEL); - if (buf) - while (first != next) { - int dev2; - u32 seg2; - - virttoseg(fs, first, &dev2, &seg2, &offset); - err = roll_one(fs, &first, p, pg, max); - if (err) - break; - if (fs->qphase == fs->phase && - fs->checkpointing) { - fs->checkpointing = 0; - clear_bit(DelayYouth, &fs->fsstate); - lafs_seg_apply_all(fs); - } + while (first != next) { + int dev2; + u32 seg2; - if (dev2 != dev || seg2 != seg) { - /* New segment - need to make sure youth is correct */ - dev = dev2; - seg = seg2; - /* if fs->checkpointing, seg_apply_all will do the youth - * update - */ - if (fs->checkpointing == 0) - lafs_update_youth(fs, dev, seg); - } + virttoseg(fs, first, &dev2, &seg2, &offset); + err = roll_one(fs, &first, p, pg, max); + if (err) + break; + + if (fs->qphase == fs->phase && + fs->checkpointing) { + fs->checkpointing = 0; + clear_bit(DelayYouth, &fs->fsstate); + lafs_seg_apply_all(fs); } - else - err = -ENOMEM; + + if (dev2 != dev || seg2 != seg) { + /* New segment - need to make sure youth is correct */ + dev = dev2; + seg = seg2; + /* if fs->checkpointing, seg_apply_all will do the youth + * update + */ + if (fs->checkpointing == 0) + lafs_update_youth(fs, dev, seg); + } + } put_page(p); put_page(pg); - kfree(buf); lafs_add_active(fs, next); -- 2.39.5