diff options
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r-- | fs/jffs2/scan.c | 55 |
1 files changed, 31 insertions, 24 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 61618080b86f..2bfdc33752d3 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -317,20 +317,23 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
317 | struct jffs2_summary *s) | 317 | struct jffs2_summary *s) |
318 | { | 318 | { |
319 | struct jffs2_xattr_datum *xd; | 319 | struct jffs2_xattr_datum *xd; |
320 | uint32_t totlen, crc; | 320 | uint32_t xid, version, totlen, crc; |
321 | int err; | 321 | int err; |
322 | 322 | ||
323 | crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4); | 323 | crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4); |
324 | if (crc != je32_to_cpu(rx->node_crc)) { | 324 | if (crc != je32_to_cpu(rx->node_crc)) { |
325 | if (je32_to_cpu(rx->node_crc) != 0xffffffff) | 325 | JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", |
326 | JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", | 326 | ofs, je32_to_cpu(rx->node_crc), crc); |
327 | ofs, je32_to_cpu(rx->node_crc), crc); | ||
328 | if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen)))) | 327 | if ((err = jffs2_scan_dirty_space(c, jeb, je32_to_cpu(rx->totlen)))) |
329 | return err; | 328 | return err; |
330 | return 0; | 329 | return 0; |
331 | } | 330 | } |
332 | 331 | ||
333 | totlen = PAD(sizeof(*rx) + rx->name_len + 1 + je16_to_cpu(rx->value_len)); | 332 | xid = je32_to_cpu(rx->xid); |
333 | version = je32_to_cpu(rx->version); | ||
334 | |||
335 | totlen = PAD(sizeof(struct jffs2_raw_xattr) | ||
336 | + rx->name_len + 1 + je16_to_cpu(rx->value_len)); | ||
334 | if (totlen != je32_to_cpu(rx->totlen)) { | 337 | if (totlen != je32_to_cpu(rx->totlen)) { |
335 | JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", | 338 | JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", |
336 | ofs, je32_to_cpu(rx->totlen), totlen); | 339 | ofs, je32_to_cpu(rx->totlen), totlen); |
@@ -339,22 +342,24 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
339 | return 0; | 342 | return 0; |
340 | } | 343 | } |
341 | 344 | ||
342 | xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version)); | 345 | xd = jffs2_setup_xattr_datum(c, xid, version); |
343 | if (IS_ERR(xd)) { | 346 | if (IS_ERR(xd)) |
344 | if (PTR_ERR(xd) == -EEXIST) { | ||
345 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rx->totlen))))) | ||
346 | return err; | ||
347 | return 0; | ||
348 | } | ||
349 | return PTR_ERR(xd); | 347 | return PTR_ERR(xd); |
350 | } | ||
351 | xd->xprefix = rx->xprefix; | ||
352 | xd->name_len = rx->name_len; | ||
353 | xd->value_len = je16_to_cpu(rx->value_len); | ||
354 | xd->data_crc = je32_to_cpu(rx->data_crc); | ||
355 | 348 | ||
356 | xd->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL); | 349 | if (xd->version > version) { |
357 | /* FIXME */ xd->node->next_in_ino = (void *)xd; | 350 | struct jffs2_raw_node_ref *raw |
351 | = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL); | ||
352 | raw->next_in_ino = xd->node->next_in_ino; | ||
353 | xd->node->next_in_ino = raw; | ||
354 | } else { | ||
355 | xd->version = version; | ||
356 | xd->xprefix = rx->xprefix; | ||
357 | xd->name_len = rx->name_len; | ||
358 | xd->value_len = je16_to_cpu(rx->value_len); | ||
359 | xd->data_crc = je32_to_cpu(rx->data_crc); | ||
360 | |||
361 | jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, (void *)xd); | ||
362 | } | ||
358 | 363 | ||
359 | if (jffs2_sum_active()) | 364 | if (jffs2_sum_active()) |
360 | jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); | 365 | jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); |
@@ -373,9 +378,8 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
373 | 378 | ||
374 | crc = crc32(0, rr, sizeof(*rr) - 4); | 379 | crc = crc32(0, rr, sizeof(*rr) - 4); |
375 | if (crc != je32_to_cpu(rr->node_crc)) { | 380 | if (crc != je32_to_cpu(rr->node_crc)) { |
376 | if (je32_to_cpu(rr->node_crc) != 0xffffffff) | 381 | JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", |
377 | JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", | 382 | ofs, je32_to_cpu(rr->node_crc), crc); |
378 | ofs, je32_to_cpu(rr->node_crc), crc); | ||
379 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen))))) | 383 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen))))) |
380 | return err; | 384 | return err; |
381 | return 0; | 385 | return 0; |
@@ -395,6 +399,7 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
395 | return -ENOMEM; | 399 | return -ENOMEM; |
396 | 400 | ||
397 | /* BEFORE jffs2_build_xattr_subsystem() called, | 401 | /* BEFORE jffs2_build_xattr_subsystem() called, |
402 | * and AFTER xattr_ref is marked as a dead xref, | ||
398 | * ref->xid is used to store 32bit xid, xd is not used | 403 | * ref->xid is used to store 32bit xid, xd is not used |
399 | * ref->ino is used to store 32bit inode-number, ic is not used | 404 | * ref->ino is used to store 32bit inode-number, ic is not used |
400 | * Thoes variables are declared as union, thus using those | 405 | * Thoes variables are declared as union, thus using those |
@@ -404,11 +409,13 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
404 | */ | 409 | */ |
405 | ref->ino = je32_to_cpu(rr->ino); | 410 | ref->ino = je32_to_cpu(rr->ino); |
406 | ref->xid = je32_to_cpu(rr->xid); | 411 | ref->xid = je32_to_cpu(rr->xid); |
412 | ref->xseqno = je32_to_cpu(rr->xseqno); | ||
413 | if (ref->xseqno > c->highest_xseqno) | ||
414 | c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER); | ||
407 | ref->next = c->xref_temp; | 415 | ref->next = c->xref_temp; |
408 | c->xref_temp = ref; | 416 | c->xref_temp = ref; |
409 | 417 | ||
410 | ref->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), NULL); | 418 | jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), (void *)ref); |
411 | /* FIXME */ ref->node->next_in_ino = (void *)ref; | ||
412 | 419 | ||
413 | if (jffs2_sum_active()) | 420 | if (jffs2_sum_active()) |
414 | jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); | 421 | jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); |