aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2/scan.c
diff options
context:
space:
mode:
authorKaiGai Kohei <kaigai@ak.jp.nec.com>2006-06-10 21:35:15 -0400
committerDavid Woodhouse <dwmw2@infradead.org>2006-06-27 11:16:26 -0400
commitc9f700f840bd481b3e01fcad1ba8da01794a6726 (patch)
tree786f4a6a3f3a2d619ae4230a62f95361fcd3245a /fs/jffs2/scan.c
parent6d4f8224d4ee065e0e3186cc554468d735e6015d (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.c57
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);