diff options
Diffstat (limited to 'fs/jffs2/nodelist.c')
-rw-r--r-- | fs/jffs2/nodelist.c | 93 |
1 files changed, 47 insertions, 46 deletions
diff --git a/fs/jffs2/nodelist.c b/fs/jffs2/nodelist.c index 0e82979c741c..5d36e9b4d7c5 100644 --- a/fs/jffs2/nodelist.c +++ b/fs/jffs2/nodelist.c | |||
@@ -954,18 +954,16 @@ void jffs2_free_raw_node_refs(struct jffs2_sb_info *c) | |||
954 | for (i=0; i<c->nr_blocks; i++) { | 954 | for (i=0; i<c->nr_blocks; i++) { |
955 | this = c->blocks[i].first_node; | 955 | this = c->blocks[i].first_node; |
956 | while (this) { | 956 | while (this) { |
957 | next = this->next_phys; | 957 | if (this[REFS_PER_BLOCK].flash_offset == REF_LINK_NODE) |
958 | __jffs2_free_raw_node_ref(this); | 958 | next = this[REFS_PER_BLOCK].next_in_ino; |
959 | else | ||
960 | next = NULL; | ||
961 | |||
962 | jffs2_free_refblock(this); | ||
959 | this = next; | 963 | this = next; |
960 | } | 964 | } |
961 | c->blocks[i].first_node = c->blocks[i].last_node = NULL; | 965 | c->blocks[i].first_node = c->blocks[i].last_node = NULL; |
962 | } | 966 | } |
963 | this = c->refs; | ||
964 | while (this) { | ||
965 | next = this->next_in_ino; | ||
966 | __jffs2_free_raw_node_ref(this); | ||
967 | this = next; | ||
968 | } | ||
969 | } | 967 | } |
970 | 968 | ||
971 | struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset) | 969 | struct jffs2_node_frag *jffs2_lookup_node_frag(struct rb_root *fragtree, uint32_t offset) |
@@ -1060,32 +1058,37 @@ struct jffs2_raw_node_ref *jffs2_link_node_ref(struct jffs2_sb_info *c, | |||
1060 | { | 1058 | { |
1061 | struct jffs2_raw_node_ref *ref; | 1059 | struct jffs2_raw_node_ref *ref; |
1062 | 1060 | ||
1063 | /* These will be preallocated _very_ shortly. */ | 1061 | BUG_ON(!jeb->allocated_refs); |
1064 | ref = c->refs; | 1062 | jeb->allocated_refs--; |
1065 | if (!c->refs) { | 1063 | |
1066 | JFFS2_WARNING("Using non-preallocated refs!\n"); | 1064 | ref = jeb->last_node; |
1067 | ref = __jffs2_alloc_raw_node_ref(); | 1065 | |
1068 | BUG_ON(!ref); | 1066 | dbg_noderef("Last node at %p is (%08x,%p)\n", ref, ref->flash_offset, |
1069 | WARN_ON(1); | 1067 | ref->next_in_ino); |
1070 | } else { | 1068 | |
1071 | c->refs = ref->next_in_ino; | 1069 | while (ref->flash_offset != REF_EMPTY_NODE) { |
1070 | if (ref->flash_offset == REF_LINK_NODE) | ||
1071 | ref = ref->next_in_ino; | ||
1072 | else | ||
1073 | ref++; | ||
1072 | } | 1074 | } |
1073 | 1075 | ||
1074 | ref->next_phys = NULL; | 1076 | dbg_noderef("New ref is %p (%08x becomes %08x,%p) len 0x%x\n", ref, |
1077 | ref->flash_offset, ofs, ref->next_in_ino, len); | ||
1078 | |||
1075 | ref->flash_offset = ofs; | 1079 | ref->flash_offset = ofs; |
1076 | 1080 | ||
1077 | if (!jeb->first_node) | 1081 | if (!jeb->first_node) { |
1078 | jeb->first_node = ref; | 1082 | jeb->first_node = ref; |
1079 | if (jeb->last_node) { | 1083 | BUG_ON(ref_offset(ref) != jeb->offset); |
1080 | jeb->last_node->next_phys = ref; | 1084 | } else if (unlikely(ref_offset(ref) != jeb->offset + c->sector_size - jeb->free_size)) { |
1081 | #ifdef TEST_TOTLEN | 1085 | uint32_t last_len = ref_totlen(c, jeb, jeb->last_node); |
1082 | if (ref_offset(jeb->last_node) + jeb->last_node->__totlen != ref_offset(ref)) { | 1086 | |
1083 | printk(KERN_CRIT "Adding new ref %p at (0x%08x-0x%08x) not immediately after previous (0x%08x-0x%08x)\n", | 1087 | JFFS2_ERROR("Adding new ref %p at (0x%08x-0x%08x) not immediately after previous (0x%08x-0x%08x)\n", |
1084 | ref, ref_offset(ref), ref_offset(ref)+ref->__totlen, | 1088 | ref, ref_offset(ref), ref_offset(ref)+len, |
1085 | ref_offset(jeb->last_node), ref_offset(jeb->last_node)+jeb->last_node->__totlen); | 1089 | ref_offset(jeb->last_node), |
1086 | WARN_ON(1); | 1090 | ref_offset(jeb->last_node)+last_len); |
1087 | } | 1091 | BUG(); |
1088 | #endif | ||
1089 | } | 1092 | } |
1090 | jeb->last_node = ref; | 1093 | jeb->last_node = ref; |
1091 | 1094 | ||
@@ -1130,12 +1133,13 @@ int jffs2_scan_dirty_space(struct jffs2_sb_info *c, struct jffs2_eraseblock *jeb | |||
1130 | { | 1133 | { |
1131 | if (!size) | 1134 | if (!size) |
1132 | return 0; | 1135 | return 0; |
1133 | if (size > c->sector_size - jeb->used_size) { | 1136 | if (unlikely(size > jeb->free_size)) { |
1134 | printk(KERN_CRIT "Dirty space 0x%x larger then used_size 0x%x (wasted 0x%x)\n", | 1137 | printk(KERN_CRIT "Dirty space 0x%x larger then free_size 0x%x (wasted 0x%x)\n", |
1135 | size, jeb->used_size, jeb->wasted_size); | 1138 | size, jeb->free_size, jeb->wasted_size); |
1136 | BUG(); | 1139 | BUG(); |
1137 | } | 1140 | } |
1138 | if (jeb->last_node && ref_obsolete(jeb->last_node)) { | 1141 | /* REF_EMPTY_NODE is !obsolete, so that works OK */ |
1142 | if (ref_obsolete(jeb->last_node)) { | ||
1139 | #ifdef TEST_TOTLEN | 1143 | #ifdef TEST_TOTLEN |
1140 | jeb->last_node->__totlen += size; | 1144 | jeb->last_node->__totlen += size; |
1141 | #endif | 1145 | #endif |
@@ -1168,7 +1172,7 @@ static inline uint32_t __ref_totlen(struct jffs2_sb_info *c, | |||
1168 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; | 1172 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; |
1169 | 1173 | ||
1170 | /* Last node in block. Use free_space */ | 1174 | /* Last node in block. Use free_space */ |
1171 | if (ref != jeb->last_node) { | 1175 | if (unlikely(ref != jeb->last_node)) { |
1172 | printk(KERN_CRIT "ref %p @0x%08x is not jeb->last_node (%p @0x%08x)\n", | 1176 | printk(KERN_CRIT "ref %p @0x%08x is not jeb->last_node (%p @0x%08x)\n", |
1173 | ref, ref_offset(ref), jeb->last_node, jeb->last_node?ref_offset(jeb->last_node):0); | 1177 | ref, ref_offset(ref), jeb->last_node, jeb->last_node?ref_offset(jeb->last_node):0); |
1174 | BUG(); | 1178 | BUG(); |
@@ -1183,17 +1187,13 @@ uint32_t __jffs2_ref_totlen(struct jffs2_sb_info *c, struct jffs2_eraseblock *je | |||
1183 | { | 1187 | { |
1184 | uint32_t ret; | 1188 | uint32_t ret; |
1185 | 1189 | ||
1186 | #if CONFIG_JFFS2_FS_DEBUG > 0 | ||
1187 | if (jeb && jeb != &c->blocks[ref->flash_offset / c->sector_size]) { | ||
1188 | printk(KERN_CRIT "ref_totlen called with wrong block -- at 0x%08x instead of 0x%08x; ref 0x%08x\n", | ||
1189 | jeb->offset, c->blocks[ref->flash_offset / c->sector_size].offset, ref_offset(ref)); | ||
1190 | BUG(); | ||
1191 | } | ||
1192 | #endif | ||
1193 | |||
1194 | ret = __ref_totlen(c, jeb, ref); | 1190 | ret = __ref_totlen(c, jeb, ref); |
1191 | |||
1195 | #ifdef TEST_TOTLEN | 1192 | #ifdef TEST_TOTLEN |
1196 | if (ret != ref->__totlen) { | 1193 | if (unlikely(ret != ref->__totlen)) { |
1194 | if (!jeb) | ||
1195 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; | ||
1196 | |||
1197 | printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n", | 1197 | printk(KERN_CRIT "Totlen for ref at %p (0x%08x-0x%08x) miscalculated as 0x%x instead of %x\n", |
1198 | ref, ref_offset(ref), ref_offset(ref)+ref->__totlen, | 1198 | ref, ref_offset(ref), ref_offset(ref)+ref->__totlen, |
1199 | ret, ref->__totlen); | 1199 | ret, ref->__totlen); |
@@ -1204,13 +1204,14 @@ uint32_t __jffs2_ref_totlen(struct jffs2_sb_info *c, struct jffs2_eraseblock *je | |||
1204 | printk(KERN_CRIT "No next ref. jeb->last_node is %p\n", jeb->last_node); | 1204 | printk(KERN_CRIT "No next ref. jeb->last_node is %p\n", jeb->last_node); |
1205 | 1205 | ||
1206 | printk(KERN_CRIT "jeb->wasted_size %x, dirty_size %x, used_size %x, free_size %x\n", jeb->wasted_size, jeb->dirty_size, jeb->used_size, jeb->free_size); | 1206 | printk(KERN_CRIT "jeb->wasted_size %x, dirty_size %x, used_size %x, free_size %x\n", jeb->wasted_size, jeb->dirty_size, jeb->used_size, jeb->free_size); |
1207 | ret = ref->__totlen; | 1207 | |
1208 | if (!jeb) | ||
1209 | jeb = &c->blocks[ref->flash_offset / c->sector_size]; | ||
1210 | #if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS) | 1208 | #if defined(JFFS2_DBG_DUMPS) || defined(JFFS2_DBG_PARANOIA_CHECKS) |
1211 | __jffs2_dbg_dump_node_refs_nolock(c, jeb); | 1209 | __jffs2_dbg_dump_node_refs_nolock(c, jeb); |
1212 | #endif | 1210 | #endif |
1211 | |||
1213 | WARN_ON(1); | 1212 | WARN_ON(1); |
1213 | |||
1214 | ret = ref->__totlen; | ||
1214 | } | 1215 | } |
1215 | #endif /* TEST_TOTLEN */ | 1216 | #endif /* TEST_TOTLEN */ |
1216 | return ret; | 1217 | return ret; |