diff options
author | David Woodhouse <dwmw2@infradead.org> | 2006-05-23 21:04:45 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@infradead.org> | 2006-05-23 21:04:45 -0400 |
commit | 2f785402f39b96a077b6e62bf26164bfb8e0c980 (patch) | |
tree | 3f3a38b484ef2dabda1599d4d8f08b121bd03a76 /fs/jffs2/scan.c | |
parent | 4cbb9b80e171107c6c34116283fe38e5a396c68b (diff) |
[JFFS2] Reduce visibility of raw_node_ref to upper layers of JFFS2 code.
As the first step towards eliminating the ref->next_phys member and saving
memory by using an _array_ of struct jffs2_raw_node_ref per eraseblock,
stop the write functions from allocating their own refs; have them just
_reserve_ the appropriate number instead. Then jffs2_link_node_ref() can
just fill them in.
Use a linked list of pre-allocated refs in the superblock, for now. Once
we switch to an array, it'll just be a case of extending that array.
Signed-off-by: David Woodhouse <dwmw2@infradead.org>
Diffstat (limited to 'fs/jffs2/scan.c')
-rw-r--r-- | fs/jffs2/scan.c | 77 |
1 files changed, 14 insertions, 63 deletions
diff --git a/fs/jffs2/scan.c b/fs/jffs2/scan.c index 6fce703c0543..87b0a416b6a0 100644 --- a/fs/jffs2/scan.c +++ b/fs/jffs2/scan.c | |||
@@ -317,7 +317,6 @@ 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 | struct jffs2_raw_node_ref *raw; | ||
321 | uint32_t totlen, crc; | 320 | uint32_t totlen, crc; |
322 | int err; | 321 | int err; |
323 | 322 | ||
@@ -340,13 +339,8 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
340 | return 0; | 339 | return 0; |
341 | } | 340 | } |
342 | 341 | ||
343 | raw = jffs2_alloc_raw_node_ref(); | ||
344 | if (!raw) | ||
345 | return -ENOMEM; | ||
346 | |||
347 | xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version)); | 342 | xd = jffs2_setup_xattr_datum(c, je32_to_cpu(rx->xid), je32_to_cpu(rx->version)); |
348 | if (IS_ERR(xd)) { | 343 | if (IS_ERR(xd)) { |
349 | jffs2_free_raw_node_ref(raw); | ||
350 | if (PTR_ERR(xd) == -EEXIST) { | 344 | if (PTR_ERR(xd) == -EEXIST) { |
351 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rx->totlen))))) | 345 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(rx->totlen))))) |
352 | return err; | 346 | return err; |
@@ -358,12 +352,9 @@ static int jffs2_scan_xattr_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
358 | xd->name_len = rx->name_len; | 352 | xd->name_len = rx->name_len; |
359 | xd->value_len = je16_to_cpu(rx->value_len); | 353 | xd->value_len = je16_to_cpu(rx->value_len); |
360 | xd->data_crc = je32_to_cpu(rx->data_crc); | 354 | xd->data_crc = je32_to_cpu(rx->data_crc); |
361 | xd->node = raw; | ||
362 | |||
363 | raw->flash_offset = ofs | REF_PRISTINE; | ||
364 | 355 | ||
365 | jffs2_link_node_ref(c, jeb, raw, totlen, NULL); | 356 | xd->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, totlen, NULL); |
366 | /* FIXME */ raw->next_in_ino = (void *)xd; | 357 | /* FIXME */ xd->node->next_in_ino = (void *)xd; |
367 | 358 | ||
368 | if (jffs2_sum_active()) | 359 | if (jffs2_sum_active()) |
369 | jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); | 360 | jffs2_sum_add_xattr_mem(s, rx, ofs - jeb->offset); |
@@ -377,7 +368,6 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
377 | struct jffs2_summary *s) | 368 | struct jffs2_summary *s) |
378 | { | 369 | { |
379 | struct jffs2_xattr_ref *ref; | 370 | struct jffs2_xattr_ref *ref; |
380 | struct jffs2_raw_node_ref *raw; | ||
381 | uint32_t crc; | 371 | uint32_t crc; |
382 | int err; | 372 | int err; |
383 | 373 | ||
@@ -404,12 +394,6 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
404 | if (!ref) | 394 | if (!ref) |
405 | return -ENOMEM; | 395 | return -ENOMEM; |
406 | 396 | ||
407 | raw = jffs2_alloc_raw_node_ref(); | ||
408 | if (!raw) { | ||
409 | jffs2_free_xattr_ref(ref); | ||
410 | return -ENOMEM; | ||
411 | } | ||
412 | |||
413 | /* BEFORE jffs2_build_xattr_subsystem() called, | 397 | /* BEFORE jffs2_build_xattr_subsystem() called, |
414 | * ref->xid is used to store 32bit xid, xd is not used | 398 | * ref->xid is used to store 32bit xid, xd is not used |
415 | * ref->ino is used to store 32bit inode-number, ic is not used | 399 | * ref->ino is used to store 32bit inode-number, ic is not used |
@@ -418,16 +402,13 @@ static int jffs2_scan_xref_node(struct jffs2_sb_info *c, struct jffs2_eraseblock | |||
418 | * used to chain all xattr_ref object. It's re-chained to | 402 | * used to chain all xattr_ref object. It's re-chained to |
419 | * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly. | 403 | * jffs2_inode_cache in jffs2_build_xattr_subsystem() correctly. |
420 | */ | 404 | */ |
421 | ref->node = raw; | ||
422 | ref->ino = je32_to_cpu(rr->ino); | 405 | ref->ino = je32_to_cpu(rr->ino); |
423 | ref->xid = je32_to_cpu(rr->xid); | 406 | ref->xid = je32_to_cpu(rr->xid); |
424 | ref->next = c->xref_temp; | 407 | ref->next = c->xref_temp; |
425 | c->xref_temp = ref; | 408 | c->xref_temp = ref; |
426 | 409 | ||
427 | raw->flash_offset = ofs | REF_PRISTINE; | 410 | ref->node = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rr->totlen)), NULL); |
428 | 411 | /* FIXME */ ref->node->next_in_ino = (void *)ref; | |
429 | jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(rr->totlen)), NULL); | ||
430 | /* FIXME */ raw->next_in_ino = (void *)ref; | ||
431 | 412 | ||
432 | if (jffs2_sum_active()) | 413 | if (jffs2_sum_active()) |
433 | jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); | 414 | jffs2_sum_add_xref_mem(s, rr, ofs - jeb->offset); |
@@ -597,6 +578,11 @@ scan_more: | |||
597 | 578 | ||
598 | jffs2_dbg_acct_paranoia_check_nolock(c, jeb); | 579 | jffs2_dbg_acct_paranoia_check_nolock(c, jeb); |
599 | 580 | ||
581 | /* Make sure there are node refs available for use */ | ||
582 | err = jffs2_prealloc_raw_node_refs(c, 2); | ||
583 | if (err) | ||
584 | return err; | ||
585 | |||
600 | cond_resched(); | 586 | cond_resched(); |
601 | 587 | ||
602 | if (ofs & 3) { | 588 | if (ofs & 3) { |
@@ -839,14 +825,7 @@ scan_more: | |||
839 | return err; | 825 | return err; |
840 | ofs += PAD(sizeof(struct jffs2_unknown_node)); | 826 | ofs += PAD(sizeof(struct jffs2_unknown_node)); |
841 | } else { | 827 | } else { |
842 | struct jffs2_raw_node_ref *marker_ref = jffs2_alloc_raw_node_ref(); | 828 | jffs2_link_node_ref(c, jeb, ofs | REF_NORMAL, c->cleanmarker_size, NULL); |
843 | if (!marker_ref) { | ||
844 | printk(KERN_NOTICE "Failed to allocate node ref for clean marker\n"); | ||
845 | return -ENOMEM; | ||
846 | } | ||
847 | marker_ref->flash_offset = ofs | REF_NORMAL; | ||
848 | |||
849 | jffs2_link_node_ref(c, jeb, marker_ref, c->cleanmarker_size, NULL); | ||
850 | 829 | ||
851 | ofs += PAD(c->cleanmarker_size); | 830 | ofs += PAD(c->cleanmarker_size); |
852 | } | 831 | } |
@@ -884,14 +863,9 @@ scan_more: | |||
884 | break; | 863 | break; |
885 | 864 | ||
886 | case JFFS2_FEATURE_RWCOMPAT_COPY: { | 865 | case JFFS2_FEATURE_RWCOMPAT_COPY: { |
887 | struct jffs2_raw_node_ref *ref; | ||
888 | D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); | 866 | D1(printk(KERN_NOTICE "Unknown but compatible feature node (0x%04x) found at offset 0x%08x\n", je16_to_cpu(node->nodetype), ofs)); |
889 | 867 | ||
890 | ref = jffs2_alloc_raw_node_ref(); | 868 | jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(node->totlen)), NULL); |
891 | if (!ref) | ||
892 | return -ENOMEM; | ||
893 | ref->flash_offset = ofs | REF_PRISTINE; | ||
894 | jffs2_link_node_ref(c, jeb, ref, PAD(je32_to_cpu(node->totlen)), NULL); | ||
895 | 869 | ||
896 | /* We can't summarise nodes we don't grok */ | 870 | /* We can't summarise nodes we don't grok */ |
897 | jffs2_sum_disable_collecting(s); | 871 | jffs2_sum_disable_collecting(s); |
@@ -953,7 +927,6 @@ struct jffs2_inode_cache *jffs2_scan_make_ino_cache(struct jffs2_sb_info *c, uin | |||
953 | static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 927 | static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
954 | struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s) | 928 | struct jffs2_raw_inode *ri, uint32_t ofs, struct jffs2_summary *s) |
955 | { | 929 | { |
956 | struct jffs2_raw_node_ref *raw; | ||
957 | struct jffs2_inode_cache *ic; | 930 | struct jffs2_inode_cache *ic; |
958 | uint32_t ino = je32_to_cpu(ri->ino); | 931 | uint32_t ino = je32_to_cpu(ri->ino); |
959 | int err; | 932 | int err; |
@@ -969,12 +942,6 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
969 | Which means that the _full_ amount of time to get to proper write mode with GC | 942 | Which means that the _full_ amount of time to get to proper write mode with GC |
970 | operational may actually be _longer_ than before. Sucks to be me. */ | 943 | operational may actually be _longer_ than before. Sucks to be me. */ |
971 | 944 | ||
972 | raw = jffs2_alloc_raw_node_ref(); | ||
973 | if (!raw) { | ||
974 | printk(KERN_NOTICE "jffs2_scan_inode_node(): allocation of node reference failed\n"); | ||
975 | return -ENOMEM; | ||
976 | } | ||
977 | |||
978 | ic = jffs2_get_ino_cache(c, ino); | 945 | ic = jffs2_get_ino_cache(c, ino); |
979 | if (!ic) { | 946 | if (!ic) { |
980 | /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the | 947 | /* Inocache get failed. Either we read a bogus ino# or it's just genuinely the |
@@ -988,21 +955,15 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
988 | /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ | 955 | /* We believe totlen because the CRC on the node _header_ was OK, just the node itself failed. */ |
989 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(ri->totlen))))) | 956 | if ((err = jffs2_scan_dirty_space(c, jeb, PAD(je32_to_cpu(ri->totlen))))) |
990 | return err; | 957 | return err; |
991 | jffs2_free_raw_node_ref(raw); | ||
992 | return 0; | 958 | return 0; |
993 | } | 959 | } |
994 | ic = jffs2_scan_make_ino_cache(c, ino); | 960 | ic = jffs2_scan_make_ino_cache(c, ino); |
995 | if (!ic) { | 961 | if (!ic) |
996 | jffs2_free_raw_node_ref(raw); | ||
997 | return -ENOMEM; | 962 | return -ENOMEM; |
998 | } | ||
999 | } | 963 | } |
1000 | 964 | ||
1001 | /* Wheee. It worked */ | 965 | /* Wheee. It worked */ |
1002 | 966 | jffs2_link_node_ref(c, jeb, ofs | REF_UNCHECKED, PAD(je32_to_cpu(ri->totlen)), ic); | |
1003 | raw->flash_offset = ofs | REF_UNCHECKED; | ||
1004 | |||
1005 | jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(ri->totlen)), ic); | ||
1006 | 967 | ||
1007 | D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", | 968 | D1(printk(KERN_DEBUG "Node is ino #%u, version %d. Range 0x%x-0x%x\n", |
1008 | je32_to_cpu(ri->ino), je32_to_cpu(ri->version), | 969 | je32_to_cpu(ri->ino), je32_to_cpu(ri->version), |
@@ -1021,7 +982,6 @@ static int jffs2_scan_inode_node(struct jffs2_sb_info *c, struct jffs2_erasebloc | |||
1021 | static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, | 982 | static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb, |
1022 | struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s) | 983 | struct jffs2_raw_dirent *rd, uint32_t ofs, struct jffs2_summary *s) |
1023 | { | 984 | { |
1024 | struct jffs2_raw_node_ref *raw; | ||
1025 | struct jffs2_full_dirent *fd; | 985 | struct jffs2_full_dirent *fd; |
1026 | struct jffs2_inode_cache *ic; | 986 | struct jffs2_inode_cache *ic; |
1027 | uint32_t crc; | 987 | uint32_t crc; |
@@ -1063,23 +1023,14 @@ static int jffs2_scan_dirent_node(struct jffs2_sb_info *c, struct jffs2_eraseblo | |||
1063 | return err; | 1023 | return err; |
1064 | return 0; | 1024 | return 0; |
1065 | } | 1025 | } |
1066 | raw = jffs2_alloc_raw_node_ref(); | ||
1067 | if (!raw) { | ||
1068 | jffs2_free_full_dirent(fd); | ||
1069 | printk(KERN_NOTICE "jffs2_scan_dirent_node(): allocation of node reference failed\n"); | ||
1070 | return -ENOMEM; | ||
1071 | } | ||
1072 | ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino)); | 1026 | ic = jffs2_scan_make_ino_cache(c, je32_to_cpu(rd->pino)); |
1073 | if (!ic) { | 1027 | if (!ic) { |
1074 | jffs2_free_full_dirent(fd); | 1028 | jffs2_free_full_dirent(fd); |
1075 | jffs2_free_raw_node_ref(raw); | ||
1076 | return -ENOMEM; | 1029 | return -ENOMEM; |
1077 | } | 1030 | } |
1078 | 1031 | ||
1079 | raw->flash_offset = ofs | REF_PRISTINE; | 1032 | fd->raw = jffs2_link_node_ref(c, jeb, ofs | REF_PRISTINE, PAD(je32_to_cpu(rd->totlen)), ic); |
1080 | jffs2_link_node_ref(c, jeb, raw, PAD(je32_to_cpu(rd->totlen)), ic); | ||
1081 | 1033 | ||
1082 | fd->raw = raw; | ||
1083 | fd->next = NULL; | 1034 | fd->next = NULL; |
1084 | fd->version = je32_to_cpu(rd->version); | 1035 | fd->version = je32_to_cpu(rd->version); |
1085 | fd->ino = je32_to_cpu(rd->ino); | 1036 | fd->ino = je32_to_cpu(rd->ino); |