diff options
author | KaiGai Kohei <kaigai@ak.jp.nec.com> | 2006-06-10 21:35:15 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-06-27 11:16:26 -0400 |
commit | c9f700f840bd481b3e01fcad1ba8da01794a6726 (patch) | |
tree | 786f4a6a3f3a2d619ae4230a62f95361fcd3245a /fs/jffs2/scan.c | |
parent | 6d4f8224d4ee065e0e3186cc554468d735e6015d (diff) |
[JFFS2][XATTR] using 'delete marker' for xdatum/xref deletion
- When xdatum is removed, a new xdatum with 'delete marker' is
written. (version==0xffffffff means 'delete marker')
- When xref is removed, a new xref with 'delete marker' is written.
(odd-numbered xseqno means 'delete marker')
- delete_xattr_(datum/xref)_delay() are new deletion functions
are added. We can only use them if we can detect the target
obsolete xdatum/xref as a orphan or errir one.
(e.g when inode deletion, or detecting crc error)
[1/3] jffs2-xattr-v6-01-delete_marker.patch
Signed-off-by: KaiGai Kohei <kaigai@ak.jp.nec.com>
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r-- | fs/jffs2/scan.c | 57 |
1 files changed, 33 insertions, 24 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 61618080b86f..79638f56c5ea 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -317,20 +317,25 @@ 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 = sizeof(struct jffs2_raw_xattr); | ||
336 | if (version != XDATUM_DELETE_MARKER) | ||
337 | totlen += rx->name_len + 1 + je16_to_cpu(rx->value_len); | ||
338 | totlen = PAD(totlen); | ||
334 | if (totlen != je32_to_cpu(rx->totlen)) { | 339 | if (totlen != je32_to_cpu(rx->totlen)) { |
335 | JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", | 340 | JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", |
336 | ofs, je32_to_cpu(rx->totlen), totlen); | 341 | ofs, je32_to_cpu(rx->totlen), totlen); |
@@ -339,22 +344,24 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
339 | return 0; | 344 | return 0; |
340 | } | 345 | } |
341 | 346 | ||
342 | xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version)); | 347 | xd = jffs2_setup_xattr_datum(c, xid, version); |
343 | if (IS_ERR(xd)) { | 348 | 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); | 349 | 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 | 350 | ||
356 | xd->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL); | 351 | if (xd->version > version) { |
357 | /* FIXME */ xd->node->next_in_ino = (void *)xd; | 352 | struct jffs2_raw_node_ref *raw |
353 | = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL); | ||
354 | raw->next_in_ino = xd->node->next_in_ino; | ||
355 | xd->node->next_in_ino = raw; | ||
356 | } else { | ||
357 | xd->version = version; | ||
358 | xd->xprefix = rx->xprefix; | ||
359 | xd->name_len = rx->name_len; | ||
360 | xd->value_len = je16_to_cpu(rx->value_len); | ||
361 | xd->data_crc = je32_to_cpu(rx->data_crc); | ||
362 | |||
363 | jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, (void *)xd); | ||
364 | } | ||
358 | 365 | ||
359 | if (jffs2_sum_active()) | 366 | if (jffs2_sum_active()) |
360 | jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); | 367 | jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); |
@@ -373,9 +380,8 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
373 | 380 | ||
374 | crc = crc32(0, rr, sizeof(*rr) - 4); | 381 | crc = crc32(0, rr, sizeof(*rr) - 4); |
375 | if (crc != je32_to_cpu(rr->node_crc)) { | 382 | if (crc != je32_to_cpu(rr->node_crc)) { |
376 | if (je32_to_cpu(rr->node_crc) != 0xffffffff) | 383 | 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", | 384 | 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))))) | 385 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rr->totlen))))) |
380 | return err; | 386 | return err; |
381 | return 0; | 387 | return 0; |
@@ -395,6 +401,7 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
395 | return -ENOMEM; | 401 | return -ENOMEM; |
396 | 402 | ||
397 | /* BEFORE jffs2_build_xattr_subsystem() called, | 403 | /* BEFORE jffs2_build_xattr_subsystem() called, |
404 | * and AFTER xattr_ref is marked as a dead xref, | ||
398 | * ref->xid is used to store 32bit xid, xd is not used | 405 | * 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 | 406 | * ref->ino is used to store 32bit inode-number, ic is not used |
400 | * Thoes variables are declared as union, thus using those | 407 | * Thoes variables are declared as union, thus using those |
@@ -404,11 +411,13 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
404 | */ | 411 | */ |
405 | ref->ino = je32_to_cpu(rr->ino); | 412 | ref->ino = je32_to_cpu(rr->ino); |
406 | ref->xid = je32_to_cpu(rr->xid); | 413 | ref->xid = je32_to_cpu(rr->xid); |
414 | ref->xseqno = je32_to_cpu(rr->xseqno); | ||
415 | if (ref->xseqno > c->highest_xseqno) | ||
416 | c->highest_xseqno = (ref->xseqno & ~XREF_DELETE_MARKER); | ||
407 | ref->next = c->xref_temp; | 417 | ref->next = c->xref_temp; |
408 | c->xref_temp = ref; | 418 | c->xref_temp = ref; |
409 | 419 | ||
410 | ref->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), NULL); | 420 | 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 | 421 | ||
413 | if (jffs2_sum_active()) | 422 | if (jffs2_sum_active()) |
414 | jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); | 423 | jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); |