diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-05-20 12:27:32 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-05-20 12:27:32 -0400 |
commit | 0cfc7da3ff4b39a3aac261ab3f6b1329e2485653 (patch) | |
tree | 447073fe757b42e6da63b96a26cbbc6b4c705946 /fs/jffs2/scan.c | |
parent | 1417fc44ee923418df3adadeb4846c891bba1ba5 (diff) | |
parent | 20a92fc74c5c91c7bc5693d51acc2b99aceb0465 (diff) |
Merge git://git.infradead.org/jffs2-xattr-2.6
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r-- | fs/jffs2/scan.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 2a24b44662bb..40d62d057aa4 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -306,6 +306,137 @@ int jffs2_scan_classify_jeb(struct jffs2_sb_info *c, struct jffs2_eraseblock *je | |||
306 | return BLK_STATE_ALLDIRTY; | 306 | return BLK_STATE_ALLDIRTY; |
307 | } | 307 | } |
308 | 308 | ||
309 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
310 | static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | ||
311 | struct jffs2_raw_xattr *rx, uint32_t ofs, | ||
312 | struct jffs2_summary *s) | ||
313 | { | ||
314 | struct jffs2_xattr_datum *xd; | ||
315 | struct jffs2_raw_node_ref *raw; | ||
316 | uint32_t totlen, crc; | ||
317 | |||
318 | crc = crc32(0, rx, sizeof(struct jffs2_raw_xattr) - 4); | ||
319 | if (crc != je32_to_cpu(rx->node_crc)) { | ||
320 | if (je32_to_cpu(rx->node_crc) != 0xffffffff) | ||
321 | JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", | ||
322 | ofs, je32_to_cpu(rx->node_crc), crc); | ||
323 | DIRTY_SPACE(je32_to_cpu(rx->totlen)); | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | totlen = PAD(sizeof(*rx) + rx->name_len + 1 + je16_to_cpu(rx->value_len)); | ||
328 | if (totlen != je32_to_cpu(rx->totlen)) { | ||
329 | JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", | ||
330 | ofs, je32_to_cpu(rx->totlen), totlen); | ||
331 | DIRTY_SPACE(je32_to_cpu(rx->totlen)); | ||
332 | return 0; | ||
333 | } | ||
334 | |||
335 | raw = jffs2_alloc_raw_node_ref(); | ||
336 | if (!raw) | ||
337 | return -ENOMEM; | ||
338 | |||
339 | xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version)); | ||
340 | if (IS_ERR(xd)) { | ||
341 | jffs2_free_raw_node_ref(raw); | ||
342 | if (PTR_ERR(xd) == -EEXIST) { | ||
343 | DIRTY_SPACE(PAD(je32_to_cpu(rx->totlen))); | ||
344 | return 0; | ||
345 | } | ||
346 | return PTR_ERR(xd); | ||
347 | } | ||
348 | xd->xprefix = rx->xprefix; | ||
349 | xd->name_len = rx->name_len; | ||
350 | xd->value_len = je16_to_cpu(rx->value_len); | ||
351 | xd->data_crc = je32_to_cpu(rx->data_crc); | ||
352 | xd->node = raw; | ||
353 | |||
354 | raw->__totlen = totlen; | ||
355 | raw->flash_offset = ofs | REF_PRISTINE; | ||
356 | raw->next_phys = NULL; | ||
357 | raw->next_in_ino = (void *)xd; | ||
358 | if (!jeb->first_node) | ||
359 | jeb->first_node = raw; | ||
360 | if (jeb->last_node) | ||
361 | jeb->last_node->next_phys = raw; | ||
362 | jeb->last_node = raw; | ||
363 | |||
364 | USED_SPACE(PAD(je32_to_cpu(rx->totlen))); | ||
365 | if (jffs2_sum_active()) | ||
366 | jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); | ||
367 | dbg_xattr("scaning xdatum at %#08x (xid=%u, version=%u)\n", | ||
368 | ofs, xd->xid, xd->version); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | ||
373 | struct jffs2_raw_xref *rr, uint32_t ofs, | ||
374 | struct jffs2_summary *s) | ||
375 | { | ||
376 | struct jffs2_xattr_ref *ref; | ||
377 | struct jffs2_raw_node_ref *raw; | ||
378 | uint32_t crc; | ||
379 | |||
380 | crc = crc32(0, rr, sizeof(*rr) - 4); | ||
381 | if (crc != je32_to_cpu(rr->node_crc)) { | ||
382 | if (je32_to_cpu(rr->node_crc) != 0xffffffff) | ||
383 | JFFS2_WARNING("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", | ||
384 | ofs, je32_to_cpu(rr->node_crc), crc); | ||
385 | DIRTY_SPACE(PAD(je32_to_cpu(rr->totlen))); | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | if (PAD(sizeof(struct jffs2_raw_xref)) != je32_to_cpu(rr->totlen)) { | ||
390 | JFFS2_WARNING("node length mismatch at %#08x, read=%u, calc=%u\n", | ||
391 | ofs, je32_to_cpu(rr->totlen), | ||
392 | PAD(sizeof(struct jffs2_raw_xref))); | ||
393 | DIRTY_SPACE(je32_to_cpu(rr->totlen)); | ||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | ref = jffs2_alloc_xattr_ref(); | ||
398 | if (!ref) | ||
399 | return -ENOMEM; | ||
400 | |||
401 | raw = jffs2_alloc_raw_node_ref(); | ||
402 | if (!raw) { | ||
403 | jffs2_free_xattr_ref(ref); | ||
404 | return -ENOMEM; | ||
405 | } | ||
406 | |||
407 | /* BEFORE jffs2_build_xattr_subsystem() called, | ||
408 | * ref->xid is used to store 32bit xid, xd is not used | ||
409 | * ref->ino is used to store 32bit inode-number, ic is not used | ||
410 | * Thoes variables are declared as union, thus using those | ||
411 | * are exclusive. In a similar way, ref->next is temporarily | ||
412 | * used to chain all xattr_ref object. It's re-chained to | ||
413 | * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly. | ||
414 | */ | ||
415 | ref->node = raw; | ||
416 | ref->ino = je32_to_cpu(rr->ino); | ||
417 | ref->xid = je32_to_cpu(rr->xid); | ||
418 | ref->next = c->xref_temp; | ||
419 | c->xref_temp = ref; | ||
420 | |||
421 | raw->__totlen = PAD(je32_to_cpu(rr->totlen)); | ||
422 | raw->flash_offset = ofs | REF_PRISTINE; | ||
423 | raw->next_phys = NULL; | ||
424 | raw->next_in_ino = (void *)ref; | ||
425 | if (!jeb->first_node) | ||
426 | jeb->first_node = raw; | ||
427 | if (jeb->last_node) | ||
428 | jeb->last_node->next_phys = raw; | ||
429 | jeb->last_node = raw; | ||
430 | |||
431 | USED_SPACE(PAD(je32_to_cpu(rr->totlen))); | ||
432 | if (jffs2_sum_active()) | ||
433 | jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); | ||
434 | dbg_xattr("scan xref at %#08x (xid=%u, ino=%u)\n", | ||
435 | ofs, ref->xid, ref->ino); | ||
436 | return 0; | ||
437 | } | ||
438 | #endif | ||
439 | |||
309 | /* Called with 'buf_size == 0' if buf is in fact a pointer _directly_ into | 440 | /* Called with 'buf_size == 0' if buf is in fact a pointer _directly_ into |
310 | the flash, XIP-style */ | 441 | the flash, XIP-style */ |
311 | static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 442 | static int jffs2_scan_eraseblock (struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
@@ -641,6 +772,43 @@ scan_more: | |||
641 | ofs += PAD(je32_to_cpu(node->totlen)); | 772 | ofs += PAD(je32_to_cpu(node->totlen)); |
642 | break; | 773 | break; |
643 | 774 | ||
775 | #ifdef CONFIG_JFFS2_FS_XATTR | ||
776 | case JFFS2_NODETYPE_XATTR: | ||
777 | if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { | ||
778 | buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); | ||
779 | D1(printk(KERN_DEBUG "Fewer than %d bytes (xattr node)" | ||
780 | " left to end of buf. Reading 0x%x at 0x%08x\n", | ||
781 | je32_to_cpu(node->totlen), buf_len, ofs)); | ||
782 | err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); | ||
783 | if (err) | ||
784 | return err; | ||
785 | buf_ofs = ofs; | ||
786 | node = (void *)buf; | ||
787 | } | ||
788 | err = jffs2_scan_xattr_node(c, jeb, (void *)node, ofs, s); | ||
789 | if (err) | ||
790 | return err; | ||
791 | ofs += PAD(je32_to_cpu(node->totlen)); | ||
792 | break; | ||
793 | case JFFS2_NODETYPE_XREF: | ||
794 | if (buf_ofs + buf_len < ofs + je32_to_cpu(node->totlen)) { | ||
795 | buf_len = min_t(uint32_t, buf_size, jeb->offset + c->sector_size - ofs); | ||
796 | D1(printk(KERN_DEBUG "Fewer than %d bytes (xref node)" | ||
797 | " left to end of buf. Reading 0x%x at 0x%08x\n", | ||
798 | je32_to_cpu(node->totlen), buf_len, ofs)); | ||
799 | err = jffs2_fill_scan_buf(c, buf, ofs, buf_len); | ||
800 | if (err) | ||
801 | return err; | ||
802 | buf_ofs = ofs; | ||
803 | node = (void *)buf; | ||
804 | } | ||
805 | err = jffs2_scan_xref_node(c, jeb, (void *)node, ofs, s); | ||
806 | if (err) | ||
807 | return err; | ||
808 | ofs += PAD(je32_to_cpu(node->totlen)); | ||
809 | break; | ||
810 | #endif /* CONFIG_JFFS2_FS_XATTR */ | ||
811 | |||
644 | case JFFS2_NODETYPE_CLEANMARKER: | 812 | case JFFS2_NODETYPE_CLEANMARKER: |
645 | D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); | 813 | D1(printk(KERN_DEBUG "CLEANMARKER node found at 0x%08x\n", ofs)); |
646 | if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { | 814 | if (je32_to_cpu(node->totlen) != c->cleanmarker_size) { |