c31ca30235758657a2ef746c7766aacb68aaf7ca
[yaffs2.git] / yaffs_guts.c
1 /*
2  * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
3  *
4  * Copyright (C) 2002-2010 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 "yportenv.h"
15 #include "yaffs_trace.h"
16
17 #include "yaffs_guts.h"
18 #include "yaffs_tagsvalidity.h"
19 #include "yaffs_getblockinfo.h"
20 #include "yaffs_tagscompat.h"
21 #include "yaffs_nand.h"
22 #include "yaffs_yaffs1.h"
23 #include "yaffs_yaffs2.h"
24 #include "yaffs_bitmap.h"
25 #include "yaffs_verify.h"
26 #include "yaffs_nand.h"
27 #include "yaffs_packedtags2.h"
28 #include "yaffs_nameval.h"
29 #include "yaffs_allocator.h"
30 #include "yaffs_attribs.h"
31
32 /* Note YAFFS_GC_GOOD_ENOUGH must be <= YAFFS_GC_PASSIVE_THRESHOLD */
33 #define YAFFS_GC_GOOD_ENOUGH 2
34 #define YAFFS_GC_PASSIVE_THRESHOLD 4
35
36 #include "yaffs_ecc.h"
37
38 /* Forward declarations */
39
40 static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
41                              const u8 *buffer, int n_bytes, int use_reserve);
42
43
44
45 /* Function to calculate chunk and offset */
46
47 static void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
48                                 int *chunk_out, u32 *offset_out)
49 {
50         int chunk;
51         u32 offset;
52
53         chunk = (u32) (addr >> dev->chunk_shift);
54
55         if (dev->chunk_div == 1) {
56                 /* easy power of 2 case */
57                 offset = (u32) (addr & dev->chunk_mask);
58         } else {
59                 /* Non power-of-2 case */
60
61                 loff_t chunk_base;
62
63                 chunk /= dev->chunk_div;
64
65                 chunk_base = ((loff_t) chunk) * dev->data_bytes_per_chunk;
66                 offset = (u32) (addr - chunk_base);
67         }
68
69         *chunk_out = chunk;
70         *offset_out = offset;
71 }
72
73 /* Function to return the number of shifts for a power of 2 greater than or
74  * equal to the given number
75  * Note we don't try to cater for all possible numbers and this does not have to
76  * be hellishly efficient.
77  */
78
79 static u32 calc_shifts_ceiling(u32 x)
80 {
81         int extra_bits;
82         int shifts;
83
84         shifts = extra_bits = 0;
85
86         while (x > 1) {
87                 if (x & 1)
88                         extra_bits++;
89                 x >>= 1;
90                 shifts++;
91         }
92
93         if (extra_bits)
94                 shifts++;
95
96         return shifts;
97 }
98
99 /* Function to return the number of shifts to get a 1 in bit 0
100  */
101
102 static u32 calc_shifts(u32 x)
103 {
104         u32 shifts;
105
106         shifts = 0;
107
108         if (!x)
109                 return 0;
110
111         while (!(x & 1)) {
112                 x >>= 1;
113                 shifts++;
114         }
115
116         return shifts;
117 }
118
119 /*
120  * Temporary buffer manipulations.
121  */
122
123 static int yaffs_init_tmp_buffers(struct yaffs_dev *dev)
124 {
125         int i;
126         u8 *buf = (u8 *) 1;
127
128         memset(dev->temp_buffer, 0, sizeof(dev->temp_buffer));
129
130         for (i = 0; buf && i < YAFFS_N_TEMP_BUFFERS; i++) {
131                 dev->temp_buffer[i].line = 0;   /* not in use */
132                 dev->temp_buffer[i].buffer = buf =
133                     kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS);
134         }
135
136         return buf ? YAFFS_OK : YAFFS_FAIL;
137 }
138
139 u8 *yaffs_get_temp_buffer(struct yaffs_dev * dev, int line_no)
140 {
141         int i;
142         int j;
143
144         dev->temp_in_use++;
145         if (dev->temp_in_use > dev->max_temp)
146                 dev->max_temp = dev->temp_in_use;
147
148         for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
149                 if (dev->temp_buffer[i].line == 0) {
150                         dev->temp_buffer[i].line = line_no;
151                         if ((i + 1) > dev->max_temp) {
152                                 dev->max_temp = i + 1;
153                                 for (j = 0; j <= i; j++)
154                                         dev->temp_buffer[j].max_line =
155                                             dev->temp_buffer[j].line;
156                         }
157
158                         return dev->temp_buffer[i].buffer;
159                 }
160         }
161
162         yaffs_trace(YAFFS_TRACE_BUFFERS,
163                 "Out of temp buffers at line %d, other held by lines:",
164                 line_no);
165         for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
166                 yaffs_trace(YAFFS_TRACE_BUFFERS,
167                         " %d", dev->temp_buffer[i].line);
168
169         /*
170          * If we got here then we have to allocate an unmanaged one
171          * This is not good.
172          */
173
174         dev->unmanaged_buffer_allocs++;
175         return kmalloc(dev->data_bytes_per_chunk, GFP_NOFS);
176
177 }
178
179 void yaffs_release_temp_buffer(struct yaffs_dev *dev, u8 *buffer, int line_no)
180 {
181         int i;
182
183         dev->temp_in_use--;
184
185         for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
186                 if (dev->temp_buffer[i].buffer == buffer) {
187                         dev->temp_buffer[i].line = 0;
188                         return;
189                 }
190         }
191
192         if (buffer) {
193                 /* assume it is an unmanaged one. */
194                 yaffs_trace(YAFFS_TRACE_BUFFERS,
195                   "Releasing unmanaged temp buffer in line %d",
196                    line_no);
197                 kfree(buffer);
198                 dev->unmanaged_buffer_deallocs++;
199         }
200
201 }
202
203 /*
204  * Determine if we have a managed buffer.
205  */
206 int yaffs_is_managed_tmp_buffer(struct yaffs_dev *dev, const u8 *buffer)
207 {
208         int i;
209
210         for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++) {
211                 if (dev->temp_buffer[i].buffer == buffer)
212                         return 1;
213         }
214
215         for (i = 0; i < dev->param.n_caches; i++) {
216                 if (dev->cache[i].data == buffer)
217                         return 1;
218         }
219
220         if (buffer == dev->checkpt_buffer)
221                 return 1;
222
223         yaffs_trace(YAFFS_TRACE_ALWAYS,
224           "yaffs: unmaged buffer detected.");
225         return 0;
226 }
227
228 /*
229  * Functions for robustisizing TODO
230  *
231  */
232
233 static void yaffs_handle_chunk_wr_ok(struct yaffs_dev *dev, int nand_chunk,
234                                      const u8 *data,
235                                      const struct yaffs_ext_tags *tags)
236 {
237         dev = dev;
238         nand_chunk = nand_chunk;
239         data = data;
240         tags = tags;
241 }
242
243 static void yaffs_handle_chunk_update(struct yaffs_dev *dev, int nand_chunk,
244                                       const struct yaffs_ext_tags *tags)
245 {
246         dev = dev;
247         nand_chunk = nand_chunk;
248         tags = tags;
249 }
250
251 void yaffs_handle_chunk_error(struct yaffs_dev *dev,
252                               struct yaffs_block_info *bi)
253 {
254         if (!bi->gc_prioritise) {
255                 bi->gc_prioritise = 1;
256                 dev->has_pending_prioritised_gc = 1;
257                 bi->chunk_error_strikes++;
258
259                 if (bi->chunk_error_strikes > 3) {
260                         bi->needs_retiring = 1; /* Too many stikes, so retire */
261                         yaffs_trace(YAFFS_TRACE_ALWAYS,
262                                 "yaffs: Block struck out");
263
264                 }
265         }
266 }
267
268 static void yaffs_handle_chunk_wr_error(struct yaffs_dev *dev, int nand_chunk,
269                                         int erased_ok)
270 {
271         int flash_block = nand_chunk / dev->param.chunks_per_block;
272         struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block);
273
274         yaffs_handle_chunk_error(dev, bi);
275
276         if (erased_ok) {
277                 /* Was an actual write failure,
278                  * so mark the block for retirement.*/
279                 bi->needs_retiring = 1;
280                 yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
281                   "**>> Block %d needs retiring", flash_block);
282         }
283
284         /* Delete the chunk */
285         yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
286         yaffs_skip_rest_of_block(dev);
287 }
288
289 /*
290  * Verification code
291  */
292
293 /*
294  *  Simple hash function. Needs to have a reasonable spread
295  */
296
297 static inline int yaffs_hash_fn(int n)
298 {
299         n = abs(n);
300         return n % YAFFS_NOBJECT_BUCKETS;
301 }
302
303 /*
304  * Access functions to useful fake objects.
305  * Note that root might have a presence in NAND if permissions are set.
306  */
307
308 struct yaffs_obj *yaffs_root(struct yaffs_dev *dev)
309 {
310         return dev->root_dir;
311 }
312
313 struct yaffs_obj *yaffs_lost_n_found(struct yaffs_dev *dev)
314 {
315         return dev->lost_n_found;
316 }
317
318 /*
319  *  Erased NAND checking functions
320  */
321
322 int yaffs_check_ff(u8 *buffer, int n_bytes)
323 {
324         /* Horrible, slow implementation */
325         while (n_bytes--) {
326                 if (*buffer != 0xFF)
327                         return 0;
328                 buffer++;
329         }
330         return 1;
331 }
332
333 static int yaffs_check_chunk_erased(struct yaffs_dev *dev, int nand_chunk)
334 {
335         int retval = YAFFS_OK;
336         u8 *data = yaffs_get_temp_buffer(dev, __LINE__);
337         struct yaffs_ext_tags tags;
338         int result;
339
340         result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, data, &tags);
341
342         if (tags.ecc_result > YAFFS_ECC_RESULT_NO_ERROR)
343                 retval = YAFFS_FAIL;
344
345         if (!yaffs_check_ff(data, dev->data_bytes_per_chunk) ||
346                 tags.chunk_used) {
347                 yaffs_trace(YAFFS_TRACE_NANDACCESS,
348                         "Chunk %d not erased", nand_chunk);
349                 retval = YAFFS_FAIL;
350         }
351
352         yaffs_release_temp_buffer(dev, data, __LINE__);
353
354         return retval;
355
356 }
357
358 static int yaffs_verify_chunk_written(struct yaffs_dev *dev,
359                                       int nand_chunk,
360                                       const u8 *data,
361                                       struct yaffs_ext_tags *tags)
362 {
363         int retval = YAFFS_OK;
364         struct yaffs_ext_tags temp_tags;
365         u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
366         int result;
367
368         result = yaffs_rd_chunk_tags_nand(dev, nand_chunk, buffer, &temp_tags);
369         if (memcmp(buffer, data, dev->data_bytes_per_chunk) ||
370             temp_tags.obj_id != tags->obj_id ||
371             temp_tags.chunk_id != tags->chunk_id ||
372             temp_tags.n_bytes != tags->n_bytes)
373                 retval = YAFFS_FAIL;
374
375         yaffs_release_temp_buffer(dev, buffer, __LINE__);
376
377         return retval;
378 }
379
380
381 int yaffs_check_alloc_available(struct yaffs_dev *dev, int n_chunks)
382 {
383         int reserved_chunks;
384         int reserved_blocks = dev->param.n_reserved_blocks;
385         int checkpt_blocks;
386
387         checkpt_blocks = yaffs_calc_checkpt_blocks_required(dev);
388
389         reserved_chunks =
390             ((reserved_blocks + checkpt_blocks) * dev->param.chunks_per_block);
391
392         return (dev->n_free_chunks > (reserved_chunks + n_chunks));
393 }
394
395 static int yaffs_find_alloc_block(struct yaffs_dev *dev)
396 {
397         int i;
398         struct yaffs_block_info *bi;
399
400         if (dev->n_erased_blocks < 1) {
401                 /* Hoosterman we've got a problem.
402                  * Can't get space to gc
403                  */
404                 yaffs_trace(YAFFS_TRACE_ERROR,
405                   "yaffs tragedy: no more erased blocks");
406
407                 return -1;
408         }
409
410         /* Find an empty block. */
411
412         for (i = dev->internal_start_block; i <= dev->internal_end_block; i++) {
413                 dev->alloc_block_finder++;
414                 if (dev->alloc_block_finder < dev->internal_start_block
415                     || dev->alloc_block_finder > dev->internal_end_block) {
416                         dev->alloc_block_finder = dev->internal_start_block;
417                 }
418
419                 bi = yaffs_get_block_info(dev, dev->alloc_block_finder);
420
421                 if (bi->block_state == YAFFS_BLOCK_STATE_EMPTY) {
422                         bi->block_state = YAFFS_BLOCK_STATE_ALLOCATING;
423                         dev->seq_number++;
424                         bi->seq_number = dev->seq_number;
425                         dev->n_erased_blocks--;
426                         yaffs_trace(YAFFS_TRACE_ALLOCATE,
427                           "Allocated block %d, seq  %d, %d left" ,
428                            dev->alloc_block_finder, dev->seq_number,
429                            dev->n_erased_blocks);
430                         return dev->alloc_block_finder;
431                 }
432         }
433
434         yaffs_trace(YAFFS_TRACE_ALWAYS,
435                 "yaffs tragedy: no more erased blocks, but there should have been %d",
436                 dev->n_erased_blocks);
437
438         return -1;
439 }
440
441 static int yaffs_alloc_chunk(struct yaffs_dev *dev, int use_reserver,
442                              struct yaffs_block_info **block_ptr)
443 {
444         int ret_val;
445         struct yaffs_block_info *bi;
446
447         if (dev->alloc_block < 0) {
448                 /* Get next block to allocate off */
449                 dev->alloc_block = yaffs_find_alloc_block(dev);
450                 dev->alloc_page = 0;
451         }
452
453         if (!use_reserver && !yaffs_check_alloc_available(dev, 1)) {
454                 /* No space unless we're allowed to use the reserve. */
455                 return -1;
456         }
457
458         if (dev->n_erased_blocks < dev->param.n_reserved_blocks
459             && dev->alloc_page == 0)
460                 yaffs_trace(YAFFS_TRACE_ALLOCATE, "Allocating reserve");
461
462         /* Next page please.... */
463         if (dev->alloc_block >= 0) {
464                 bi = yaffs_get_block_info(dev, dev->alloc_block);
465
466                 ret_val = (dev->alloc_block * dev->param.chunks_per_block) +
467                     dev->alloc_page;
468                 bi->pages_in_use++;
469                 yaffs_set_chunk_bit(dev, dev->alloc_block, dev->alloc_page);
470
471                 dev->alloc_page++;
472
473                 dev->n_free_chunks--;
474
475                 /* If the block is full set the state to full */
476                 if (dev->alloc_page >= dev->param.chunks_per_block) {
477                         bi->block_state = YAFFS_BLOCK_STATE_FULL;
478                         dev->alloc_block = -1;
479                 }
480
481                 if (block_ptr)
482                         *block_ptr = bi;
483
484                 return ret_val;
485         }
486
487         yaffs_trace(YAFFS_TRACE_ERROR,
488                 "!!!!!!!!! Allocator out !!!!!!!!!!!!!!!!!");
489
490         return -1;
491 }
492
493 static int yaffs_get_erased_chunks(struct yaffs_dev *dev)
494 {
495         int n;
496
497         n = dev->n_erased_blocks * dev->param.chunks_per_block;
498
499         if (dev->alloc_block > 0)
500                 n += (dev->param.chunks_per_block - dev->alloc_page);
501
502         return n;
503
504 }
505
506 /*
507  * yaffs_skip_rest_of_block() skips over the rest of the allocation block
508  * if we don't want to write to it.
509  */
510 void yaffs_skip_rest_of_block(struct yaffs_dev *dev)
511 {
512         if (dev->alloc_block > 0) {
513                 struct yaffs_block_info *bi =
514                     yaffs_get_block_info(dev, dev->alloc_block);
515                 if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING) {
516                         bi->block_state = YAFFS_BLOCK_STATE_FULL;
517                         dev->alloc_block = -1;
518                 }
519         }
520 }
521
522 static int yaffs_write_new_chunk(struct yaffs_dev *dev,
523                                  const u8 *data,
524                                  struct yaffs_ext_tags *tags, int use_reserver)
525 {
526         int attempts = 0;
527         int write_ok = 0;
528         int chunk;
529
530         yaffs2_checkpt_invalidate(dev);
531
532         do {
533                 struct yaffs_block_info *bi = 0;
534                 int erased_ok = 0;
535
536                 chunk = yaffs_alloc_chunk(dev, use_reserver, &bi);
537                 if (chunk < 0) {
538                         /* no space */
539                         break;
540                 }
541
542                 /* First check this chunk is erased, if it needs
543                  * checking.  The checking policy (unless forced
544                  * always on) is as follows:
545                  *
546                  * Check the first page we try to write in a block.
547                  * If the check passes then we don't need to check any
548                  * more.        If the check fails, we check again...
549                  * If the block has been erased, we don't need to check.
550                  *
551                  * However, if the block has been prioritised for gc,
552                  * then we think there might be something odd about
553                  * this block and stop using it.
554                  *
555                  * Rationale: We should only ever see chunks that have
556                  * not been erased if there was a partially written
557                  * chunk due to power loss.  This checking policy should
558                  * catch that case with very few checks and thus save a
559                  * lot of checks that are most likely not needed.
560                  *
561                  * Mods to the above
562                  * If an erase check fails or the write fails we skip the
563                  * rest of the block.
564                  */
565
566                 /* let's give it a try */
567                 attempts++;
568
569                 if (dev->param.always_check_erased)
570                         bi->skip_erased_check = 0;
571
572                 if (!bi->skip_erased_check) {
573                         erased_ok = yaffs_check_chunk_erased(dev, chunk);
574                         if (erased_ok != YAFFS_OK) {
575                                 yaffs_trace(YAFFS_TRACE_ERROR,
576                                   "**>> yaffs chunk %d was not erased",
577                                   chunk);
578
579                                 /* If not erased, delete this one,
580                                  * skip rest of block and
581                                  * try another chunk */
582                                 yaffs_chunk_del(dev, chunk, 1, __LINE__);
583                                 yaffs_skip_rest_of_block(dev);
584                                 continue;
585                         }
586                 }
587
588                 write_ok = yaffs_wr_chunk_tags_nand(dev, chunk, data, tags);
589
590                 if (!bi->skip_erased_check)
591                         write_ok =
592                             yaffs_verify_chunk_written(dev, chunk, data, tags);
593
594                 if (write_ok != YAFFS_OK) {
595                         /* Clean up aborted write, skip to next block and
596                          * try another chunk */
597                         yaffs_handle_chunk_wr_error(dev, chunk, erased_ok);
598                         continue;
599                 }
600
601                 bi->skip_erased_check = 1;
602
603                 /* Copy the data into the robustification buffer */
604                 yaffs_handle_chunk_wr_ok(dev, chunk, data, tags);
605
606         } while (write_ok != YAFFS_OK &&
607                  (yaffs_wr_attempts <= 0 || attempts <= yaffs_wr_attempts));
608
609         if (!write_ok)
610                 chunk = -1;
611
612         if (attempts > 1) {
613                 yaffs_trace(YAFFS_TRACE_ERROR,
614                         "**>> yaffs write required %d attempts",
615                         attempts);
616                 dev->n_retired_writes += (attempts - 1);
617         }
618
619         return chunk;
620 }
621
622 /*
623  * Block retiring for handling a broken block.
624  */
625
626 static void yaffs_retire_block(struct yaffs_dev *dev, int flash_block)
627 {
628         struct yaffs_block_info *bi = yaffs_get_block_info(dev, flash_block);
629
630         yaffs2_checkpt_invalidate(dev);
631
632         yaffs2_clear_oldest_dirty_seq(dev, bi);
633
634         if (yaffs_mark_bad(dev, flash_block) != YAFFS_OK) {
635                 if (yaffs_erase_block(dev, flash_block) != YAFFS_OK) {
636                         yaffs_trace(YAFFS_TRACE_ALWAYS,
637                                 "yaffs: Failed to mark bad and erase block %d",
638                                 flash_block);
639                 } else {
640                         struct yaffs_ext_tags tags;
641                         int chunk_id =
642                             flash_block * dev->param.chunks_per_block;
643
644                         u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
645
646                         memset(buffer, 0xff, dev->data_bytes_per_chunk);
647                         yaffs_init_tags(&tags);
648                         tags.seq_number = YAFFS_SEQUENCE_BAD_BLOCK;
649                         if (dev->param.write_chunk_tags_fn(dev, chunk_id -
650                                                            dev->chunk_offset,
651                                                            buffer,
652                                                            &tags) != YAFFS_OK)
653                                 yaffs_trace(YAFFS_TRACE_ALWAYS,
654                                         "yaffs: Failed to write bad block marker to block %d",
655                                         flash_block);
656
657                         yaffs_release_temp_buffer(dev, buffer, __LINE__);
658                 }
659         }
660
661         bi->block_state = YAFFS_BLOCK_STATE_DEAD;
662         bi->gc_prioritise = 0;
663         bi->needs_retiring = 0;
664
665         dev->n_retired_blocks++;
666 }
667
668 /*---------------- Name handling functions ------------*/
669
670 static u16 yaffs_calc_name_sum(const YCHAR *name)
671 {
672         u16 sum = 0;
673         u16 i = 1;
674         const YUCHAR *bname = (const YUCHAR *)name;
675
676         if (bname) {
677                 while ((*bname) && (i < (YAFFS_MAX_NAME_LENGTH / 2))) {
678
679                         /* 0x1f mask is case insensitive */
680                         sum += ((*bname) & 0x1f) * i;
681                         i++;
682                         bname++;
683                 }
684         }
685         return sum;
686 }
687
688 void yaffs_set_obj_name(struct yaffs_obj *obj, const YCHAR * name)
689 {
690 #ifndef CONFIG_YAFFS_NO_SHORT_NAMES
691         memset(obj->short_name, 0, sizeof(obj->short_name));
692         if (name &&
693                 strnlen(name, YAFFS_SHORT_NAME_LENGTH + 1) <=
694                 YAFFS_SHORT_NAME_LENGTH)
695                 strcpy(obj->short_name, name);
696         else
697                 obj->short_name[0] = _Y('\0');
698 #endif
699         obj->sum = yaffs_calc_name_sum(name);
700 }
701
702 void yaffs_set_obj_name_from_oh(struct yaffs_obj *obj,
703                                 const struct yaffs_obj_hdr *oh)
704 {
705 #ifdef CONFIG_YAFFS_AUTO_UNICODE
706         YCHAR tmp_name[YAFFS_MAX_NAME_LENGTH + 1];
707         memset(tmp_name, 0, sizeof(tmp_name));
708         yaffs_load_name_from_oh(obj->my_dev, tmp_name, oh->name,
709                                 YAFFS_MAX_NAME_LENGTH + 1);
710         yaffs_set_obj_name(obj, tmp_name);
711 #else
712         yaffs_set_obj_name(obj, oh->name);
713 #endif
714 }
715
716 /*-------------------- TNODES -------------------
717
718  * List of spare tnodes
719  * The list is hooked together using the first pointer
720  * in the tnode.
721  */
722
723 struct yaffs_tnode *yaffs_get_tnode(struct yaffs_dev *dev)
724 {
725         struct yaffs_tnode *tn = yaffs_alloc_raw_tnode(dev);
726
727         if (tn) {
728                 memset(tn, 0, dev->tnode_size);
729                 dev->n_tnodes++;
730         }
731
732         dev->checkpoint_blocks_required = 0;    /* force recalculation */
733
734         return tn;
735 }
736
737 /* FreeTnode frees up a tnode and puts it back on the free list */
738 static void yaffs_free_tnode(struct yaffs_dev *dev, struct yaffs_tnode *tn)
739 {
740         yaffs_free_raw_tnode(dev, tn);
741         dev->n_tnodes--;
742         dev->checkpoint_blocks_required = 0;    /* force recalculation */
743 }
744
745 static void yaffs_deinit_tnodes_and_objs(struct yaffs_dev *dev)
746 {
747         yaffs_deinit_raw_tnodes_and_objs(dev);
748         dev->n_obj = 0;
749         dev->n_tnodes = 0;
750 }
751
752 void yaffs_load_tnode_0(struct yaffs_dev *dev, struct yaffs_tnode *tn,
753                         unsigned pos, unsigned val)
754 {
755         u32 *map = (u32 *) tn;
756         u32 bit_in_map;
757         u32 bit_in_word;
758         u32 word_in_map;
759         u32 mask;
760
761         pos &= YAFFS_TNODES_LEVEL0_MASK;
762         val >>= dev->chunk_grp_bits;
763
764         bit_in_map = pos * dev->tnode_width;
765         word_in_map = bit_in_map / 32;
766         bit_in_word = bit_in_map & (32 - 1);
767
768         mask = dev->tnode_mask << bit_in_word;
769
770         map[word_in_map] &= ~mask;
771         map[word_in_map] |= (mask & (val << bit_in_word));
772
773         if (dev->tnode_width > (32 - bit_in_word)) {
774                 bit_in_word = (32 - bit_in_word);
775                 word_in_map++;;
776                 mask =
777                     dev->tnode_mask >> bit_in_word;
778                 map[word_in_map] &= ~mask;
779                 map[word_in_map] |= (mask & (val >> bit_in_word));
780         }
781 }
782
783 u32 yaffs_get_group_base(struct yaffs_dev *dev, struct yaffs_tnode *tn,
784                          unsigned pos)
785 {
786         u32 *map = (u32 *) tn;
787         u32 bit_in_map;
788         u32 bit_in_word;
789         u32 word_in_map;
790         u32 val;
791
792         pos &= YAFFS_TNODES_LEVEL0_MASK;
793
794         bit_in_map = pos * dev->tnode_width;
795         word_in_map = bit_in_map / 32;
796         bit_in_word = bit_in_map & (32 - 1);
797
798         val = map[word_in_map] >> bit_in_word;
799
800         if (dev->tnode_width > (32 - bit_in_word)) {
801                 bit_in_word = (32 - bit_in_word);
802                 word_in_map++;;
803                 val |= (map[word_in_map] << bit_in_word);
804         }
805
806         val &= dev->tnode_mask;
807         val <<= dev->chunk_grp_bits;
808
809         return val;
810 }
811
812 /* ------------------- End of individual tnode manipulation -----------------*/
813
814 /* ---------Functions to manipulate the look-up tree (made up of tnodes) ------
815  * The look up tree is represented by the top tnode and the number of top_level
816  * in the tree. 0 means only the level 0 tnode is in the tree.
817  */
818
819 /* FindLevel0Tnode finds the level 0 tnode, if one exists. */
820 struct yaffs_tnode *yaffs_find_tnode_0(struct yaffs_dev *dev,
821                                        struct yaffs_file_var *file_struct,
822                                        u32 chunk_id)
823 {
824         struct yaffs_tnode *tn = file_struct->top;
825         u32 i;
826         int required_depth;
827         int level = file_struct->top_level;
828
829         dev = dev;
830
831         /* Check sane level and chunk Id */
832         if (level < 0 || level > YAFFS_TNODES_MAX_LEVEL)
833                 return NULL;
834
835         if (chunk_id > YAFFS_MAX_CHUNK_ID)
836                 return NULL;
837
838         /* First check we're tall enough (ie enough top_level) */
839
840         i = chunk_id >> YAFFS_TNODES_LEVEL0_BITS;
841         required_depth = 0;
842         while (i) {
843                 i >>= YAFFS_TNODES_INTERNAL_BITS;
844                 required_depth++;
845         }
846
847         if (required_depth > file_struct->top_level)
848                 return NULL;    /* Not tall enough, so we can't find it */
849
850         /* Traverse down to level 0 */
851         while (level > 0 && tn) {
852                 tn = tn->internal[(chunk_id >>
853                                    (YAFFS_TNODES_LEVEL0_BITS +
854                                     (level - 1) *
855                                     YAFFS_TNODES_INTERNAL_BITS)) &
856                                   YAFFS_TNODES_INTERNAL_MASK];
857                 level--;
858         }
859
860         return tn;
861 }
862
863 /* add_find_tnode_0 finds the level 0 tnode if it exists,
864  * otherwise first expands the tree.
865  * This happens in two steps:
866  *  1. If the tree isn't tall enough, then make it taller.
867  *  2. Scan down the tree towards the level 0 tnode adding tnodes if required.
868  *
869  * Used when modifying the tree.
870  *
871  *  If the tn argument is NULL, then a fresh tnode will be added otherwise the
872  *  specified tn will be plugged into the ttree.
873  */
874
875 struct yaffs_tnode *yaffs_add_find_tnode_0(struct yaffs_dev *dev,
876                                            struct yaffs_file_var *file_struct,
877                                            u32 chunk_id,
878                                            struct yaffs_tnode *passed_tn)
879 {
880         int required_depth;
881         int i;
882         int l;
883         struct yaffs_tnode *tn;
884         u32 x;
885
886         /* Check sane level and page Id */
887         if (file_struct->top_level < 0
888             || file_struct->top_level > YAFFS_TNODES_MAX_LEVEL)
889                 return NULL;
890
891         if (chunk_id > YAFFS_MAX_CHUNK_ID)
892                 return NULL;
893
894         /* First check we're tall enough (ie enough top_level) */
895
896         x = chunk_id >> YAFFS_TNODES_LEVEL0_BITS;
897         required_depth = 0;
898         while (x) {
899                 x >>= YAFFS_TNODES_INTERNAL_BITS;
900                 required_depth++;
901         }
902
903         if (required_depth > file_struct->top_level) {
904                 /* Not tall enough, gotta make the tree taller */
905                 for (i = file_struct->top_level; i < required_depth; i++) {
906
907                         tn = yaffs_get_tnode(dev);
908
909                         if (tn) {
910                                 tn->internal[0] = file_struct->top;
911                                 file_struct->top = tn;
912                                 file_struct->top_level++;
913                         } else {
914                                 yaffs_trace(YAFFS_TRACE_ERROR,
915                                         "yaffs: no more tnodes");
916                                 return NULL;
917                         }
918                 }
919         }
920
921         /* Traverse down to level 0, adding anything we need */
922
923         l = file_struct->top_level;
924         tn = file_struct->top;
925
926         if (l > 0) {
927                 while (l > 0 && tn) {
928                         x = (chunk_id >>
929                              (YAFFS_TNODES_LEVEL0_BITS +
930                               (l - 1) * YAFFS_TNODES_INTERNAL_BITS)) &
931                             YAFFS_TNODES_INTERNAL_MASK;
932
933                         if ((l > 1) && !tn->internal[x]) {
934                                 /* Add missing non-level-zero tnode */
935                                 tn->internal[x] = yaffs_get_tnode(dev);
936                                 if (!tn->internal[x])
937                                         return NULL;
938                         } else if (l == 1) {
939                                 /* Looking from level 1 at level 0 */
940                                 if (passed_tn) {
941                                         /* If we already have one, release it */
942                                         if (tn->internal[x])
943                                                 yaffs_free_tnode(dev,
944                                                         tn->internal[x]);
945                                         tn->internal[x] = passed_tn;
946
947                                 } else if (!tn->internal[x]) {
948                                         /* Don't have one, none passed in */
949                                         tn->internal[x] = yaffs_get_tnode(dev);
950                                         if (!tn->internal[x])
951                                                 return NULL;
952                                 }
953                         }
954
955                         tn = tn->internal[x];
956                         l--;
957                 }
958         } else {
959                 /* top is level 0 */
960                 if (passed_tn) {
961                         memcpy(tn, passed_tn,
962                                (dev->tnode_width * YAFFS_NTNODES_LEVEL0) / 8);
963                         yaffs_free_tnode(dev, passed_tn);
964                 }
965         }
966
967         return tn;
968 }
969
970 static int yaffs_tags_match(const struct yaffs_ext_tags *tags, int obj_id,
971                             int chunk_obj)
972 {
973         return (tags->chunk_id == chunk_obj &&
974                 tags->obj_id == obj_id && !tags->is_deleted) ? 1 : 0;
975
976 }
977
978 static int yaffs_find_chunk_in_group(struct yaffs_dev *dev, int the_chunk,
979                                         struct yaffs_ext_tags *tags, int obj_id,
980                                         int inode_chunk)
981 {
982         int j;
983
984         for (j = 0; the_chunk && j < dev->chunk_grp_size; j++) {
985                 if (yaffs_check_chunk_bit
986                     (dev, the_chunk / dev->param.chunks_per_block,
987                      the_chunk % dev->param.chunks_per_block)) {
988
989                         if (dev->chunk_grp_size == 1)
990                                 return the_chunk;
991                         else {
992                                 yaffs_rd_chunk_tags_nand(dev, the_chunk, NULL,
993                                                          tags);
994                                 if (yaffs_tags_match(tags,
995                                                         obj_id, inode_chunk)) {
996                                         /* found it; */
997                                         return the_chunk;
998                                 }
999                         }
1000                 }
1001                 the_chunk++;
1002         }
1003         return -1;
1004 }
1005
1006 static int yaffs_find_chunk_in_file(struct yaffs_obj *in, int inode_chunk,
1007                                     struct yaffs_ext_tags *tags)
1008 {
1009         /*Get the Tnode, then get the level 0 offset chunk offset */
1010         struct yaffs_tnode *tn;
1011         int the_chunk = -1;
1012         struct yaffs_ext_tags local_tags;
1013         int ret_val = -1;
1014         struct yaffs_dev *dev = in->my_dev;
1015
1016         if (!tags) {
1017                 /* Passed a NULL, so use our own tags space */
1018                 tags = &local_tags;
1019         }
1020
1021         tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk);
1022
1023         if (tn) {
1024                 the_chunk = yaffs_get_group_base(dev, tn, inode_chunk);
1025
1026                 ret_val =
1027                     yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id,
1028                                               inode_chunk);
1029         }
1030         return ret_val;
1031 }
1032
1033 static int yaffs_find_del_file_chunk(struct yaffs_obj *in, int inode_chunk,
1034                                      struct yaffs_ext_tags *tags)
1035 {
1036         /* Get the Tnode, then get the level 0 offset chunk offset */
1037         struct yaffs_tnode *tn;
1038         int the_chunk = -1;
1039         struct yaffs_ext_tags local_tags;
1040         struct yaffs_dev *dev = in->my_dev;
1041         int ret_val = -1;
1042
1043         if (!tags) {
1044                 /* Passed a NULL, so use our own tags space */
1045                 tags = &local_tags;
1046         }
1047
1048         tn = yaffs_find_tnode_0(dev, &in->variant.file_variant, inode_chunk);
1049
1050         if (tn) {
1051
1052                 the_chunk = yaffs_get_group_base(dev, tn, inode_chunk);
1053
1054                 ret_val =
1055                     yaffs_find_chunk_in_group(dev, the_chunk, tags, in->obj_id,
1056                                               inode_chunk);
1057
1058                 /* Delete the entry in the filestructure (if found) */
1059                 if (ret_val != -1)
1060                         yaffs_load_tnode_0(dev, tn, inode_chunk, 0);
1061         }
1062
1063         return ret_val;
1064 }
1065
1066 int yaffs_put_chunk_in_file(struct yaffs_obj *in, int inode_chunk,
1067                             int nand_chunk, int in_scan)
1068 {
1069         /* NB in_scan is zero unless scanning.
1070          * For forward scanning, in_scan is > 0;
1071          * for backward scanning in_scan is < 0
1072          *
1073          * nand_chunk = 0 is a dummy insert to make sure the tnodes are there.
1074          */
1075
1076         struct yaffs_tnode *tn;
1077         struct yaffs_dev *dev = in->my_dev;
1078         int existing_cunk;
1079         struct yaffs_ext_tags existing_tags;
1080         struct yaffs_ext_tags new_tags;
1081         unsigned existing_serial, new_serial;
1082
1083         if (in->variant_type != YAFFS_OBJECT_TYPE_FILE) {
1084                 /* Just ignore an attempt at putting a chunk into a non-file
1085                  * during scanning.
1086                  * If it is not during Scanning then something went wrong!
1087                  */
1088                 if (!in_scan) {
1089                         yaffs_trace(YAFFS_TRACE_ERROR,
1090                                 "yaffs tragedy:attempt to put data chunk into a non-file"
1091                                 );
1092                         BUG();
1093                 }
1094
1095                 yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
1096                 return YAFFS_OK;
1097         }
1098
1099         tn = yaffs_add_find_tnode_0(dev,
1100                                     &in->variant.file_variant,
1101                                     inode_chunk, NULL);
1102         if (!tn)
1103                 return YAFFS_FAIL;
1104
1105         if (!nand_chunk)
1106                 /* Dummy insert, bail now */
1107                 return YAFFS_OK;
1108
1109         existing_cunk = yaffs_get_group_base(dev, tn, inode_chunk);
1110
1111         if (in_scan != 0) {
1112                 /* If we're scanning then we need to test for duplicates
1113                  * NB This does not need to be efficient since it should only
1114                  * happen when the power fails during a write, then only one
1115                  * chunk should ever be affected.
1116                  *
1117                  * Correction for YAFFS2: This could happen quite a lot and we
1118                  * need to think about efficiency! TODO
1119                  * Update: For backward scanning we don't need to re-read tags
1120                  * so this is quite cheap.
1121                  */
1122
1123                 if (existing_cunk > 0) {
1124                         /* NB Right now existing chunk will not be real
1125                          * chunk_id if the chunk group size > 1
1126                          * thus we have to do a FindChunkInFile to get the
1127                          * real chunk id.
1128                          *
1129                          * We have a duplicate now we need to decide which
1130                          * one to use:
1131                          *
1132                          * Backwards scanning YAFFS2: The old one is what
1133                          * we use, dump the new one.
1134                          * YAFFS1: Get both sets of tags and compare serial
1135                          * numbers.
1136                          */
1137
1138                         if (in_scan > 0) {
1139                                 /* Only do this for forward scanning */
1140                                 yaffs_rd_chunk_tags_nand(dev,
1141                                                          nand_chunk,
1142                                                          NULL, &new_tags);
1143
1144                                 /* Do a proper find */
1145                                 existing_cunk =
1146                                     yaffs_find_chunk_in_file(in, inode_chunk,
1147                                                              &existing_tags);
1148                         }
1149
1150                         if (existing_cunk <= 0) {
1151                                 /*Hoosterman - how did this happen? */
1152
1153                                 yaffs_trace(YAFFS_TRACE_ERROR,
1154                                         "yaffs tragedy: existing chunk < 0 in scan"
1155                                         );
1156
1157                         }
1158
1159                         /* NB The deleted flags should be false, otherwise
1160                          * the chunks will not be loaded during a scan
1161                          */
1162
1163                         if (in_scan > 0) {
1164                                 new_serial = new_tags.serial_number;
1165                                 existing_serial = existing_tags.serial_number;
1166                         }
1167
1168                         if ((in_scan > 0) &&
1169                             (existing_cunk <= 0 ||
1170                              ((existing_serial + 1) & 3) == new_serial)) {
1171                                 /* Forward scanning.
1172                                  * Use new
1173                                  * Delete the old one and drop through to
1174                                  * update the tnode
1175                                  */
1176                                 yaffs_chunk_del(dev, existing_cunk, 1,
1177                                                 __LINE__);
1178                         } else {
1179                                 /* Backward scanning or we want to use the
1180                                  * existing one
1181                                  * Delete the new one and return early so that
1182                                  * the tnode isn't changed
1183                                  */
1184                                 yaffs_chunk_del(dev, nand_chunk, 1, __LINE__);
1185                                 return YAFFS_OK;
1186                         }
1187                 }
1188
1189         }
1190
1191         if (existing_cunk == 0)
1192                 in->n_data_chunks++;
1193
1194         yaffs_load_tnode_0(dev, tn, inode_chunk, nand_chunk);
1195
1196         return YAFFS_OK;
1197 }
1198
1199 static void yaffs_soft_del_chunk(struct yaffs_dev *dev, int chunk)
1200 {
1201         struct yaffs_block_info *the_block;
1202         unsigned block_no;
1203
1204         yaffs_trace(YAFFS_TRACE_DELETION, "soft delete chunk %d", chunk);
1205
1206         block_no = chunk / dev->param.chunks_per_block;
1207         the_block = yaffs_get_block_info(dev, block_no);
1208         if (the_block) {
1209                 the_block->soft_del_pages++;
1210                 dev->n_free_chunks++;
1211                 yaffs2_update_oldest_dirty_seq(dev, block_no, the_block);
1212         }
1213 }
1214
1215 /* SoftDeleteWorker scans backwards through the tnode tree and soft deletes all
1216  * the chunks in the file.
1217  * All soft deleting does is increment the block's softdelete count and pulls
1218  * the chunk out of the tnode.
1219  * Thus, essentially this is the same as DeleteWorker except that the chunks
1220  * are soft deleted.
1221  */
1222
1223 static int yaffs_soft_del_worker(struct yaffs_obj *in, struct yaffs_tnode *tn,
1224                                  u32 level, int chunk_offset)
1225 {
1226         int i;
1227         int the_chunk;
1228         int all_done = 1;
1229         struct yaffs_dev *dev = in->my_dev;
1230
1231         if (tn) {
1232                 if (level > 0) {
1233                         for (i = YAFFS_NTNODES_INTERNAL - 1;
1234                                 all_done && i >= 0;
1235                                 i--) {
1236                                 if (tn->internal[i]) {
1237                                         all_done =
1238                                             yaffs_soft_del_worker(in,
1239                                                 tn->internal[i],
1240                                                 level - 1,
1241                                                 (chunk_offset <<
1242                                                 YAFFS_TNODES_INTERNAL_BITS)
1243                                                 + i);
1244                                         if (all_done) {
1245                                                 yaffs_free_tnode(dev,
1246                                                         tn->internal[i]);
1247                                                 tn->internal[i] = NULL;
1248                                         } else {
1249                                                 /* Can this happen? */
1250                                         }
1251                                 }
1252                         }
1253                         return (all_done) ? 1 : 0;
1254                 } else if (level == 0) {
1255                         for (i = YAFFS_NTNODES_LEVEL0 - 1; i >= 0; i--) {
1256                                 the_chunk = yaffs_get_group_base(dev, tn, i);
1257                                 if (the_chunk) {
1258                                         yaffs_soft_del_chunk(dev, the_chunk);
1259                                         yaffs_load_tnode_0(dev, tn, i, 0);
1260                                 }
1261                         }
1262                         return 1;
1263                 }
1264         }
1265         return 1;
1266 }
1267
1268 static void yaffs_remove_obj_from_dir(struct yaffs_obj *obj)
1269 {
1270         struct yaffs_dev *dev = obj->my_dev;
1271         struct yaffs_obj *parent;
1272
1273         yaffs_verify_obj_in_dir(obj);
1274         parent = obj->parent;
1275
1276         yaffs_verify_dir(parent);
1277
1278         if (dev && dev->param.remove_obj_fn)
1279                 dev->param.remove_obj_fn(obj);
1280
1281         list_del_init(&obj->siblings);
1282         obj->parent = NULL;
1283
1284         yaffs_verify_dir(parent);
1285 }
1286
1287 void yaffs_add_obj_to_dir(struct yaffs_obj *directory, struct yaffs_obj *obj)
1288 {
1289         if (!directory) {
1290                 yaffs_trace(YAFFS_TRACE_ALWAYS,
1291                         "tragedy: Trying to add an object to a null pointer directory"
1292                         );
1293                 BUG();
1294                 return;
1295         }
1296         if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
1297                 yaffs_trace(YAFFS_TRACE_ALWAYS,
1298                         "tragedy: Trying to add an object to a non-directory"
1299                         );
1300                 BUG();
1301         }
1302
1303         if (obj->siblings.prev == NULL) {
1304                 /* Not initialised */
1305                 BUG();
1306         }
1307
1308         yaffs_verify_dir(directory);
1309
1310         yaffs_remove_obj_from_dir(obj);
1311
1312         /* Now add it */
1313         list_add(&obj->siblings, &directory->variant.dir_variant.children);
1314         obj->parent = directory;
1315
1316         if (directory == obj->my_dev->unlinked_dir
1317             || directory == obj->my_dev->del_dir) {
1318                 obj->unlinked = 1;
1319                 obj->my_dev->n_unlinked_files++;
1320                 obj->rename_allowed = 0;
1321         }
1322
1323         yaffs_verify_dir(directory);
1324         yaffs_verify_obj_in_dir(obj);
1325 }
1326
1327 static int yaffs_change_obj_name(struct yaffs_obj *obj,
1328                                  struct yaffs_obj *new_dir,
1329                                  const YCHAR *new_name, int force, int shadows)
1330 {
1331         int unlink_op;
1332         int del_op;
1333         struct yaffs_obj *existing_target;
1334
1335         if (new_dir == NULL)
1336                 new_dir = obj->parent;  /* use the old directory */
1337
1338         if (new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
1339                 yaffs_trace(YAFFS_TRACE_ALWAYS,
1340                         "tragedy: yaffs_change_obj_name: new_dir is not a directory"
1341                         );
1342                 BUG();
1343         }
1344
1345         /* TODO: Do we need this different handling for YAFFS2 and YAFFS1?? */
1346         if (obj->my_dev->param.is_yaffs2)
1347                 unlink_op = (new_dir == obj->my_dev->unlinked_dir);
1348         else
1349                 unlink_op = (new_dir == obj->my_dev->unlinked_dir
1350                              && obj->variant_type == YAFFS_OBJECT_TYPE_FILE);
1351
1352         del_op = (new_dir == obj->my_dev->del_dir);
1353
1354         existing_target = yaffs_find_by_name(new_dir, new_name);
1355
1356         /* If the object is a file going into the unlinked directory,
1357          *   then it is OK to just stuff it in since duplicate names are OK.
1358          *   else only proceed if the new name does not exist and we're putting
1359          *   it into a directory.
1360          */
1361         if ((unlink_op ||
1362              del_op ||
1363              force ||
1364              (shadows > 0) ||
1365              !existing_target) &&
1366             new_dir->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) {
1367                 yaffs_set_obj_name(obj, new_name);
1368                 obj->dirty = 1;
1369
1370                 yaffs_add_obj_to_dir(new_dir, obj);
1371
1372                 if (unlink_op)
1373                         obj->unlinked = 1;
1374
1375                 /* If it is a deletion then we mark it as a shrink for gc  */
1376                 if (yaffs_update_oh(obj, new_name, 0, del_op, shadows, NULL) >=
1377                     0)
1378                         return YAFFS_OK;
1379         }
1380         return YAFFS_FAIL;
1381 }
1382
1383 /*------------------------ Short Operations Cache ------------------------------
1384  *   In many situations where there is no high level buffering  a lot of
1385  *   reads might be short sequential reads, and a lot of writes may be short
1386  *   sequential writes. eg. scanning/writing a jpeg file.
1387  *   In these cases, a short read/write cache can provide a huge perfomance
1388  *   benefit with dumb-as-a-rock code.
1389  *   In Linux, the page cache provides read buffering and the short op cache
1390  *   provides write buffering.
1391  *
1392  *   There are a small number (~10) of cache chunks per device so that we don't
1393  *   need a very intelligent search.
1394  */
1395
1396 static int yaffs_obj_cache_dirty(struct yaffs_obj *obj)
1397 {
1398         struct yaffs_dev *dev = obj->my_dev;
1399         int i;
1400         struct yaffs_cache *cache;
1401         int n_caches = obj->my_dev->param.n_caches;
1402
1403         for (i = 0; i < n_caches; i++) {
1404                 cache = &dev->cache[i];
1405                 if (cache->object == obj && cache->dirty)
1406                         return 1;
1407         }
1408
1409         return 0;
1410 }
1411
1412 static void yaffs_flush_file_cache(struct yaffs_obj *obj)
1413 {
1414         struct yaffs_dev *dev = obj->my_dev;
1415         int lowest = -99;       /* Stop compiler whining. */
1416         int i;
1417         struct yaffs_cache *cache;
1418         int chunk_written = 0;
1419         int n_caches = obj->my_dev->param.n_caches;
1420
1421         if (n_caches > 0) {
1422                 do {
1423                         cache = NULL;
1424
1425                         /* Find the lowest dirty chunk for this object */
1426                         for (i = 0; i < n_caches; i++) {
1427                                 if (dev->cache[i].object == obj &&
1428                                     dev->cache[i].dirty) {
1429                                         if (!cache
1430                                             || dev->cache[i].chunk_id <
1431                                             lowest) {
1432                                                 cache = &dev->cache[i];
1433                                                 lowest = cache->chunk_id;
1434                                         }
1435                                 }
1436                         }
1437
1438                         if (cache && !cache->locked) {
1439                                 /* Write it out and free it up */
1440                                 chunk_written =
1441                                     yaffs_wr_data_obj(cache->object,
1442                                                       cache->chunk_id,
1443                                                       cache->data,
1444                                                       cache->n_bytes, 1);
1445                                 cache->dirty = 0;
1446                                 cache->object = NULL;
1447                         }
1448                 } while (cache && chunk_written > 0);
1449
1450                 if (cache)
1451                         /* Hoosterman, disk full while writing cache out. */
1452                         yaffs_trace(YAFFS_TRACE_ERROR,
1453                                 "yaffs tragedy: no space during cache write");
1454         }
1455 }
1456
1457 /*yaffs_flush_whole_cache(dev)
1458  *
1459  *
1460  */
1461
1462 void yaffs_flush_whole_cache(struct yaffs_dev *dev)
1463 {
1464         struct yaffs_obj *obj;
1465         int n_caches = dev->param.n_caches;
1466         int i;
1467
1468         /* Find a dirty object in the cache and flush it...
1469          * until there are no further dirty objects.
1470          */
1471         do {
1472                 obj = NULL;
1473                 for (i = 0; i < n_caches && !obj; i++) {
1474                         if (dev->cache[i].object && dev->cache[i].dirty)
1475                                 obj = dev->cache[i].object;
1476                 }
1477                 if (obj)
1478                         yaffs_flush_file_cache(obj);
1479         } while (obj);
1480
1481 }
1482
1483 /* Grab us a cache chunk for use.
1484  * First look for an empty one.
1485  * Then look for the least recently used non-dirty one.
1486  * Then look for the least recently used dirty one...., flush and look again.
1487  */
1488 static struct yaffs_cache *yaffs_grab_chunk_worker(struct yaffs_dev *dev)
1489 {
1490         int i;
1491
1492         if (dev->param.n_caches > 0) {
1493                 for (i = 0; i < dev->param.n_caches; i++) {
1494                         if (!dev->cache[i].object)
1495                                 return &dev->cache[i];
1496                 }
1497         }
1498         return NULL;
1499 }
1500
1501 static struct yaffs_cache *yaffs_grab_chunk_cache(struct yaffs_dev *dev)
1502 {
1503         struct yaffs_cache *cache;
1504         struct yaffs_obj *the_obj;
1505         int usage;
1506         int i;
1507         int pushout;
1508
1509         if (dev->param.n_caches > 0) {
1510                 /* Try find a non-dirty one... */
1511
1512                 cache = yaffs_grab_chunk_worker(dev);
1513
1514                 if (!cache) {
1515                         /* They were all dirty, find the LRU object and flush
1516                          * its cache, then  find again.
1517                          * NB what's here is not very accurate,
1518                          * we actually flush the object with the LRU chunk.
1519                          */
1520
1521                         /* With locking we can't assume we can use entry zero,
1522                          * Set the_obj to a valid pointer for Coverity. */
1523
1524                         the_obj = dev->cache[0].object;
1525                         usage = -1;
1526                         cache = NULL;
1527                         pushout = -1;
1528
1529                         for (i = 0; i < dev->param.n_caches; i++) {
1530                                 if (dev->cache[i].object &&
1531                                     !dev->cache[i].locked &&
1532                                     (dev->cache[i].last_use < usage
1533                                      || !cache)) {
1534                                         usage = dev->cache[i].last_use;
1535                                         the_obj = dev->cache[i].object;
1536                                         cache = &dev->cache[i];
1537                                         pushout = i;
1538                                 }
1539                         }
1540
1541                         if (!cache || cache->dirty) {
1542                                 /* Flush and try again */
1543                                 yaffs_flush_file_cache(the_obj);
1544                                 cache = yaffs_grab_chunk_worker(dev);
1545                         }
1546                 }
1547                 return cache;
1548         } else {
1549                 return NULL;
1550         }
1551 }
1552
1553 /* Find a cached chunk */
1554 static struct yaffs_cache *yaffs_find_chunk_cache(const struct yaffs_obj *obj,
1555                                                   int chunk_id)
1556 {
1557         struct yaffs_dev *dev = obj->my_dev;
1558         int i;
1559
1560         if (dev->param.n_caches > 0) {
1561                 for (i = 0; i < dev->param.n_caches; i++) {
1562                         if (dev->cache[i].object == obj &&
1563                             dev->cache[i].chunk_id == chunk_id) {
1564                                 dev->cache_hits++;
1565
1566                                 return &dev->cache[i];
1567                         }
1568                 }
1569         }
1570         return NULL;
1571 }
1572
1573 /* Mark the chunk for the least recently used algorithym */
1574 static void yaffs_use_cache(struct yaffs_dev *dev, struct yaffs_cache *cache,
1575                             int is_write)
1576 {
1577         if (dev->param.n_caches > 0) {
1578                 if (dev->cache_last_use < 0 ||
1579                         dev->cache_last_use > 100000000) {
1580                         /* Reset the cache usages */
1581                         int i;
1582                         for (i = 1; i < dev->param.n_caches; i++)
1583                                 dev->cache[i].last_use = 0;
1584
1585                         dev->cache_last_use = 0;
1586                 }
1587                 dev->cache_last_use++;
1588                 cache->last_use = dev->cache_last_use;
1589
1590                 if (is_write)
1591                         cache->dirty = 1;
1592         }
1593 }
1594
1595 /* Invalidate a single cache page.
1596  * Do this when a whole page gets written,
1597  * ie the short cache for this page is no longer valid.
1598  */
1599 static void yaffs_invalidate_chunk_cache(struct yaffs_obj *object, int chunk_id)
1600 {
1601         if (object->my_dev->param.n_caches > 0) {
1602                 struct yaffs_cache *cache =
1603                     yaffs_find_chunk_cache(object, chunk_id);
1604
1605                 if (cache)
1606                         cache->object = NULL;
1607         }
1608 }
1609
1610 /* Invalidate all the cache pages associated with this object
1611  * Do this whenever ther file is deleted or resized.
1612  */
1613 static void yaffs_invalidate_whole_cache(struct yaffs_obj *in)
1614 {
1615         int i;
1616         struct yaffs_dev *dev = in->my_dev;
1617
1618         if (dev->param.n_caches > 0) {
1619                 /* Invalidate it. */
1620                 for (i = 0; i < dev->param.n_caches; i++) {
1621                         if (dev->cache[i].object == in)
1622                                 dev->cache[i].object = NULL;
1623                 }
1624         }
1625 }
1626
1627 static void yaffs_unhash_obj(struct yaffs_obj *obj)
1628 {
1629         int bucket;
1630         struct yaffs_dev *dev = obj->my_dev;
1631
1632         /* If it is still linked into the bucket list, free from the list */
1633         if (!list_empty(&obj->hash_link)) {
1634                 list_del_init(&obj->hash_link);
1635                 bucket = yaffs_hash_fn(obj->obj_id);
1636                 dev->obj_bucket[bucket].count--;
1637         }
1638 }
1639
1640 /*  FreeObject frees up a Object and puts it back on the free list */
1641 static void yaffs_free_obj(struct yaffs_obj *obj)
1642 {
1643         struct yaffs_dev *dev;
1644
1645         if (!obj) {
1646                 BUG();
1647                 return;
1648         }
1649         dev = obj->my_dev;
1650         yaffs_trace(YAFFS_TRACE_OS, "FreeObject %p inode %p",
1651                 obj, obj->my_inode);
1652         if (obj->parent)
1653                 BUG();
1654         if (!list_empty(&obj->siblings))
1655                 BUG();
1656
1657         if (obj->my_inode) {
1658                 /* We're still hooked up to a cached inode.
1659                  * Don't delete now, but mark for later deletion
1660                  */
1661                 obj->defered_free = 1;
1662                 return;
1663         }
1664
1665         yaffs_unhash_obj(obj);
1666
1667         yaffs_free_raw_obj(dev, obj);
1668         dev->n_obj--;
1669         dev->checkpoint_blocks_required = 0;    /* force recalculation */
1670 }
1671
1672 void yaffs_handle_defered_free(struct yaffs_obj *obj)
1673 {
1674         if (obj->defered_free)
1675                 yaffs_free_obj(obj);
1676 }
1677
1678 static int yaffs_generic_obj_del(struct yaffs_obj *in)
1679 {
1680         /* Iinvalidate the file's data in the cache, without flushing. */
1681         yaffs_invalidate_whole_cache(in);
1682
1683         if (in->my_dev->param.is_yaffs2 && in->parent != in->my_dev->del_dir) {
1684                 /* Move to unlinked directory so we have a deletion record */
1685                 yaffs_change_obj_name(in, in->my_dev->del_dir, _Y("deleted"), 0,
1686                                       0);
1687         }
1688
1689         yaffs_remove_obj_from_dir(in);
1690         yaffs_chunk_del(in->my_dev, in->hdr_chunk, 1, __LINE__);
1691         in->hdr_chunk = 0;
1692
1693         yaffs_free_obj(in);
1694         return YAFFS_OK;
1695
1696 }
1697
1698 static void yaffs_soft_del_file(struct yaffs_obj *obj)
1699 {
1700         if (obj->deleted &&
1701             obj->variant_type == YAFFS_OBJECT_TYPE_FILE && !obj->soft_del) {
1702                 if (obj->n_data_chunks <= 0) {
1703                         /* Empty file with no duplicate object headers,
1704                          * just delete it immediately */
1705                         yaffs_free_tnode(obj->my_dev,
1706                                          obj->variant.file_variant.top);
1707                         obj->variant.file_variant.top = NULL;
1708                         yaffs_trace(YAFFS_TRACE_TRACING,
1709                                 "yaffs: Deleting empty file %d",
1710                                 obj->obj_id);
1711                         yaffs_generic_obj_del(obj);
1712                 } else {
1713                         yaffs_soft_del_worker(obj,
1714                                               obj->variant.file_variant.top,
1715                                               obj->variant.
1716                                               file_variant.top_level, 0);
1717                         obj->soft_del = 1;
1718                 }
1719         }
1720 }
1721
1722 /* Pruning removes any part of the file structure tree that is beyond the
1723  * bounds of the file (ie that does not point to chunks).
1724  *
1725  * A file should only get pruned when its size is reduced.
1726  *
1727  * Before pruning, the chunks must be pulled from the tree and the
1728  * level 0 tnode entries must be zeroed out.
1729  * Could also use this for file deletion, but that's probably better handled
1730  * by a special case.
1731  *
1732  * This function is recursive. For levels > 0 the function is called again on
1733  * any sub-tree. For level == 0 we just check if the sub-tree has data.
1734  * If there is no data in a subtree then it is pruned.
1735  */
1736
1737 static struct yaffs_tnode *yaffs_prune_worker(struct yaffs_dev *dev,
1738                                               struct yaffs_tnode *tn, u32 level,
1739                                               int del0)
1740 {
1741         int i;
1742         int has_data;
1743
1744         if (tn) {
1745                 has_data = 0;
1746
1747                 if (level > 0) {
1748                         for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) {
1749                                 if (tn->internal[i]) {
1750                                         tn->internal[i] =
1751                                             yaffs_prune_worker(dev,
1752                                                         tn->internal[i],
1753                                                         level - 1,
1754                                                         (i == 0) ? del0 : 1);
1755                                 }
1756
1757                                 if (tn->internal[i])
1758                                         has_data++;
1759                         }
1760                 } else {
1761                         int tnode_size_u32 = dev->tnode_size / sizeof(u32);
1762                         u32 *map = (u32 *) tn;
1763
1764                         for (i = 0; !has_data && i < tnode_size_u32; i++) {
1765                                 if (map[i])
1766                                         has_data++;
1767                         }
1768                 }
1769
1770                 if (has_data == 0 && del0) {
1771                         /* Free and return NULL */
1772
1773                         yaffs_free_tnode(dev, tn);
1774                         tn = NULL;
1775                 }
1776         }
1777         return tn;
1778 }
1779
1780 static int yaffs_prune_tree(struct yaffs_dev *dev,
1781                             struct yaffs_file_var *file_struct)
1782 {
1783         int i;
1784         int has_data;
1785         int done = 0;
1786         struct yaffs_tnode *tn;
1787
1788         if (file_struct->top_level > 0) {
1789                 file_struct->top =
1790                     yaffs_prune_worker(dev, file_struct->top,
1791                                        file_struct->top_level, 0);
1792
1793                 /* Now we have a tree with all the non-zero branches NULL but
1794                  * the height is the same as it was.
1795                  * Let's see if we can trim internal tnodes to shorten the tree.
1796                  * We can do this if only the 0th element in the tnode is in use
1797                  * (ie all the non-zero are NULL)
1798                  */
1799
1800                 while (file_struct->top_level && !done) {
1801                         tn = file_struct->top;
1802
1803                         has_data = 0;
1804                         for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {
1805                                 if (tn->internal[i])
1806                                         has_data++;
1807                         }
1808
1809                         if (!has_data) {
1810                                 file_struct->top = tn->internal[0];
1811                                 file_struct->top_level--;
1812                                 yaffs_free_tnode(dev, tn);
1813                         } else {
1814                                 done = 1;
1815                         }
1816                 }
1817         }
1818         return YAFFS_OK;
1819 }
1820
1821 /*-------------------- End of File Structure functions.-------------------*/
1822
1823 /* alloc_empty_obj gets us a clean Object.*/
1824 static struct yaffs_obj *yaffs_alloc_empty_obj(struct yaffs_dev *dev)
1825 {
1826         struct yaffs_obj *obj = yaffs_alloc_raw_obj(dev);
1827
1828         if (obj) {
1829                 dev->n_obj++;
1830
1831                 /* Now sweeten it up... */
1832
1833                 memset(obj, 0, sizeof(struct yaffs_obj));
1834                 obj->being_created = 1;
1835
1836                 obj->my_dev = dev;
1837                 obj->hdr_chunk = 0;
1838                 obj->variant_type = YAFFS_OBJECT_TYPE_UNKNOWN;
1839                 INIT_LIST_HEAD(&(obj->hard_links));
1840                 INIT_LIST_HEAD(&(obj->hash_link));
1841                 INIT_LIST_HEAD(&obj->siblings);
1842
1843                 /* Now make the directory sane */
1844                 if (dev->root_dir) {
1845                         obj->parent = dev->root_dir;
1846                         list_add(&(obj->siblings),
1847                                  &dev->root_dir->variant.dir_variant.children);
1848                 }
1849
1850                 /* Add it to the lost and found directory.
1851                  * NB Can't put root or lost-n-found in lost-n-found so
1852                  * check if lost-n-found exists first
1853                  */
1854                 if (dev->lost_n_found)
1855                         yaffs_add_obj_to_dir(dev->lost_n_found, obj);
1856
1857                 obj->being_created = 0;
1858         }
1859
1860         dev->checkpoint_blocks_required = 0;    /* force recalculation */
1861
1862         return obj;
1863 }
1864
1865 static int yaffs_find_nice_bucket(struct yaffs_dev *dev)
1866 {
1867         int i;
1868         int l = 999;
1869         int lowest = 999999;
1870
1871         /* Search for the shortest list or one that
1872          * isn't too long.
1873          */
1874
1875         for (i = 0; i < 10 && lowest > 4; i++) {
1876                 dev->bucket_finder++;
1877                 dev->bucket_finder %= YAFFS_NOBJECT_BUCKETS;
1878                 if (dev->obj_bucket[dev->bucket_finder].count < lowest) {
1879                         lowest = dev->obj_bucket[dev->bucket_finder].count;
1880                         l = dev->bucket_finder;
1881                 }
1882         }
1883
1884         return l;
1885 }
1886
1887 static int yaffs_new_obj_id(struct yaffs_dev *dev)
1888 {
1889         int bucket = yaffs_find_nice_bucket(dev);
1890         int found = 0;
1891         struct list_head *i;
1892         u32 n = (u32) bucket;
1893
1894         /* Now find an object value that has not already been taken
1895          * by scanning the list.
1896          */
1897
1898         while (!found) {
1899                 found = 1;
1900                 n += YAFFS_NOBJECT_BUCKETS;
1901                 if (1 || dev->obj_bucket[bucket].count > 0) {
1902                         list_for_each(i, &dev->obj_bucket[bucket].list) {
1903                                 /* If there is already one in the list */
1904                                 if (i && list_entry(i, struct yaffs_obj,
1905                                                     hash_link)->obj_id == n) {
1906                                         found = 0;
1907                                 }
1908                         }
1909                 }
1910         }
1911         return n;
1912 }
1913
1914 static void yaffs_hash_obj(struct yaffs_obj *in)
1915 {
1916         int bucket = yaffs_hash_fn(in->obj_id);
1917         struct yaffs_dev *dev = in->my_dev;
1918
1919         list_add(&in->hash_link, &dev->obj_bucket[bucket].list);
1920         dev->obj_bucket[bucket].count++;
1921 }
1922
1923 struct yaffs_obj *yaffs_find_by_number(struct yaffs_dev *dev, u32 number)
1924 {
1925         int bucket = yaffs_hash_fn(number);
1926         struct list_head *i;
1927         struct yaffs_obj *in;
1928
1929         list_for_each(i, &dev->obj_bucket[bucket].list) {
1930                 /* Look if it is in the list */
1931                 in = list_entry(i, struct yaffs_obj, hash_link);
1932                 if (in->obj_id == number) {
1933                         /* Don't show if it is defered free */
1934                         if (in->defered_free)
1935                                 return NULL;
1936                         return in;
1937                 }
1938         }
1939
1940         return NULL;
1941 }
1942
1943 struct yaffs_obj *yaffs_new_obj(struct yaffs_dev *dev, int number,
1944                                 enum yaffs_obj_type type)
1945 {
1946         struct yaffs_obj *the_obj = NULL;
1947         struct yaffs_tnode *tn = NULL;
1948
1949         if (number < 0)
1950                 number = yaffs_new_obj_id(dev);
1951
1952         if (type == YAFFS_OBJECT_TYPE_FILE) {
1953                 tn = yaffs_get_tnode(dev);
1954                 if (!tn)
1955                         return NULL;
1956         }
1957
1958         the_obj = yaffs_alloc_empty_obj(dev);
1959         if (!the_obj) {
1960                 if (tn)
1961                         yaffs_free_tnode(dev, tn);
1962                 return NULL;
1963         }
1964
1965         if (the_obj) {
1966                 the_obj->fake = 0;
1967                 the_obj->rename_allowed = 1;
1968                 the_obj->unlink_allowed = 1;
1969                 the_obj->obj_id = number;
1970                 yaffs_hash_obj(the_obj);
1971                 the_obj->variant_type = type;
1972                 yaffs_load_current_time(the_obj, 1, 1);
1973
1974                 switch (type) {
1975                 case YAFFS_OBJECT_TYPE_FILE:
1976                         the_obj->variant.file_variant.file_size = 0;
1977                         the_obj->variant.file_variant.scanned_size = 0;
1978                         the_obj->variant.file_variant.shrink_size = ~0;
1979                                                                 /* max */
1980                         the_obj->variant.file_variant.top_level = 0;
1981                         the_obj->variant.file_variant.top = tn;
1982                         break;
1983                 case YAFFS_OBJECT_TYPE_DIRECTORY:
1984                         INIT_LIST_HEAD(&the_obj->variant.dir_variant.children);
1985                         INIT_LIST_HEAD(&the_obj->variant.dir_variant.dirty);
1986                         break;
1987                 case YAFFS_OBJECT_TYPE_SYMLINK:
1988                 case YAFFS_OBJECT_TYPE_HARDLINK:
1989                 case YAFFS_OBJECT_TYPE_SPECIAL:
1990                         /* No action required */
1991                         break;
1992                 case YAFFS_OBJECT_TYPE_UNKNOWN:
1993                         /* todo this should not happen */
1994                         break;
1995                 }
1996         }
1997
1998         return the_obj;
1999 }
2000
2001 static struct yaffs_obj *yaffs_create_fake_dir(struct yaffs_dev *dev,
2002                                                int number, u32 mode)
2003 {
2004
2005         struct yaffs_obj *obj =
2006             yaffs_new_obj(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);
2007
2008         if (obj) {
2009                 obj->fake = 1;  /* it is fake so it might not use NAND */
2010                 obj->rename_allowed = 0;
2011                 obj->unlink_allowed = 0;
2012                 obj->deleted = 0;
2013                 obj->unlinked = 0;
2014                 obj->yst_mode = mode;
2015                 obj->my_dev = dev;
2016                 obj->hdr_chunk = 0;     /* Not a valid chunk. */
2017         }
2018         return obj;
2019
2020 }
2021
2022
2023 static void yaffs_init_tnodes_and_objs(struct yaffs_dev *dev)
2024 {
2025         int i;
2026
2027         dev->n_obj = 0;
2028         dev->n_tnodes = 0;
2029         yaffs_init_raw_tnodes_and_objs(dev);
2030
2031         for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
2032                 INIT_LIST_HEAD(&dev->obj_bucket[i].list);
2033                 dev->obj_bucket[i].count = 0;
2034         }
2035 }
2036
2037 struct yaffs_obj *yaffs_find_or_create_by_number(struct yaffs_dev *dev,
2038                                                  int number,
2039                                                  enum yaffs_obj_type type)
2040 {
2041         struct yaffs_obj *the_obj = NULL;
2042
2043         if (number > 0)
2044                 the_obj = yaffs_find_by_number(dev, number);
2045
2046         if (!the_obj)
2047                 the_obj = yaffs_new_obj(dev, number, type);
2048
2049         return the_obj;
2050
2051 }
2052
2053 YCHAR *yaffs_clone_str(const YCHAR *str)
2054 {
2055         YCHAR *new_str = NULL;
2056         int len;
2057
2058         if (!str)
2059                 str = _Y("");
2060
2061         len = strnlen(str, YAFFS_MAX_ALIAS_LENGTH);
2062         new_str = kmalloc((len + 1) * sizeof(YCHAR), GFP_NOFS);
2063         if (new_str) {
2064                 strncpy(new_str, str, len);
2065                 new_str[len] = 0;
2066         }
2067         return new_str;
2068
2069 }
2070 /*
2071  *yaffs_update_parent() handles fixing a directories mtime and ctime when a new
2072  * link (ie. name) is created or deleted in the directory.
2073  *
2074  * ie.
2075  *   create dir/a : update dir's mtime/ctime
2076  *   rm dir/a:   update dir's mtime/ctime
2077  *   modify dir/a: don't update dir's mtimme/ctime
2078  *
2079  * This can be handled immediately or defered. Defering helps reduce the number
2080  * of updates when many files in a directory are changed within a brief period.
2081  *
2082  * If the directory updating is defered then yaffs_update_dirty_dirs must be
2083  * called periodically.
2084  */
2085
2086 static void yaffs_update_parent(struct yaffs_obj *obj)
2087 {
2088         struct yaffs_dev *dev;
2089
2090         if (!obj)
2091                 return;
2092         dev = obj->my_dev;
2093         obj->dirty = 1;
2094         yaffs_load_current_time(obj, 0, 1);
2095         if (dev->param.defered_dir_update) {
2096                 struct list_head *link = &obj->variant.dir_variant.dirty;
2097
2098                 if (list_empty(link)) {
2099                         list_add(link, &dev->dirty_dirs);
2100                         yaffs_trace(YAFFS_TRACE_BACKGROUND,
2101                           "Added object %d to dirty directories",
2102                            obj->obj_id);
2103                 }
2104
2105         } else {
2106                 yaffs_update_oh(obj, NULL, 0, 0, 0, NULL);
2107         }
2108 }
2109
2110 void yaffs_update_dirty_dirs(struct yaffs_dev *dev)
2111 {
2112         struct list_head *link;
2113         struct yaffs_obj *obj;
2114         struct yaffs_dir_var *d_s;
2115         union yaffs_obj_var *o_v;
2116
2117         yaffs_trace(YAFFS_TRACE_BACKGROUND, "Update dirty directories");
2118
2119         while (!list_empty(&dev->dirty_dirs)) {
2120                 link = dev->dirty_dirs.next;
2121                 list_del_init(link);
2122
2123                 d_s = list_entry(link, struct yaffs_dir_var, dirty);
2124                 o_v = list_entry(d_s, union yaffs_obj_var, dir_variant);
2125                 obj = list_entry(o_v, struct yaffs_obj, variant);
2126
2127                 yaffs_trace(YAFFS_TRACE_BACKGROUND, "Update directory %d",
2128                         obj->obj_id);
2129
2130                 if (obj->dirty)
2131                         yaffs_update_oh(obj, NULL, 0, 0, 0, NULL);
2132         }
2133 }
2134
2135 /*
2136  * Mknod (create) a new object.
2137  * equiv_obj only has meaning for a hard link;
2138  * alias_str only has meaning for a symlink.
2139  * rdev only has meaning for devices (a subset of special objects)
2140  */
2141
2142 static struct yaffs_obj *yaffs_create_obj(enum yaffs_obj_type type,
2143                                           struct yaffs_obj *parent,
2144                                           const YCHAR *name,
2145                                           u32 mode,
2146                                           u32 uid,
2147                                           u32 gid,
2148                                           struct yaffs_obj *equiv_obj,
2149                                           const YCHAR *alias_str, u32 rdev)
2150 {
2151         struct yaffs_obj *in;
2152         YCHAR *str = NULL;
2153         struct yaffs_dev *dev = parent->my_dev;
2154
2155         /* Check if the entry exists.
2156          * If it does then fail the call since we don't want a dup. */
2157         if (yaffs_find_by_name(parent, name))
2158                 return NULL;
2159
2160         if (type == YAFFS_OBJECT_TYPE_SYMLINK) {
2161                 str = yaffs_clone_str(alias_str);
2162                 if (!str)
2163                         return NULL;
2164         }
2165
2166         in = yaffs_new_obj(dev, -1, type);
2167
2168         if (!in) {
2169                 kfree(str);
2170                 return NULL;
2171         }
2172
2173         if (in) {
2174                 in->hdr_chunk = 0;
2175                 in->valid = 1;
2176                 in->variant_type = type;
2177
2178                 in->yst_mode = mode;
2179
2180                 yaffs_attribs_init(in, gid, uid, rdev);
2181
2182                 in->n_data_chunks = 0;
2183
2184                 yaffs_set_obj_name(in, name);
2185                 in->dirty = 1;
2186
2187                 yaffs_add_obj_to_dir(parent, in);
2188
2189                 in->my_dev = parent->my_dev;
2190
2191                 switch (type) {
2192                 case YAFFS_OBJECT_TYPE_SYMLINK:
2193                         in->variant.symlink_variant.alias = str;
2194                         break;
2195                 case YAFFS_OBJECT_TYPE_HARDLINK:
2196                         in->variant.hardlink_variant.equiv_obj = equiv_obj;
2197                         in->variant.hardlink_variant.equiv_id =
2198                             equiv_obj->obj_id;
2199                         list_add(&in->hard_links, &equiv_obj->hard_links);
2200                         break;
2201                 case YAFFS_OBJECT_TYPE_FILE:
2202                 case YAFFS_OBJECT_TYPE_DIRECTORY:
2203                 case YAFFS_OBJECT_TYPE_SPECIAL:
2204                 case YAFFS_OBJECT_TYPE_UNKNOWN:
2205                         /* do nothing */
2206                         break;
2207                 }
2208
2209                 if (yaffs_update_oh(in, name, 0, 0, 0, NULL) < 0) {
2210                         /* Could not create the object header, fail */
2211                         yaffs_del_obj(in);
2212                         in = NULL;
2213                 }
2214
2215                 yaffs_update_parent(parent);
2216         }
2217
2218         return in;
2219 }
2220
2221 struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent,
2222                                     const YCHAR *name, u32 mode, u32 uid,
2223                                     u32 gid)
2224 {
2225         return yaffs_create_obj(YAFFS_OBJECT_TYPE_FILE, parent, name, mode,
2226                                 uid, gid, NULL, NULL, 0);
2227 }
2228
2229 struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name,
2230                                    u32 mode, u32 uid, u32 gid)
2231 {
2232         return yaffs_create_obj(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name,
2233                                 mode, uid, gid, NULL, NULL, 0);
2234 }
2235
2236 struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent,
2237                                        const YCHAR *name, u32 mode, u32 uid,
2238                                        u32 gid, u32 rdev)
2239 {
2240         return yaffs_create_obj(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode,
2241                                 uid, gid, NULL, NULL, rdev);
2242 }
2243
2244 struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent,
2245                                        const YCHAR *name, u32 mode, u32 uid,
2246                                        u32 gid, const YCHAR *alias)
2247 {
2248         return yaffs_create_obj(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode,
2249                                 uid, gid, NULL, alias, 0);
2250 }
2251
2252 /* yaffs_link_obj returns the object id of the equivalent object.*/
2253 struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR * name,
2254                                  struct yaffs_obj *equiv_obj)
2255 {
2256         /* Get the real object in case we were fed a hard link obj */
2257         equiv_obj = yaffs_get_equivalent_obj(equiv_obj);
2258
2259         if (yaffs_create_obj
2260             (YAFFS_OBJECT_TYPE_HARDLINK, parent, name, 0, 0, 0,
2261              equiv_obj, NULL, 0))
2262                 return equiv_obj;
2263         else
2264                 return NULL;
2265
2266 }
2267
2268
2269
2270 /*---------------------- Block Management and Page Allocation -------------*/
2271
2272 static int yaffs_init_blocks(struct yaffs_dev *dev)
2273 {
2274         int n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
2275
2276         dev->block_info = NULL;
2277         dev->chunk_bits = NULL;
2278         dev->alloc_block = -1;  /* force it to get a new one */
2279
2280         /* If the first allocation strategy fails, thry the alternate one */
2281         dev->block_info =
2282                 kmalloc(n_blocks * sizeof(struct yaffs_block_info), GFP_NOFS);
2283         if (!dev->block_info) {
2284                 dev->block_info =
2285                     vmalloc(n_blocks * sizeof(struct yaffs_block_info));
2286                 dev->block_info_alt = 1;
2287         } else {
2288                 dev->block_info_alt = 0;
2289         }
2290
2291         if (dev->block_info) {
2292                 /* Set up dynamic blockinfo stuff. Round up bytes. */
2293                 dev->chunk_bit_stride = (dev->param.chunks_per_block + 7) / 8;
2294                 dev->chunk_bits =
2295                         kmalloc(dev->chunk_bit_stride * n_blocks, GFP_NOFS);
2296                 if (!dev->chunk_bits) {
2297                         dev->chunk_bits =
2298                             vmalloc(dev->chunk_bit_stride * n_blocks);
2299                         dev->chunk_bits_alt = 1;
2300                 } else {
2301                         dev->chunk_bits_alt = 0;
2302                 }
2303         }
2304
2305         if (dev->block_info && dev->chunk_bits) {
2306                 memset(dev->block_info, 0,
2307                        n_blocks * sizeof(struct yaffs_block_info));
2308                 memset(dev->chunk_bits, 0, dev->chunk_bit_stride * n_blocks);
2309                 return YAFFS_OK;
2310         }
2311
2312         return YAFFS_FAIL;
2313 }
2314
2315 static void yaffs_deinit_blocks(struct yaffs_dev *dev)
2316 {
2317         if (dev->block_info_alt && dev->block_info)
2318                 vfree(dev->block_info);
2319         else
2320                 kfree(dev->block_info);
2321
2322         dev->block_info_alt = 0;
2323
2324         dev->block_info = NULL;
2325
2326         if (dev->chunk_bits_alt && dev->chunk_bits)
2327                 vfree(dev->chunk_bits);
2328         else
2329                 kfree(dev->chunk_bits);
2330         dev->chunk_bits_alt = 0;
2331         dev->chunk_bits = NULL;
2332 }
2333
2334 void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no)
2335 {
2336         struct yaffs_block_info *bi = yaffs_get_block_info(dev, block_no);
2337         int erased_ok = 0;
2338
2339         /* If the block is still healthy erase it and mark as clean.
2340          * If the block has had a data failure, then retire it.
2341          */
2342
2343         yaffs_trace(YAFFS_TRACE_GC | YAFFS_TRACE_ERASE,
2344                 "yaffs_block_became_dirty block %d state %d %s",
2345                 block_no, bi->block_state,
2346                 (bi->needs_retiring) ? "needs retiring" : "");
2347
2348         yaffs2_clear_oldest_dirty_seq(dev, bi);
2349
2350         bi->block_state = YAFFS_BLOCK_STATE_DIRTY;
2351
2352         /* If this is the block being garbage collected then stop gc'ing */
2353         if (block_no == dev->gc_block)
2354                 dev->gc_block = 0;
2355
2356         /* If this block is currently the best candidate for gc
2357          * then drop as a candidate */
2358         if (block_no == dev->gc_dirtiest) {
2359                 dev->gc_dirtiest = 0;
2360                 dev->gc_pages_in_use = 0;
2361         }
2362
2363         if (!bi->needs_retiring) {
2364                 yaffs2_checkpt_invalidate(dev);
2365                 erased_ok = yaffs_erase_block(dev, block_no);
2366                 if (!erased_ok) {
2367                         dev->n_erase_failures++;
2368                         yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
2369                           "**>> Erasure failed %d", block_no);
2370                 }
2371         }
2372
2373         if (erased_ok &&
2374             ((yaffs_trace_mask & YAFFS_TRACE_ERASE)
2375              || !yaffs_skip_verification(dev))) {
2376                 int i;
2377                 for (i = 0; i < dev->param.chunks_per_block; i++) {
2378                         if (!yaffs_check_chunk_erased
2379                             (dev, block_no * dev->param.chunks_per_block + i)) {
2380                                 yaffs_trace(YAFFS_TRACE_ERROR,
2381                                         ">>Block %d erasure supposedly OK, but chunk %d not erased",
2382                                         block_no, i);
2383                         }
2384                 }
2385         }
2386
2387         if (erased_ok) {
2388                 /* Clean it up... */
2389                 bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
2390                 bi->seq_number = 0;
2391                 dev->n_erased_blocks++;
2392                 bi->pages_in_use = 0;
2393                 bi->soft_del_pages = 0;
2394                 bi->has_shrink_hdr = 0;
2395                 bi->skip_erased_check = 1;      /* Clean, so no need to check */
2396                 bi->gc_prioritise = 0;
2397                 yaffs_clear_chunk_bits(dev, block_no);
2398
2399                 yaffs_trace(YAFFS_TRACE_ERASE,
2400                         "Erased block %d", block_no);
2401         } else {
2402                 /* We lost a block of free space */
2403                 dev->n_free_chunks -= dev->param.chunks_per_block;
2404                 yaffs_retire_block(dev, block_no);
2405                 yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
2406                         "**>> Block %d retired", block_no);
2407         }
2408 }
2409
2410 static int yaffs_gc_process_chunk(struct yaffs_dev *dev,
2411                                 struct yaffs_block_info *bi,
2412                                 int old_chunk, u8 *buffer)
2413 {
2414         int new_chunk;
2415         int mark_flash = 1;
2416         struct yaffs_ext_tags tags;
2417         struct yaffs_obj *object;
2418         int matching_chunk;
2419         int ret_val = YAFFS_OK;
2420
2421         yaffs_init_tags(&tags);
2422         yaffs_rd_chunk_tags_nand(dev, old_chunk,
2423                                  buffer, &tags);
2424         object = yaffs_find_by_number(dev, tags.obj_id);
2425
2426         yaffs_trace(YAFFS_TRACE_GC_DETAIL,
2427                 "Collecting chunk in block %d, %d %d %d ",
2428                 dev->gc_chunk, tags.obj_id,
2429                 tags.chunk_id, tags.n_bytes);
2430
2431         if (object && !yaffs_skip_verification(dev)) {
2432                 if (tags.chunk_id == 0)
2433                         matching_chunk =
2434                             object->hdr_chunk;
2435                 else if (object->soft_del)
2436                         /* Defeat the test */
2437                         matching_chunk = old_chunk;
2438                 else
2439                         matching_chunk =
2440                             yaffs_find_chunk_in_file
2441                             (object, tags.chunk_id,
2442                              NULL);
2443
2444                 if (old_chunk != matching_chunk)
2445                         yaffs_trace(YAFFS_TRACE_ERROR,
2446                                 "gc: page in gc mismatch: %d %d %d %d",
2447                                 old_chunk,
2448                                 matching_chunk,
2449                                 tags.obj_id,
2450                                 tags.chunk_id);
2451         }
2452
2453         if (!object) {
2454                 yaffs_trace(YAFFS_TRACE_ERROR,
2455                         "page %d in gc has no object: %d %d %d ",
2456                         old_chunk,
2457                         tags.obj_id, tags.chunk_id,
2458                         tags.n_bytes);
2459         }
2460
2461         if (object &&
2462             object->deleted &&
2463             object->soft_del && tags.chunk_id != 0) {
2464                 /* Data chunk in a soft deleted file,
2465                  * throw it away.
2466                  * It's a soft deleted data chunk,
2467                  * No need to copy this, just forget
2468                  * about it and fix up the object.
2469                  */
2470
2471                 /* Free chunks already includes
2472                  * softdeleted chunks, how ever this
2473                  * chunk is going to soon be really
2474                  * deleted which will increment free
2475                  * chunks. We have to decrement free
2476                  * chunks so this works out properly.
2477                  */
2478                 dev->n_free_chunks--;
2479                 bi->soft_del_pages--;
2480
2481                 object->n_data_chunks--;
2482                 if (object->n_data_chunks <= 0) {
2483                         /* remeber to clean up obj */
2484                         dev->gc_cleanup_list[dev->n_clean_ups] = tags.obj_id;
2485                         dev->n_clean_ups++;
2486                 }
2487                 mark_flash = 0;
2488         } else if (object) {
2489                 /* It's either a data chunk in a live
2490                  * file or an ObjectHeader, so we're
2491                  * interested in it.
2492                  * NB Need to keep the ObjectHeaders of
2493                  * deleted files until the whole file
2494                  * has been deleted off
2495                  */
2496                 tags.serial_number++;
2497                 dev->n_gc_copies++;
2498
2499                 if (tags.chunk_id == 0) {
2500                         /* It is an object Id,
2501                          * We need to nuke the
2502                          * shrinkheader flags since its
2503                          * work is done.
2504                          * Also need to clean up
2505                          * shadowing.
2506                          */
2507                         struct yaffs_obj_hdr *oh;
2508                         oh = (struct yaffs_obj_hdr *) buffer;
2509
2510                         oh->is_shrink = 0;
2511                         tags.extra_is_shrink = 0;
2512                         oh->shadows_obj = 0;
2513                         oh->inband_shadowed_obj_id = 0;
2514                         tags.extra_shadows = 0;
2515
2516                         /* Update file size */
2517                         if (object->variant_type == YAFFS_OBJECT_TYPE_FILE) {
2518                                 oh->file_size =
2519                                     object->variant.file_variant.file_size;
2520                                 tags.extra_length = oh->file_size;
2521                         }
2522
2523                         yaffs_verify_oh(object, oh, &tags, 1);
2524                         new_chunk =
2525                             yaffs_write_new_chunk(dev, (u8 *) oh, &tags, 1);
2526                 } else {
2527                         new_chunk =
2528                             yaffs_write_new_chunk(dev, buffer, &tags, 1);
2529                 }
2530
2531                 if (new_chunk < 0) {
2532                         ret_val = YAFFS_FAIL;
2533                 } else {
2534
2535                         /* Now fix up the Tnodes etc. */
2536
2537                         if (tags.chunk_id == 0) {
2538                                 /* It's a header */
2539                                 object->hdr_chunk = new_chunk;
2540                                 object->serial = tags.serial_number;
2541                         } else {
2542                                 /* It's a data chunk */
2543                                 yaffs_put_chunk_in_file(object, tags.chunk_id,
2544                                                         new_chunk, 0);
2545                         }
2546                 }
2547         }
2548         if (ret_val == YAFFS_OK)
2549                 yaffs_chunk_del(dev, old_chunk, mark_flash, __LINE__);
2550         return ret_val;
2551 }
2552
2553 static int yaffs_gc_block(struct yaffs_dev *dev, int block, int whole_block)
2554 {
2555         int old_chunk;
2556         int ret_val = YAFFS_OK;
2557         int i;
2558         int is_checkpt_block;
2559         int max_copies;
2560         int chunks_before = yaffs_get_erased_chunks(dev);
2561         int chunks_after;
2562         struct yaffs_block_info *bi = yaffs_get_block_info(dev, block);
2563
2564         is_checkpt_block = (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT);
2565
2566         yaffs_trace(YAFFS_TRACE_TRACING,
2567                 "Collecting block %d, in use %d, shrink %d, whole_block %d",
2568                 block, bi->pages_in_use, bi->has_shrink_hdr,
2569                 whole_block);
2570
2571         /*yaffs_verify_free_chunks(dev); */
2572
2573         if (bi->block_state == YAFFS_BLOCK_STATE_FULL)
2574                 bi->block_state = YAFFS_BLOCK_STATE_COLLECTING;
2575
2576         bi->has_shrink_hdr = 0; /* clear the flag so that the block can erase */
2577
2578         dev->gc_disable = 1;
2579
2580         if (is_checkpt_block || !yaffs_still_some_chunks(dev, block)) {
2581                 yaffs_trace(YAFFS_TRACE_TRACING,
2582                         "Collecting block %d that has no chunks in use",
2583                         block);
2584                 yaffs_block_became_dirty(dev, block);
2585         } else {
2586
2587                 u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
2588
2589                 yaffs_verify_blk(dev, bi, block);
2590
2591                 max_copies = (whole_block) ? dev->param.chunks_per_block : 5;
2592                 old_chunk = block * dev->param.chunks_per_block + dev->gc_chunk;
2593
2594                 for (/* init already done */ ;
2595                      ret_val == YAFFS_OK &&
2596                      dev->gc_chunk < dev->param.chunks_per_block &&
2597                      (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) &&
2598                      max_copies > 0;
2599                      dev->gc_chunk++, old_chunk++) {
2600                         if (yaffs_check_chunk_bit(dev, block, dev->gc_chunk)) {
2601                                 /* Page is in use and might need to be copied */
2602                                 max_copies--;
2603                                 ret_val = yaffs_gc_process_chunk(dev, bi,
2604                                                         old_chunk, buffer);
2605                         }
2606                 }
2607                 yaffs_release_temp_buffer(dev, buffer, __LINE__);
2608         }
2609
2610         yaffs_verify_collected_blk(dev, bi, block);
2611
2612         if (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) {
2613                 /*
2614                  * The gc did not complete. Set block state back to FULL
2615                  * because checkpointing does not restore gc.
2616                  */
2617                 bi->block_state = YAFFS_BLOCK_STATE_FULL;
2618         } else {
2619                 /* The gc completed. */
2620                 /* Do any required cleanups */
2621                 for (i = 0; i < dev->n_clean_ups; i++) {
2622                         /* Time to delete the file too */
2623                         struct yaffs_obj *object =
2624                             yaffs_find_by_number(dev, dev->gc_cleanup_list[i]);
2625                         if (object) {
2626                                 yaffs_free_tnode(dev,
2627                                           object->variant.file_variant.top);
2628                                 object->variant.file_variant.top = NULL;
2629                                 yaffs_trace(YAFFS_TRACE_GC,
2630                                         "yaffs: About to finally delete object %d",
2631                                         object->obj_id);
2632                                 yaffs_generic_obj_del(object);
2633                                 object->my_dev->n_deleted_files--;
2634                         }
2635
2636                 }
2637                 chunks_after = yaffs_get_erased_chunks(dev);
2638                 if (chunks_before >= chunks_after)
2639                         yaffs_trace(YAFFS_TRACE_GC,
2640                                 "gc did not increase free chunks before %d after %d",
2641                                 chunks_before, chunks_after);
2642                 dev->gc_block = 0;
2643                 dev->gc_chunk = 0;
2644                 dev->n_clean_ups = 0;
2645         }
2646
2647         dev->gc_disable = 0;
2648
2649         return ret_val;
2650 }
2651
2652 /*
2653  * find_gc_block() selects the dirtiest block (or close enough)
2654  * for garbage collection.
2655  */
2656
2657 static unsigned yaffs_find_gc_block(struct yaffs_dev *dev,
2658                                     int aggressive, int background)
2659 {
2660         int i;
2661         int iterations;
2662         unsigned selected = 0;
2663         int prioritised = 0;
2664         int prioritised_exist = 0;
2665         struct yaffs_block_info *bi;
2666         int threshold;
2667
2668         /* First let's see if we need to grab a prioritised block */
2669         if (dev->has_pending_prioritised_gc && !aggressive) {
2670                 dev->gc_dirtiest = 0;
2671                 bi = dev->block_info;
2672                 for (i = dev->internal_start_block;
2673                      i <= dev->internal_end_block && !selected; i++) {
2674
2675                         if (bi->gc_prioritise) {
2676                                 prioritised_exist = 1;
2677                                 if (bi->block_state == YAFFS_BLOCK_STATE_FULL &&
2678                                     yaffs_block_ok_for_gc(dev, bi)) {
2679                                         selected = i;
2680                                         prioritised = 1;
2681                                 }
2682                         }
2683                         bi++;
2684                 }
2685
2686                 /*
2687                  * If there is a prioritised block and none was selected then
2688                  * this happened because there is at least one old dirty block
2689                  * gumming up the works. Let's gc the oldest dirty block.
2690                  */
2691
2692                 if (prioritised_exist &&
2693                     !selected && dev->oldest_dirty_block > 0)
2694                         selected = dev->oldest_dirty_block;
2695
2696                 if (!prioritised_exist) /* None found, so we can clear this */
2697                         dev->has_pending_prioritised_gc = 0;
2698         }
2699
2700         /* If we're doing aggressive GC then we are happy to take a less-dirty
2701          * block, and search harder.
2702          * else (leasurely gc), then we only bother to do this if the
2703          * block has only a few pages in use.
2704          */
2705
2706         if (!selected) {
2707                 int pages_used;
2708                 int n_blocks =
2709                     dev->internal_end_block - dev->internal_start_block + 1;
2710                 if (aggressive) {
2711                         threshold = dev->param.chunks_per_block;
2712                         iterations = n_blocks;
2713                 } else {
2714                         int max_threshold;
2715
2716                         if (background)
2717                                 max_threshold = dev->param.chunks_per_block / 2;
2718                         else
2719                                 max_threshold = dev->param.chunks_per_block / 8;
2720
2721                         if (max_threshold < YAFFS_GC_PASSIVE_THRESHOLD)
2722                                 max_threshold = YAFFS_GC_PASSIVE_THRESHOLD;
2723
2724                         threshold = background ? (dev->gc_not_done + 2) * 2 : 0;
2725                         if (threshold < YAFFS_GC_PASSIVE_THRESHOLD)
2726                                 threshold = YAFFS_GC_PASSIVE_THRESHOLD;
2727                         if (threshold > max_threshold)
2728                                 threshold = max_threshold;
2729
2730                         iterations = n_blocks / 16 + 1;
2731                         if (iterations > 100)
2732                                 iterations = 100;
2733                 }
2734
2735                 for (i = 0;
2736                      i < iterations &&
2737                      (dev->gc_dirtiest < 1 ||
2738                       dev->gc_pages_in_use > YAFFS_GC_GOOD_ENOUGH);
2739                      i++) {
2740                         dev->gc_block_finder++;
2741                         if (dev->gc_block_finder < dev->internal_start_block ||
2742                             dev->gc_block_finder > dev->internal_end_block)
2743                                 dev->gc_block_finder =
2744                                     dev->internal_start_block;
2745
2746                         bi = yaffs_get_block_info(dev, dev->gc_block_finder);
2747
2748                         pages_used = bi->pages_in_use - bi->soft_del_pages;
2749
2750                         if (bi->block_state == YAFFS_BLOCK_STATE_FULL &&
2751                             pages_used < dev->param.chunks_per_block &&
2752                             (dev->gc_dirtiest < 1 ||
2753                              pages_used < dev->gc_pages_in_use) &&
2754                             yaffs_block_ok_for_gc(dev, bi)) {
2755                                 dev->gc_dirtiest = dev->gc_block_finder;
2756                                 dev->gc_pages_in_use = pages_used;
2757                         }
2758                 }
2759
2760                 if (dev->gc_dirtiest > 0 && dev->gc_pages_in_use <= threshold)
2761                         selected = dev->gc_dirtiest;
2762         }
2763
2764         /*
2765          * If nothing has been selected for a while, try the oldest dirty
2766          * because that's gumming up the works.
2767          */
2768
2769         if (!selected && dev->param.is_yaffs2 &&
2770             dev->gc_not_done >= (background ? 10 : 20)) {
2771                 yaffs2_find_oldest_dirty_seq(dev);
2772                 if (dev->oldest_dirty_block > 0) {
2773                         selected = dev->oldest_dirty_block;
2774                         dev->gc_dirtiest = selected;
2775                         dev->oldest_dirty_gc_count++;
2776                         bi = yaffs_get_block_info(dev, selected);
2777                         dev->gc_pages_in_use =
2778                             bi->pages_in_use - bi->soft_del_pages;
2779                 } else {
2780                         dev->gc_not_done = 0;
2781                 }
2782         }
2783
2784         if (selected) {
2785                 yaffs_trace(YAFFS_TRACE_GC,
2786                         "GC Selected block %d with %d free, prioritised:%d",
2787                         selected,
2788                         dev->param.chunks_per_block - dev->gc_pages_in_use,
2789                         prioritised);
2790
2791                 dev->n_gc_blocks++;
2792                 if (background)
2793                         dev->bg_gcs++;
2794
2795                 dev->gc_dirtiest = 0;
2796                 dev->gc_pages_in_use = 0;
2797                 dev->gc_not_done = 0;
2798                 if (dev->refresh_skip > 0)
2799                         dev->refresh_skip--;
2800         } else {
2801                 dev->gc_not_done++;
2802                 yaffs_trace(YAFFS_TRACE_GC,
2803                         "GC none: finder %d skip %d threshold %d dirtiest %d using %d oldest %d%s",
2804                         dev->gc_block_finder, dev->gc_not_done, threshold,
2805                         dev->gc_dirtiest, dev->gc_pages_in_use,
2806                         dev->oldest_dirty_block, background ? " bg" : "");
2807         }
2808
2809         return selected;
2810 }
2811
2812 /* New garbage collector
2813  * If we're very low on erased blocks then we do aggressive garbage collection
2814  * otherwise we do "leasurely" garbage collection.
2815  * Aggressive gc looks further (whole array) and will accept less dirty blocks.
2816  * Passive gc only inspects smaller areas and only accepts more dirty blocks.
2817  *
2818  * The idea is to help clear out space in a more spread-out manner.
2819  * Dunno if it really does anything useful.
2820  */
2821 static int yaffs_check_gc(struct yaffs_dev *dev, int background)
2822 {
2823         int aggressive = 0;
2824         int gc_ok = YAFFS_OK;
2825         int max_tries = 0;
2826         int min_erased;
2827         int erased_chunks;
2828         int checkpt_block_adjust;
2829
2830         if (dev->param.gc_control && (dev->param.gc_control(dev) & 1) == 0)
2831                 return YAFFS_OK;
2832
2833         if (dev->gc_disable) {
2834                 /* Bail out so we don't get recursive gc */
2835                 return YAFFS_OK;
2836         }
2837
2838         /* This loop should pass the first time.
2839          * Only loops here if the collection does not increase space.
2840          */
2841
2842         do {
2843                 max_tries++;
2844
2845                 checkpt_block_adjust = yaffs_calc_checkpt_blocks_required(dev);
2846
2847                 min_erased =
2848                     dev->param.n_reserved_blocks + checkpt_block_adjust + 1;
2849                 erased_chunks =
2850                     dev->n_erased_blocks * dev->param.chunks_per_block;
2851
2852                 /* If we need a block soon then do aggressive gc. */
2853                 if (dev->n_erased_blocks < min_erased)
2854                         aggressive = 1;
2855                 else {
2856                         if (!background
2857                             && erased_chunks > (dev->n_free_chunks / 4))
2858                                 break;
2859
2860                         if (dev->gc_skip > 20)
2861                                 dev->gc_skip = 20;
2862                         if (erased_chunks < dev->n_free_chunks / 2 ||
2863                             dev->gc_skip < 1 || background)
2864                                 aggressive = 0;
2865                         else {
2866                                 dev->gc_skip--;
2867                                 break;
2868                         }
2869                 }
2870
2871                 dev->gc_skip = 5;
2872
2873                 /* If we don't already have a block being gc'd then see if we
2874                  * should start another */
2875
2876                 if (dev->gc_block < 1 && !aggressive) {
2877                         dev->gc_block = yaffs2_find_refresh_block(dev);
2878                         dev->gc_chunk = 0;
2879                         dev->n_clean_ups = 0;
2880                 }
2881                 if (dev->gc_block < 1) {
2882                         dev->gc_block =
2883                             yaffs_find_gc_block(dev, aggressive, background);
2884                         dev->gc_chunk = 0;
2885                         dev->n_clean_ups = 0;
2886                 }
2887
2888                 if (dev->gc_block > 0) {
2889                         dev->all_gcs++;
2890                         if (!aggressive)
2891                                 dev->passive_gc_count++;
2892
2893                         yaffs_trace(YAFFS_TRACE_GC,
2894                                 "yaffs: GC n_erased_blocks %d aggressive %d",
2895                                 dev->n_erased_blocks, aggressive);
2896
2897                         gc_ok = yaffs_gc_block(dev, dev->gc_block, aggressive);
2898                 }
2899
2900                 if (dev->n_erased_blocks < (dev->param.n_reserved_blocks)
2901                     && dev->gc_block > 0) {
2902                         yaffs_trace(YAFFS_TRACE_GC,
2903                                 "yaffs: GC !!!no reclaim!!! n_erased_blocks %d after try %d block %d",
2904                                 dev->n_erased_blocks, max_tries,
2905                                 dev->gc_block);
2906                 }
2907         } while ((dev->n_erased_blocks < dev->param.n_reserved_blocks) &&
2908                  (dev->gc_block > 0) && (max_tries < 2));
2909
2910         return aggressive ? gc_ok : YAFFS_OK;
2911 }
2912
2913 /*
2914  * yaffs_bg_gc()
2915  * Garbage collects. Intended to be called from a background thread.
2916  * Returns non-zero if at least half the free chunks are erased.
2917  */
2918 int yaffs_bg_gc(struct yaffs_dev *dev, unsigned urgency)
2919 {
2920         int erased_chunks = dev->n_erased_blocks * dev->param.chunks_per_block;
2921
2922         yaffs_trace(YAFFS_TRACE_BACKGROUND, "Background gc %u", urgency);
2923
2924         yaffs_check_gc(dev, 1);
2925         return erased_chunks > dev->n_free_chunks / 2;
2926 }
2927
2928 /*-------------------- Data file manipulation -----------------*/
2929
2930 static int yaffs_rd_data_obj(struct yaffs_obj *in, int inode_chunk, u8 * buffer)
2931 {
2932         int nand_chunk = yaffs_find_chunk_in_file(in, inode_chunk, NULL);
2933
2934         if (nand_chunk >= 0)
2935                 return yaffs_rd_chunk_tags_nand(in->my_dev, nand_chunk,
2936                                                 buffer, NULL);
2937         else {
2938                 yaffs_trace(YAFFS_TRACE_NANDACCESS,
2939                         "Chunk %d not found zero instead",
2940                         nand_chunk);
2941                 /* get sane (zero) data if you read a hole */
2942                 memset(buffer, 0, in->my_dev->data_bytes_per_chunk);
2943                 return 0;
2944         }
2945
2946 }
2947
2948 void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash,
2949                      int lyn)
2950 {
2951         int block;
2952         int page;
2953         struct yaffs_ext_tags tags;
2954         struct yaffs_block_info *bi;
2955
2956         if (chunk_id <= 0)
2957                 return;
2958
2959         dev->n_deletions++;
2960         block = chunk_id / dev->param.chunks_per_block;
2961         page = chunk_id % dev->param.chunks_per_block;
2962
2963         if (!yaffs_check_chunk_bit(dev, block, page))
2964                 yaffs_trace(YAFFS_TRACE_VERIFY,
2965                         "Deleting invalid chunk %d", chunk_id);
2966
2967         bi = yaffs_get_block_info(dev, block);
2968
2969         yaffs2_update_oldest_dirty_seq(dev, block, bi);
2970
2971         yaffs_trace(YAFFS_TRACE_DELETION,
2972                 "line %d delete of chunk %d",
2973                 lyn, chunk_id);
2974
2975         if (!dev->param.is_yaffs2 && mark_flash &&
2976             bi->block_state != YAFFS_BLOCK_STATE_COLLECTING) {
2977
2978                 yaffs_init_tags(&tags);
2979                 tags.is_deleted = 1;
2980                 yaffs_wr_chunk_tags_nand(dev, chunk_id, NULL, &tags);
2981                 yaffs_handle_chunk_update(dev, chunk_id, &tags);
2982         } else {
2983                 dev->n_unmarked_deletions++;
2984         }
2985
2986         /* Pull out of the management area.
2987          * If the whole block became dirty, this will kick off an erasure.
2988          */
2989         if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING ||
2990             bi->block_state == YAFFS_BLOCK_STATE_FULL ||
2991             bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
2992             bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) {
2993                 dev->n_free_chunks++;
2994                 yaffs_clear_chunk_bit(dev, block, page);
2995                 bi->pages_in_use--;
2996
2997                 if (bi->pages_in_use == 0 &&
2998                     !bi->has_shrink_hdr &&
2999                     bi->block_state != YAFFS_BLOCK_STATE_ALLOCATING &&
3000                     bi->block_state != YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
3001                         yaffs_block_became_dirty(dev, block);
3002                 }
3003         }
3004 }
3005
3006 static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
3007                              const u8 *buffer, int n_bytes, int use_reserve)
3008 {
3009         /* Find old chunk Need to do this to get serial number
3010          * Write new one and patch into tree.
3011          * Invalidate old tags.
3012          */
3013
3014         int prev_chunk_id;
3015         struct yaffs_ext_tags prev_tags;
3016         int new_chunk_id;
3017         struct yaffs_ext_tags new_tags;
3018         struct yaffs_dev *dev = in->my_dev;
3019
3020         yaffs_check_gc(dev, 0);
3021
3022         /* Get the previous chunk at this location in the file if it exists.
3023          * If it does not exist then put a zero into the tree. This creates
3024          * the tnode now, rather than later when it is harder to clean up.
3025          */
3026         prev_chunk_id = yaffs_find_chunk_in_file(in, inode_chunk, &prev_tags);
3027         if (prev_chunk_id < 1 &&
3028             !yaffs_put_chunk_in_file(in, inode_chunk, 0, 0))
3029                 return 0;
3030
3031         /* Set up new tags */
3032         yaffs_init_tags(&new_tags);
3033
3034         new_tags.chunk_id = inode_chunk;
3035         new_tags.obj_id = in->obj_id;
3036         new_tags.serial_number =
3037             (prev_chunk_id > 0) ? prev_tags.serial_number + 1 : 1;
3038         new_tags.n_bytes = n_bytes;
3039
3040         if (n_bytes < 1 || n_bytes > dev->param.total_bytes_per_chunk) {
3041                 yaffs_trace(YAFFS_TRACE_ERROR,
3042                   "Writing %d bytes to chunk!!!!!!!!!",
3043                    n_bytes);
3044                 BUG();
3045         }
3046
3047         new_chunk_id =
3048             yaffs_write_new_chunk(dev, buffer, &new_tags, use_reserve);
3049
3050         if (new_chunk_id > 0) {
3051                 yaffs_put_chunk_in_file(in, inode_chunk, new_chunk_id, 0);
3052
3053                 if (prev_chunk_id > 0)
3054                         yaffs_chunk_del(dev, prev_chunk_id, 1, __LINE__);
3055
3056                 yaffs_verify_file_sane(in);
3057         }
3058         return new_chunk_id;
3059
3060 }
3061
3062
3063
3064 static int yaffs_do_xattrib_mod(struct yaffs_obj *obj, int set,
3065                                 const YCHAR *name, const void *value, int size,
3066                                 int flags)
3067 {
3068         struct yaffs_xattr_mod xmod;
3069         int result;
3070
3071         xmod.set = set;
3072         xmod.name = name;
3073         xmod.data = value;
3074         xmod.size = size;
3075         xmod.flags = flags;
3076         xmod.result = -ENOSPC;
3077
3078         result = yaffs_update_oh(obj, NULL, 0, 0, 0, &xmod);
3079
3080         if (result > 0)
3081                 return xmod.result;
3082         else
3083                 return -ENOSPC;
3084 }
3085
3086 static int yaffs_apply_xattrib_mod(struct yaffs_obj *obj, char *buffer,
3087                                    struct yaffs_xattr_mod *xmod)
3088 {
3089         int retval = 0;
3090         int x_offs = sizeof(struct yaffs_obj_hdr);
3091         struct yaffs_dev *dev = obj->my_dev;
3092         int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr);
3093         char *x_buffer = buffer + x_offs;
3094
3095         if (xmod->set)
3096                 retval =
3097                     nval_set(x_buffer, x_size, xmod->name, xmod->data,
3098                              xmod->size, xmod->flags);
3099         else
3100                 retval = nval_del(x_buffer, x_size, xmod->name);
3101
3102         obj->has_xattr = nval_hasvalues(x_buffer, x_size);
3103         obj->xattr_known = 1;
3104         xmod->result = retval;
3105
3106         return retval;
3107 }
3108
3109 static int yaffs_do_xattrib_fetch(struct yaffs_obj *obj, const YCHAR *name,
3110                                   void *value, int size)
3111 {
3112         char *buffer = NULL;
3113         int result;
3114         struct yaffs_ext_tags tags;
3115         struct yaffs_dev *dev = obj->my_dev;
3116         int x_offs = sizeof(struct yaffs_obj_hdr);
3117         int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr);
3118         char *x_buffer;
3119         int retval = 0;
3120
3121         if (obj->hdr_chunk < 1)
3122                 return -ENODATA;
3123
3124         /* If we know that the object has no xattribs then don't do all the
3125          * reading and parsing.
3126          */
3127         if (obj->xattr_known && !obj->has_xattr) {
3128                 if (name)
3129                         return -ENODATA;
3130                 else
3131                         return 0;
3132         }
3133
3134         buffer = (char *)yaffs_get_temp_buffer(dev, __LINE__);
3135         if (!buffer)
3136                 return -ENOMEM;
3137
3138         result =
3139             yaffs_rd_chunk_tags_nand(dev, obj->hdr_chunk, (u8 *) buffer, &tags);
3140
3141         if (result != YAFFS_OK)
3142                 retval = -ENOENT;
3143         else {
3144                 x_buffer = buffer + x_offs;
3145
3146                 if (!obj->xattr_known) {
3147                         obj->has_xattr = nval_hasvalues(x_buffer, x_size);
3148                         obj->xattr_known = 1;
3149                 }
3150
3151                 if (name)
3152                         retval = nval_get(x_buffer, x_size, name, value, size);
3153                 else
3154                         retval = nval_list(x_buffer, x_size, value, size);
3155         }
3156         yaffs_release_temp_buffer(dev, (u8 *) buffer, __LINE__);
3157         return retval;
3158 }
3159
3160 int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR * name,
3161                       const void *value, int size, int flags)
3162 {
3163         return yaffs_do_xattrib_mod(obj, 1, name, value, size, flags);
3164 }
3165
3166 int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR * name)
3167 {
3168         return yaffs_do_xattrib_mod(obj, 0, name, NULL, 0, 0);
3169 }
3170
3171 int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR * name, void *value,
3172                       int size)
3173 {
3174         return yaffs_do_xattrib_fetch(obj, name, value, size);
3175 }
3176
3177 int yaffs_list_xattrib(struct yaffs_obj *obj, char *buffer, int size)
3178 {
3179         return yaffs_do_xattrib_fetch(obj, NULL, buffer, size);
3180 }
3181
3182 static void yaffs_check_obj_details_loaded(struct yaffs_obj *in)
3183 {
3184         u8 *chunk_data;
3185         struct yaffs_obj_hdr *oh;
3186         struct yaffs_dev *dev;
3187         struct yaffs_ext_tags tags;
3188         int result;
3189         int alloc_failed = 0;
3190
3191         if (!in)
3192                 return;
3193
3194         dev = in->my_dev;
3195
3196         if (in->lazy_loaded && in->hdr_chunk > 0) {
3197                 in->lazy_loaded = 0;
3198                 chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
3199
3200                 result =
3201                     yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, chunk_data,
3202                                              &tags);
3203                 oh = (struct yaffs_obj_hdr *)chunk_data;
3204
3205                 in->yst_mode = oh->yst_mode;
3206                 yaffs_load_attribs(in, oh);
3207                 yaffs_set_obj_name_from_oh(in, oh);
3208
3209                 if (in->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
3210                         in->variant.symlink_variant.alias =
3211                             yaffs_clone_str(oh->alias);
3212                         if (!in->variant.symlink_variant.alias)
3213                                 alloc_failed = 1;       /* Not returned */
3214                 }
3215
3216                 yaffs_release_temp_buffer(dev, chunk_data, __LINE__);
3217         }
3218 }
3219
3220 static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name,
3221                                     const YCHAR *oh_name, int buff_size)
3222 {
3223 #ifdef CONFIG_YAFFS_AUTO_UNICODE
3224         if (dev->param.auto_unicode) {
3225                 if (*oh_name) {
3226                         /* It is an ASCII name, do an ASCII to
3227                          * unicode conversion */
3228                         const char *ascii_oh_name = (const char *)oh_name;
3229                         int n = buff_size - 1;
3230                         while (n > 0 && *ascii_oh_name) {
3231                                 *name = *ascii_oh_name;
3232                                 name++;
3233                                 ascii_oh_name++;
3234                                 n--;
3235                         }
3236                 } else {
3237                         strncpy(name, oh_name + 1, buff_size - 1);
3238                 }
3239         } else {
3240 #else
3241         {
3242 #endif
3243                 strncpy(name, oh_name, buff_size - 1);
3244         }
3245 }
3246
3247 static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name,
3248                                     const YCHAR *name)
3249 {
3250 #ifdef CONFIG_YAFFS_AUTO_UNICODE
3251
3252         int is_ascii;
3253         YCHAR *w;
3254
3255         if (dev->param.auto_unicode) {
3256
3257                 is_ascii = 1;
3258                 w = name;
3259
3260                 /* Figure out if the name will fit in ascii character set */
3261                 while (is_ascii && *w) {
3262                         if ((*w) & 0xff00)
3263                                 is_ascii = 0;
3264                         w++;
3265                 }
3266
3267                 if (is_ascii) {
3268                         /* It is an ASCII name, so convert unicode to ascii */
3269                         char *ascii_oh_name = (char *)oh_name;
3270                         int n = YAFFS_MAX_NAME_LENGTH - 1;
3271                         while (n > 0 && *name) {
3272                                 *ascii_oh_name = *name;
3273                                 name++;
3274                                 ascii_oh_name++;
3275                                 n--;
3276                         }
3277                 } else {
3278                         /* Unicode name, so save starting at the second YCHAR */
3279                         *oh_name = 0;
3280                         strncpy(oh_name + 1, name,
3281                                         YAFFS_MAX_NAME_LENGTH - 2);
3282                 }
3283         } else {
3284 #else
3285         {
3286 #endif
3287                 strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1);
3288         }
3289 }
3290
3291 /* UpdateObjectHeader updates the header on NAND for an object.
3292  * If name is not NULL, then that new name is used.
3293  */
3294 int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force,
3295                     int is_shrink, int shadows, struct yaffs_xattr_mod *xmod)
3296 {
3297
3298         struct yaffs_block_info *bi;
3299         struct yaffs_dev *dev = in->my_dev;
3300         int prev_chunk_id;
3301         int ret_val = 0;
3302         int result = 0;
3303         int new_chunk_id;
3304         struct yaffs_ext_tags new_tags;
3305         struct yaffs_ext_tags old_tags;
3306         const YCHAR *alias = NULL;
3307         u8 *buffer = NULL;
3308         YCHAR old_name[YAFFS_MAX_NAME_LENGTH + 1];
3309         struct yaffs_obj_hdr *oh = NULL;
3310
3311         strcpy(old_name, _Y("silly old name"));
3312
3313         if (!in->fake || in == dev->root_dir ||
3314             force || xmod) {
3315
3316                 yaffs_check_gc(dev, 0);
3317                 yaffs_check_obj_details_loaded(in);
3318
3319                 buffer = yaffs_get_temp_buffer(in->my_dev, __LINE__);
3320                 oh = (struct yaffs_obj_hdr *)buffer;
3321
3322                 prev_chunk_id = in->hdr_chunk;
3323
3324                 if (prev_chunk_id > 0) {
3325                         result = yaffs_rd_chunk_tags_nand(dev, prev_chunk_id,
3326                                                           buffer, &old_tags);
3327
3328                         yaffs_verify_oh(in, oh, &old_tags, 0);
3329
3330                         memcpy(old_name, oh->name, sizeof(oh->name));
3331                         memset(buffer, 0xFF, sizeof(struct yaffs_obj_hdr));
3332                 } else {
3333                         memset(buffer, 0xFF, dev->data_bytes_per_chunk);
3334                 }
3335
3336                 oh->type = in->variant_type;
3337                 oh->yst_mode = in->yst_mode;
3338                 oh->shadows_obj = oh->inband_shadowed_obj_id = shadows;
3339
3340                 yaffs_load_attribs_oh(oh, in);
3341
3342                 if (in->parent)
3343                         oh->parent_obj_id = in->parent->obj_id;
3344                 else
3345                         oh->parent_obj_id = 0;
3346
3347                 if (name && *name) {
3348                         memset(oh->name, 0, sizeof(oh->name));
3349                         yaffs_load_oh_from_name(dev, oh->name, name);
3350                 } else if (prev_chunk_id > 0) {
3351                         memcpy(oh->name, old_name, sizeof(oh->name));
3352                 } else {
3353                         memset(oh->name, 0, sizeof(oh->name));
3354                 }
3355
3356                 oh->is_shrink = is_shrink;
3357
3358                 switch (in->variant_type) {
3359                 case YAFFS_OBJECT_TYPE_UNKNOWN:
3360                         /* Should not happen */
3361                         break;
3362                 case YAFFS_OBJECT_TYPE_FILE:
3363                         oh->file_size =
3364                             (oh->parent_obj_id == YAFFS_OBJECTID_DELETED
3365                              || oh->parent_obj_id ==
3366                              YAFFS_OBJECTID_UNLINKED) ? 0 : in->
3367                             variant.file_variant.file_size;
3368                         break;
3369                 case YAFFS_OBJECT_TYPE_HARDLINK:
3370                         oh->equiv_id = in->variant.hardlink_variant.equiv_id;
3371                         break;
3372                 case YAFFS_OBJECT_TYPE_SPECIAL:
3373                         /* Do nothing */
3374                         break;
3375                 case YAFFS_OBJECT_TYPE_DIRECTORY:
3376                         /* Do nothing */
3377                         break;
3378                 case YAFFS_OBJECT_TYPE_SYMLINK:
3379                         alias = in->variant.symlink_variant.alias;
3380                         if (!alias)
3381                                 alias = _Y("no alias");
3382                         strncpy(oh->alias, alias, YAFFS_MAX_ALIAS_LENGTH);
3383                         oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0;
3384                         break;
3385                 }
3386
3387                 /* process any xattrib modifications */
3388                 if (xmod)
3389                         yaffs_apply_xattrib_mod(in, (char *)buffer, xmod);
3390
3391                 /* Tags */
3392                 yaffs_init_tags(&new_tags);
3393                 in->serial++;
3394                 new_tags.chunk_id = 0;
3395                 new_tags.obj_id = in->obj_id;
3396                 new_tags.serial_number = in->serial;
3397
3398                 /* Add extra info for file header */
3399                 new_tags.extra_available = 1;
3400                 new_tags.extra_parent_id = oh->parent_obj_id;
3401                 new_tags.extra_length = oh->file_size;
3402                 new_tags.extra_is_shrink = oh->is_shrink;
3403                 new_tags.extra_equiv_id = oh->equiv_id;
3404                 new_tags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0;
3405                 new_tags.extra_obj_type = in->variant_type;
3406                 yaffs_verify_oh(in, oh, &new_tags, 1);
3407
3408                 /* Create new chunk in NAND */
3409                 new_chunk_id =
3410                     yaffs_write_new_chunk(dev, buffer, &new_tags,
3411                                           (prev_chunk_id > 0) ? 1 : 0);
3412
3413                 if (new_chunk_id >= 0) {
3414
3415                         in->hdr_chunk = new_chunk_id;
3416
3417                         if (prev_chunk_id > 0) {
3418                                 yaffs_chunk_del(dev, prev_chunk_id, 1,
3419                                                 __LINE__);
3420                         }
3421
3422                         if (!yaffs_obj_cache_dirty(in))
3423                                 in->dirty = 0;
3424
3425                         /* If this was a shrink, then mark the block
3426                          * that the chunk lives on */
3427                         if (is_shrink) {
3428                                 bi = yaffs_get_block_info(in->my_dev,
3429                                                           new_chunk_id /
3430                                                           in->my_dev->param.
3431                                                           chunks_per_block);
3432                                 bi->has_shrink_hdr = 1;
3433                         }
3434                 }
3435                 ret_val = new_chunk_id;
3436         }
3437
3438         if (buffer)
3439                 yaffs_release_temp_buffer(dev, buffer, __LINE__);
3440
3441         return ret_val;
3442 }
3443
3444 /*--------------------- File read/write ------------------------
3445  * Read and write have very similar structures.
3446  * In general the read/write has three parts to it
3447  * An incomplete chunk to start with (if the read/write is not chunk-aligned)
3448  * Some complete chunks
3449  * An incomplete chunk to end off with
3450  *
3451  * Curve-balls: the first chunk might also be the last chunk.
3452  */
3453
3454 int yaffs_file_rd(struct yaffs_obj *in, u8 * buffer, loff_t offset, int n_bytes)
3455 {
3456         int chunk;
3457         u32 start;
3458         int n_copy;
3459         int n = n_bytes;
3460         int n_done = 0;
3461         struct yaffs_cache *cache;
3462         struct yaffs_dev *dev;
3463
3464         dev = in->my_dev;
3465
3466         while (n > 0) {
3467                 yaffs_addr_to_chunk(dev, offset, &chunk, &start);
3468                 chunk++;
3469
3470                 /* OK now check for the curveball where the start and end are in
3471                  * the same chunk.
3472                  */
3473                 if ((start + n) < dev->data_bytes_per_chunk)
3474                         n_copy = n;
3475                 else
3476                         n_copy = dev->data_bytes_per_chunk - start;
3477
3478                 cache = yaffs_find_chunk_cache(in, chunk);
3479
3480                 /* If the chunk is already in the cache or it is less than
3481                  * a whole chunk or we're using inband tags then use the cache
3482                  * (if there is caching) else bypass the cache.
3483                  */
3484                 if (cache || n_copy != dev->data_bytes_per_chunk
3485                     || dev->param.inband_tags) {
3486                         if (dev->param.n_caches > 0) {
3487
3488                                 /* If we can't find the data in the cache,
3489                                  * then load it up. */
3490
3491                                 if (!cache) {
3492                                         cache =
3493                                             yaffs_grab_chunk_cache(in->my_dev);
3494                                         cache->object = in;
3495                                         cache->chunk_id = chunk;
3496                                         cache->dirty = 0;
3497                                         cache->locked = 0;
3498                                         yaffs_rd_data_obj(in, chunk,
3499                                                           cache->data);
3500                                         cache->n_bytes = 0;
3501                                 }
3502
3503                                 yaffs_use_cache(dev, cache, 0);
3504
3505                                 cache->locked = 1;
3506
3507                                 memcpy(buffer, &cache->data[start], n_copy);
3508
3509                                 cache->locked = 0;
3510                         } else {
3511                                 /* Read into the local buffer then copy.. */
3512
3513                                 u8 *local_buffer =
3514                                     yaffs_get_temp_buffer(dev, __LINE__);
3515                                 yaffs_rd_data_obj(in, chunk, local_buffer);
3516
3517                                 memcpy(buffer, &local_buffer[start], n_copy);
3518
3519                                 yaffs_release_temp_buffer(dev, local_buffer,
3520                                                           __LINE__);
3521                         }
3522                 } else {
3523                         /* A full chunk. Read directly into the buffer. */
3524                         yaffs_rd_data_obj(in, chunk, buffer);
3525                 }
3526                 n -= n_copy;
3527                 offset += n_copy;
3528                 buffer += n_copy;
3529                 n_done += n_copy;
3530         }
3531         return n_done;
3532 }
3533
3534 int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
3535                      int n_bytes, int write_trhrough)
3536 {
3537
3538         int chunk;
3539         u32 start;
3540         int n_copy;
3541         int n = n_bytes;
3542         int n_done = 0;
3543         int n_writeback;
3544         int start_write = offset;
3545         int chunk_written = 0;
3546         u32 n_bytes_read;
3547         u32 chunk_start;
3548         struct yaffs_dev *dev;
3549
3550         dev = in->my_dev;
3551
3552         while (n > 0 && chunk_written >= 0) {
3553                 yaffs_addr_to_chunk(dev, offset, &chunk, &start);
3554
3555                 if (chunk * dev->data_bytes_per_chunk + start != offset ||
3556                     start >= dev->data_bytes_per_chunk) {
3557                         yaffs_trace(YAFFS_TRACE_ERROR,
3558                                 "AddrToChunk of offset %d gives chunk %d start %d",
3559                                 (int)offset, chunk, start);
3560                 }
3561                 chunk++;        /* File pos to chunk in file offset */
3562
3563                 /* OK now check for the curveball where the start and end are in
3564                  * the same chunk.
3565                  */
3566
3567                 if ((start + n) < dev->data_bytes_per_chunk) {
3568                         n_copy = n;
3569
3570                         /* Now calculate how many bytes to write back....
3571                          * If we're overwriting and not writing to then end of
3572                          * file then we need to write back as much as was there
3573                          * before.
3574                          */
3575
3576                         chunk_start = ((chunk - 1) * dev->data_bytes_per_chunk);
3577
3578                         if (chunk_start > in->variant.file_variant.file_size)
3579                                 n_bytes_read = 0;       /* Past end of file */
3580                         else
3581                                 n_bytes_read =
3582                                     in->variant.file_variant.file_size -
3583                                     chunk_start;
3584
3585                         if (n_bytes_read > dev->data_bytes_per_chunk)
3586                                 n_bytes_read = dev->data_bytes_per_chunk;
3587
3588                         n_writeback =
3589                             (n_bytes_read >
3590                              (start + n)) ? n_bytes_read : (start + n);
3591
3592                         if (n_writeback < 0 ||
3593                             n_writeback > dev->data_bytes_per_chunk)
3594                                 BUG();
3595
3596                 } else {
3597                         n_copy = dev->data_bytes_per_chunk - start;
3598                         n_writeback = dev->data_bytes_per_chunk;
3599                 }
3600
3601                 if (n_copy != dev->data_bytes_per_chunk ||
3602                     dev->param.inband_tags) {
3603                         /* An incomplete start or end chunk (or maybe both
3604                          * start and end chunk), or we're using inband tags,
3605                          * so we want to use the cache buffers.
3606                          */
3607                         if (dev->param.n_caches > 0) {
3608                                 struct yaffs_cache *cache;
3609
3610                                 /* If we can't find the data in the cache, then
3611                                  * load the cache */
3612                                 cache = yaffs_find_chunk_cache(in, chunk);
3613
3614                                 if (!cache
3615                                     && yaffs_check_alloc_available(dev, 1)) {
3616                                         cache = yaffs_grab_chunk_cache(dev);
3617                                         cache->object = in;
3618                                         cache->chunk_id = chunk;
3619                                         cache->dirty = 0;
3620                                         cache->locked = 0;
3621                                         yaffs_rd_data_obj(in, chunk,
3622                                                           cache->data);
3623                                 } else if (cache &&
3624                                            !cache->dirty &&
3625                                            !yaffs_check_alloc_available(dev,
3626                                                                         1)) {
3627                                         /* Drop the cache if it was a read cache
3628                                          * item and no space check has been made
3629                                          * for it.
3630                                          */
3631                                         cache = NULL;
3632                                 }
3633
3634                                 if (cache) {
3635                                         yaffs_use_cache(dev, cache, 1);
3636                                         cache->locked = 1;
3637
3638                                         memcpy(&cache->data[start], buffer,
3639                                                n_copy);
3640
3641                                         cache->locked = 0;
3642                                         cache->n_bytes = n_writeback;
3643
3644                                         if (write_trhrough) {
3645                                                 chunk_written =
3646                                                     yaffs_wr_data_obj
3647                                                     (cache->object,
3648                                                      cache->chunk_id,
3649                                                      cache->data,
3650                                                      cache->n_bytes, 1);
3651                                                 cache->dirty = 0;
3652                                         }
3653                                 } else {
3654                                         chunk_written = -1;     /* fail write */
3655                                 }
3656                         } else {
3657                                 /* An incomplete start or end chunk (or maybe
3658                                  * both start and end chunk). Read into the
3659                                  * local buffer then copy over and write back.
3660                                  */
3661
3662                                 u8 *local_buffer =
3663                                     yaffs_get_temp_buffer(dev, __LINE__);
3664
3665                                 yaffs_rd_data_obj(in, chunk, local_buffer);
3666                                 memcpy(&local_buffer[start], buffer, n_copy);
3667
3668                                 chunk_written =
3669                                     yaffs_wr_data_obj(in, chunk,
3670                                                       local_buffer,
3671                                                       n_writeback, 0);
3672
3673                                 yaffs_release_temp_buffer(dev, local_buffer,
3674                                                           __LINE__);
3675                         }
3676                 } else {
3677                         /* A full chunk. Write directly from the buffer. */
3678
3679                         chunk_written =
3680                             yaffs_wr_data_obj(in, chunk, buffer,
3681                                               dev->data_bytes_per_chunk, 0);
3682
3683                         /* Since we've overwritten the cached data,
3684                          * we better invalidate it. */
3685                         yaffs_invalidate_chunk_cache(in, chunk);
3686                 }
3687
3688                 if (chunk_written >= 0) {
3689                         n -= n_copy;
3690                         offset += n_copy;
3691                         buffer += n_copy;
3692                         n_done += n_copy;
3693                 }
3694         }
3695
3696         /* Update file object */
3697
3698         if ((start_write + n_done) > in->variant.file_variant.file_size)
3699                 in->variant.file_variant.file_size = (start_write + n_done);
3700
3701         in->dirty = 1;
3702         return n_done;
3703 }
3704
3705 int yaffs_wr_file(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
3706                   int n_bytes, int write_trhrough)
3707 {
3708         yaffs2_handle_hole(in, offset);
3709         return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_trhrough);
3710 }
3711
3712 /* ---------------------- File resizing stuff ------------------ */
3713
3714 static void yaffs_prune_chunks(struct yaffs_obj *in, int new_size)
3715 {
3716
3717         struct yaffs_dev *dev = in->my_dev;
3718         int old_size = in->variant.file_variant.file_size;
3719         int i;
3720         int chunk_id;
3721         int last_del = 1 + (old_size - 1) / dev->data_bytes_per_chunk;
3722         int start_del = 1 + (new_size + dev->data_bytes_per_chunk - 1) /
3723             dev->data_bytes_per_chunk;
3724
3725
3726         /* Delete backwards so that we don't end up with holes if
3727          * power is lost part-way through the operation.
3728          */
3729         for (i = last_del; i >= start_del; i--) {
3730                 /* NB this could be optimised somewhat,
3731                  * eg. could retrieve the tags and write them without
3732                  * using yaffs_chunk_del
3733                  */
3734
3735                 chunk_id = yaffs_find_del_file_chunk(in, i, NULL);
3736                 if (chunk_id > 0) {
3737                         if (chunk_id <
3738                             (dev->internal_start_block *
3739                              dev->param.chunks_per_block) ||
3740                             chunk_id >=
3741                             ((dev->internal_end_block + 1) *
3742                               dev->param.chunks_per_block)) {
3743                                 yaffs_trace(YAFFS_TRACE_ALWAYS,
3744                                         "Found daft chunk_id %d for %d",
3745                                         chunk_id, i);
3746                         } else {
3747                                 in->n_data_chunks--;
3748                                 yaffs_chunk_del(dev, chunk_id, 1, __LINE__);
3749                         }
3750                 }
3751         }
3752 }
3753
3754 void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size)
3755 {
3756         int new_full;
3757         u32 new_partial;
3758         struct yaffs_dev *dev = obj->my_dev;
3759
3760         yaffs_addr_to_chunk(dev, new_size, &new_full, &new_partial);
3761
3762         yaffs_prune_chunks(obj, new_size);
3763
3764         if (new_partial != 0) {
3765                 int last_chunk = 1 + new_full;
3766                 u8 *local_buffer = yaffs_get_temp_buffer(dev, __LINE__);
3767
3768                 /* Rewrite the last chunk with its new size and zero pad */
3769                 yaffs_rd_data_obj(obj, last_chunk, local_buffer);
3770                 memset(local_buffer + new_partial, 0,
3771                        dev->data_bytes_per_chunk - new_partial);
3772
3773                 yaffs_wr_data_obj(obj, last_chunk, local_buffer,
3774                                   new_partial, 1);
3775
3776                 yaffs_release_temp_buffer(dev, local_buffer, __LINE__);
3777         }
3778
3779         obj->variant.file_variant.file_size = new_size;
3780
3781         yaffs_prune_tree(dev, &obj->variant.file_variant);
3782 }
3783
3784 int yaffs_resize_file(struct yaffs_obj *in, loff_t new_size)
3785 {
3786         struct yaffs_dev *dev = in->my_dev;
3787         int old_size = in->variant.file_variant.file_size;
3788
3789         yaffs_flush_file_cache(in);
3790         yaffs_invalidate_whole_cache(in);
3791
3792         yaffs_check_gc(dev, 0);
3793
3794         if (in->variant_type != YAFFS_OBJECT_TYPE_FILE)
3795                 return YAFFS_FAIL;
3796
3797         if (new_size == old_size)
3798                 return YAFFS_OK;
3799
3800         if (new_size > old_size) {
3801                 yaffs2_handle_hole(in, new_size);
3802                 in->variant.file_variant.file_size = new_size;
3803         } else {
3804                 /* new_size < old_size */
3805                 yaffs_resize_file_down(in, new_size);
3806         }
3807
3808         /* Write a new object header to reflect the resize.
3809          * show we've shrunk the file, if need be
3810          * Do this only if the file is not in the deleted directories
3811          * and is not shadowed.
3812          */
3813         if (in->parent &&
3814             !in->is_shadowed &&
3815             in->parent->obj_id != YAFFS_OBJECTID_UNLINKED &&
3816             in->parent->obj_id != YAFFS_OBJECTID_DELETED)
3817                 yaffs_update_oh(in, NULL, 0, 0, 0, NULL);
3818
3819         return YAFFS_OK;
3820 }
3821
3822 int yaffs_flush_file(struct yaffs_obj *in, int update_time, int data_sync)
3823 {
3824         int ret_val;
3825
3826         if (in->dirty) {
3827                 yaffs_flush_file_cache(in);
3828                 if (data_sync)  /* Only sync data */
3829                         ret_val = YAFFS_OK;
3830                 else {
3831                         if (update_time)
3832                                 yaffs_load_current_time(in, 0, 0);
3833
3834                         ret_val = (yaffs_update_oh(in, NULL, 0, 0, 0, NULL) >=
3835                                    0) ? YAFFS_OK : YAFFS_FAIL;
3836                 }
3837         } else {
3838                 ret_val = YAFFS_OK;
3839         }
3840         return ret_val;
3841 }
3842
3843
3844 /* yaffs_del_file deletes the whole file data
3845  * and the inode associated with the file.
3846  * It does not delete the links associated with the file.
3847  */
3848 static int yaffs_unlink_file_if_needed(struct yaffs_obj *in)
3849 {
3850         int ret_val;