Chean up nand test script
[yaffs2.git] / yaffs_yaffs2.c
1 /*
2  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2011 Aleph One Ltd.
5  *   for Toby Churchill Ltd and Brightstar Engineering
6  *
7  * Created by Charles Manning <charles@aleph1.co.uk>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License version 2 as
11  * published by the Free Software Foundation.
12  */
13
14 #include "yaffs_guts.h"
15 #include "yaffs_trace.h"
16 #include "yaffs_yaffs2.h"
17 #include "yaffs_checkptrw.h"
18 #include "yaffs_bitmap.h"
19 #include "yaffs_nand.h"
20 #include "yaffs_getblockinfo.h"
21 #include "yaffs_verify.h"
22 #include "yaffs_attribs.h"
23 #include "yaffs_summary.h"
24 #include "yaffs_endian.h"
25
26 /*
27  * Checkpoints are really no benefit on very small partitions.
28  *
29  * To save space on small partitions don't bother with checkpoints unless
30  * the partition is at least this big.
31  */
32 #define YAFFS_CHECKPOINT_MIN_BLOCKS 60
33 #define YAFFS_SMALL_HOLE_THRESHOLD 4
34
35 /*
36  * Oldest Dirty Sequence Number handling.
37  */
38
39 /* yaffs_calc_oldest_dirty_seq()
40  * yaffs2_find_oldest_dirty_seq()
41  * Calculate the oldest dirty sequence number if we don't know it.
42  */
43 void yaffs_calc_oldest_dirty_seq(struct yaffs_dev *dev)
44 {
45         int i;
46         unsigned seq;
47         unsigned block_no = 0;
48         struct yaffs_block_info *b;
49
50         if (!dev->param.is_yaffs2)
51                 return;
52
53         /* Find the oldest dirty sequence number. */
54         seq = dev->seq_number + 1;
55         b = dev->block_info;
56         for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
57                 if (b->block_state == YAFFS_BLOCK_STATE_FULL &&
58                     (b->pages_in_use - b->soft_del_pages) <
59                     dev->param.chunks_per_block &&
60                     b->seq_number < seq) {
61                         seq = b->seq_number;
62                         block_no = i;
63                 }
64                 b++;
65         }
66
67         if (block_no) {
68                 dev->oldest_dirty_seq = seq;
69                 dev->oldest_dirty_block = block_no;
70         }
71 }
72
73 void yaffs2_find_oldest_dirty_seq(struct yaffs_dev *dev)
74 {
75         if (!dev->param.is_yaffs2)
76                 return;
77
78         if (!dev->oldest_dirty_seq)
79                 yaffs_calc_oldest_dirty_seq(dev);
80 }
81
82 /*
83  * yaffs_clear_oldest_dirty_seq()
84  * Called when a block is erased or marked bad. (ie. when its seq_number
85  * becomes invalid). If the value matches the oldest then we clear
86  * dev->oldest_dirty_seq to force its recomputation.
87  */
88 void yaffs2_clear_oldest_dirty_seq(struct yaffs_dev *dev,
89                                    struct yaffs_block_info *bi)
90 {
91
92         if (!dev->param.is_yaffs2)
93                 return;
94
95         if (!bi || bi->seq_number == dev->oldest_dirty_seq) {
96                 dev->oldest_dirty_seq = 0;
97                 dev->oldest_dirty_block = 0;
98         }
99 }
100
101 /*
102  * yaffs2_update_oldest_dirty_seq()
103  * Update the oldest dirty sequence number whenever we dirty a block.
104  * Only do this if the oldest_dirty_seq is actually being tracked.
105  */
106 void yaffs2_update_oldest_dirty_seq(struct yaffs_dev *dev, unsigned block_no,
107                                     struct yaffs_block_info *bi)
108 {
109         if (!dev->param.is_yaffs2)
110                 return;
111
112         if (dev->oldest_dirty_seq) {
113                 if (dev->oldest_dirty_seq > bi->seq_number) {
114                         dev->oldest_dirty_seq = bi->seq_number;
115                         dev->oldest_dirty_block = block_no;
116                 }
117         }
118 }
119
120 int yaffs_block_ok_for_gc(struct yaffs_dev *dev, struct yaffs_block_info *bi)
121 {
122
123         if (!dev->param.is_yaffs2)
124                 return 1;       /* disqualification only applies to yaffs2. */
125
126         if (!bi->has_shrink_hdr)
127                 return 1;       /* can gc */
128
129         yaffs2_find_oldest_dirty_seq(dev);
130
131         /* Can't do gc of this block if there are any blocks older than this
132          * one that have discarded pages.
133          */
134         return (bi->seq_number <= dev->oldest_dirty_seq);
135 }
136
137 /*
138  * yaffs2_find_refresh_block()
139  * periodically finds the oldest full block by sequence number for refreshing.
140  * Only for yaffs2.
141  */
142 u32 yaffs2_find_refresh_block(struct yaffs_dev *dev)
143 {
144         u32 b;
145         u32 oldest = 0;
146         u32 oldest_seq = 0;
147         struct yaffs_block_info *bi;
148
149         if (!dev->param.is_yaffs2)
150                 return oldest;
151
152         /*
153          * If refresh period < 10 then refreshing is disabled.
154          */
155         if (dev->param.refresh_period < 10)
156                 return oldest;
157
158         /*
159          * Fix broken values.
160          */
161         if (dev->refresh_skip > dev->param.refresh_period)
162                 dev->refresh_skip = dev->param.refresh_period;
163
164         if (dev->refresh_skip > 0)
165                 return oldest;
166
167         /*
168          * Refresh skip is now zero.
169          * We'll do a refresh this time around....
170          * Update the refresh skip and find the oldest block.
171          */
172         dev->refresh_skip = dev->param.refresh_period;
173         dev->refresh_count++;
174         bi = dev->block_info;
175         for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) {
176
177                 if (bi->block_state == YAFFS_BLOCK_STATE_FULL) {
178
179                         if (oldest < 1 || bi->seq_number < oldest_seq) {
180                                 oldest = b;
181                                 oldest_seq = bi->seq_number;
182                         }
183                 }
184                 bi++;
185         }
186
187         if (oldest > 0) {
188                 yaffs_trace(YAFFS_TRACE_GC,
189                         "GC refresh count %d selected block %d with seq_number %d",
190                         dev->refresh_count, oldest, oldest_seq);
191         }
192
193         return oldest;
194 }
195
196 int yaffs2_checkpt_required(struct yaffs_dev *dev)
197 {
198         int nblocks;
199
200         if (!dev->param.is_yaffs2)
201                 return 0;
202
203         nblocks = dev->internal_end_block - dev->internal_start_block + 1;
204
205         return !dev->param.skip_checkpt_wr &&
206             !dev->read_only && (nblocks >= YAFFS_CHECKPOINT_MIN_BLOCKS);
207 }
208
209 int yaffs_calc_checkpt_blocks_required(struct yaffs_dev *dev)
210 {
211         int retval;
212         int n_bytes = 0;
213         int n_blocks;
214         int dev_blocks;
215
216         if (!dev->param.is_yaffs2)
217                 return 0;
218
219         if (!dev->checkpoint_blocks_required && yaffs2_checkpt_required(dev)) {
220                 /* Not a valid value so recalculate */
221                 dev_blocks = dev->param.end_block - dev->param.start_block + 1;
222                 n_bytes += sizeof(struct yaffs_checkpt_validity);
223                 n_bytes += sizeof(struct yaffs_checkpt_dev);
224                 n_bytes += dev_blocks * sizeof(struct yaffs_block_info);
225                 n_bytes += dev_blocks * dev->chunk_bit_stride;
226                 n_bytes +=
227                     (sizeof(struct yaffs_checkpt_obj) + sizeof(u32)) *
228                     dev->n_obj;
229                 n_bytes += (dev->tnode_size + sizeof(u32)) * dev->n_tnodes;
230                 n_bytes += sizeof(struct yaffs_checkpt_validity);
231                 n_bytes += sizeof(u32); /* checksum */
232
233                 /* Round up and add 2 blocks to allow for some bad blocks,
234                  * so add 3 */
235
236                 n_blocks =
237                     (n_bytes /
238                      (dev->data_bytes_per_chunk *
239                       dev->param.chunks_per_block)) + 3;
240
241                 dev->checkpoint_blocks_required = n_blocks;
242         }
243
244         retval = dev->checkpoint_blocks_required - dev->blocks_in_checkpt;
245         if (retval < 0)
246                 retval = 0;
247         return retval;
248 }
249
250 /*--------------------- Checkpointing --------------------*/
251
252 static void yaffs2_do_endian_validity_marker(struct yaffs_dev *dev,
253                                              struct yaffs_checkpt_validity *v)
254 {
255
256         if (!dev->swap_endian)
257                 return;
258         v->struct_type = swap_s32(v->struct_type);
259         v->magic = swap_u32(v->magic);
260         v->version = swap_u32(v->version);
261         v->head = swap_u32(v->head);
262 }
263
264 static int yaffs2_wr_checkpt_validity_marker(struct yaffs_dev *dev, int head)
265 {
266         struct yaffs_checkpt_validity cp;
267
268         memset(&cp, 0, sizeof(cp));
269
270         cp.struct_type = sizeof(cp);
271         cp.magic = YAFFS_MAGIC;
272         cp.version = YAFFS_CHECKPOINT_VERSION;
273         cp.head = (head) ? 1 : 0;
274
275         yaffs2_do_endian_validity_marker(dev, &cp);
276
277         return (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp)) ? 1 : 0;
278 }
279
280 static int yaffs2_rd_checkpt_validity_marker(struct yaffs_dev *dev, int head)
281 {
282         struct yaffs_checkpt_validity cp;
283         int ok;
284
285         ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
286         yaffs2_do_endian_validity_marker(dev, &cp);
287
288         if (ok)
289                 ok = (cp.struct_type == sizeof(cp)) &&
290                     (cp.magic == YAFFS_MAGIC) &&
291                     (cp.version == YAFFS_CHECKPOINT_VERSION) &&
292                     (cp.head == ((head) ? 1 : 0));
293         return ok ? 1 : 0;
294 }
295
296 static void yaffs2_dev_to_checkpt_dev(struct yaffs_checkpt_dev *cp,
297                                       struct yaffs_dev *dev)
298 {
299         cp->struct_type = sizeof(*cp);
300
301         cp->n_erased_blocks = dev->n_erased_blocks;
302         cp->alloc_block = dev->alloc_block;
303         cp->alloc_page = dev->alloc_page;
304         cp->n_free_chunks = dev->n_free_chunks;
305
306         cp->n_deleted_files = dev->n_deleted_files;
307         cp->n_unlinked_files = dev->n_unlinked_files;
308         cp->n_bg_deletions = dev->n_bg_deletions;
309         cp->seq_number = dev->seq_number;
310
311 }
312
313 static void yaffs_checkpt_dev_to_dev(struct yaffs_dev *dev,
314                                      struct yaffs_checkpt_dev *cp)
315 {
316         dev->n_erased_blocks = cp->n_erased_blocks;
317         dev->alloc_block = cp->alloc_block;
318         dev->alloc_page = cp->alloc_page;
319         dev->n_free_chunks = cp->n_free_chunks;
320
321         dev->n_deleted_files = cp->n_deleted_files;
322         dev->n_unlinked_files = cp->n_unlinked_files;
323         dev->n_bg_deletions = cp->n_bg_deletions;
324         dev->seq_number = cp->seq_number;
325 }
326
327 static void yaffs2_do_endian_checkpt_dev(struct yaffs_dev *dev,
328                                      struct yaffs_checkpt_dev *cp)
329 {
330         if (!dev->swap_endian)
331                 return;
332         cp->struct_type = swap_s32(cp->struct_type);
333         cp->n_erased_blocks = swap_s32(cp->n_erased_blocks);
334         cp->alloc_block = swap_s32(cp->alloc_block);
335         cp->alloc_page = swap_u32(cp->alloc_page);
336         cp->n_free_chunks = swap_s32(cp->n_free_chunks);
337         cp->n_deleted_files = swap_s32(cp->n_deleted_files);
338         cp->n_unlinked_files = swap_s32(cp->n_unlinked_files);
339         cp->n_bg_deletions = swap_s32(cp->n_bg_deletions);
340 }
341
342 static int yaffs2_wr_checkpt_dev(struct yaffs_dev *dev)
343 {
344         struct yaffs_checkpt_dev cp;
345         u32 n_bytes;
346         u32 n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
347         int ok;
348         int i;
349         union yaffs_block_info_union bu;
350
351         /* Write device runtime values */
352         yaffs2_dev_to_checkpt_dev(&cp, dev);
353         yaffs2_do_endian_checkpt_dev(dev, &cp);
354
355         ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
356         if (!ok)
357                 return 0;
358
359         /* Write block info. */
360         if (!dev->swap_endian) {
361                 n_bytes = n_blocks * sizeof(struct yaffs_block_info);
362                 ok = (yaffs2_checkpt_wr(dev, dev->block_info, n_bytes) == n_bytes);
363         } else {
364                 /*
365                  * Need to swap the endianisms. We can't do this in place
366                  * since that would damage live data,
367                  * so write one block info at a time using a copy.
368                  */
369                 for (i = 0; i < n_blocks && ok; i++) {
370                         bu.bi = dev->block_info[i];
371                         bu.as_u32[0] = swap_u32(bu.as_u32[0]);
372                         bu.as_u32[1] = swap_u32(bu.as_u32[1]);
373                         ok = (yaffs2_checkpt_wr(dev, &bu, sizeof(bu)) == sizeof(bu));
374                 }
375         }
376
377         if (!ok)
378                 return 0;
379
380         /*
381          * Write chunk bits. Chunk bits are in bytes so
382          * no endian conversion is needed.
383          */
384         n_bytes = n_blocks * dev->chunk_bit_stride;
385         ok = (yaffs2_checkpt_wr(dev, dev->chunk_bits, n_bytes) == n_bytes);
386
387         return ok ? 1 : 0;
388 }
389
390 static int yaffs2_rd_checkpt_dev(struct yaffs_dev *dev)
391 {
392         struct yaffs_checkpt_dev cp;
393         u32 n_bytes;
394         u32 n_blocks =
395             (dev->internal_end_block - dev->internal_start_block + 1);
396         int ok;
397
398         ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
399         if (!ok)
400                 return 0;
401         yaffs2_do_endian_checkpt_dev(dev, &cp);
402
403         if (cp.struct_type != sizeof(cp))
404                 return 0;
405
406         yaffs_checkpt_dev_to_dev(dev, &cp);
407
408         n_bytes = n_blocks * sizeof(struct yaffs_block_info);
409
410         ok = (yaffs2_checkpt_rd(dev, dev->block_info, n_bytes) == n_bytes);
411
412         if (!ok)
413                 return 0;
414
415         if (dev->swap_endian) {
416                 /* The block info can just be handled as a list of u32s. */
417                 u32 *as_u32 = (u32 *) dev->block_info;
418                 u32 n_u32s = n_bytes/sizeof(u32);
419                 u32 i;
420
421                 for (i=0; i < n_u32s; i++)
422                         as_u32[i] = swap_u32(as_u32[i]);
423         }
424
425         n_bytes = n_blocks * dev->chunk_bit_stride;
426
427         ok = (yaffs2_checkpt_rd(dev, dev->chunk_bits, n_bytes) == n_bytes);
428
429
430         return ok ? 1 : 0;
431 }
432
433
434 static void yaffs2_checkpt_obj_bit_assign(struct yaffs_checkpt_obj *cp,
435                                           int bit_offset,
436                                           int bit_width,
437                                           u32 value)
438 {
439         u32 and_mask;
440
441         and_mask = ((1<<bit_width)-1) << bit_offset;
442
443         cp->bit_field &= ~and_mask;
444         cp->bit_field |= ((value << bit_offset) & and_mask);
445 }
446
447 static u32 yaffs2_checkpt_obj_bit_get(struct yaffs_checkpt_obj *cp,
448                                       int bit_offset,
449                                       int bit_width)
450 {
451         u32 and_mask;
452
453         and_mask = ((1<<bit_width)-1);
454
455         return (cp->bit_field >> bit_offset) & and_mask;
456 }
457
458 static void yaffs2_obj_checkpt_obj(struct yaffs_checkpt_obj *cp,
459                                    struct yaffs_obj *obj)
460 {
461         cp->obj_id = obj->obj_id;
462         cp->parent_id = (obj->parent) ? obj->parent->obj_id : 0;
463         cp->hdr_chunk = obj->hdr_chunk;
464
465         yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_VARIANT_BITS, obj->variant_type);
466         yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_DELETED_BITS, obj->deleted);
467         yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_SOFT_DEL_BITS, obj->soft_del);
468         yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_UNLINKED_BITS, obj->unlinked);
469         yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_FAKE_BITS, obj->fake);
470         yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_RENAME_ALLOWED_BITS, obj->rename_allowed);
471         yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_UNLINK_ALLOWED_BITS, obj->unlink_allowed);
472         yaffs2_checkpt_obj_bit_assign(cp, CHECKPOINT_SERIAL_BITS, obj->serial);
473
474         cp->n_data_chunks = obj->n_data_chunks;
475
476         if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
477                 cp->size_or_equiv_obj = obj->variant.file_variant.file_size;
478         else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK)
479                 cp->size_or_equiv_obj = obj->variant.hardlink_variant.equiv_id;
480 }
481
482 static int yaffs2_checkpt_obj_to_obj(struct yaffs_obj *obj,
483                                      struct yaffs_checkpt_obj *cp)
484 {
485         struct yaffs_obj *parent;
486         u32 cp_variant_type = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_VARIANT_BITS);
487
488         if (obj->variant_type != cp_variant_type) {
489                 yaffs_trace(YAFFS_TRACE_ERROR,
490                         "Checkpoint read object %d type %d chunk %d does not match existing object type %d",
491                         cp->obj_id, cp_variant_type, cp->hdr_chunk,
492                         obj->variant_type);
493                 return 0;
494         }
495
496         obj->obj_id = cp->obj_id;
497
498         if (cp->parent_id)
499                 parent = yaffs_find_or_create_by_number(obj->my_dev,
500                                                 cp->parent_id,
501                                                 YAFFS_OBJECT_TYPE_DIRECTORY);
502         else
503                 parent = NULL;
504
505         if (parent) {
506                 if (parent->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
507                         yaffs_trace(YAFFS_TRACE_ALWAYS,
508                                 "Checkpoint read object %d parent %d type %d chunk %d Parent type, %d, not directory",
509                                 cp->obj_id, cp->parent_id,
510                                 cp_variant_type, cp->hdr_chunk,
511                                 parent->variant_type);
512                         return 0;
513                 }
514                 yaffs_add_obj_to_dir(parent, obj);
515         }
516
517         obj->hdr_chunk = cp->hdr_chunk;
518
519         obj->variant_type = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_VARIANT_BITS);
520         obj->deleted = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_DELETED_BITS);
521         obj->soft_del = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_SOFT_DEL_BITS);
522         obj->unlinked = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_UNLINKED_BITS);
523         obj->fake = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_FAKE_BITS);
524         obj->rename_allowed = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_RENAME_ALLOWED_BITS);
525         obj->unlink_allowed = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_UNLINK_ALLOWED_BITS);
526         obj->serial = yaffs2_checkpt_obj_bit_get(cp, CHECKPOINT_SERIAL_BITS);
527
528         obj->n_data_chunks = cp->n_data_chunks;
529
530         if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE) {
531                 obj->variant.file_variant.file_size = cp->size_or_equiv_obj;
532                 obj->variant.file_variant.stored_size = cp->size_or_equiv_obj;
533         } else if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) {
534                 obj->variant.hardlink_variant.equiv_id = cp->size_or_equiv_obj;
535         }
536         if (obj->hdr_chunk > 0)
537                 obj->lazy_loaded = 1;
538         return 1;
539 }
540
541 static void yaffs2_do_endian_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn)
542 {
543         int i;
544         u32 *as_u32 = (u32 *)tn;
545         int tnode_size_u32 = dev->tnode_size / sizeof(u32);
546
547         if (!dev->swap_endian)
548                 return;
549         /* Swap all the tnode data as u32s to fix endianisms. */
550         for (i = 0; i<tnode_size_u32; i++)
551                 as_u32[i] = swap_u32(as_u32[i]);
552 }
553
554 struct yaffs_tnode *yaffs2_do_endian_tnode_copy(struct yaffs_dev *dev,
555                                                struct yaffs_tnode *tn)
556 {
557         if (!dev->swap_endian)
558                 return tn;
559
560         memcpy(dev->tn_swap_buffer, tn, dev->tnode_size);
561         tn = dev->tn_swap_buffer;
562
563         yaffs2_do_endian_tnode(dev, tn);
564
565         return tn;
566 }
567
568 static int yaffs2_checkpt_tnode_worker(struct yaffs_obj *in,
569                                        struct yaffs_tnode *tn, u32 level,
570                                        int chunk_offset)
571 {
572         int i;
573         struct yaffs_dev *dev = in->my_dev;
574         int ok = 1;
575         u32 base_offset;
576
577         if (!tn)
578                 return 1;
579
580         if (level > 0) {
581                 for (i = 0; i < YAFFS_NTNODES_INTERNAL && ok; i++) {
582                         if (!tn->internal[i])
583                                 continue;
584                         ok = yaffs2_checkpt_tnode_worker(in,
585                                  tn->internal[i],
586                                  level - 1,
587                                  (chunk_offset <<
588                                   YAFFS_TNODES_INTERNAL_BITS) + i);
589                 }
590                 return ok;
591         }
592
593         /* Level 0 tnode */
594         base_offset = chunk_offset << YAFFS_TNODES_LEVEL0_BITS;
595         yaffs_do_endian_u32(dev, &base_offset);
596
597         ok = (yaffs2_checkpt_wr(dev, &base_offset, sizeof(base_offset)) ==
598                         sizeof(base_offset));
599         if (ok) {
600                 /*
601                  * NB Can't do an in-place endian swizzle since that would
602                  * damage current tnode data.
603                  * If a tnode endian conversion is required we do a copy.
604                  */
605                 tn = yaffs2_do_endian_tnode_copy(dev, tn);
606                 ok = (yaffs2_checkpt_wr(dev, tn, dev->tnode_size) ==
607                         dev->tnode_size);
608         }
609         return ok;
610 }
611
612 static int yaffs2_wr_checkpt_tnodes(struct yaffs_obj *obj)
613 {
614         u32 end_marker = ~0;
615         int ok = 1;
616
617         if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
618                 return ok;
619
620         ok = yaffs2_checkpt_tnode_worker(obj,
621                                          obj->variant.file_variant.top,
622                                          obj->variant.file_variant.
623                                          top_level, 0);
624         if (ok)
625                 ok = (yaffs2_checkpt_wr(obj->my_dev, &end_marker,
626                                 sizeof(end_marker)) == sizeof(end_marker));
627
628         return ok ? 1 : 0;
629 }
630
631 static int yaffs2_rd_checkpt_tnodes(struct yaffs_obj *obj)
632 {
633         u32 base_chunk;
634         int ok = 1;
635         struct yaffs_dev *dev = obj->my_dev;
636         struct yaffs_file_var *file_stuct_ptr = &obj->variant.file_variant;
637         struct yaffs_tnode *tn;
638         int nread = 0;
639
640         ok = (yaffs2_checkpt_rd(dev, &base_chunk, sizeof(base_chunk)) ==
641               sizeof(base_chunk));
642
643         yaffs_do_endian_u32(dev, &base_chunk);
644
645         while (ok && (~base_chunk)) {
646                 nread++;
647                 /* Read level 0 tnode */
648
649                 tn = yaffs_get_tnode(dev);
650                 if (tn) {
651                         ok = (yaffs2_checkpt_rd(dev, tn, dev->tnode_size) ==
652                                 dev->tnode_size);
653                         yaffs2_do_endian_tnode(dev, tn);
654                 }
655                 else
656                         ok = 0;
657
658                 if (tn && ok)
659                         ok = yaffs_add_find_tnode_0(dev,
660                                                     file_stuct_ptr,
661                                                     base_chunk, tn) ? 1 : 0;
662
663                 if (ok) {
664                         ok = (yaffs2_checkpt_rd
665                               (dev, &base_chunk,
666                                sizeof(base_chunk)) == sizeof(base_chunk));
667                         yaffs_do_endian_u32(dev, &base_chunk);
668                 }
669
670         }
671
672         yaffs_trace(YAFFS_TRACE_CHECKPOINT,
673                 "Checkpoint read tnodes %d records, last %d. ok %d",
674                 nread, base_chunk, ok);
675
676         return ok ? 1 : 0;
677 }
678
679
680 static void yaffs2_do_endian_checkpt_obj(struct yaffs_dev *dev,
681                                          struct yaffs_checkpt_obj *cp)
682 {
683         if (!dev->swap_endian)
684                 return;
685         cp->struct_type = swap_s32(cp->struct_type);
686         cp->obj_id = swap_u32(cp->obj_id);
687         cp->parent_id = swap_u32(cp->parent_id);
688         cp->hdr_chunk = swap_s32(cp->hdr_chunk);
689         cp->bit_field = swap_u32(cp->bit_field);
690         cp->n_data_chunks = swap_s32(cp->n_data_chunks);
691         cp->size_or_equiv_obj = swap_loff_t(cp->size_or_equiv_obj);
692 }
693
694 static int yaffs2_wr_checkpt_objs(struct yaffs_dev *dev)
695 {
696         struct yaffs_obj *obj;
697         struct yaffs_checkpt_obj cp;
698         int i;
699         int ok = 1;
700         struct list_head *lh;
701         u32 cp_variant_type;
702
703         /* Iterate through the objects in each hash entry,
704          * dumping them to the checkpointing stream.
705          */
706
707         for (i = 0; ok && i < YAFFS_NOBJECT_BUCKETS; i++) {
708                 list_for_each(lh, &dev->obj_bucket[i].list) {
709                         obj = list_entry(lh, struct yaffs_obj, hash_link);
710                         if (!obj->defered_free) {
711                                 yaffs2_obj_checkpt_obj(&cp, obj);
712                                 cp.struct_type = sizeof(cp);
713                                 cp_variant_type = yaffs2_checkpt_obj_bit_get(
714                                                 &cp, CHECKPOINT_VARIANT_BITS);
715                                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
716                                         "Checkpoint write object %d parent %d type %d chunk %d obj addr %p",
717                                         cp.obj_id, cp.parent_id,
718                                         cp_variant_type, cp.hdr_chunk, obj);
719
720                                 yaffs2_do_endian_checkpt_obj (dev, &cp);
721                                 ok = (yaffs2_checkpt_wr(dev, &cp,
722                                                 sizeof(cp)) == sizeof(cp));
723
724                                 if (ok &&
725                                         obj->variant_type ==
726                                         YAFFS_OBJECT_TYPE_FILE)
727                                         ok = yaffs2_wr_checkpt_tnodes(obj);
728                         }
729                 }
730         }
731
732         /* Dump end of list */
733         memset(&cp, 0xff, sizeof(struct yaffs_checkpt_obj));
734         cp.struct_type = sizeof(cp);
735         yaffs2_do_endian_checkpt_obj (dev, &cp);
736
737         if (ok)
738                 ok = (yaffs2_checkpt_wr(dev, &cp, sizeof(cp)) == sizeof(cp));
739
740         return ok ? 1 : 0;
741 }
742
743 static int yaffs2_rd_checkpt_objs(struct yaffs_dev *dev)
744 {
745         struct yaffs_obj *obj;
746         struct yaffs_checkpt_obj cp;
747         int ok = 1;
748         int done = 0;
749         u32 cp_variant_type;
750         LIST_HEAD(hard_list);
751
752
753         while (ok && !done) {
754                 ok = (yaffs2_checkpt_rd(dev, &cp, sizeof(cp)) == sizeof(cp));
755                 yaffs2_do_endian_checkpt_obj (dev, &cp);
756
757                 if (cp.struct_type != sizeof(cp)) {
758                         yaffs_trace(YAFFS_TRACE_CHECKPOINT,
759                                 "struct size %d instead of %d ok %d",
760                                 cp.struct_type, (int)sizeof(cp), ok);
761                         ok = 0;
762                 }
763
764                 cp_variant_type = yaffs2_checkpt_obj_bit_get(
765                                                 &cp, CHECKPOINT_VARIANT_BITS);
766                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
767                         "Checkpoint read object %d parent %d type %d chunk %d ",
768                         cp.obj_id, cp.parent_id, cp_variant_type,
769                         cp.hdr_chunk);
770
771                 if (ok && cp.obj_id == ~0) {
772                         done = 1;
773                 } else if (ok) {
774                         obj =
775                             yaffs_find_or_create_by_number(dev, cp.obj_id,
776                                                            cp_variant_type);
777                         if (obj) {
778                                 ok = yaffs2_checkpt_obj_to_obj(obj, &cp);
779                                 if (!ok)
780                                         break;
781                                 if (obj->variant_type ==
782                                         YAFFS_OBJECT_TYPE_FILE) {
783                                         ok = yaffs2_rd_checkpt_tnodes(obj);
784                                 } else if (obj->variant_type ==
785                                         YAFFS_OBJECT_TYPE_HARDLINK) {
786                                         list_add(&obj->hard_links, &hard_list);
787                                 }
788                         } else {
789                                 ok = 0;
790                         }
791                 }
792         }
793
794         if (ok)
795                 yaffs_link_fixup(dev, &hard_list);
796
797         return ok ? 1 : 0;
798 }
799
800 static int yaffs2_wr_checkpt_sum(struct yaffs_dev *dev)
801 {
802         u32 checkpt_sum;
803         int ok;
804
805         yaffs2_get_checkpt_sum(dev, &checkpt_sum);
806
807         yaffs_do_endian_u32(dev, &checkpt_sum);
808
809         ok = (yaffs2_checkpt_wr(dev, &checkpt_sum, sizeof(checkpt_sum)) ==
810                 sizeof(checkpt_sum));
811
812         if (!ok)
813                 return 0;
814
815         return 1;
816 }
817
818 static int yaffs2_rd_checkpt_sum(struct yaffs_dev *dev)
819 {
820         u32 checkpt_sum0;
821         u32 checkpt_sum1;
822         int ok;
823
824         yaffs2_get_checkpt_sum(dev, &checkpt_sum0);
825
826         ok = (yaffs2_checkpt_rd(dev, &checkpt_sum1, sizeof(checkpt_sum1)) ==
827                 sizeof(checkpt_sum1));
828
829         if (!ok)
830                 return 0;
831         yaffs_do_endian_u32(dev, &checkpt_sum1);
832
833         if (checkpt_sum0 != checkpt_sum1)
834                 return 0;
835
836         return 1;
837 }
838
839 static int yaffs2_wr_checkpt_data(struct yaffs_dev *dev)
840 {
841         int ok = 1;
842
843         if (!yaffs2_checkpt_required(dev)) {
844                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
845                         "skipping checkpoint write");
846                 ok = 0;
847         }
848
849         if (ok)
850                 ok = yaffs2_checkpt_open(dev, 1);
851
852         if (ok) {
853                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
854                         "write checkpoint validity");
855                 ok = yaffs2_wr_checkpt_validity_marker(dev, 1);
856         }
857         if (ok) {
858                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
859                         "write checkpoint device");
860                 ok = yaffs2_wr_checkpt_dev(dev);
861         }
862         if (ok) {
863                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
864                         "write checkpoint objects");
865                 ok = yaffs2_wr_checkpt_objs(dev);
866         }
867         if (ok) {
868                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
869                         "write checkpoint validity");
870                 ok = yaffs2_wr_checkpt_validity_marker(dev, 0);
871         }
872
873         if (ok)
874                 ok = yaffs2_wr_checkpt_sum(dev);
875
876         if (!yaffs_checkpt_close(dev))
877                 ok = 0;
878
879         if (ok)
880                 dev->is_checkpointed = 1;
881         else
882                 dev->is_checkpointed = 0;
883
884         return dev->is_checkpointed;
885 }
886
887 static int yaffs2_rd_checkpt_data(struct yaffs_dev *dev)
888 {
889         int ok = 1;
890
891         if (!dev->param.is_yaffs2)
892                 ok = 0;
893
894         if (ok && dev->param.skip_checkpt_rd) {
895                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
896                         "skipping checkpoint read");
897                 ok = 0;
898         }
899
900         if (ok)
901                 ok = yaffs2_checkpt_open(dev, 0); /* open for read */
902
903         if (ok) {
904                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
905                         "read checkpoint validity");
906                 ok = yaffs2_rd_checkpt_validity_marker(dev, 1);
907         }
908         if (ok) {
909                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
910                         "read checkpoint device");
911                 ok = yaffs2_rd_checkpt_dev(dev);
912         }
913         if (ok) {
914                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
915                         "read checkpoint objects");
916                 ok = yaffs2_rd_checkpt_objs(dev);
917         }
918         if (ok) {
919                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
920                         "read checkpoint validity");
921                 ok = yaffs2_rd_checkpt_validity_marker(dev, 0);
922         }
923
924         if (ok) {
925                 ok = yaffs2_rd_checkpt_sum(dev);
926                 yaffs_trace(YAFFS_TRACE_CHECKPOINT,
927                         "read checkpoint checksum %d", ok);
928         }
929
930         if (!yaffs_checkpt_close(dev))
931                 ok = 0;
932
933         if (ok)
934                 dev->is_checkpointed = 1;
935         else
936                 dev->is_checkpointed = 0;
937
938         return ok ? 1 : 0;
939 }
940
941 void yaffs2_checkpt_invalidate(struct yaffs_dev *dev)
942 {
943         if (dev->is_checkpointed || dev->blocks_in_checkpt > 0) {
944                 dev->is_checkpointed = 0;
945                 yaffs2_checkpt_invalidate_stream(dev);
946         }
947         if (dev->param.sb_dirty_fn)
948                 dev->param.sb_dirty_fn(dev);
949 }
950
951 int yaffs_checkpoint_save(struct yaffs_dev *dev)
952 {
953         yaffs_trace(YAFFS_TRACE_CHECKPOINT,
954                 "save entry: is_checkpointed %d",
955                 dev->is_checkpointed);
956
957         yaffs_verify_objects(dev);
958         yaffs_verify_blocks(dev);
959         yaffs_verify_free_chunks(dev);
960
961         if (!dev->is_checkpointed) {
962                 yaffs2_checkpt_invalidate(dev);
963                 yaffs2_wr_checkpt_data(dev);
964         }
965
966         yaffs_trace(YAFFS_TRACE_CHECKPOINT | YAFFS_TRACE_MOUNT,
967                 "save exit: is_checkpointed %d",
968                 dev->is_checkpointed);
969
970         return dev->is_checkpointed;
971 }
972
973 int yaffs2_checkpt_restore(struct yaffs_dev *dev)
974 {
975         int retval;
976
977         yaffs_trace(YAFFS_TRACE_CHECKPOINT,
978                 "restore entry: is_checkpointed %d",
979                 dev->is_checkpointed);
980
981         retval = yaffs2_rd_checkpt_data(dev);
982
983         if (dev->is_checkpointed) {
984                 yaffs_verify_objects(dev);
985                 yaffs_verify_blocks(dev);
986                 yaffs_verify_free_chunks(dev);
987         }
988
989         yaffs_trace(YAFFS_TRACE_CHECKPOINT,
990                 "restore exit: is_checkpointed %d",
991                 dev->is_checkpointed);
992
993         return retval;
994 }
995
996 /* End of checkpointing */
997
998 /* Hole handling logic for truncate past end of file */
999
1000 int yaffs2_handle_hole(struct yaffs_obj *obj, loff_t new_size)
1001 {
1002         /* if new_size > old_file_size.
1003          * We're going to be writing a hole.
1004          * If the hole is small then write zeros otherwise write a start
1005          * of hole marker.
1006          */
1007         loff_t old_file_size;
1008         loff_t increase;
1009         int small_hole;
1010         int result = YAFFS_OK;
1011         struct yaffs_dev *dev = NULL;
1012         u8 *local_buffer = NULL;
1013         int small_increase_ok = 0;
1014
1015         if (!obj)
1016                 return YAFFS_FAIL;
1017
1018         if (obj->variant_type != YAFFS_OBJECT_TYPE_FILE)
1019                 return YAFFS_FAIL;
1020
1021         dev = obj->my_dev;
1022
1023         /* Bail out if not yaffs2 mode */
1024         if (!dev->param.is_yaffs2)
1025                 return YAFFS_OK;
1026
1027         old_file_size = obj->variant.file_variant.file_size;
1028
1029         if (new_size <= old_file_size)
1030                 return YAFFS_OK;
1031
1032         increase = new_size - old_file_size;
1033
1034         if (increase < YAFFS_SMALL_HOLE_THRESHOLD * dev->data_bytes_per_chunk &&
1035             yaffs_check_alloc_available(dev, YAFFS_SMALL_HOLE_THRESHOLD + 1))
1036                 small_hole = 1;
1037         else
1038                 small_hole = 0;
1039
1040         if (small_hole)
1041                 local_buffer = yaffs_get_temp_buffer(dev);
1042
1043         if (local_buffer) {
1044                 /* fill hole with zero bytes */
1045                 loff_t pos = old_file_size;
1046                 int this_write;
1047                 int written;
1048                 memset(local_buffer, 0, dev->data_bytes_per_chunk);
1049                 small_increase_ok = 1;
1050
1051                 while (increase > 0 && small_increase_ok) {
1052                         this_write = increase;
1053                         if (this_write > dev->data_bytes_per_chunk)
1054                                 this_write = dev->data_bytes_per_chunk;
1055                         written =
1056                             yaffs_do_file_wr(obj, local_buffer, pos, this_write,
1057                                              0);
1058                         if (written == this_write) {
1059                                 pos += this_write;
1060                                 increase -= this_write;
1061                         } else {
1062                                 small_increase_ok = 0;
1063                         }
1064                 }
1065
1066                 yaffs_release_temp_buffer(dev, local_buffer);
1067
1068                 /* If out of space then reverse any chunks we've added */
1069                 if (!small_increase_ok)
1070                         yaffs_resize_file_down(obj, old_file_size);
1071         }
1072
1073         if (!small_increase_ok &&
1074             obj->parent &&
1075             obj->parent->obj_id != YAFFS_OBJECTID_UNLINKED &&
1076             obj->parent->obj_id != YAFFS_OBJECTID_DELETED) {
1077                 /* Write a hole start header with the old file size */
1078                 yaffs_update_oh(obj, NULL, 0, 1, 0, NULL);
1079         }
1080
1081         return result;
1082 }
1083
1084 /* Yaffs2 scanning */
1085
1086 struct yaffs_block_index {
1087         int seq;
1088         int block;
1089 };
1090
1091 static int yaffs2_ybicmp(const void *a, const void *b)
1092 {
1093         int aseq = ((struct yaffs_block_index *)a)->seq;
1094         int bseq = ((struct yaffs_block_index *)b)->seq;
1095         int ablock = ((struct yaffs_block_index *)a)->block;
1096         int bblock = ((struct yaffs_block_index *)b)->block;
1097
1098         if (aseq == bseq)
1099                 return ablock - bblock;
1100
1101         return aseq - bseq;
1102 }
1103
1104 static inline int yaffs2_scan_chunk(struct yaffs_dev *dev,
1105                 struct yaffs_block_info *bi,
1106                 int blk, int chunk_in_block,
1107                 int *found_chunks,
1108                 u8 *chunk_data,
1109                 struct list_head *hard_list,
1110                 int summary_available)
1111 {
1112         struct yaffs_obj_hdr *oh;
1113         struct yaffs_obj *in;
1114         struct yaffs_obj *parent;
1115         int equiv_id;
1116         loff_t file_size;
1117         int is_shrink;
1118         int is_unlinked;
1119         struct yaffs_ext_tags tags;
1120         int result;
1121         int alloc_failed = 0;
1122         int chunk = blk * dev->param.chunks_per_block + chunk_in_block;
1123         struct yaffs_file_var *file_var;
1124         struct yaffs_hardlink_var *hl_var;
1125         struct yaffs_symlink_var *sl_var;
1126
1127         if (summary_available) {
1128                 result = yaffs_summary_fetch(dev, &tags, chunk_in_block);
1129                 tags.seq_number = bi->seq_number;
1130         }
1131
1132         if (!summary_available || tags.obj_id == 0) {
1133                 result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL, &tags);
1134                 dev->tags_used++;
1135         } else {
1136                 dev->summary_used++;
1137         }
1138
1139         /* Let's have a good look at this chunk... */
1140
1141         if (!tags.chunk_used) {
1142                 /* An unassigned chunk in the block.
1143                  * If there are used chunks after this one, then
1144                  * it is a chunk that was skipped due to failing
1145                  * the erased check. Just skip it so that it can
1146                  * be deleted.
1147                  * But, more typically, We get here when this is
1148                  * an unallocated chunk and his means that
1149                  * either the block is empty or this is the one
1150                  * being allocated from
1151                  */
1152
1153                 if (*found_chunks) {
1154                         /* This is a chunk that was skipped due
1155                          * to failing the erased check */
1156                 } else if (chunk_in_block == 0) {
1157                         /* We're looking at the first chunk in
1158                          * the block so the block is unused */
1159                         bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
1160                         dev->n_erased_blocks++;
1161                 } else {
1162                         if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN ||
1163                             bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) {
1164                                 if (dev->seq_number == bi->seq_number) {
1165                                         /* Allocating from this block*/
1166                                         yaffs_trace(YAFFS_TRACE_SCAN,
1167                                             " Allocating from %d %d",
1168                                             blk, chunk_in_block);
1169
1170                                         bi->block_state =
1171                                                 YAFFS_BLOCK_STATE_ALLOCATING;
1172                                         dev->alloc_block = blk;
1173                                         dev->alloc_page = chunk_in_block;
1174                                         dev->alloc_block_finder = blk;
1175                                 } else {
1176                                         /* This is a partially written block
1177                                          * that is not the current
1178                                          * allocation block.
1179                                          */
1180                                         yaffs_trace(YAFFS_TRACE_SCAN,
1181                                                 "Partially written block %d detected. gc will fix this.",
1182                                                 blk);
1183                                 }
1184                         }
1185                 }
1186
1187                 dev->n_free_chunks++;
1188
1189         } else if (tags.ecc_result ==
1190                 YAFFS_ECC_RESULT_UNFIXED) {
1191                 yaffs_trace(YAFFS_TRACE_SCAN,
1192                         " Unfixed ECC in chunk(%d:%d), chunk ignored",
1193                         blk, chunk_in_block);
1194                         dev->n_free_chunks++;
1195         } else if (tags.obj_id > YAFFS_MAX_OBJECT_ID ||
1196                    tags.chunk_id > YAFFS_MAX_CHUNK_ID ||
1197                    tags.obj_id == YAFFS_OBJECTID_SUMMARY ||
1198                    (tags.chunk_id > 0 &&
1199                      tags.n_bytes > dev->data_bytes_per_chunk) ||
1200                    tags.seq_number != bi->seq_number) {
1201                 yaffs_trace(YAFFS_TRACE_SCAN,
1202                         "Chunk (%d:%d) with bad tags:obj = %d, chunk_id = %d, n_bytes = %d, ignored",
1203                         blk, chunk_in_block, tags.obj_id,
1204                         tags.chunk_id, tags.n_bytes);
1205                 dev->n_free_chunks++;
1206         } else if (tags.chunk_id > 0) {
1207                 /* chunk_id > 0 so it is a data chunk... */
1208                 loff_t endpos;
1209                 loff_t chunk_base = (tags.chunk_id - 1) *
1210                                         dev->data_bytes_per_chunk;
1211
1212                 *found_chunks = 1;
1213
1214                 yaffs_set_chunk_bit(dev, blk, chunk_in_block);
1215                 bi->pages_in_use++;
1216
1217                 in = yaffs_find_or_create_by_number(dev,
1218                                         tags.obj_id,
1219                                         YAFFS_OBJECT_TYPE_FILE);
1220                 if (!in)
1221                         /* Out of memory */
1222                         alloc_failed = 1;
1223
1224                 if (in &&
1225                     in->variant_type == YAFFS_OBJECT_TYPE_FILE &&
1226                     chunk_base < in->variant.file_variant.shrink_size) {
1227                         /* This has not been invalidated by
1228                          * a resize */
1229                         if (!yaffs_put_chunk_in_file(in, tags.chunk_id,
1230                                                                 chunk, -1))
1231                                 alloc_failed = 1;
1232
1233                         /* File size is calculated by looking at
1234                          * the data chunks if we have not
1235                          * seen an object header yet.
1236                          * Stop this practice once we find an
1237                          * object header.
1238                          */
1239                         endpos = chunk_base + tags.n_bytes;
1240
1241                         if (!in->valid &&
1242                             in->variant.file_variant.stored_size < endpos) {
1243                                 in->variant.file_variant.
1244                                     stored_size = endpos;
1245                                 in->variant.file_variant.
1246                                     file_size = endpos;
1247                         }
1248                 } else if (in) {
1249                         /* This chunk has been invalidated by a
1250                          * resize, or a past file deletion
1251                          * so delete the chunk*/
1252                         yaffs_chunk_del(dev, chunk, 1, __LINE__);
1253                 }
1254         } else {
1255                 /* chunk_id == 0, so it is an ObjectHeader.
1256                  * Thus, we read in the object header and make
1257                  * the object
1258                  */
1259                 *found_chunks = 1;
1260
1261                 yaffs_set_chunk_bit(dev, blk, chunk_in_block);
1262                 bi->pages_in_use++;
1263
1264                 oh = NULL;
1265                 in = NULL;
1266
1267                 if (tags.extra_available) {
1268                         in = yaffs_find_or_create_by_number(dev,
1269                                         tags.obj_id,
1270                                         tags.extra_obj_type);
1271                         if (!in)
1272                                 alloc_failed = 1;
1273                 }
1274
1275                 if (!in ||
1276                     (!in->valid && dev->param.disable_lazy_load) ||
1277                     tags.extra_shadows ||
1278                     (!in->valid && (tags.obj_id == YAFFS_OBJECTID_ROOT ||
1279                                  tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND))) {
1280
1281                         /* If we don't have  valid info then we
1282                          * need to read the chunk
1283                          * TODO In future we can probably defer
1284                          * reading the chunk and living with
1285                          * invalid data until needed.
1286                          */
1287
1288                         result = yaffs_rd_chunk_tags_nand(dev,
1289                                                   chunk,
1290                                                   chunk_data,
1291                                                   NULL);
1292
1293                         oh = (struct yaffs_obj_hdr *)chunk_data;
1294
1295                         yaffs_do_endian_oh(dev, oh);
1296
1297                         if (dev->param.inband_tags) {
1298                                 /* Fix up the header if they got
1299                                  * corrupted by inband tags */
1300                                 oh->shadows_obj =
1301                                     oh->inband_shadowed_obj_id;
1302                                 oh->is_shrink =
1303                                     oh->inband_is_shrink;
1304                         }
1305
1306                         if (!in) {
1307                                 in = yaffs_find_or_create_by_number(dev,
1308                                                         tags.obj_id, oh->type);
1309                                 if (!in)
1310                                         alloc_failed = 1;
1311                         }
1312                 }
1313
1314                 if (!in) {
1315                         /* TODO Hoosterman we have a problem! */
1316                         yaffs_trace(YAFFS_TRACE_ERROR,
1317                                 "yaffs tragedy: Could not make object for object  %d at chunk %d during scan",
1318                                 tags.obj_id, chunk);
1319                         return YAFFS_FAIL;
1320                 }
1321
1322                 if (in->valid) {
1323                         /* We have already filled this one.
1324                          * We have a duplicate that will be
1325                          * discarded, but we first have to suck
1326                          * out resize info if it is a file.
1327                          */
1328                         if ((in->variant_type == YAFFS_OBJECT_TYPE_FILE) &&
1329                                 ((oh && oh->type == YAFFS_OBJECT_TYPE_FILE) ||
1330                                  (tags.extra_available &&
1331                                   tags.extra_obj_type == YAFFS_OBJECT_TYPE_FILE)
1332                                 )) {
1333                                 loff_t this_size = (oh) ?
1334                                         yaffs_oh_to_size(dev, oh, 0) :
1335                                         tags.extra_file_size;
1336                                 u32 parent_obj_id = (oh) ?
1337                                         oh->parent_obj_id :
1338                                         tags.extra_parent_id;
1339
1340                                 is_shrink = (oh) ?
1341                                         oh->is_shrink :
1342                                         tags.extra_is_shrink;
1343
1344                                 /* If it is deleted (unlinked
1345                                  * at start also means deleted)
1346                                  * we treat the file size as
1347                                  * being zeroed at this point.
1348                                  */
1349                                 if (parent_obj_id == YAFFS_OBJECTID_DELETED ||
1350                                     parent_obj_id == YAFFS_OBJECTID_UNLINKED) {
1351                                         this_size = 0;
1352                                         is_shrink = 1;
1353                                 }
1354
1355                                 if (is_shrink &&
1356                                     in->variant.file_variant.shrink_size >
1357                                     this_size)
1358                                         in->variant.file_variant.shrink_size =
1359                                         this_size;
1360
1361                                 if (is_shrink)
1362                                         bi->has_shrink_hdr = 1;
1363                         }
1364                         /* Use existing - destroy this one. */
1365                         yaffs_chunk_del(dev, chunk, 1, __LINE__);
1366                 }
1367
1368                 if (!in->valid && in->variant_type !=
1369                     (oh ? oh->type : tags.extra_obj_type)) {
1370                         yaffs_trace(YAFFS_TRACE_ERROR,
1371                                 "yaffs tragedy: Bad type, %d != %d, for object %d at chunk %d during scan",
1372                                 oh ? oh->type : tags.extra_obj_type,
1373                                 in->variant_type, tags.obj_id,
1374                                 chunk);
1375                         in = yaffs_retype_obj(in, oh ? oh->type : tags.extra_obj_type);
1376                 }
1377
1378                 if (!in->valid &&
1379                     (tags.obj_id == YAFFS_OBJECTID_ROOT ||
1380                      tags.obj_id == YAFFS_OBJECTID_LOSTNFOUND)) {
1381                         /* We only load some info, don't fiddle
1382                          * with directory structure */
1383                         in->valid = 1;
1384
1385                         if (oh) {
1386                                 in->yst_mode = oh->yst_mode;
1387                                 yaffs_load_attribs(in, oh);
1388                                 in->lazy_loaded = 0;
1389                         } else {
1390                                 in->lazy_loaded = 1;
1391                         }
1392                         in->hdr_chunk = chunk;
1393
1394                 } else if (!in->valid) {
1395                         /* we need to load this info */
1396                         in->valid = 1;
1397                         in->hdr_chunk = chunk;
1398                         if (oh) {
1399                                 in->variant_type = oh->type;
1400                                 in->yst_mode = oh->yst_mode;
1401                                 yaffs_load_attribs(in, oh);
1402
1403                                 if (oh->shadows_obj > 0)
1404                                         yaffs_handle_shadowed_obj(dev,
1405                                              oh->shadows_obj, 1);
1406
1407                                 yaffs_set_obj_name_from_oh(in, oh);
1408                                 parent = yaffs_find_or_create_by_number(dev,
1409                                                 oh->parent_obj_id,
1410                                                 YAFFS_OBJECT_TYPE_DIRECTORY);
1411                                 file_size = yaffs_oh_to_size(dev, oh, 0);
1412                                 is_shrink = oh->is_shrink;
1413                                 equiv_id = oh->equiv_id;
1414                         } else {
1415                                 in->variant_type = tags.extra_obj_type;
1416                                 parent = yaffs_find_or_create_by_number(dev,
1417                                                 tags.extra_parent_id,
1418                                                 YAFFS_OBJECT_TYPE_DIRECTORY);
1419                                 file_size = tags.extra_file_size;
1420                                 is_shrink = tags.extra_is_shrink;
1421                                 equiv_id = tags.extra_equiv_id;
1422                                 in->lazy_loaded = 1;
1423                         }
1424                         in->dirty = 0;
1425
1426                         if (!parent)
1427                                 alloc_failed = 1;
1428
1429                         /* directory stuff...
1430                          * hook up to parent
1431                          */
1432
1433                         if (parent &&
1434                             parent->variant_type == YAFFS_OBJECT_TYPE_UNKNOWN) {
1435                                 /* Set up as a directory */
1436                                 parent->variant_type =
1437                                         YAFFS_OBJECT_TYPE_DIRECTORY;
1438                                 INIT_LIST_HEAD(&parent->
1439                                                 variant.dir_variant.children);
1440                         } else if (!parent ||
1441                                    parent->variant_type !=
1442                                         YAFFS_OBJECT_TYPE_DIRECTORY) {
1443                                 /* Hoosterman, another problem....
1444                                  * Trying to use a non-directory as a directory
1445                                  */
1446
1447                                 yaffs_trace(YAFFS_TRACE_ERROR,
1448                                         "yaffs tragedy: attempting to use non-directory as a directory in scan. Put in lost+found."
1449                                         );
1450                                 parent = dev->lost_n_found;
1451                         }
1452                         yaffs_add_obj_to_dir(parent, in);
1453
1454                         is_unlinked = (parent == dev->del_dir) ||
1455                                         (parent == dev->unlinked_dir);
1456
1457                         if (is_shrink)
1458                                 /* Mark the block */
1459                                 bi->has_shrink_hdr = 1;
1460
1461                         /* Note re hardlinks.
1462                          * Since we might scan a hardlink before its equivalent
1463                          * object is scanned we put them all in a list.
1464                          * After scanning is complete, we should have all the
1465                          * objects, so we run through this list and fix up all
1466                          * the chains.
1467                          */
1468
1469                         switch (in->variant_type) {
1470                         case YAFFS_OBJECT_TYPE_UNKNOWN:
1471                                 /* Todo got a problem */
1472                                 break;
1473                         case YAFFS_OBJECT_TYPE_FILE:
1474                                 file_var = &in->variant.file_variant;
1475                                 if (file_var->stored_size < file_size) {
1476                                         /* This covers the case where the file
1477                                          * size is greater than the data held.
1478                                          * This will happen if the file is
1479                                          * resized to be larger than its
1480                                          * current data extents.
1481                                          */
1482                                         file_var->file_size = file_size;
1483                                         file_var->stored_size = file_size;
1484                                 }
1485
1486                                 if (file_var->shrink_size > file_size)
1487                                         file_var->shrink_size = file_size;
1488
1489                                 break;
1490                         case YAFFS_OBJECT_TYPE_HARDLINK:
1491                                 hl_var = &in->variant.hardlink_variant;
1492                                 if (!is_unlinked) {
1493                                         hl_var->equiv_id = equiv_id;
1494                                         list_add(&in->hard_links, hard_list);
1495                                 }
1496                                 break;
1497                         case YAFFS_OBJECT_TYPE_DIRECTORY:
1498                                 /* Do nothing */
1499                                 break;
1500                         case YAFFS_OBJECT_TYPE_SPECIAL:
1501                                 /* Do nothing */
1502                                 break;
1503                         case YAFFS_OBJECT_TYPE_SYMLINK:
1504                                 sl_var = &in->variant.symlink_variant;
1505                                 if (oh) {
1506                                         sl_var->alias =
1507                                             yaffs_clone_str(oh->alias);
1508                                         if (!sl_var->alias)
1509                                                 alloc_failed = 1;
1510                                 }
1511                                 break;
1512                         }
1513                 }
1514         }
1515         return alloc_failed ? YAFFS_FAIL : YAFFS_OK;
1516 }
1517
1518 int yaffs2_scan_backwards(struct yaffs_dev *dev)
1519 {
1520         int blk;
1521         int block_iter;
1522         int start_iter;
1523         int end_iter;
1524         int n_to_scan = 0;
1525         enum yaffs_block_state state;
1526         int c;
1527         LIST_HEAD(hard_list);
1528         struct yaffs_block_info *bi;
1529         u32 seq_number;
1530         int n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
1531         u8 *chunk_data;
1532         int found_chunks;
1533         int alloc_failed = 0;
1534         struct yaffs_block_index *block_index = NULL;
1535         int alt_block_index = 0;
1536         int summary_available;
1537
1538         yaffs_trace(YAFFS_TRACE_SCAN,
1539                 "yaffs2_scan_backwards starts  intstartblk %d intendblk %d...",
1540                 dev->internal_start_block, dev->internal_end_block);
1541
1542         dev->seq_number = YAFFS_LOWEST_SEQUENCE_NUMBER;
1543
1544         block_index =
1545                 kmalloc(n_blocks * sizeof(struct yaffs_block_index), GFP_NOFS);
1546
1547         if (!block_index) {
1548                 block_index =
1549                     vmalloc(n_blocks * sizeof(struct yaffs_block_index));
1550                 alt_block_index = 1;
1551         }
1552
1553         if (!block_index) {
1554                 yaffs_trace(YAFFS_TRACE_SCAN,
1555                         "yaffs2_scan_backwards() could not allocate block index!"
1556                         );
1557                 return YAFFS_FAIL;
1558         }
1559
1560         dev->blocks_in_checkpt = 0;
1561
1562         chunk_data = yaffs_get_temp_buffer(dev);
1563
1564         /* Scan all the blocks to determine their state */
1565         bi = dev->block_info;
1566         for (blk = dev->internal_start_block; blk <= dev->internal_end_block;
1567              blk++) {
1568                 yaffs_clear_chunk_bits(dev, blk);
1569                 bi->pages_in_use = 0;
1570                 bi->soft_del_pages = 0;
1571
1572                 yaffs_query_init_block_state(dev, blk, &state, &seq_number);
1573
1574                 bi->block_state = state;
1575                 bi->seq_number = seq_number;
1576
1577                 if (bi->seq_number == YAFFS_SEQUENCE_CHECKPOINT_DATA)
1578                         bi->block_state = YAFFS_BLOCK_STATE_CHECKPOINT;
1579                 if (bi->seq_number == YAFFS_SEQUENCE_BAD_BLOCK)
1580                         bi->block_state = YAFFS_BLOCK_STATE_DEAD;
1581
1582                 yaffs_trace(YAFFS_TRACE_SCAN_DEBUG,
1583                         "Block scanning block %d state %d seq %d",
1584                         blk, bi->block_state, seq_number);
1585
1586                 if (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT) {
1587                         dev->blocks_in_checkpt++;
1588
1589                 } else if (bi->block_state == YAFFS_BLOCK_STATE_DEAD) {
1590                         yaffs_trace(YAFFS_TRACE_BAD_BLOCKS,
1591                                 "block %d is bad", blk);
1592                 } else if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) {
1593                         yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "Block empty ");
1594                         dev->n_erased_blocks++;
1595                         dev->n_free_chunks += dev->param.chunks_per_block;
1596                 } else if (bi->block_state ==
1597                                 YAFFS_BLOCK_STATE_NEEDS_SCAN) {
1598                         /* Determine the highest sequence number */
1599                         if (seq_number >= YAFFS_LOWEST_SEQUENCE_NUMBER &&
1600                             seq_number < YAFFS_HIGHEST_SEQUENCE_NUMBER) {
1601                                 block_index[n_to_scan].seq = seq_number;
1602                                 block_index[n_to_scan].block = blk;
1603                                 n_to_scan++;
1604                                 if (seq_number >= dev->seq_number)
1605                                         dev->seq_number = seq_number;
1606                         } else {
1607                                 /* TODO: Nasty sequence number! */
1608                                 yaffs_trace(YAFFS_TRACE_SCAN,
1609                                         "Block scanning block %d has bad sequence number %d",
1610                                         blk, seq_number);
1611                         }
1612                 }
1613                 bi++;
1614         }
1615
1616         yaffs_trace(YAFFS_TRACE_ALWAYS, "%d blocks to be sorted...", n_to_scan);
1617
1618         cond_resched();
1619
1620         /* Sort the blocks by sequence number */
1621         sort(block_index, n_to_scan, sizeof(struct yaffs_block_index),
1622                    yaffs2_ybicmp, NULL);
1623
1624         cond_resched();
1625
1626         yaffs_trace(YAFFS_TRACE_SCAN, "...done");
1627
1628         /* Now scan the blocks looking at the data. */
1629         start_iter = 0;
1630         end_iter = n_to_scan - 1;
1631         yaffs_trace(YAFFS_TRACE_SCAN_DEBUG, "%d blocks to scan", n_to_scan);
1632
1633         /* For each block.... backwards */
1634         for (block_iter = end_iter;
1635              !alloc_failed && block_iter >= start_iter;
1636              block_iter--) {
1637                 /* Cooperative multitasking! This loop can run for so
1638                    long that watchdog timers expire. */
1639                 cond_resched();
1640
1641                 /* get the block to scan in the correct order */
1642                 blk = block_index[block_iter].block;
1643                 bi = yaffs_get_block_info(dev, blk);
1644
1645                 summary_available = yaffs_summary_read(dev, dev->sum_tags, blk);
1646
1647                 /* For each chunk in each block that needs scanning.... */
1648                 found_chunks = 0;
1649                 if (summary_available)
1650                         c = dev->chunks_per_summary - 1;
1651                 else
1652                         c = dev->param.chunks_per_block - 1;
1653
1654                 for (/* c is already initialised */;
1655                      !alloc_failed && c >= 0 &&
1656                      (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN ||
1657                       bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING);
1658                       c--) {
1659                         /* Scan backwards...
1660                          * Read the tags and decide what to do
1661                          */
1662                         if (yaffs2_scan_chunk(dev, bi, blk, c,
1663                                         &found_chunks, chunk_data,
1664                                         &hard_list, summary_available) ==
1665                                         YAFFS_FAIL)
1666                                 alloc_failed = 1;
1667                 }
1668
1669                 if (bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN) {
1670                         /* If we got this far while scanning, then the block
1671                          * is fully allocated. */
1672                         bi->block_state = YAFFS_BLOCK_STATE_FULL;
1673                 }
1674
1675                 /* Now let's see if it was dirty */
1676                 if (bi->pages_in_use == 0 &&
1677                     !bi->has_shrink_hdr &&
1678                     bi->block_state == YAFFS_BLOCK_STATE_FULL) {
1679                         yaffs_block_became_dirty(dev, blk);
1680                 }
1681         }
1682
1683         yaffs_skip_rest_of_block(dev);
1684
1685         if (alt_block_index)
1686                 vfree(block_index);
1687         else
1688                 kfree(block_index);
1689
1690         /* Ok, we've done all the scanning.
1691          * Fix up the hard link chains.
1692          * We have scanned all the objects, now it's time to add these
1693          * hardlinks.
1694          */
1695         yaffs_link_fixup(dev, &hard_list);
1696
1697         yaffs_release_temp_buffer(dev, chunk_data);
1698
1699         if (alloc_failed)
1700                 return YAFFS_FAIL;
1701
1702         yaffs_trace(YAFFS_TRACE_SCAN, "yaffs2_scan_backwards ends");
1703
1704         return YAFFS_OK;
1705 }