yaffs: Reformatting to be kernel friendly.
[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                         YBUG();
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                 YBUG();
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                 YBUG();
1301         }
1302
1303         if (obj->siblings.prev == NULL) {
1304                 /* Not initialised */
1305                 YBUG();
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                 YBUG();
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 = obj->my_dev;
1644
1645         yaffs_trace(YAFFS_TRACE_OS, "FreeObject %p inode %p",
1646                 obj, obj->my_inode);
1647
1648         if (!obj)
1649                 YBUG();
1650         if (obj->parent)
1651                 YBUG();
1652         if (!list_empty(&obj->siblings))
1653                 YBUG();
1654
1655         if (obj->my_inode) {
1656                 /* We're still hooked up to a cached inode.
1657                  * Don't delete now, but mark for later deletion
1658                  */
1659                 obj->defered_free = 1;
1660                 return;
1661         }
1662
1663         yaffs_unhash_obj(obj);
1664
1665         yaffs_free_raw_obj(dev, obj);
1666         dev->n_obj--;
1667         dev->checkpoint_blocks_required = 0;    /* force recalculation */
1668 }
1669
1670 void yaffs_handle_defered_free(struct yaffs_obj *obj)
1671 {
1672         if (obj->defered_free)
1673                 yaffs_free_obj(obj);
1674 }
1675
1676 static int yaffs_generic_obj_del(struct yaffs_obj *in)
1677 {
1678         /* Iinvalidate the file's data in the cache, without flushing. */
1679         yaffs_invalidate_whole_cache(in);
1680
1681         if (in->my_dev->param.is_yaffs2 && in->parent != in->my_dev->del_dir) {
1682                 /* Move to unlinked directory so we have a deletion record */
1683                 yaffs_change_obj_name(in, in->my_dev->del_dir, _Y("deleted"), 0,
1684                                       0);
1685         }
1686
1687         yaffs_remove_obj_from_dir(in);
1688         yaffs_chunk_del(in->my_dev, in->hdr_chunk, 1, __LINE__);
1689         in->hdr_chunk = 0;
1690
1691         yaffs_free_obj(in);
1692         return YAFFS_OK;
1693
1694 }
1695
1696 static void yaffs_soft_del_file(struct yaffs_obj *obj)
1697 {
1698         if (obj->deleted &&
1699             obj->variant_type == YAFFS_OBJECT_TYPE_FILE && !obj->soft_del) {
1700                 if (obj->n_data_chunks <= 0) {
1701                         /* Empty file with no duplicate object headers,
1702                          * just delete it immediately */
1703                         yaffs_free_tnode(obj->my_dev,
1704                                          obj->variant.file_variant.top);
1705                         obj->variant.file_variant.top = NULL;
1706                         yaffs_trace(YAFFS_TRACE_TRACING,
1707                                 "yaffs: Deleting empty file %d",
1708                                 obj->obj_id);
1709                         yaffs_generic_obj_del(obj);
1710                 } else {
1711                         yaffs_soft_del_worker(obj,
1712                                               obj->variant.file_variant.top,
1713                                               obj->variant.
1714                                               file_variant.top_level, 0);
1715                         obj->soft_del = 1;
1716                 }
1717         }
1718 }
1719
1720 /* Pruning removes any part of the file structure tree that is beyond the
1721  * bounds of the file (ie that does not point to chunks).
1722  *
1723  * A file should only get pruned when its size is reduced.
1724  *
1725  * Before pruning, the chunks must be pulled from the tree and the
1726  * level 0 tnode entries must be zeroed out.
1727  * Could also use this for file deletion, but that's probably better handled
1728  * by a special case.
1729  *
1730  * This function is recursive. For levels > 0 the function is called again on
1731  * any sub-tree. For level == 0 we just check if the sub-tree has data.
1732  * If there is no data in a subtree then it is pruned.
1733  */
1734
1735 static struct yaffs_tnode *yaffs_prune_worker(struct yaffs_dev *dev,
1736                                               struct yaffs_tnode *tn, u32 level,
1737                                               int del0)
1738 {
1739         int i;
1740         int has_data;
1741
1742         if (tn) {
1743                 has_data = 0;
1744
1745                 if (level > 0) {
1746                         for (i = 0; i < YAFFS_NTNODES_INTERNAL; i++) {
1747                                 if (tn->internal[i]) {
1748                                         tn->internal[i] =
1749                                             yaffs_prune_worker(dev,
1750                                                         tn->internal[i],
1751                                                         level - 1,
1752                                                         (i == 0) ? del0 : 1);
1753                                 }
1754
1755                                 if (tn->internal[i])
1756                                         has_data++;
1757                         }
1758                 } else {
1759                         int tnode_size_u32 = dev->tnode_size / sizeof(u32);
1760                         u32 *map = (u32 *) tn;
1761
1762                         for (i = 0; !has_data && i < tnode_size_u32; i++) {
1763                                 if (map[i])
1764                                         has_data++;
1765                         }
1766                 }
1767
1768                 if (has_data == 0 && del0) {
1769                         /* Free and return NULL */
1770
1771                         yaffs_free_tnode(dev, tn);
1772                         tn = NULL;
1773                 }
1774         }
1775         return tn;
1776 }
1777
1778 static int yaffs_prune_tree(struct yaffs_dev *dev,
1779                             struct yaffs_file_var *file_struct)
1780 {
1781         int i;
1782         int has_data;
1783         int done = 0;
1784         struct yaffs_tnode *tn;
1785
1786         if (file_struct->top_level > 0) {
1787                 file_struct->top =
1788                     yaffs_prune_worker(dev, file_struct->top,
1789                                        file_struct->top_level, 0);
1790
1791                 /* Now we have a tree with all the non-zero branches NULL but
1792                  * the height is the same as it was.
1793                  * Let's see if we can trim internal tnodes to shorten the tree.
1794                  * We can do this if only the 0th element in the tnode is in use
1795                  * (ie all the non-zero are NULL)
1796                  */
1797
1798                 while (file_struct->top_level && !done) {
1799                         tn = file_struct->top;
1800
1801                         has_data = 0;
1802                         for (i = 1; i < YAFFS_NTNODES_INTERNAL; i++) {
1803                                 if (tn->internal[i])
1804                                         has_data++;
1805                         }
1806
1807                         if (!has_data) {
1808                                 file_struct->top = tn->internal[0];
1809                                 file_struct->top_level--;
1810                                 yaffs_free_tnode(dev, tn);
1811                         } else {
1812                                 done = 1;
1813                         }
1814                 }
1815         }
1816         return YAFFS_OK;
1817 }
1818
1819 /*-------------------- End of File Structure functions.-------------------*/
1820
1821 /* alloc_empty_obj gets us a clean Object.*/
1822 static struct yaffs_obj *yaffs_alloc_empty_obj(struct yaffs_dev *dev)
1823 {
1824         struct yaffs_obj *obj = yaffs_alloc_raw_obj(dev);
1825
1826         if (obj) {
1827                 dev->n_obj++;
1828
1829                 /* Now sweeten it up... */
1830
1831                 memset(obj, 0, sizeof(struct yaffs_obj));
1832                 obj->being_created = 1;
1833
1834                 obj->my_dev = dev;
1835                 obj->hdr_chunk = 0;
1836                 obj->variant_type = YAFFS_OBJECT_TYPE_UNKNOWN;
1837                 INIT_LIST_HEAD(&(obj->hard_links));
1838                 INIT_LIST_HEAD(&(obj->hash_link));
1839                 INIT_LIST_HEAD(&obj->siblings);
1840
1841                 /* Now make the directory sane */
1842                 if (dev->root_dir) {
1843                         obj->parent = dev->root_dir;
1844                         list_add(&(obj->siblings),
1845                                  &dev->root_dir->variant.dir_variant.children);
1846                 }
1847
1848                 /* Add it to the lost and found directory.
1849                  * NB Can't put root or lost-n-found in lost-n-found so
1850                  * check if lost-n-found exists first
1851                  */
1852                 if (dev->lost_n_found)
1853                         yaffs_add_obj_to_dir(dev->lost_n_found, obj);
1854
1855                 obj->being_created = 0;
1856         }
1857
1858         dev->checkpoint_blocks_required = 0;    /* force recalculation */
1859
1860         return obj;
1861 }
1862
1863 static int yaffs_find_nice_bucket(struct yaffs_dev *dev)
1864 {
1865         int i;
1866         int l = 999;
1867         int lowest = 999999;
1868
1869         /* Search for the shortest list or one that
1870          * isn't too long.
1871          */
1872
1873         for (i = 0; i < 10 && lowest > 4; i++) {
1874                 dev->bucket_finder++;
1875                 dev->bucket_finder %= YAFFS_NOBJECT_BUCKETS;
1876                 if (dev->obj_bucket[dev->bucket_finder].count < lowest) {
1877                         lowest = dev->obj_bucket[dev->bucket_finder].count;
1878                         l = dev->bucket_finder;
1879                 }
1880         }
1881
1882         return l;
1883 }
1884
1885 static int yaffs_new_obj_id(struct yaffs_dev *dev)
1886 {
1887         int bucket = yaffs_find_nice_bucket(dev);
1888         int found = 0;
1889         struct list_head *i;
1890         u32 n = (u32) bucket;
1891
1892         /* Now find an object value that has not already been taken
1893          * by scanning the list.
1894          */
1895
1896         while (!found) {
1897                 found = 1;
1898                 n += YAFFS_NOBJECT_BUCKETS;
1899                 if (1 || dev->obj_bucket[bucket].count > 0) {
1900                         list_for_each(i, &dev->obj_bucket[bucket].list) {
1901                                 /* If there is already one in the list */
1902                                 if (i && list_entry(i, struct yaffs_obj,
1903                                                     hash_link)->obj_id == n) {
1904                                         found = 0;
1905                                 }
1906                         }
1907                 }
1908         }
1909         return n;
1910 }
1911
1912 static void yaffs_hash_obj(struct yaffs_obj *in)
1913 {
1914         int bucket = yaffs_hash_fn(in->obj_id);
1915         struct yaffs_dev *dev = in->my_dev;
1916
1917         list_add(&in->hash_link, &dev->obj_bucket[bucket].list);
1918         dev->obj_bucket[bucket].count++;
1919 }
1920
1921 struct yaffs_obj *yaffs_find_by_number(struct yaffs_dev *dev, u32 number)
1922 {
1923         int bucket = yaffs_hash_fn(number);
1924         struct list_head *i;
1925         struct yaffs_obj *in;
1926
1927         list_for_each(i, &dev->obj_bucket[bucket].list) {
1928                 /* Look if it is in the list */
1929                 in = list_entry(i, struct yaffs_obj, hash_link);
1930                 if (in->obj_id == number) {
1931                         /* Don't show if it is defered free */
1932                         if (in->defered_free)
1933                                 return NULL;
1934                         return in;
1935                 }
1936         }
1937
1938         return NULL;
1939 }
1940
1941 struct yaffs_obj *yaffs_new_obj(struct yaffs_dev *dev, int number,
1942                                 enum yaffs_obj_type type)
1943 {
1944         struct yaffs_obj *the_obj = NULL;
1945         struct yaffs_tnode *tn = NULL;
1946
1947         if (number < 0)
1948                 number = yaffs_new_obj_id(dev);
1949
1950         if (type == YAFFS_OBJECT_TYPE_FILE) {
1951                 tn = yaffs_get_tnode(dev);
1952                 if (!tn)
1953                         return NULL;
1954         }
1955
1956         the_obj = yaffs_alloc_empty_obj(dev);
1957         if (!the_obj) {
1958                 if (tn)
1959                         yaffs_free_tnode(dev, tn);
1960                 return NULL;
1961         }
1962
1963         if (the_obj) {
1964                 the_obj->fake = 0;
1965                 the_obj->rename_allowed = 1;
1966                 the_obj->unlink_allowed = 1;
1967                 the_obj->obj_id = number;
1968                 yaffs_hash_obj(the_obj);
1969                 the_obj->variant_type = type;
1970                 yaffs_load_current_time(the_obj, 1, 1);
1971
1972                 switch (type) {
1973                 case YAFFS_OBJECT_TYPE_FILE:
1974                         the_obj->variant.file_variant.file_size = 0;
1975                         the_obj->variant.file_variant.scanned_size = 0;
1976                         the_obj->variant.file_variant.shrink_size = ~0;
1977                                                                 /* max */
1978                         the_obj->variant.file_variant.top_level = 0;
1979                         the_obj->variant.file_variant.top = tn;
1980                         break;
1981                 case YAFFS_OBJECT_TYPE_DIRECTORY:
1982                         INIT_LIST_HEAD(&the_obj->variant.dir_variant.children);
1983                         INIT_LIST_HEAD(&the_obj->variant.dir_variant.dirty);
1984                         break;
1985                 case YAFFS_OBJECT_TYPE_SYMLINK:
1986                 case YAFFS_OBJECT_TYPE_HARDLINK:
1987                 case YAFFS_OBJECT_TYPE_SPECIAL:
1988                         /* No action required */
1989                         break;
1990                 case YAFFS_OBJECT_TYPE_UNKNOWN:
1991                         /* todo this should not happen */
1992                         break;
1993                 }
1994         }
1995
1996         return the_obj;
1997 }
1998
1999 static struct yaffs_obj *yaffs_create_fake_dir(struct yaffs_dev *dev,
2000                                                int number, u32 mode)
2001 {
2002
2003         struct yaffs_obj *obj =
2004             yaffs_new_obj(dev, number, YAFFS_OBJECT_TYPE_DIRECTORY);
2005
2006         if (obj) {
2007                 obj->fake = 1;  /* it is fake so it might not use NAND */
2008                 obj->rename_allowed = 0;
2009                 obj->unlink_allowed = 0;
2010                 obj->deleted = 0;
2011                 obj->unlinked = 0;
2012                 obj->yst_mode = mode;
2013                 obj->my_dev = dev;
2014                 obj->hdr_chunk = 0;     /* Not a valid chunk. */
2015         }
2016         return obj;
2017
2018 }
2019
2020
2021 static void yaffs_init_tnodes_and_objs(struct yaffs_dev *dev)
2022 {
2023         int i;
2024
2025         dev->n_obj = 0;
2026         dev->n_tnodes = 0;
2027         yaffs_init_raw_tnodes_and_objs(dev);
2028
2029         for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
2030                 INIT_LIST_HEAD(&dev->obj_bucket[i].list);
2031                 dev->obj_bucket[i].count = 0;
2032         }
2033 }
2034
2035 struct yaffs_obj *yaffs_find_or_create_by_number(struct yaffs_dev *dev,
2036                                                  int number,
2037                                                  enum yaffs_obj_type type)
2038 {
2039         struct yaffs_obj *the_obj = NULL;
2040
2041         if (number > 0)
2042                 the_obj = yaffs_find_by_number(dev, number);
2043
2044         if (!the_obj)
2045                 the_obj = yaffs_new_obj(dev, number, type);
2046
2047         return the_obj;
2048
2049 }
2050
2051 YCHAR *yaffs_clone_str(const YCHAR *str)
2052 {
2053         YCHAR *new_str = NULL;
2054         int len;
2055
2056         if (!str)
2057                 str = _Y("");
2058
2059         len = strnlen(str, YAFFS_MAX_ALIAS_LENGTH);
2060         new_str = kmalloc((len + 1) * sizeof(YCHAR), GFP_NOFS);
2061         if (new_str) {
2062                 strncpy(new_str, str, len);
2063                 new_str[len] = 0;
2064         }
2065         return new_str;
2066
2067 }
2068 /*
2069  *yaffs_update_parent() handles fixing a directories mtime and ctime when a new
2070  * link (ie. name) is created or deleted in the directory.
2071  *
2072  * ie.
2073  *   create dir/a : update dir's mtime/ctime
2074  *   rm dir/a:   update dir's mtime/ctime
2075  *   modify dir/a: don't update dir's mtimme/ctime
2076  *
2077  * This can be handled immediately or defered. Defering helps reduce the number
2078  * of updates when many files in a directory are changed within a brief period.
2079  *
2080  * If the directory updating is defered then yaffs_update_dirty_dirs must be
2081  * called periodically.
2082  */
2083
2084 static void yaffs_update_parent(struct yaffs_obj *obj)
2085 {
2086         struct yaffs_dev *dev;
2087
2088         if (!obj)
2089                 return;
2090         dev = obj->my_dev;
2091         obj->dirty = 1;
2092         yaffs_load_current_time(obj, 0, 1);
2093         if (dev->param.defered_dir_update) {
2094                 struct list_head *link = &obj->variant.dir_variant.dirty;
2095
2096                 if (list_empty(link)) {
2097                         list_add(link, &dev->dirty_dirs);
2098                         yaffs_trace(YAFFS_TRACE_BACKGROUND,
2099                           "Added object %d to dirty directories",
2100                            obj->obj_id);
2101                 }
2102
2103         } else {
2104                 yaffs_update_oh(obj, NULL, 0, 0, 0, NULL);
2105         }
2106 }
2107
2108 void yaffs_update_dirty_dirs(struct yaffs_dev *dev)
2109 {
2110         struct list_head *link;
2111         struct yaffs_obj *obj;
2112         struct yaffs_dir_var *d_s;
2113         union yaffs_obj_var *o_v;
2114
2115         yaffs_trace(YAFFS_TRACE_BACKGROUND, "Update dirty directories");
2116
2117         while (!list_empty(&dev->dirty_dirs)) {
2118                 link = dev->dirty_dirs.next;
2119                 list_del_init(link);
2120
2121                 d_s = list_entry(link, struct yaffs_dir_var, dirty);
2122                 o_v = list_entry(d_s, union yaffs_obj_var, dir_variant);
2123                 obj = list_entry(o_v, struct yaffs_obj, variant);
2124
2125                 yaffs_trace(YAFFS_TRACE_BACKGROUND, "Update directory %d",
2126                         obj->obj_id);
2127
2128                 if (obj->dirty)
2129                         yaffs_update_oh(obj, NULL, 0, 0, 0, NULL);
2130         }
2131 }
2132
2133 /*
2134  * Mknod (create) a new object.
2135  * equiv_obj only has meaning for a hard link;
2136  * alias_str only has meaning for a symlink.
2137  * rdev only has meaning for devices (a subset of special objects)
2138  */
2139
2140 static struct yaffs_obj *yaffs_create_obj(enum yaffs_obj_type type,
2141                                           struct yaffs_obj *parent,
2142                                           const YCHAR *name,
2143                                           u32 mode,
2144                                           u32 uid,
2145                                           u32 gid,
2146                                           struct yaffs_obj *equiv_obj,
2147                                           const YCHAR *alias_str, u32 rdev)
2148 {
2149         struct yaffs_obj *in;
2150         YCHAR *str = NULL;
2151         struct yaffs_dev *dev = parent->my_dev;
2152
2153         /* Check if the entry exists.
2154          * If it does then fail the call since we don't want a dup. */
2155         if (yaffs_find_by_name(parent, name))
2156                 return NULL;
2157
2158         if (type == YAFFS_OBJECT_TYPE_SYMLINK) {
2159                 str = yaffs_clone_str(alias_str);
2160                 if (!str)
2161                         return NULL;
2162         }
2163
2164         in = yaffs_new_obj(dev, -1, type);
2165
2166         if (!in) {
2167                 kfree(str);
2168                 return NULL;
2169         }
2170
2171         if (in) {
2172                 in->hdr_chunk = 0;
2173                 in->valid = 1;
2174                 in->variant_type = type;
2175
2176                 in->yst_mode = mode;
2177
2178                 yaffs_attribs_init(in, gid, uid, rdev);
2179
2180                 in->n_data_chunks = 0;
2181
2182                 yaffs_set_obj_name(in, name);
2183                 in->dirty = 1;
2184
2185                 yaffs_add_obj_to_dir(parent, in);
2186
2187                 in->my_dev = parent->my_dev;
2188
2189                 switch (type) {
2190                 case YAFFS_OBJECT_TYPE_SYMLINK:
2191                         in->variant.symlink_variant.alias = str;
2192                         break;
2193                 case YAFFS_OBJECT_TYPE_HARDLINK:
2194                         in->variant.hardlink_variant.equiv_obj = equiv_obj;
2195                         in->variant.hardlink_variant.equiv_id =
2196                             equiv_obj->obj_id;
2197                         list_add(&in->hard_links, &equiv_obj->hard_links);
2198                         break;
2199                 case YAFFS_OBJECT_TYPE_FILE:
2200                 case YAFFS_OBJECT_TYPE_DIRECTORY:
2201                 case YAFFS_OBJECT_TYPE_SPECIAL:
2202                 case YAFFS_OBJECT_TYPE_UNKNOWN:
2203                         /* do nothing */
2204                         break;
2205                 }
2206
2207                 if (yaffs_update_oh(in, name, 0, 0, 0, NULL) < 0) {
2208                         /* Could not create the object header, fail */
2209                         yaffs_del_obj(in);
2210                         in = NULL;
2211                 }
2212
2213                 yaffs_update_parent(parent);
2214         }
2215
2216         return in;
2217 }
2218
2219 struct yaffs_obj *yaffs_create_file(struct yaffs_obj *parent,
2220                                     const YCHAR *name, u32 mode, u32 uid,
2221                                     u32 gid)
2222 {
2223         return yaffs_create_obj(YAFFS_OBJECT_TYPE_FILE, parent, name, mode,
2224                                 uid, gid, NULL, NULL, 0);
2225 }
2226
2227 struct yaffs_obj *yaffs_create_dir(struct yaffs_obj *parent, const YCHAR *name,
2228                                    u32 mode, u32 uid, u32 gid)
2229 {
2230         return yaffs_create_obj(YAFFS_OBJECT_TYPE_DIRECTORY, parent, name,
2231                                 mode, uid, gid, NULL, NULL, 0);
2232 }
2233
2234 struct yaffs_obj *yaffs_create_special(struct yaffs_obj *parent,
2235                                        const YCHAR *name, u32 mode, u32 uid,
2236                                        u32 gid, u32 rdev)
2237 {
2238         return yaffs_create_obj(YAFFS_OBJECT_TYPE_SPECIAL, parent, name, mode,
2239                                 uid, gid, NULL, NULL, rdev);
2240 }
2241
2242 struct yaffs_obj *yaffs_create_symlink(struct yaffs_obj *parent,
2243                                        const YCHAR *name, u32 mode, u32 uid,
2244                                        u32 gid, const YCHAR *alias)
2245 {
2246         return yaffs_create_obj(YAFFS_OBJECT_TYPE_SYMLINK, parent, name, mode,
2247                                 uid, gid, NULL, alias, 0);
2248 }
2249
2250 /* yaffs_link_obj returns the object id of the equivalent object.*/
2251 struct yaffs_obj *yaffs_link_obj(struct yaffs_obj *parent, const YCHAR * name,
2252                                  struct yaffs_obj *equiv_obj)
2253 {
2254         /* Get the real object in case we were fed a hard link obj */
2255         equiv_obj = yaffs_get_equivalent_obj(equiv_obj);
2256
2257         if (yaffs_create_obj
2258             (YAFFS_OBJECT_TYPE_HARDLINK, parent, name, 0, 0, 0,
2259              equiv_obj, NULL, 0))
2260                 return equiv_obj;
2261         else
2262                 return NULL;
2263
2264 }
2265
2266
2267
2268 /*---------------------- Block Management and Page Allocation -------------*/
2269
2270 static int yaffs_init_blocks(struct yaffs_dev *dev)
2271 {
2272         int n_blocks = dev->internal_end_block - dev->internal_start_block + 1;
2273
2274         dev->block_info = NULL;
2275         dev->chunk_bits = NULL;
2276         dev->alloc_block = -1;  /* force it to get a new one */
2277
2278         /* If the first allocation strategy fails, thry the alternate one */
2279         dev->block_info =
2280                 kmalloc(n_blocks * sizeof(struct yaffs_block_info), GFP_NOFS);
2281         if (!dev->block_info) {
2282                 dev->block_info =
2283                     vmalloc(n_blocks * sizeof(struct yaffs_block_info));
2284                 dev->block_info_alt = 1;
2285         } else {
2286                 dev->block_info_alt = 0;
2287         }
2288
2289         if (dev->block_info) {
2290                 /* Set up dynamic blockinfo stuff. Round up bytes. */
2291                 dev->chunk_bit_stride = (dev->param.chunks_per_block + 7) / 8;
2292                 dev->chunk_bits =
2293                         kmalloc(dev->chunk_bit_stride * n_blocks, GFP_NOFS);
2294                 if (!dev->chunk_bits) {
2295                         dev->chunk_bits =
2296                             vmalloc(dev->chunk_bit_stride * n_blocks);
2297                         dev->chunk_bits_alt = 1;
2298                 } else {
2299                         dev->chunk_bits_alt = 0;
2300                 }
2301         }
2302
2303         if (dev->block_info && dev->chunk_bits) {
2304                 memset(dev->block_info, 0,
2305                        n_blocks * sizeof(struct yaffs_block_info));
2306                 memset(dev->chunk_bits, 0, dev->chunk_bit_stride * n_blocks);
2307                 return YAFFS_OK;
2308         }
2309
2310         return YAFFS_FAIL;
2311 }
2312
2313 static void yaffs_deinit_blocks(struct yaffs_dev *dev)
2314 {
2315         if (dev->block_info_alt && dev->block_info)
2316                 vfree(dev->block_info);
2317         else
2318                 kfree(dev->block_info);
2319
2320         dev->block_info_alt = 0;
2321
2322         dev->block_info = NULL;
2323
2324         if (dev->chunk_bits_alt && dev->chunk_bits)
2325                 vfree(dev->chunk_bits);
2326         else
2327                 kfree(dev->chunk_bits);
2328         dev->chunk_bits_alt = 0;
2329         dev->chunk_bits = NULL;
2330 }
2331
2332 void yaffs_block_became_dirty(struct yaffs_dev *dev, int block_no)
2333 {
2334         struct yaffs_block_info *bi = yaffs_get_block_info(dev, block_no);
2335         int erased_ok = 0;
2336
2337         /* If the block is still healthy erase it and mark as clean.
2338          * If the block has had a data failure, then retire it.
2339          */
2340
2341         yaffs_trace(YAFFS_TRACE_GC | YAFFS_TRACE_ERASE,
2342                 "yaffs_block_became_dirty block %d state %d %s",
2343                 block_no, bi->block_state,
2344                 (bi->needs_retiring) ? "needs retiring" : "");
2345
2346         yaffs2_clear_oldest_dirty_seq(dev, bi);
2347
2348         bi->block_state = YAFFS_BLOCK_STATE_DIRTY;
2349
2350         /* If this is the block being garbage collected then stop gc'ing */
2351         if (block_no == dev->gc_block)
2352                 dev->gc_block = 0;
2353
2354         /* If this block is currently the best candidate for gc
2355          * then drop as a candidate */
2356         if (block_no == dev->gc_dirtiest) {
2357                 dev->gc_dirtiest = 0;
2358                 dev->gc_pages_in_use = 0;
2359         }
2360
2361         if (!bi->needs_retiring) {
2362                 yaffs2_checkpt_invalidate(dev);
2363                 erased_ok = yaffs_erase_block(dev, block_no);
2364                 if (!erased_ok) {
2365                         dev->n_erase_failures++;
2366                         yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
2367                           "**>> Erasure failed %d", block_no);
2368                 }
2369         }
2370
2371         if (erased_ok &&
2372             ((yaffs_trace_mask & YAFFS_TRACE_ERASE)
2373              || !yaffs_skip_verification(dev))) {
2374                 int i;
2375                 for (i = 0; i < dev->param.chunks_per_block; i++) {
2376                         if (!yaffs_check_chunk_erased
2377                             (dev, block_no * dev->param.chunks_per_block + i)) {
2378                                 yaffs_trace(YAFFS_TRACE_ERROR,
2379                                         ">>Block %d erasure supposedly OK, but chunk %d not erased",
2380                                         block_no, i);
2381                         }
2382                 }
2383         }
2384
2385         if (erased_ok) {
2386                 /* Clean it up... */
2387                 bi->block_state = YAFFS_BLOCK_STATE_EMPTY;
2388                 bi->seq_number = 0;
2389                 dev->n_erased_blocks++;
2390                 bi->pages_in_use = 0;
2391                 bi->soft_del_pages = 0;
2392                 bi->has_shrink_hdr = 0;
2393                 bi->skip_erased_check = 1;      /* Clean, so no need to check */
2394                 bi->gc_prioritise = 0;
2395                 yaffs_clear_chunk_bits(dev, block_no);
2396
2397                 yaffs_trace(YAFFS_TRACE_ERASE,
2398                         "Erased block %d", block_no);
2399         } else {
2400                 /* We lost a block of free space */
2401                 dev->n_free_chunks -= dev->param.chunks_per_block;
2402                 yaffs_retire_block(dev, block_no);
2403                 yaffs_trace(YAFFS_TRACE_ERROR | YAFFS_TRACE_BAD_BLOCKS,
2404                         "**>> Block %d retired", block_no);
2405         }
2406 }
2407
2408 static int yaffs_gc_process_chunk(struct yaffs_dev *dev,
2409                                 struct yaffs_block_info *bi,
2410                                 int old_chunk, u8 *buffer)
2411 {
2412         int new_chunk;
2413         int mark_flash = 1;
2414         struct yaffs_ext_tags tags;
2415         struct yaffs_obj *object;
2416         int matching_chunk;
2417         int ret_val = YAFFS_OK;
2418
2419         yaffs_init_tags(&tags);
2420         yaffs_rd_chunk_tags_nand(dev, old_chunk,
2421                                  buffer, &tags);
2422         object = yaffs_find_by_number(dev, tags.obj_id);
2423
2424         yaffs_trace(YAFFS_TRACE_GC_DETAIL,
2425                 "Collecting chunk in block %d, %d %d %d ",
2426                 dev->gc_chunk, tags.obj_id,
2427                 tags.chunk_id, tags.n_bytes);
2428
2429         if (object && !yaffs_skip_verification(dev)) {
2430                 if (tags.chunk_id == 0)
2431                         matching_chunk =
2432                             object->hdr_chunk;
2433                 else if (object->soft_del)
2434                         /* Defeat the test */
2435                         matching_chunk = old_chunk;
2436                 else
2437                         matching_chunk =
2438                             yaffs_find_chunk_in_file
2439                             (object, tags.chunk_id,
2440                              NULL);
2441
2442                 if (old_chunk != matching_chunk)
2443                         yaffs_trace(YAFFS_TRACE_ERROR,
2444                                 "gc: page in gc mismatch: %d %d %d %d",
2445                                 old_chunk,
2446                                 matching_chunk,
2447                                 tags.obj_id,
2448                                 tags.chunk_id);
2449         }
2450
2451         if (!object) {
2452                 yaffs_trace(YAFFS_TRACE_ERROR,
2453                         "page %d in gc has no object: %d %d %d ",
2454                         old_chunk,
2455                         tags.obj_id, tags.chunk_id,
2456                         tags.n_bytes);
2457         }
2458
2459         if (object &&
2460             object->deleted &&
2461             object->soft_del && tags.chunk_id != 0) {
2462                 /* Data chunk in a soft deleted file,
2463                  * throw it away.
2464                  * It's a soft deleted data chunk,
2465                  * No need to copy this, just forget
2466                  * about it and fix up the object.
2467                  */
2468
2469                 /* Free chunks already includes
2470                  * softdeleted chunks, how ever this
2471                  * chunk is going to soon be really
2472                  * deleted which will increment free
2473                  * chunks. We have to decrement free
2474                  * chunks so this works out properly.
2475                  */
2476                 dev->n_free_chunks--;
2477                 bi->soft_del_pages--;
2478
2479                 object->n_data_chunks--;
2480                 if (object->n_data_chunks <= 0) {
2481                         /* remeber to clean up obj */
2482                         dev->gc_cleanup_list[dev->n_clean_ups] = tags.obj_id;
2483                         dev->n_clean_ups++;
2484                 }
2485                 mark_flash = 0;
2486         } else if (object) {
2487                 /* It's either a data chunk in a live
2488                  * file or an ObjectHeader, so we're
2489                  * interested in it.
2490                  * NB Need to keep the ObjectHeaders of
2491                  * deleted files until the whole file
2492                  * has been deleted off
2493                  */
2494                 tags.serial_number++;
2495                 dev->n_gc_copies++;
2496
2497                 if (tags.chunk_id == 0) {
2498                         /* It is an object Id,
2499                          * We need to nuke the
2500                          * shrinkheader flags since its
2501                          * work is done.
2502                          * Also need to clean up
2503                          * shadowing.
2504                          */
2505                         struct yaffs_obj_hdr *oh;
2506                         oh = (struct yaffs_obj_hdr *) buffer;
2507
2508                         oh->is_shrink = 0;
2509                         tags.extra_is_shrink = 0;
2510                         oh->shadows_obj = 0;
2511                         oh->inband_shadowed_obj_id = 0;
2512                         tags.extra_shadows = 0;
2513
2514                         /* Update file size */
2515                         if (object->variant_type == YAFFS_OBJECT_TYPE_FILE) {
2516                                 oh->file_size =
2517                                     object->variant.file_variant.file_size;
2518                                 tags.extra_length = oh->file_size;
2519                         }
2520
2521                         yaffs_verify_oh(object, oh, &tags, 1);
2522                         new_chunk =
2523                             yaffs_write_new_chunk(dev, (u8 *) oh, &tags, 1);
2524                 } else {
2525                         new_chunk =
2526                             yaffs_write_new_chunk(dev, buffer, &tags, 1);
2527                 }
2528
2529                 if (new_chunk < 0) {
2530                         ret_val = YAFFS_FAIL;
2531                 } else {
2532
2533                         /* Now fix up the Tnodes etc. */
2534
2535                         if (tags.chunk_id == 0) {
2536                                 /* It's a header */
2537                                 object->hdr_chunk = new_chunk;
2538                                 object->serial = tags.serial_number;
2539                         } else {
2540                                 /* It's a data chunk */
2541                                 yaffs_put_chunk_in_file(object, tags.chunk_id,
2542                                                         new_chunk, 0);
2543                         }
2544                 }
2545         }
2546         if (ret_val == YAFFS_OK)
2547                 yaffs_chunk_del(dev, old_chunk, mark_flash, __LINE__);
2548         return ret_val;
2549 }
2550
2551 static int yaffs_gc_block(struct yaffs_dev *dev, int block, int whole_block)
2552 {
2553         int old_chunk;
2554         int ret_val = YAFFS_OK;
2555         int i;
2556         int is_checkpt_block;
2557         int max_copies;
2558         int chunks_before = yaffs_get_erased_chunks(dev);
2559         int chunks_after;
2560         struct yaffs_block_info *bi = yaffs_get_block_info(dev, block);
2561
2562         is_checkpt_block = (bi->block_state == YAFFS_BLOCK_STATE_CHECKPOINT);
2563
2564         yaffs_trace(YAFFS_TRACE_TRACING,
2565                 "Collecting block %d, in use %d, shrink %d, whole_block %d",
2566                 block, bi->pages_in_use, bi->has_shrink_hdr,
2567                 whole_block);
2568
2569         /*yaffs_verify_free_chunks(dev); */
2570
2571         if (bi->block_state == YAFFS_BLOCK_STATE_FULL)
2572                 bi->block_state = YAFFS_BLOCK_STATE_COLLECTING;
2573
2574         bi->has_shrink_hdr = 0; /* clear the flag so that the block can erase */
2575
2576         dev->gc_disable = 1;
2577
2578         if (is_checkpt_block || !yaffs_still_some_chunks(dev, block)) {
2579                 yaffs_trace(YAFFS_TRACE_TRACING,
2580                         "Collecting block %d that has no chunks in use",
2581                         block);
2582                 yaffs_block_became_dirty(dev, block);
2583         } else {
2584
2585                 u8 *buffer = yaffs_get_temp_buffer(dev, __LINE__);
2586
2587                 yaffs_verify_blk(dev, bi, block);
2588
2589                 max_copies = (whole_block) ? dev->param.chunks_per_block : 5;
2590                 old_chunk = block * dev->param.chunks_per_block + dev->gc_chunk;
2591
2592                 for (/* init already done */ ;
2593                      ret_val == YAFFS_OK &&
2594                      dev->gc_chunk < dev->param.chunks_per_block &&
2595                      (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) &&
2596                      max_copies > 0;
2597                      dev->gc_chunk++, old_chunk++) {
2598                         if (yaffs_check_chunk_bit(dev, block, dev->gc_chunk)) {
2599                                 /* Page is in use and might need to be copied */
2600                                 max_copies--;
2601                                 ret_val = yaffs_gc_process_chunk(dev, bi,
2602                                                         old_chunk, buffer);
2603                         }
2604                 }
2605                 yaffs_release_temp_buffer(dev, buffer, __LINE__);
2606         }
2607
2608         yaffs_verify_collected_blk(dev, bi, block);
2609
2610         if (bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) {
2611                 /*
2612                  * The gc did not complete. Set block state back to FULL
2613                  * because checkpointing does not restore gc.
2614                  */
2615                 bi->block_state = YAFFS_BLOCK_STATE_FULL;
2616         } else {
2617                 /* The gc completed. */
2618                 /* Do any required cleanups */
2619                 for (i = 0; i < dev->n_clean_ups; i++) {
2620                         /* Time to delete the file too */
2621                         struct yaffs_obj *object =
2622                             yaffs_find_by_number(dev, dev->gc_cleanup_list[i]);
2623                         if (object) {
2624                                 yaffs_free_tnode(dev,
2625                                           object->variant.file_variant.top);
2626                                 object->variant.file_variant.top = NULL;
2627                                 yaffs_trace(YAFFS_TRACE_GC,
2628                                         "yaffs: About to finally delete object %d",
2629                                         object->obj_id);
2630                                 yaffs_generic_obj_del(object);
2631                                 object->my_dev->n_deleted_files--;
2632                         }
2633
2634                 }
2635                 chunks_after = yaffs_get_erased_chunks(dev);
2636                 if (chunks_before >= chunks_after)
2637                         yaffs_trace(YAFFS_TRACE_GC,
2638                                 "gc did not increase free chunks before %d after %d",
2639                                 chunks_before, chunks_after);
2640                 dev->gc_block = 0;
2641                 dev->gc_chunk = 0;
2642                 dev->n_clean_ups = 0;
2643         }
2644
2645         dev->gc_disable = 0;
2646
2647         return ret_val;
2648 }
2649
2650 /*
2651  * find_gc_block() selects the dirtiest block (or close enough)
2652  * for garbage collection.
2653  */
2654
2655 static unsigned yaffs_find_gc_block(struct yaffs_dev *dev,
2656                                     int aggressive, int background)
2657 {
2658         int i;
2659         int iterations;
2660         unsigned selected = 0;
2661         int prioritised = 0;
2662         int prioritised_exist = 0;
2663         struct yaffs_block_info *bi;
2664         int threshold;
2665
2666         /* First let's see if we need to grab a prioritised block */
2667         if (dev->has_pending_prioritised_gc && !aggressive) {
2668                 dev->gc_dirtiest = 0;
2669                 bi = dev->block_info;
2670                 for (i = dev->internal_start_block;
2671                      i <= dev->internal_end_block && !selected; i++) {
2672
2673                         if (bi->gc_prioritise) {
2674                                 prioritised_exist = 1;
2675                                 if (bi->block_state == YAFFS_BLOCK_STATE_FULL &&
2676                                     yaffs_block_ok_for_gc(dev, bi)) {
2677                                         selected = i;
2678                                         prioritised = 1;
2679                                 }
2680                         }
2681                         bi++;
2682                 }
2683
2684                 /*
2685                  * If there is a prioritised block and none was selected then
2686                  * this happened because there is at least one old dirty block
2687                  * gumming up the works. Let's gc the oldest dirty block.
2688                  */
2689
2690                 if (prioritised_exist &&
2691                     !selected && dev->oldest_dirty_block > 0)
2692                         selected = dev->oldest_dirty_block;
2693
2694                 if (!prioritised_exist) /* None found, so we can clear this */
2695                         dev->has_pending_prioritised_gc = 0;
2696         }
2697
2698         /* If we're doing aggressive GC then we are happy to take a less-dirty
2699          * block, and search harder.
2700          * else (leasurely gc), then we only bother to do this if the
2701          * block has only a few pages in use.
2702          */
2703
2704         if (!selected) {
2705                 int pages_used;
2706                 int n_blocks =
2707                     dev->internal_end_block - dev->internal_start_block + 1;
2708                 if (aggressive) {
2709                         threshold = dev->param.chunks_per_block;
2710                         iterations = n_blocks;
2711                 } else {
2712                         int max_threshold;
2713
2714                         if (background)
2715                                 max_threshold = dev->param.chunks_per_block / 2;
2716                         else
2717                                 max_threshold = dev->param.chunks_per_block / 8;
2718
2719                         if (max_threshold < YAFFS_GC_PASSIVE_THRESHOLD)
2720                                 max_threshold = YAFFS_GC_PASSIVE_THRESHOLD;
2721
2722                         threshold = background ? (dev->gc_not_done + 2) * 2 : 0;
2723                         if (threshold < YAFFS_GC_PASSIVE_THRESHOLD)
2724                                 threshold = YAFFS_GC_PASSIVE_THRESHOLD;
2725                         if (threshold > max_threshold)
2726                                 threshold = max_threshold;
2727
2728                         iterations = n_blocks / 16 + 1;
2729                         if (iterations > 100)
2730                                 iterations = 100;
2731                 }
2732
2733                 for (i = 0;
2734                      i < iterations &&
2735                      (dev->gc_dirtiest < 1 ||
2736                       dev->gc_pages_in_use > YAFFS_GC_GOOD_ENOUGH);
2737                      i++) {
2738                         dev->gc_block_finder++;
2739                         if (dev->gc_block_finder < dev->internal_start_block ||
2740                             dev->gc_block_finder > dev->internal_end_block)
2741                                 dev->gc_block_finder =
2742                                     dev->internal_start_block;
2743
2744                         bi = yaffs_get_block_info(dev, dev->gc_block_finder);
2745
2746                         pages_used = bi->pages_in_use - bi->soft_del_pages;
2747
2748                         if (bi->block_state == YAFFS_BLOCK_STATE_FULL &&
2749                             pages_used < dev->param.chunks_per_block &&
2750                             (dev->gc_dirtiest < 1 ||
2751                              pages_used < dev->gc_pages_in_use) &&
2752                             yaffs_block_ok_for_gc(dev, bi)) {
2753                                 dev->gc_dirtiest = dev->gc_block_finder;
2754                                 dev->gc_pages_in_use = pages_used;
2755                         }
2756                 }
2757
2758                 if (dev->gc_dirtiest > 0 && dev->gc_pages_in_use <= threshold)
2759                         selected = dev->gc_dirtiest;
2760         }
2761
2762         /*
2763          * If nothing has been selected for a while, try the oldest dirty
2764          * because that's gumming up the works.
2765          */
2766
2767         if (!selected && dev->param.is_yaffs2 &&
2768             dev->gc_not_done >= (background ? 10 : 20)) {
2769                 yaffs2_find_oldest_dirty_seq(dev);
2770                 if (dev->oldest_dirty_block > 0) {
2771                         selected = dev->oldest_dirty_block;
2772                         dev->gc_dirtiest = selected;
2773                         dev->oldest_dirty_gc_count++;
2774                         bi = yaffs_get_block_info(dev, selected);
2775                         dev->gc_pages_in_use =
2776                             bi->pages_in_use - bi->soft_del_pages;
2777                 } else {
2778                         dev->gc_not_done = 0;
2779                 }
2780         }
2781
2782         if (selected) {
2783                 yaffs_trace(YAFFS_TRACE_GC,
2784                         "GC Selected block %d with %d free, prioritised:%d",
2785                         selected,
2786                         dev->param.chunks_per_block - dev->gc_pages_in_use,
2787                         prioritised);
2788
2789                 dev->n_gc_blocks++;
2790                 if (background)
2791                         dev->bg_gcs++;
2792
2793                 dev->gc_dirtiest = 0;
2794                 dev->gc_pages_in_use = 0;
2795                 dev->gc_not_done = 0;
2796                 if (dev->refresh_skip > 0)
2797                         dev->refresh_skip--;
2798         } else {
2799                 dev->gc_not_done++;
2800                 yaffs_trace(YAFFS_TRACE_GC,
2801                         "GC none: finder %d skip %d threshold %d dirtiest %d using %d oldest %d%s",
2802                         dev->gc_block_finder, dev->gc_not_done, threshold,
2803                         dev->gc_dirtiest, dev->gc_pages_in_use,
2804                         dev->oldest_dirty_block, background ? " bg" : "");
2805         }
2806
2807         return selected;
2808 }
2809
2810 /* New garbage collector
2811  * If we're very low on erased blocks then we do aggressive garbage collection
2812  * otherwise we do "leasurely" garbage collection.
2813  * Aggressive gc looks further (whole array) and will accept less dirty blocks.
2814  * Passive gc only inspects smaller areas and only accepts more dirty blocks.
2815  *
2816  * The idea is to help clear out space in a more spread-out manner.
2817  * Dunno if it really does anything useful.
2818  */
2819 static int yaffs_check_gc(struct yaffs_dev *dev, int background)
2820 {
2821         int aggressive = 0;
2822         int gc_ok = YAFFS_OK;
2823         int max_tries = 0;
2824         int min_erased;
2825         int erased_chunks;
2826         int checkpt_block_adjust;
2827
2828         if (dev->param.gc_control && (dev->param.gc_control(dev) & 1) == 0)
2829                 return YAFFS_OK;
2830
2831         if (dev->gc_disable) {
2832                 /* Bail out so we don't get recursive gc */
2833                 return YAFFS_OK;
2834         }
2835
2836         /* This loop should pass the first time.
2837          * Only loops here if the collection does not increase space.
2838          */
2839
2840         do {
2841                 max_tries++;
2842
2843                 checkpt_block_adjust = yaffs_calc_checkpt_blocks_required(dev);
2844
2845                 min_erased =
2846                     dev->param.n_reserved_blocks + checkpt_block_adjust + 1;
2847                 erased_chunks =
2848                     dev->n_erased_blocks * dev->param.chunks_per_block;
2849
2850                 /* If we need a block soon then do aggressive gc. */
2851                 if (dev->n_erased_blocks < min_erased)
2852                         aggressive = 1;
2853                 else {
2854                         if (!background
2855                             && erased_chunks > (dev->n_free_chunks / 4))
2856                                 break;
2857
2858                         if (dev->gc_skip > 20)
2859                                 dev->gc_skip = 20;
2860                         if (erased_chunks < dev->n_free_chunks / 2 ||
2861                             dev->gc_skip < 1 || background)
2862                                 aggressive = 0;
2863                         else {
2864                                 dev->gc_skip--;
2865                                 break;
2866                         }
2867                 }
2868
2869                 dev->gc_skip = 5;
2870
2871                 /* If we don't already have a block being gc'd then see if we
2872                  * should start another */
2873
2874                 if (dev->gc_block < 1 && !aggressive) {
2875                         dev->gc_block = yaffs2_find_refresh_block(dev);
2876                         dev->gc_chunk = 0;
2877                         dev->n_clean_ups = 0;
2878                 }
2879                 if (dev->gc_block < 1) {
2880                         dev->gc_block =
2881                             yaffs_find_gc_block(dev, aggressive, background);
2882                         dev->gc_chunk = 0;
2883                         dev->n_clean_ups = 0;
2884                 }
2885
2886                 if (dev->gc_block > 0) {
2887                         dev->all_gcs++;
2888                         if (!aggressive)
2889                                 dev->passive_gc_count++;
2890
2891                         yaffs_trace(YAFFS_TRACE_GC,
2892                                 "yaffs: GC n_erased_blocks %d aggressive %d",
2893                                 dev->n_erased_blocks, aggressive);
2894
2895                         gc_ok = yaffs_gc_block(dev, dev->gc_block, aggressive);
2896                 }
2897
2898                 if (dev->n_erased_blocks < (dev->param.n_reserved_blocks)
2899                     && dev->gc_block > 0) {
2900                         yaffs_trace(YAFFS_TRACE_GC,
2901                                 "yaffs: GC !!!no reclaim!!! n_erased_blocks %d after try %d block %d",
2902                                 dev->n_erased_blocks, max_tries,
2903                                 dev->gc_block);
2904                 }
2905         } while ((dev->n_erased_blocks < dev->param.n_reserved_blocks) &&
2906                  (dev->gc_block > 0) && (max_tries < 2));
2907
2908         return aggressive ? gc_ok : YAFFS_OK;
2909 }
2910
2911 /*
2912  * yaffs_bg_gc()
2913  * Garbage collects. Intended to be called from a background thread.
2914  * Returns non-zero if at least half the free chunks are erased.
2915  */
2916 int yaffs_bg_gc(struct yaffs_dev *dev, unsigned urgency)
2917 {
2918         int erased_chunks = dev->n_erased_blocks * dev->param.chunks_per_block;
2919
2920         yaffs_trace(YAFFS_TRACE_BACKGROUND, "Background gc %u", urgency);
2921
2922         yaffs_check_gc(dev, 1);
2923         return erased_chunks > dev->n_free_chunks / 2;
2924 }
2925
2926 /*-------------------- Data file manipulation -----------------*/
2927
2928 static int yaffs_rd_data_obj(struct yaffs_obj *in, int inode_chunk, u8 * buffer)
2929 {
2930         int nand_chunk = yaffs_find_chunk_in_file(in, inode_chunk, NULL);
2931
2932         if (nand_chunk >= 0)
2933                 return yaffs_rd_chunk_tags_nand(in->my_dev, nand_chunk,
2934                                                 buffer, NULL);
2935         else {
2936                 yaffs_trace(YAFFS_TRACE_NANDACCESS,
2937                         "Chunk %d not found zero instead",
2938                         nand_chunk);
2939                 /* get sane (zero) data if you read a hole */
2940                 memset(buffer, 0, in->my_dev->data_bytes_per_chunk);
2941                 return 0;
2942         }
2943
2944 }
2945
2946 void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash,
2947                      int lyn)
2948 {
2949         int block;
2950         int page;
2951         struct yaffs_ext_tags tags;
2952         struct yaffs_block_info *bi;
2953
2954         if (chunk_id <= 0)
2955                 return;
2956
2957         dev->n_deletions++;
2958         block = chunk_id / dev->param.chunks_per_block;
2959         page = chunk_id % dev->param.chunks_per_block;
2960
2961         if (!yaffs_check_chunk_bit(dev, block, page))
2962                 yaffs_trace(YAFFS_TRACE_VERIFY,
2963                         "Deleting invalid chunk %d", chunk_id);
2964
2965         bi = yaffs_get_block_info(dev, block);
2966
2967         yaffs2_update_oldest_dirty_seq(dev, block, bi);
2968
2969         yaffs_trace(YAFFS_TRACE_DELETION,
2970                 "line %d delete of chunk %d",
2971                 lyn, chunk_id);
2972
2973         if (!dev->param.is_yaffs2 && mark_flash &&
2974             bi->block_state != YAFFS_BLOCK_STATE_COLLECTING) {
2975
2976                 yaffs_init_tags(&tags);
2977                 tags.is_deleted = 1;
2978                 yaffs_wr_chunk_tags_nand(dev, chunk_id, NULL, &tags);
2979                 yaffs_handle_chunk_update(dev, chunk_id, &tags);
2980         } else {
2981                 dev->n_unmarked_deletions++;
2982         }
2983
2984         /* Pull out of the management area.
2985          * If the whole block became dirty, this will kick off an erasure.
2986          */
2987         if (bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING ||
2988             bi->block_state == YAFFS_BLOCK_STATE_FULL ||
2989             bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCANNING ||
2990             bi->block_state == YAFFS_BLOCK_STATE_COLLECTING) {
2991                 dev->n_free_chunks++;
2992                 yaffs_clear_chunk_bit(dev, block, page);
2993                 bi->pages_in_use--;
2994
2995                 if (bi->pages_in_use == 0 &&
2996                     !bi->has_shrink_hdr &&
2997                     bi->block_state != YAFFS_BLOCK_STATE_ALLOCATING &&
2998                     bi->block_state != YAFFS_BLOCK_STATE_NEEDS_SCANNING) {
2999                         yaffs_block_became_dirty(dev, block);
3000                 }
3001         }
3002 }
3003
3004 static int yaffs_wr_data_obj(struct yaffs_obj *in, int inode_chunk,
3005                              const u8 *buffer, int n_bytes, int use_reserve)
3006 {
3007         /* Find old chunk Need to do this to get serial number
3008          * Write new one and patch into tree.
3009          * Invalidate old tags.
3010          */
3011
3012         int prev_chunk_id;
3013         struct yaffs_ext_tags prev_tags;
3014         int new_chunk_id;
3015         struct yaffs_ext_tags new_tags;
3016         struct yaffs_dev *dev = in->my_dev;
3017
3018         yaffs_check_gc(dev, 0);
3019
3020         /* Get the previous chunk at this location in the file if it exists.
3021          * If it does not exist then put a zero into the tree. This creates
3022          * the tnode now, rather than later when it is harder to clean up.
3023          */
3024         prev_chunk_id = yaffs_find_chunk_in_file(in, inode_chunk, &prev_tags);
3025         if (prev_chunk_id < 1 &&
3026             !yaffs_put_chunk_in_file(in, inode_chunk, 0, 0))
3027                 return 0;
3028
3029         /* Set up new tags */
3030         yaffs_init_tags(&new_tags);
3031
3032         new_tags.chunk_id = inode_chunk;
3033         new_tags.obj_id = in->obj_id;
3034         new_tags.serial_number =
3035             (prev_chunk_id > 0) ? prev_tags.serial_number + 1 : 1;
3036         new_tags.n_bytes = n_bytes;
3037
3038         if (n_bytes < 1 || n_bytes > dev->param.total_bytes_per_chunk) {
3039                 yaffs_trace(YAFFS_TRACE_ERROR,
3040                   "Writing %d bytes to chunk!!!!!!!!!",
3041                    n_bytes);
3042                 YBUG();
3043         }
3044
3045         new_chunk_id =
3046             yaffs_write_new_chunk(dev, buffer, &new_tags, use_reserve);
3047
3048         if (new_chunk_id > 0) {
3049                 yaffs_put_chunk_in_file(in, inode_chunk, new_chunk_id, 0);
3050
3051                 if (prev_chunk_id > 0)
3052                         yaffs_chunk_del(dev, prev_chunk_id, 1, __LINE__);
3053
3054                 yaffs_verify_file_sane(in);
3055         }
3056         return new_chunk_id;
3057
3058 }
3059
3060
3061
3062 static int yaffs_do_xattrib_mod(struct yaffs_obj *obj, int set,
3063                                 const YCHAR *name, const void *value, int size,
3064                                 int flags)
3065 {
3066         struct yaffs_xattr_mod xmod;
3067         int result;
3068
3069         xmod.set = set;
3070         xmod.name = name;
3071         xmod.data = value;
3072         xmod.size = size;
3073         xmod.flags = flags;
3074         xmod.result = -ENOSPC;
3075
3076         result = yaffs_update_oh(obj, NULL, 0, 0, 0, &xmod);
3077
3078         if (result > 0)
3079                 return xmod.result;
3080         else
3081                 return -ENOSPC;
3082 }
3083
3084 static int yaffs_apply_xattrib_mod(struct yaffs_obj *obj, char *buffer,
3085                                    struct yaffs_xattr_mod *xmod)
3086 {
3087         int retval = 0;
3088         int x_offs = sizeof(struct yaffs_obj_hdr);
3089         struct yaffs_dev *dev = obj->my_dev;
3090         int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr);
3091         char *x_buffer = buffer + x_offs;
3092
3093         if (xmod->set)
3094                 retval =
3095                     nval_set(x_buffer, x_size, xmod->name, xmod->data,
3096                              xmod->size, xmod->flags);
3097         else
3098                 retval = nval_del(x_buffer, x_size, xmod->name);
3099
3100         obj->has_xattr = nval_hasvalues(x_buffer, x_size);
3101         obj->xattr_known = 1;
3102         xmod->result = retval;
3103
3104         return retval;
3105 }
3106
3107 static int yaffs_do_xattrib_fetch(struct yaffs_obj *obj, const YCHAR *name,
3108                                   void *value, int size)
3109 {
3110         char *buffer = NULL;
3111         int result;
3112         struct yaffs_ext_tags tags;
3113         struct yaffs_dev *dev = obj->my_dev;
3114         int x_offs = sizeof(struct yaffs_obj_hdr);
3115         int x_size = dev->data_bytes_per_chunk - sizeof(struct yaffs_obj_hdr);
3116         char *x_buffer;
3117         int retval = 0;
3118
3119         if (obj->hdr_chunk < 1)
3120                 return -ENODATA;
3121
3122         /* If we know that the object has no xattribs then don't do all the
3123          * reading and parsing.
3124          */
3125         if (obj->xattr_known && !obj->has_xattr) {
3126                 if (name)
3127                         return -ENODATA;
3128                 else
3129                         return 0;
3130         }
3131
3132         buffer = (char *)yaffs_get_temp_buffer(dev, __LINE__);
3133         if (!buffer)
3134                 return -ENOMEM;
3135
3136         result =
3137             yaffs_rd_chunk_tags_nand(dev, obj->hdr_chunk, (u8 *) buffer, &tags);
3138
3139         if (result != YAFFS_OK)
3140                 retval = -ENOENT;
3141         else {
3142                 x_buffer = buffer + x_offs;
3143
3144                 if (!obj->xattr_known) {
3145                         obj->has_xattr = nval_hasvalues(x_buffer, x_size);
3146                         obj->xattr_known = 1;
3147                 }
3148
3149                 if (name)
3150                         retval = nval_get(x_buffer, x_size, name, value, size);
3151                 else
3152                         retval = nval_list(x_buffer, x_size, value, size);
3153         }
3154         yaffs_release_temp_buffer(dev, (u8 *) buffer, __LINE__);
3155         return retval;
3156 }
3157
3158 int yaffs_set_xattrib(struct yaffs_obj *obj, const YCHAR * name,
3159                       const void *value, int size, int flags)
3160 {
3161         return yaffs_do_xattrib_mod(obj, 1, name, value, size, flags);
3162 }
3163
3164 int yaffs_remove_xattrib(struct yaffs_obj *obj, const YCHAR * name)
3165 {
3166         return yaffs_do_xattrib_mod(obj, 0, name, NULL, 0, 0);
3167 }
3168
3169 int yaffs_get_xattrib(struct yaffs_obj *obj, const YCHAR * name, void *value,
3170                       int size)
3171 {
3172         return yaffs_do_xattrib_fetch(obj, name, value, size);
3173 }
3174
3175 int yaffs_list_xattrib(struct yaffs_obj *obj, char *buffer, int size)
3176 {
3177         return yaffs_do_xattrib_fetch(obj, NULL, buffer, size);
3178 }
3179
3180 static void yaffs_check_obj_details_loaded(struct yaffs_obj *in)
3181 {
3182         u8 *chunk_data;
3183         struct yaffs_obj_hdr *oh;
3184         struct yaffs_dev *dev;
3185         struct yaffs_ext_tags tags;
3186         int result;
3187         int alloc_failed = 0;
3188
3189         if (!in)
3190                 return;
3191
3192         dev = in->my_dev;
3193
3194         if (in->lazy_loaded && in->hdr_chunk > 0) {
3195                 in->lazy_loaded = 0;
3196                 chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
3197
3198                 result =
3199                     yaffs_rd_chunk_tags_nand(dev, in->hdr_chunk, chunk_data,
3200                                              &tags);
3201                 oh = (struct yaffs_obj_hdr *)chunk_data;
3202
3203                 in->yst_mode = oh->yst_mode;
3204                 yaffs_load_attribs(in, oh);
3205                 yaffs_set_obj_name_from_oh(in, oh);
3206
3207                 if (in->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
3208                         in->variant.symlink_variant.alias =
3209                             yaffs_clone_str(oh->alias);
3210                         if (!in->variant.symlink_variant.alias)
3211                                 alloc_failed = 1;       /* Not returned */
3212                 }
3213
3214                 yaffs_release_temp_buffer(dev, chunk_data, __LINE__);
3215         }
3216 }
3217
3218 static void yaffs_load_name_from_oh(struct yaffs_dev *dev, YCHAR *name,
3219                                     const YCHAR *oh_name, int buff_size)
3220 {
3221 #ifdef CONFIG_YAFFS_AUTO_UNICODE
3222         if (dev->param.auto_unicode) {
3223                 if (*oh_name) {
3224                         /* It is an ASCII name, do an ASCII to
3225                          * unicode conversion */
3226                         const char *ascii_oh_name = (const char *)oh_name;
3227                         int n = buff_size - 1;
3228                         while (n > 0 && *ascii_oh_name) {
3229                                 *name = *ascii_oh_name;
3230                                 name++;
3231                                 ascii_oh_name++;
3232                                 n--;
3233                         }
3234                 } else {
3235                         strncpy(name, oh_name + 1, buff_size - 1);
3236                 }
3237         } else {
3238 #else
3239         {
3240 #endif
3241                 strncpy(name, oh_name, buff_size - 1);
3242         }
3243 }
3244
3245 static void yaffs_load_oh_from_name(struct yaffs_dev *dev, YCHAR *oh_name,
3246                                     const YCHAR *name)
3247 {
3248 #ifdef CONFIG_YAFFS_AUTO_UNICODE
3249
3250         int is_ascii;
3251         YCHAR *w;
3252
3253         if (dev->param.auto_unicode) {
3254
3255                 is_ascii = 1;
3256                 w = name;
3257
3258                 /* Figure out if the name will fit in ascii character set */
3259                 while (is_ascii && *w) {
3260                         if ((*w) & 0xff00)
3261                                 is_ascii = 0;
3262                         w++;
3263                 }
3264
3265                 if (is_ascii) {
3266                         /* It is an ASCII name, so convert unicode to ascii */
3267                         char *ascii_oh_name = (char *)oh_name;
3268                         int n = YAFFS_MAX_NAME_LENGTH - 1;
3269                         while (n > 0 && *name) {
3270                                 *ascii_oh_name = *name;
3271                                 name++;
3272                                 ascii_oh_name++;
3273                                 n--;
3274                         }
3275                 } else {
3276                         /* Unicode name, so save starting at the second YCHAR */
3277                         *oh_name = 0;
3278                         strncpy(oh_name + 1, name,
3279                                         YAFFS_MAX_NAME_LENGTH - 2);
3280                 }
3281         } else {
3282 #else
3283         {
3284 #endif
3285                 strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1);
3286         }
3287 }
3288
3289 /* UpdateObjectHeader updates the header on NAND for an object.
3290  * If name is not NULL, then that new name is used.
3291  */
3292 int yaffs_update_oh(struct yaffs_obj *in, const YCHAR *name, int force,
3293                     int is_shrink, int shadows, struct yaffs_xattr_mod *xmod)
3294 {
3295
3296         struct yaffs_block_info *bi;
3297         struct yaffs_dev *dev = in->my_dev;
3298         int prev_chunk_id;
3299         int ret_val = 0;
3300         int result = 0;
3301         int new_chunk_id;
3302         struct yaffs_ext_tags new_tags;
3303         struct yaffs_ext_tags old_tags;
3304         const YCHAR *alias = NULL;
3305         u8 *buffer = NULL;
3306         YCHAR old_name[YAFFS_MAX_NAME_LENGTH + 1];
3307         struct yaffs_obj_hdr *oh = NULL;
3308
3309         strcpy(old_name, _Y("silly old name"));
3310
3311         if (!in->fake || in == dev->root_dir ||
3312             force || xmod) {
3313
3314                 yaffs_check_gc(dev, 0);
3315                 yaffs_check_obj_details_loaded(in);
3316
3317                 buffer = yaffs_get_temp_buffer(in->my_dev, __LINE__);
3318                 oh = (struct yaffs_obj_hdr *)buffer;
3319
3320                 prev_chunk_id = in->hdr_chunk;
3321
3322                 if (prev_chunk_id > 0) {
3323                         result = yaffs_rd_chunk_tags_nand(dev, prev_chunk_id,
3324                                                           buffer, &old_tags);
3325
3326                         yaffs_verify_oh(in, oh, &old_tags, 0);
3327
3328                         memcpy(old_name, oh->name, sizeof(oh->name));
3329                         memset(buffer, 0xFF, sizeof(struct yaffs_obj_hdr));
3330                 } else {
3331                         memset(buffer, 0xFF, dev->data_bytes_per_chunk);
3332                 }
3333
3334                 oh->type = in->variant_type;
3335                 oh->yst_mode = in->yst_mode;
3336                 oh->shadows_obj = oh->inband_shadowed_obj_id = shadows;
3337
3338                 yaffs_load_attribs_oh(oh, in);
3339
3340                 if (in->parent)
3341                         oh->parent_obj_id = in->parent->obj_id;
3342                 else
3343                         oh->parent_obj_id = 0;
3344
3345                 if (name && *name) {
3346                         memset(oh->name, 0, sizeof(oh->name));
3347                         yaffs_load_oh_from_name(dev, oh->name, name);
3348                 } else if (prev_chunk_id > 0) {
3349                         memcpy(oh->name, old_name, sizeof(oh->name));
3350                 } else {
3351                         memset(oh->name, 0, sizeof(oh->name));
3352                 }
3353
3354                 oh->is_shrink = is_shrink;
3355
3356                 switch (in->variant_type) {
3357                 case YAFFS_OBJECT_TYPE_UNKNOWN:
3358                         /* Should not happen */
3359                         break;
3360                 case YAFFS_OBJECT_TYPE_FILE:
3361                         oh->file_size =
3362                             (oh->parent_obj_id == YAFFS_OBJECTID_DELETED
3363                              || oh->parent_obj_id ==
3364                              YAFFS_OBJECTID_UNLINKED) ? 0 : in->
3365                             variant.file_variant.file_size;
3366                         break;
3367                 case YAFFS_OBJECT_TYPE_HARDLINK:
3368                         oh->equiv_id = in->variant.hardlink_variant.equiv_id;
3369                         break;
3370                 case YAFFS_OBJECT_TYPE_SPECIAL:
3371                         /* Do nothing */
3372                         break;
3373                 case YAFFS_OBJECT_TYPE_DIRECTORY:
3374                         /* Do nothing */
3375                         break;
3376                 case YAFFS_OBJECT_TYPE_SYMLINK:
3377                         alias = in->variant.symlink_variant.alias;
3378                         if (!alias)
3379                                 alias = _Y("no alias");
3380                         strncpy(oh->alias, alias, YAFFS_MAX_ALIAS_LENGTH);
3381                         oh->alias[YAFFS_MAX_ALIAS_LENGTH] = 0;
3382                         break;
3383                 }
3384
3385                 /* process any xattrib modifications */
3386                 if (xmod)
3387                         yaffs_apply_xattrib_mod(in, (char *)buffer, xmod);
3388
3389                 /* Tags */
3390                 yaffs_init_tags(&new_tags);
3391                 in->serial++;
3392                 new_tags.chunk_id = 0;
3393                 new_tags.obj_id = in->obj_id;
3394                 new_tags.serial_number = in->serial;
3395
3396                 /* Add extra info for file header */
3397                 new_tags.extra_available = 1;
3398                 new_tags.extra_parent_id = oh->parent_obj_id;
3399                 new_tags.extra_length = oh->file_size;
3400                 new_tags.extra_is_shrink = oh->is_shrink;
3401                 new_tags.extra_equiv_id = oh->equiv_id;
3402                 new_tags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0;
3403                 new_tags.extra_obj_type = in->variant_type;
3404                 yaffs_verify_oh(in, oh, &new_tags, 1);
3405
3406                 /* Create new chunk in NAND */
3407                 new_chunk_id =
3408                     yaffs_write_new_chunk(dev, buffer, &new_tags,
3409                                           (prev_chunk_id > 0) ? 1 : 0);
3410
3411                 if (new_chunk_id >= 0) {
3412
3413                         in->hdr_chunk = new_chunk_id;
3414
3415                         if (prev_chunk_id > 0) {
3416                                 yaffs_chunk_del(dev, prev_chunk_id, 1,
3417                                                 __LINE__);
3418                         }
3419
3420                         if (!yaffs_obj_cache_dirty(in))
3421                                 in->dirty = 0;
3422
3423                         /* If this was a shrink, then mark the block
3424                          * that the chunk lives on */
3425                         if (is_shrink) {
3426                                 bi = yaffs_get_block_info(in->my_dev,
3427                                                           new_chunk_id /
3428                                                           in->my_dev->param.
3429                                                           chunks_per_block);
3430                                 bi->has_shrink_hdr = 1;
3431                         }
3432                 }
3433                 ret_val = new_chunk_id;
3434         }
3435
3436         if (buffer)
3437                 yaffs_release_temp_buffer(dev, buffer, __LINE__);
3438
3439         return ret_val;
3440 }
3441
3442 /*--------------------- File read/write ------------------------
3443  * Read and write have very similar structures.
3444  * In general the read/write has three parts to it
3445  * An incomplete chunk to start with (if the read/write is not chunk-aligned)
3446  * Some complete chunks
3447  * An incomplete chunk to end off with
3448  *
3449  * Curve-balls: the first chunk might also be the last chunk.
3450  */
3451
3452 int yaffs_file_rd(struct yaffs_obj *in, u8 * buffer, loff_t offset, int n_bytes)
3453 {
3454         int chunk;
3455         u32 start;
3456         int n_copy;
3457         int n = n_bytes;
3458         int n_done = 0;
3459         struct yaffs_cache *cache;
3460         struct yaffs_dev *dev;
3461
3462         dev = in->my_dev;
3463
3464         while (n > 0) {
3465                 yaffs_addr_to_chunk(dev, offset, &chunk, &start);
3466                 chunk++;
3467
3468                 /* OK now check for the curveball where the start and end are in
3469                  * the same chunk.
3470                  */
3471                 if ((start + n) < dev->data_bytes_per_chunk)
3472                         n_copy = n;
3473                 else
3474                         n_copy = dev->data_bytes_per_chunk - start;
3475
3476                 cache = yaffs_find_chunk_cache(in, chunk);
3477
3478                 /* If the chunk is already in the cache or it is less than
3479                  * a whole chunk or we're using inband tags then use the cache
3480                  * (if there is caching) else bypass the cache.
3481                  */
3482                 if (cache || n_copy != dev->data_bytes_per_chunk
3483                     || dev->param.inband_tags) {
3484                         if (dev->param.n_caches > 0) {
3485
3486                                 /* If we can't find the data in the cache,
3487                                  * then load it up. */
3488
3489                                 if (!cache) {
3490                                         cache =
3491                                             yaffs_grab_chunk_cache(in->my_dev);
3492                                         cache->object = in;
3493                                         cache->chunk_id = chunk;
3494                                         cache->dirty = 0;
3495                                         cache->locked = 0;
3496                                         yaffs_rd_data_obj(in, chunk,
3497                                                           cache->data);
3498                                         cache->n_bytes = 0;
3499                                 }
3500
3501                                 yaffs_use_cache(dev, cache, 0);
3502
3503                                 cache->locked = 1;
3504
3505                                 memcpy(buffer, &cache->data[start], n_copy);
3506
3507                                 cache->locked = 0;
3508                         } else {
3509                                 /* Read into the local buffer then copy.. */
3510
3511                                 u8 *local_buffer =
3512                                     yaffs_get_temp_buffer(dev, __LINE__);
3513                                 yaffs_rd_data_obj(in, chunk, local_buffer);
3514
3515                                 memcpy(buffer, &local_buffer[start], n_copy);
3516
3517                                 yaffs_release_temp_buffer(dev, local_buffer,
3518                                                           __LINE__);
3519                         }
3520                 } else {
3521                         /* A full chunk. Read directly into the buffer. */
3522                         yaffs_rd_data_obj(in, chunk, buffer);
3523                 }
3524                 n -= n_copy;
3525                 offset += n_copy;
3526                 buffer += n_copy;
3527                 n_done += n_copy;
3528         }
3529         return n_done;
3530 }
3531
3532 int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
3533                      int n_bytes, int write_trhrough)
3534 {
3535
3536         int chunk;
3537         u32 start;
3538         int n_copy;
3539         int n = n_bytes;
3540         int n_done = 0;
3541         int n_writeback;
3542         int start_write = offset;
3543         int chunk_written = 0;
3544         u32 n_bytes_read;
3545         u32 chunk_start;
3546         struct yaffs_dev *dev;
3547
3548         dev = in->my_dev;
3549
3550         while (n > 0 && chunk_written >= 0) {
3551                 yaffs_addr_to_chunk(dev, offset, &chunk, &start);
3552
3553                 if (chunk * dev->data_bytes_per_chunk + start != offset ||
3554                     start >= dev->data_bytes_per_chunk) {
3555                         yaffs_trace(YAFFS_TRACE_ERROR,
3556                                 "AddrToChunk of offset %d gives chunk %d start %d",
3557                                 (int)offset, chunk, start);
3558                 }
3559                 chunk++;        /* File pos to chunk in file offset */
3560
3561                 /* OK now check for the curveball where the start and end are in
3562                  * the same chunk.
3563                  */
3564
3565                 if ((start + n) < dev->data_bytes_per_chunk) {
3566                         n_copy = n;
3567
3568                         /* Now calculate how many bytes to write back....
3569                          * If we're overwriting and not writing to then end of
3570                          * file then we need to write back as much as was there
3571                          * before.
3572                          */
3573
3574                         chunk_start = ((chunk - 1) * dev->data_bytes_per_chunk);
3575
3576                         if (chunk_start > in->variant.file_variant.file_size)
3577                                 n_bytes_read = 0;       /* Past end of file */
3578                         else
3579                                 n_bytes_read =
3580                                     in->variant.file_variant.file_size -
3581                                     chunk_start;
3582
3583                         if (n_bytes_read > dev->data_bytes_per_chunk)
3584                                 n_bytes_read = dev->data_bytes_per_chunk;
3585
3586                         n_writeback =
3587                             (n_bytes_read >
3588                              (start + n)) ? n_bytes_read : (start + n);
3589
3590                         if (n_writeback < 0 ||
3591                             n_writeback > dev->data_bytes_per_chunk)
3592                                 YBUG();
3593
3594                 } else {
3595                         n_copy = dev->data_bytes_per_chunk - start;
3596                         n_writeback = dev->data_bytes_per_chunk;
3597                 }
3598
3599                 if (n_copy != dev->data_bytes_per_chunk ||
3600                     dev->param.inband_tags) {
3601                         /* An incomplete start or end chunk (or maybe both
3602                          * start and end chunk), or we're using inband tags,
3603                          * so we want to use the cache buffers.
3604                          */
3605                         if (dev->param.n_caches > 0) {
3606                                 struct yaffs_cache *cache;
3607
3608                                 /* If we can't find the data in the cache, then
3609                                  * load the cache */
3610                                 cache = yaffs_find_chunk_cache(in, chunk);
3611
3612                                 if (!cache
3613                                     && yaffs_check_alloc_available(dev, 1)) {
3614                                         cache = yaffs_grab_chunk_cache(dev);
3615                                         cache->object = in;
3616                                         cache->chunk_id = chunk;
3617                                         cache->dirty = 0;
3618                                         cache->locked = 0;
3619                                         yaffs_rd_data_obj(in, chunk,
3620                                                           cache->data);
3621                                 } else if (cache &&
3622                                            !cache->dirty &&
3623                                            !yaffs_check_alloc_available(dev,
3624                                                                         1)) {
3625                                         /* Drop the cache if it was a read cache
3626                                          * item and no space check has been made
3627                                          * for it.
3628                                          */
3629                                         cache = NULL;
3630                                 }
3631
3632                                 if (cache) {
3633                                         yaffs_use_cache(dev, cache, 1);
3634                                         cache->locked = 1;
3635
3636                                         memcpy(&cache->data[start], buffer,
3637                                                n_copy);
3638
3639                                         cache->locked = 0;
3640                                         cache->n_bytes = n_writeback;
3641
3642                                         if (write_trhrough) {
3643                                                 chunk_written =
3644                                                     yaffs_wr_data_obj
3645                                                     (cache->object,
3646                                                      cache->chunk_id,
3647                                                      cache->data,
3648                                                      cache->n_bytes, 1);
3649                                                 cache->dirty = 0;
3650                                         }
3651                                 } else {
3652                                         chunk_written = -1;     /* fail write */
3653                                 }
3654                         } else {
3655                                 /* An incomplete start or end chunk (or maybe
3656                                  * both start and end chunk). Read into the
3657                                  * local buffer then copy over and write back.
3658                                  */
3659
3660                                 u8 *local_buffer =
3661                                     yaffs_get_temp_buffer(dev, __LINE__);
3662
3663                                 yaffs_rd_data_obj(in, chunk, local_buffer);
3664                                 memcpy(&local_buffer[start], buffer, n_copy);
3665
3666                                 chunk_written =
3667                                     yaffs_wr_data_obj(in, chunk,
3668                                                       local_buffer,
3669                                                       n_writeback, 0);
3670
3671                                 yaffs_release_temp_buffer(dev, local_buffer,
3672                                                           __LINE__);
3673                         }
3674                 } else {
3675                         /* A full chunk. Write directly from the buffer. */
3676
3677                         chunk_written =
3678                             yaffs_wr_data_obj(in, chunk, buffer,
3679                                               dev->data_bytes_per_chunk, 0);
3680
3681                         /* Since we've overwritten the cached data,
3682                          * we better invalidate it. */
3683                         yaffs_invalidate_chunk_cache(in, chunk);
3684                 }
3685
3686                 if (chunk_written >= 0) {
3687                         n -= n_copy;
3688                         offset += n_copy;
3689                         buffer += n_copy;
3690                         n_done += n_copy;
3691                 }
3692         }
3693
3694         /* Update file object */
3695
3696         if ((start_write + n_done) > in->variant.file_variant.file_size)
3697                 in->variant.file_variant.file_size = (start_write + n_done);
3698
3699         in->dirty = 1;
3700         return n_done;
3701 }
3702
3703 int yaffs_wr_file(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
3704                   int n_bytes, int write_trhrough)
3705 {
3706         yaffs2_handle_hole(in, offset);
3707         return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_trhrough);
3708 }
3709
3710 /* ---------------------- File resizing stuff ------------------ */
3711
3712 static void yaffs_prune_chunks(struct yaffs_obj *in, int new_size)
3713 {
3714
3715         struct yaffs_dev *dev = in->my_dev;
3716         int old_size = in->variant.file_variant.file_size;
3717         int i;
3718         int chunk_id;
3719         int last_del = 1 + (old_size - 1) / dev->data_bytes_per_chunk;
3720         int start_del = 1 + (new_size + dev->data_bytes_per_chunk - 1) /
3721             dev->data_bytes_per_chunk;
3722
3723
3724         /* Delete backwards so that we don't end up with holes if
3725          * power is lost part-way through the operation.
3726          */
3727         for (i = last_del; i >= start_del; i--) {
3728                 /* NB this could be optimised somewhat,
3729                  * eg. could retrieve the tags and write them without
3730                  * using yaffs_chunk_del
3731                  */
3732
3733                 chunk_id = yaffs_find_del_file_chunk(in, i, NULL);
3734                 if (chunk_id > 0) {
3735                         if (chunk_id <
3736                             (dev->internal_start_block *
3737                              dev->param.chunks_per_block) ||
3738                             chunk_id >=
3739                             ((dev->internal_end_block + 1) *
3740                               dev->param.chunks_per_block)) {
3741                                 yaffs_trace(YAFFS_TRACE_ALWAYS,
3742                                         "Found daft chunk_id %d for %d",
3743                                         chunk_id, i);
3744                         } else {
3745                                 in->n_data_chunks--;
3746                                 yaffs_chunk_del(dev, chunk_id, 1, __LINE__);
3747                         }
3748                 }
3749         }
3750 }
3751
3752 void yaffs_resize_file_down(struct yaffs_obj *obj, loff_t new_size)
3753 {
3754         int new_full;
3755         u32 new_partial;
3756         struct yaffs_dev *dev = obj->my_dev;
3757
3758         yaffs_addr_to_chunk(dev, new_size, &new_full, &new_partial);
3759
3760         yaffs_prune_chunks(obj, new_size);
3761
3762         if (new_partial != 0) {
3763                 int last_chunk = 1 + new_full;
3764                 u8 *local_buffer = yaffs_get_temp_buffer(dev, __LINE__);
3765
3766                 /* Rewrite the last chunk with its new size and zero pad */
3767                 yaffs_rd_data_obj(obj, last_chunk, local_buffer);
3768                 memset(local_buffer + new_partial, 0,
3769                        dev->data_bytes_per_chunk - new_partial);
3770
3771                 yaffs_wr_data_obj(obj, last_chunk, local_buffer,
3772                                   new_partial, 1);
3773
3774                 yaffs_release_temp_buffer(dev, local_buffer, __LINE__);
3775         }
3776
3777         obj->variant.file_variant.file_size = new_size;
3778
3779         yaffs_prune_tree(dev, &obj->variant.file_variant);
3780 }
3781
3782 int yaffs_resize_file(struct yaffs_obj *in, loff_t new_size)
3783 {
3784         struct yaffs_dev *dev = in->my_dev;
3785         int old_size = in->variant.file_variant.file_size;
3786
3787         yaffs_flush_file_cache(in);
3788         yaffs_invalidate_whole_cache(in);
3789
3790         yaffs_check_gc(dev, 0);
3791
3792         if (in->variant_type != YAFFS_OBJECT_TYPE_FILE)
3793                 return YAFFS_FAIL;
3794
3795         if (new_size == old_size)
3796                 return YAFFS_OK;
3797
3798         if (new_size > old_size) {
3799                 yaffs2_handle_hole(in, new_size);
3800                 in->variant.file_variant.file_size = new_size;
3801         } else {
3802                 /* new_size < old_size */
3803                 yaffs_resize_file_down(in, new_size);
3804         }
3805
3806         /* Write a new object header to reflect the resize.
3807          * show we've shrunk the file, if need be
3808          * Do this only if the file is not in the deleted directories
3809          * and is not shadowed.
3810          */
3811         if (in->parent &&
3812             !in->is_shadowed &&
3813             in->parent->obj_id != YAFFS_OBJECTID_UNLINKED &&
3814             in->parent->obj_id != YAFFS_OBJECTID_DELETED)
3815                 yaffs_update_oh(in, NULL, 0, 0, 0, NULL);
3816
3817         return YAFFS_OK;
3818 }
3819
3820 int yaffs_flush_file(struct yaffs_obj *in, int update_time, int data_sync)
3821 {
3822         int ret_val;
3823
3824         if (in->dirty) {
3825                 yaffs_flush_file_cache(in);
3826                 if (data_sync)  /* Only sync data */
3827                         ret_val = YAFFS_OK;
3828                 else {
3829                         if (update_time)
3830                                 yaffs_load_current_time(in, 0, 0);
3831
3832                         ret_val = (yaffs_update_oh(in, NULL, 0, 0, 0, NULL) >=
3833                                    0) ? YAFFS_OK : YAFFS_FAIL;
3834                 }
3835         } else {
3836                 ret_val = YAFFS_OK;
3837         }
3838         return ret_val;
3839 }
3840
3841
3842 /* yaffs_del_file deletes the whole file data
3843  * and the inode associated with the file.
3844  * It does not delete the links associated with the file.
3845  */
3846 static int yaffs_unlink_file_if_needed(struct yaffs_obj *in)
3847 {
3848         int ret_val;
3849         int del_now = 0;
3850         struct yaffs_dev *dev = in->my_dev;
3851
3852         if (!in->my_inode)
3853                 del_now = 1;
3854
3855         if (del_now) {
3856                 ret_val =
3857                     yaffs_change_obj_name(in, in->my_dev->del_dir,
3858                                           _Y("deleted"), 0, 0);
3859                 yaffs_trace(YAFFS_TRACE_TRACING,
3860                         "yaffs: immediate deletion of file %d",
3861                         in->obj_id);
3862                 in->deleted = 1;
3863                 in->my_dev->n_deleted_files++;
3864                 if (dev->param.disable_soft_del || dev->param.is_yaffs2)
3865                         yaffs_resize_file(in, 0);
3866                 yaffs_soft_del_file(in);
3867         } else {
3868                 ret_val =
3869                     yaffs_change_obj_name(in, in->my_dev->unlinked_dir,
3870                                           _Y("unlinked"), 0, 0);
3871         }
3872         return ret_val;
3873 }
3874
3875 int yaffs_del_file(struct yaffs_obj *in)
3876 {
3877         int ret_val = YAFFS_OK;
3878         int deleted;    /* Need to cache value on stack if in is freed */
3879         struct yaffs_dev *dev = in->my_dev;
3880
3881         if (dev->param.disable_soft_del || dev->param.is_yaffs2)
3882                 yaffs_resize_file(in, 0);
3883
3884         if (in->n_data_chunks > 0) {
3885                 /* Use soft deletion if there is data in the file.
3886                  * That won't be the case if it has been resized to zero.
3887                  */
3888                 if (!in->unlinked)
3889                         ret_val = yaffs_unlink_file_if_needed(in);
3890
3891                 deleted = in->deleted;
3892
3893                 if (ret_val == YAFFS_OK && in->unlinked && !in->deleted) {
3894                         in->deleted = 1;
3895                         deleted = 1;
3896                         in->my_dev->n_deleted_files++;
3897                         yaffs_soft_del_file(in);
3898                 }
3899                 return deleted ? YAFFS_OK : YAFFS_FAIL;
3900         } else {
3901                 /* The file has no data chunks so we toss it immediately */
3902                 yaffs_free_tnode(in->my_dev, in->variant.file_variant.top);
3903                 in->variant.file_variant.top = NULL;
3904                 yaffs_generic_obj_del(in);
3905
3906                 return YAFFS_OK;
3907         }
3908 }
3909
3910 int yaffs_is_non_empty_dir(struct yaffs_obj *obj)
3911 {
3912         return (obj &&
3913                 obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY) &&
3914                 !(list_empty(&obj->variant.dir_variant.children));
3915 }
3916
3917 static int yaffs_del_dir(struct yaffs_obj *obj)
3918 {
3919         /* First check that the directory is empty. */
3920         if (yaffs_is_non_empty_dir(obj))
3921                 return YAFFS_FAIL;
3922
3923         return yaffs_generic_obj_del(obj);
3924 }
3925
3926 static int yaffs_del_symlink(struct yaffs_obj *in)
3927 {
3928         kfree(in->variant.symlink_variant.alias);
3929         in->variant.symlink_variant.alias = NULL;
3930
3931         return yaffs_generic_obj_del(in);
3932 }
3933
3934 static int yaffs_del_link(struct yaffs_obj *in)
3935 {
3936         /* remove this hardlink from the list associated with the equivalent
3937          * object
3938          */
3939         list_del_init(&in->hard_links);
3940         return yaffs_generic_obj_del(in);
3941 }
3942
3943 int yaffs_del_obj(struct yaffs_obj *obj)
3944 {
3945         int ret_val = -1;
3946
3947         switch (obj->variant_type) {
3948         case YAFFS_OBJECT_TYPE_FILE:
3949                 ret_val = yaffs_del_file(obj);
3950                 break;
3951         case YAFFS_OBJECT_TYPE_DIRECTORY:
3952                 if (!list_empty(&obj->variant.dir_variant.dirty)) {
3953                         yaffs_trace(YAFFS_TRACE_BACKGROUND,
3954                                 "Remove object %d from dirty directories",
3955                                 obj->obj_id);
3956                         list_del_init(&obj->variant.dir_variant.dirty);
3957                 }
3958                 return yaffs_del_dir(obj);
3959                 break;
3960         case YAFFS_OBJECT_TYPE_SYMLINK:
3961                 ret_val = yaffs_del_symlink(obj);
3962                 break;
3963         case YAFFS_OBJECT_TYPE_HARDLINK:
3964                 ret_val = yaffs_del_link(obj);
3965                 break;
3966         case YAFFS_OBJECT_TYPE_SPECIAL:
3967                 ret_val = yaffs_generic_obj_del(obj);
3968                 break;
3969         case YAFFS_OBJECT_TYPE_UNKNOWN:
3970                 ret_val = 0;
3971                 break;          /* should not happen. */
3972         }
3973         return ret_val;
3974 }
3975
3976 static int yaffs_unlink_worker(struct yaffs_obj *obj)
3977 {
3978         int del_now = 0;
3979
3980         if (!obj)
3981                 return YAFFS_FAIL;
3982
3983         if (!obj->my_inode)
3984                 del_now = 1;
3985
3986         yaffs_update_parent(obj->parent);
3987
3988         if (obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) {
3989                 return yaffs_del_link(obj);
3990         } else if (!list_empty(&obj->hard_links)) {
3991                 /* Curve ball: We're unlinking an object that has a hardlink.
3992                  *
3993                  * This problem arises because we are not strictly following
3994                  * The Linux link/inode model.
3995                  *
3996                  * We can't really delete the object.
3997                  * Instead, we do the following:
3998                  * - Select a hardlink.
3999                  * - Unhook it from the hard links
4000                  * - Move it from its parent directory so that the rename works.
4001                  * - Rename the object to the hardlink's name.
4002                  * - Delete the hardlink
4003                  */
4004
4005                 struct yaffs_obj *hl;
4006                 struct yaffs_obj *parent;
4007                 int ret_val;
4008                 YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
4009
4010                 hl = list_entry(obj->hard_links.next, struct yaffs_obj,
4011                                 hard_links);
4012
4013                 yaffs_get_obj_name(hl, name, YAFFS_MAX_NAME_LENGTH + 1);
4014                 parent = hl->parent;
4015
4016                 list_del_init(&hl->hard_links);
4017
4018                 yaffs_add_obj_to_dir(obj->my_dev->unlinked_dir, hl);
4019
4020                 ret_val = yaffs_change_obj_name(obj, parent, name, 0, 0);
4021
4022                 if (ret_val == YAFFS_OK)
4023                         ret_val = yaffs_generic_obj_del(hl);
4024
4025                 return ret_val;
4026
4027         } else if (del_now) {
4028                 switch (obj->variant_type) {
4029                 case YAFFS_OBJECT_TYPE_FILE:
4030                         return yaffs_del_file(obj);
4031                         break;
4032                 case YAFFS_OBJECT_TYPE_DIRECTORY:
4033                         list_del_init(&obj->variant.dir_variant.dirty);
4034                         return yaffs_del_dir(obj);
4035                         break;
4036                 case YAFFS_OBJECT_TYPE_SYMLINK:
4037                         return yaffs_del_symlink(obj);
4038                         break;
4039                 case YAFFS_OBJECT_TYPE_SPECIAL:
4040                         return yaffs_generic_obj_del(obj);
4041                         break;
4042                 case YAFFS_OBJECT_TYPE_HARDLINK:
4043                 case YAFFS_OBJECT_TYPE_UNKNOWN:
4044                 default:
4045                         return YAFFS_FAIL;
4046                 }
4047         } else if (yaffs_is_non_empty_dir(obj)) {
4048                 return YAFFS_FAIL;
4049         } else {
4050                 return yaffs_change_obj_name(obj, obj->my_dev->unlinked_dir,
4051                                                 _Y("unlinked"), 0, 0);
4052         }
4053 }
4054
4055 static int yaffs_unlink_obj(struct yaffs_obj *obj)
4056 {
4057         if (obj && obj->unlink_allowed)
4058                 return yaffs_unlink_worker(obj);
4059
4060         return YAFFS_FAIL;
4061 }
4062
4063 int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR *name)
4064 {
4065         struct yaffs_obj *obj;
4066
4067         obj = yaffs_find_by_name(dir, name);
4068         return yaffs_unlink_obj(obj);
4069 }
4070
4071 /* Note:
4072  * If old_name is NULL then we take old_dir as the object to be renamed.
4073  */
4074 int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR *old_name,
4075                      struct yaffs_obj *new_dir, const YCHAR *new_name)
4076 {
4077         struct yaffs_obj *obj = NULL;
4078         struct yaffs_obj *existing_target = NULL;
4079         int force = 0;
4080         int result;
4081         struct yaffs_dev *dev;
4082
4083         if (!old_dir || old_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
4084                 YBUG();
4085         if (!new_dir || new_dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
4086                 YBUG();
4087
4088         dev = old_dir->my_dev;
4089
4090 #ifdef CONFIG_YAFFS_CASE_INSENSITIVE
4091         /* Special case for case insemsitive systems.
4092          * While look-up is case insensitive, the name isn't.
4093          * Therefore we might want to change x.txt to X.txt
4094          */
4095         if (old_dir == new_dir &&
4096                 old_name && new_name &&
4097                 strcmp(old_name, new_name) == 0)
4098                 force = 1;
4099 #endif
4100
4101         if (strnlen(new_name, YAFFS_MAX_NAME_LENGTH + 1) >
4102             YAFFS_MAX_NAME_LENGTH)
4103                 /* ENAMETOOLONG */
4104                 return YAFFS_FAIL;
4105
4106         if (old_name)
4107                 obj = yaffs_find_by_name(old_dir, old_name);
4108         else{
4109                 obj = old_dir;
4110                 old_dir = obj->parent;
4111         }
4112
4113         if (obj && obj->rename_allowed) {
4114                 /* Now handle an existing target, if there is one */
4115                 existing_target = yaffs_find_by_name(new_dir, new_name);
4116                 if (yaffs_is_non_empty_dir(existing_target)) {
4117                         return YAFFS_FAIL;      /* ENOTEMPTY */
4118                 } else if (existing_target && existing_target != obj) {
4119                         /* Nuke the target first, using shadowing,
4120                          * but only if it isn't the same object.
4121                          *
4122                          * Note we must disable gc here otherwise it can mess
4123                          * up the shadowing.
4124                          *
4125                          */
4126                         dev->gc_disable = 1;
4127                         yaffs_change_obj_name(obj, new_dir, new_name, force,
4128                                               existing_target->obj_id);
4129                         existing_target->is_shadowed = 1;
4130                         yaffs_unlink_obj(existing_target);
4131                         dev->gc_disable = 0;
4132                 }
4133
4134                 result = yaffs_change_obj_name(obj, new_dir, new_name, 1, 0);
4135
4136                 yaffs_update_parent(old_dir);
4137                 if (new_dir != old_dir)
4138                         yaffs_update_parent(new_dir);
4139
4140                 return result;
4141         }
4142         return YAFFS_FAIL;
4143 }
4144
4145 /*----------------------- Initialisation Scanning ---------------------- */
4146
4147 void yaffs_handle_shadowed_obj(struct yaffs_dev *dev, int obj_id,
4148                                int backward_scanning)
4149 {
4150         struct yaffs_obj *obj;
4151
4152         if (!backward_scanning) {
4153                 /* Handle YAFFS1 forward scanning case
4154                  * For YAFFS1 we always do the deletion
4155                  */
4156
4157         } else {
4158                 /* Handle YAFFS2 case (backward scanning)
4159                  * If the shadowed object exists then ignore.
4160                  */
4161                 obj = yaffs_find_by_number(dev, obj_id);
4162                 if (obj)
4163                         return;
4164         }
4165
4166         /* Let's create it (if it does not exist) assuming it is a file so that
4167          * it can do shrinking etc.
4168          * We put it in unlinked dir to be cleaned up after the scanning
4169          */
4170         obj =
4171             yaffs_find_or_create_by_number(dev, obj_id, YAFFS_OBJECT_TYPE_FILE);
4172         if (!obj)
4173                 return;
4174         obj->is_shadowed = 1;
4175         yaffs_add_obj_to_dir(dev->unlinked_dir, obj);
4176         obj->variant.file_variant.shrink_size = 0;
4177         obj->valid = 1;         /* So that we don't read any other info. */
4178 }
4179
4180 void yaffs_link_fixup(struct yaffs_dev *dev, struct yaffs_obj *hard_list)
4181 {
4182         struct yaffs_obj *hl;
4183         struct yaffs_obj *in;
4184
4185         while (hard_list) {
4186                 hl = hard_list;
4187                 hard_list = (struct yaffs_obj *)(hard_list->hard_links.next);
4188
4189                 in = yaffs_find_by_number(dev,
4190                                           hl->variant.
4191                                           hardlink_variant.equiv_id);
4192
4193                 if (in) {
4194                         /* Add the hardlink pointers */
4195                         hl->variant.hardlink_variant.equiv_obj = in;
4196                         list_add(&hl->hard_links, &in->hard_links);
4197                 } else {
4198                         /* Todo Need to report/handle this better.
4199                          * Got a problem... hardlink to a non-existant object
4200                          */
4201                         hl->variant.hardlink_variant.equiv_obj = NULL;
4202                         INIT_LIST_HEAD(&hl->hard_links);
4203                 }
4204         }
4205 }
4206
4207 static void yaffs_strip_deleted_objs(struct yaffs_dev *dev)
4208 {
4209         /*
4210          *  Sort out state of unlinked and deleted objects after scanning.
4211          */
4212         struct list_head *i;
4213         struct list_head *n;
4214         struct yaffs_obj *l;
4215
4216         if (dev->read_only)
4217                 return;
4218
4219         /* Soft delete all the unlinked files */
4220         list_for_each_safe(i, n,
4221                            &dev->unlinked_dir->variant.dir_variant.children) {
4222                 if (i) {
4223                         l = list_entry(i, struct yaffs_obj, siblings);
4224                         yaffs_del_obj(l);
4225                 }
4226         }
4227
4228         list_for_each_safe(i, n, &dev->del_dir->variant.dir_variant.children) {
4229                 if (i) {
4230                         l = list_entry(i, struct yaffs_obj, siblings);
4231                         yaffs_del_obj(l);
4232                 }
4233         }
4234 }
4235
4236 /*
4237  * This code iterates through all the objects making sure that they are rooted.
4238  * Any unrooted objects are re-rooted in lost+found.
4239  * An object needs to be in one of:
4240  * - Directly under deleted, unlinked
4241  * - Directly or indirectly under root.
4242  *
4243  * Note:
4244  *  This code assumes that we don't ever change the current relationships
4245  *  between directories:
4246  *   root_dir->parent == unlinked_dir->parent == del_dir->parent == NULL
4247  *   lost-n-found->parent == root_dir
4248  *
4249  * This fixes the problem where directories might have inadvertently been
4250  * deleted leaving the object "hanging" without being rooted in the
4251  * directory tree.
4252  */
4253
4254 static int yaffs_has_null_parent(struct yaffs_dev *dev, struct yaffs_obj *obj)
4255 {
4256         return (obj == dev->del_dir ||
4257                 obj == dev->unlinked_dir || obj == dev->root_dir);
4258 }
4259
4260 static void yaffs_fix_hanging_objs(struct yaffs_dev *dev)
4261 {
4262         struct yaffs_obj *obj;
4263         struct yaffs_obj *parent;
4264         int i;
4265         struct list_head *lh;
4266         struct list_head *n;
4267         int depth_limit;
4268         int hanging;
4269
4270         if (dev->read_only)
4271                 return;
4272
4273         /* Iterate through the objects in each hash entry,
4274          * looking at each object.
4275          * Make sure it is rooted.
4276          */
4277
4278         for (i = 0; i < YAFFS_NOBJECT_BUCKETS; i++) {
4279                 list_for_each_safe(lh, n, &dev->obj_bucket[i].list) {
4280                         if (lh) {
4281                                 obj =
4282                                     list_entry(lh, struct yaffs_obj, hash_link);
4283                                 parent = obj->parent;
4284
4285                                 if (yaffs_has_null_parent(dev, obj)) {
4286                                         /* These directories are not hanging */
4287                                         hanging = 0;
4288                                 } else if (!parent
4289                                            || parent->variant_type !=
4290                                            YAFFS_OBJECT_TYPE_DIRECTORY) {
4291                                         hanging = 1;
4292                                 } else if (yaffs_has_null_parent(dev, parent)) {
4293                                         hanging = 0;
4294                                 } else {
4295                                         /*
4296                                          * Need to follow the parent chain to
4297                                          * see if it is hanging.
4298                                          */
4299                                         hanging = 0;
4300                                         depth_limit = 100;
4301
4302                                         while (parent != dev->root_dir &&
4303                                                parent->parent &&
4304                                                parent->parent->variant_type ==
4305                                                YAFFS_OBJECT_TYPE_DIRECTORY &&
4306                                                depth_limit > 0) {
4307                                                 parent = parent->parent;
4308                                                 depth_limit--;
4309                                         }
4310                                         if (parent != dev->root_dir)
4311                                                 hanging = 1;
4312                                 }
4313                                 if (hanging) {
4314                                         yaffs_trace(YAFFS_TRACE_SCAN,
4315                                                 "Hanging object %d moved to lost and found",
4316                                                 obj->obj_id);
4317                                         yaffs_add_obj_to_dir(dev->lost_n_found,
4318                                                              obj);
4319                                 }
4320                         }
4321                 }
4322         }
4323 }
4324
4325 /*
4326  * Delete directory contents for cleaning up lost and found.
4327  */
4328 static void yaffs_del_dir_contents(struct yaffs_obj *dir)
4329 {
4330         struct yaffs_obj *obj;
4331         struct list_head *lh;
4332         struct list_head *n;
4333
4334         if (dir->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY)
4335                 YBUG();
4336
4337         list_for_each_safe(lh, n, &dir->variant.dir_variant.children) {
4338                 if (lh) {
4339                         obj = list_entry(lh, struct yaffs_obj, siblings);
4340                         if (obj->variant_type == YAFFS_OBJECT_TYPE_DIRECTORY)
4341                                 yaffs_del_dir_contents(obj);
4342                         yaffs_trace(YAFFS_TRACE_SCAN,
4343                                 "Deleting lost_found object %d",
4344                                 obj->obj_id);
4345                         yaffs_unlink_obj(obj);
4346                 }
4347         }
4348 }
4349
4350 static void yaffs_empty_l_n_f(struct yaffs_dev *dev)
4351 {
4352         yaffs_del_dir_contents(dev->lost_n_found);
4353 }
4354
4355
4356 struct yaffs_obj *yaffs_find_by_name(struct yaffs_obj *directory,
4357                                      const YCHAR *name)
4358 {
4359         int sum;
4360         struct list_head *i;
4361         YCHAR buffer[YAFFS_MAX_NAME_LENGTH + 1];
4362         struct yaffs_obj *l;
4363
4364         if (!name)
4365                 return NULL;
4366
4367         if (!directory) {
4368                 yaffs_trace(YAFFS_TRACE_ALWAYS,
4369                         "tragedy: yaffs_find_by_name: null pointer directory"
4370                         );
4371                 YBUG();
4372                 return NULL;
4373         }
4374         if (directory->variant_type != YAFFS_OBJECT_TYPE_DIRECTORY) {
4375                 yaffs_trace(YAFFS_TRACE_ALWAYS,
4376                         "tragedy: yaffs_find_by_name: non-directory"
4377                         );
4378                 YBUG();
4379         }
4380
4381         sum = yaffs_calc_name_sum(name);
4382
4383         list_for_each(i, &directory->variant.dir_variant.children) {
4384                 l = list_entry(i, struct yaffs_obj, siblings);
4385
4386                 if (l->parent != directory)
4387                         YBUG();
4388
4389                 yaffs_check_obj_details_loaded(l);
4390
4391                 /* Special case for lost-n-found */
4392                 if (l->obj_id == YAFFS_OBJECTID_LOSTNFOUND) {
4393                         if (!strcmp(name, YAFFS_LOSTNFOUND_NAME))
4394                                 return l;
4395                 } else if (l->sum == sum
4396                            || l->hdr_chunk <= 0) {
4397                         /* LostnFound chunk called Objxxx
4398                          * Do a real check
4399                          */
4400                         yaffs_get_obj_name(l, buffer,
4401                                 YAFFS_MAX_NAME_LENGTH + 1);
4402                         if (strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH) == 0)
4403                                 return l;
4404                 }
4405         }
4406         return NULL;
4407 }
4408
4409 /* GetEquivalentObject dereferences any hard links to get to the
4410  * actual object.
4411  */
4412
4413 struct yaffs_obj *yaffs_get_equivalent_obj(struct yaffs_obj *obj)
4414 {
4415         if (obj && obj->variant_type == YAFFS_OBJECT_TYPE_HARDLINK) {
4416                 obj = obj->variant.hardlink_variant.equiv_obj;
4417                 yaffs_check_obj_details_loaded(obj);
4418         }
4419         return obj;
4420 }
4421
4422 /*
4423  *  A note or two on object names.
4424  *  * If the object name is missing, we then make one up in the form objnnn
4425  *
4426  *  * ASCII names are stored in the object header's name field from byte zero
4427  *  * Unicode names are historically stored starting from byte zero.
4428  *
4429  * Then there are automatic Unicode names...
4430  * The purpose of these is to save names in a way that can be read as
4431  * ASCII or Unicode names as appropriate, thus allowing a Unicode and ASCII
4432  * system to share files.
4433  *
4434  * These automatic unicode are stored slightly differently...
4435  *  - If the name can fit in the ASCII character space then they are saved as
4436  *    ascii names as per above.
4437  *  - If the name needs Unicode then the name is saved in Unicode
4438  *    starting at oh->name[1].
4439
4440  */
4441 static void yaffs_fix_null_name(struct yaffs_obj *obj, YCHAR *name,
4442                                 int buffer_size)
4443 {
4444         /* Create an object name if we could not find one. */
4445         if (strnlen(name, YAFFS_MAX_NAME_LENGTH) == 0) {
4446                 YCHAR local_name[20];
4447                 YCHAR num_string[20];
4448                 YCHAR *x = &num_string[19];
4449                 unsigned v = obj->obj_id;
4450                 num_string[19] = 0;
4451                 while (v > 0) {
4452                         x--;
4453                         *x = '0' + (v % 10);
4454                         v /= 10;
4455                 }
4456                 /* make up a name */
4457                 strcpy(local_name, YAFFS_LOSTNFOUND_PREFIX);
4458                 strcat(local_name, x);
4459                 strncpy(name, local_name, buffer_size - 1);
4460         }
4461 }
4462
4463 int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR *name, int buffer_size)
4464 {
4465         memset(name, 0, buffer_size * sizeof(YCHAR));
4466         yaffs_check_obj_details_loaded(obj);
4467         if (obj->obj_id == YAFFS_OBJECTID_LOSTNFOUND)
4468                 strncpy(name, YAFFS_LOSTNFOUND_NAME, buffer_size - 1);
4469 #ifndef CONFIG_YAFFS_NO_SHORT_NAMES
4470         else if (obj->short_name[0])
4471                 strcpy(name, obj->short_name);
4472 #endif
4473         else if (obj->hdr_chunk > 0) {
4474                 int result;
4475                 u8 *buffer = yaffs_get_temp_buffer(obj->my_dev, __LINE__);
4476
4477                 struct yaffs_obj_hdr *oh = (struct yaffs_obj_hdr *)buffer;
4478
4479                 memset(buffer, 0, obj->my_dev->data_bytes_per_chunk);
4480
4481                 if (obj->hdr_chunk > 0) {
4482                         result = yaffs_rd_chunk_tags_nand(obj->my_dev,
4483                                                           obj->hdr_chunk,
4484                                                           buffer, NULL);
4485                 }
4486                 yaffs_load_name_from_oh(obj->my_dev, name, oh->name,
4487                                         buffer_size);
4488
4489                 yaffs_release_temp_buffer(obj->my_dev, buffer, __LINE__);
4490         }
4491
4492         yaffs_fix_null_name(obj, name, buffer_size);
4493
4494         return strnlen(name, YAFFS_MAX_NAME_LENGTH);
4495 }
4496
4497 int yaffs_get_obj_length(struct yaffs_obj *obj)
4498 {
4499         /* Dereference any hard linking */
4500         obj = yaffs_get_equivalent_obj(obj);
4501
4502         if (obj->variant_type == YAFFS_OBJECT_TYPE_FILE)
4503                 return obj->variant.file_variant.file_size;
4504         if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK) {
4505                 if (!obj->variant.symlink_variant.alias)
4506                         return 0;
4507                 return strnlen(obj->variant.symlink_variant.alias,
4508                                      YAFFS_MAX_ALIAS_LENGTH);
4509         } else {
4510                 /* Only a directory should drop through to here */
4511                 return obj->my_dev->data_bytes_per_chunk;
4512         }
4513 }
4514
4515 int yaffs_get_obj_link_count(struct yaffs_obj *obj)
4516 {
4517         int count = 0;
4518         struct list_head *i;
4519
4520         if (!obj->unlinked)
4521                 count++;        /* the object itself */
4522
4523         list_for_each(i, &obj->hard_links)
4524             count++;            /* add the hard links; */
4525
4526         return count;
4527 }
4528
4529 int yaffs_get_obj_inode(struct yaffs_obj *obj)
4530 {
4531         obj = yaffs_get_equivalent_obj(obj);
4532
4533         return obj->obj_id;
4534 }
4535
4536 unsigned yaffs_get_obj_type(struct yaffs_obj *obj)
4537 {
4538         obj = yaffs_get_equivalent_obj(obj);
4539
4540         switch (obj->variant_type) {
4541         case YAFFS_OBJECT_TYPE_FILE:
4542                 return DT_REG;
4543                 break;
4544         case YAFFS_OBJECT_TYPE_DIRECTORY:
4545                 return DT_DIR;
4546                 break;
4547         case YAFFS_OBJECT_TYPE_SYMLINK:
4548                 return DT_LNK;
4549                 break;
4550         case YAFFS_OBJECT_TYPE_HARDLINK:
4551                 return DT_REG;
4552                 break;
4553         case YAFFS_OBJECT_TYPE_SPECIAL:
4554                 if (S_ISFIFO(obj->yst_mode))
4555                         return DT_FIFO;
4556                 if (S_ISCHR(obj->yst_mode))
4557                         return DT_CHR;
4558                 if (S_ISBLK(obj->yst_mode))
4559                         return DT_BLK;
4560                 if (S_ISSOCK(obj->yst_mode))
4561                         return DT_SOCK;
4562         default:
4563                 return DT_REG;
4564                 break;
4565         }
4566 }
4567
4568 YCHAR *yaffs_get_symlink_alias(struct yaffs_obj *obj)
4569 {
4570         obj = yaffs_get_equivalent_obj(obj);
4571         if (obj->variant_type == YAFFS_OBJECT_TYPE_SYMLINK)
4572                 return yaffs_clone_str(obj->variant.symlink_variant.alias);
4573         else
4574                 return yaffs_clone_str(_Y(""));
4575 }
4576
4577 /*--------------------------- Initialisation code -------------------------- */
4578
4579 static int yaffs_check_dev_fns(const struct yaffs_dev *dev)
4580 {
4581         /* Common functions, gotta have */
4582         if (!dev->param.erase_fn || !dev->param.initialise_flash_fn)
4583                 return 0;
4584
4585 #ifdef CONFIG_YAFFS_YAFFS2
4586
4587         /* Can use the "with tags" style interface for yaffs1 or yaffs2 */
4588         if (dev->param.write_chunk_tags_fn &&
4589             dev->param.read_chunk_tags_fn &&
4590             !dev->param.write_chunk_fn &&
4591             !dev->param.read_chunk_fn &&
4592             dev->param.bad_block_fn && dev->param.query_block_fn)
4593                 return 1;
4594 #endif
4595
4596         /* Can use the "spare" style interface for yaffs1 */
4597         if (!dev->param.is_yaffs2 &&
4598             !dev->param.write_chunk_tags_fn &&
4599             !dev->param.read_chunk_tags_fn &&
4600             dev->param.write_chunk_fn &&
4601             dev->param.read_chunk_fn &&
4602             !dev->param.bad_block_fn && !dev->param.query_block_fn)
4603                 return 1;
4604
4605         return 0;               /* bad */
4606 }
4607
4608 static int yaffs_create_initial_dir(struct yaffs_dev *dev)
4609 {
4610         /* Initialise the unlinked, deleted, root and lost+found directories */
4611         dev->lost_n_found = dev->root_dir = NULL;
4612         dev->unlinked_dir = dev->del_dir = NULL;
4613         dev->unlinked_dir =
4614             yaffs_create_fake_dir(dev, YAFFS_OBJECTID_UNLINKED, S_IFDIR);
4615         dev->del_dir =
4616             yaffs_create_fake_dir(dev, YAFFS_OBJECTID_DELETED, S_IFDIR);
4617         dev->root_dir =
4618             yaffs_create_fake_dir(dev, YAFFS_OBJECTID_ROOT,
4619                                   YAFFS_ROOT_MODE | S_IFDIR);
4620         dev->lost_n_found =
4621             yaffs_create_fake_dir(dev, YAFFS_OBJECTID_LOSTNFOUND,
4622                                   YAFFS_LOSTNFOUND_MODE | S_IFDIR);
4623
4624         if (dev->lost_n_found && dev->root_dir && dev->unlinked_dir
4625             && dev->del_dir) {
4626                 yaffs_add_obj_to_dir(dev->root_dir, dev->lost_n_found);
4627                 return YAFFS_OK;
4628         }
4629         return YAFFS_FAIL;
4630 }
4631
4632 int yaffs_guts_initialise(struct yaffs_dev *dev)
4633 {
4634         int init_failed = 0;
4635         unsigned x;
4636         int bits;
4637
4638         yaffs_trace(YAFFS_TRACE_TRACING, "yaffs: yaffs_guts_initialise()");
4639
4640         /* Check stuff that must be set */
4641
4642         if (!dev) {
4643                 yaffs_trace(YAFFS_TRACE_ALWAYS,
4644                         "yaffs: Need a device"
4645                         );
4646                 return YAFFS_FAIL;
4647         }
4648
4649         dev->internal_start_block = dev->param.start_block;
4650         dev->internal_end_block = dev->param.end_block;
4651         dev->block_offset = 0;
4652         dev->chunk_offset = 0;
4653         dev->n_free_chunks = 0;
4654
4655         dev->gc_block = 0;
4656
4657         if (dev->param.start_block == 0) {
4658                 dev->internal_start_block = dev->param.start_block + 1;
4659                 dev->internal_end_block = dev->param.end_block + 1;
4660                 dev->block_offset = 1;
4661                 dev->chunk_offset = dev->param.chunks_per_block;
4662         }
4663
4664         /* Check geometry parameters. */
4665
4666         if ((!dev->param.inband_tags && dev->param.is_yaffs2 &&
4667                 dev->param.total_bytes_per_chunk < 1024) ||
4668                 (!dev->param.is_yaffs2 &&
4669                         dev->param.total_bytes_per_chunk < 512) ||
4670                 (dev->param.inband_tags && !dev->param.is_yaffs2) ||
4671                  dev->param.chunks_per_block < 2 ||
4672                  dev->param.n_reserved_blocks < 2 ||
4673                 dev->internal_start_block <= 0 ||
4674                 dev->internal_end_block <= 0 ||
4675                 dev->internal_end_block <=
4676                 (dev->internal_start_block + dev->param.n_reserved_blocks + 2)
4677                 ) {
4678                 /* otherwise it is too small */
4679                 yaffs_trace(YAFFS_TRACE_ALWAYS,
4680                         "NAND geometry problems: chunk size %d, type is yaffs%s, inband_tags %d ",
4681                         dev->param.total_bytes_per_chunk,
4682                         dev->param.is_yaffs2 ? "2" : "",
4683                         dev->param.inband_tags);
4684                 return YAFFS_FAIL;
4685         }
4686
4687         if (yaffs_init_nand(dev) != YAFFS_OK) {
4688                 yaffs_trace(YAFFS_TRACE_ALWAYS, "InitialiseNAND failed");
4689                 return YAFFS_FAIL;
4690         }
4691
4692         /* Sort out space for inband tags, if required */
4693         if (dev->param.inband_tags)
4694                 dev->data_bytes_per_chunk =
4695                     dev->param.total_bytes_per_chunk -
4696                     sizeof(struct yaffs_packed_tags2_tags_only);
4697         else
4698                 dev->data_bytes_per_chunk = dev->param.total_bytes_per_chunk;
4699
4700         /* Got the right mix of functions? */
4701         if (!yaffs_check_dev_fns(dev)) {
4702                 /* Function missing */
4703                 yaffs_trace(YAFFS_TRACE_ALWAYS,
4704                         "device function(s) missing or wrong");
4705
4706                 return YAFFS_FAIL;
4707         }
4708
4709         if (dev->is_mounted) {
4710                 yaffs_trace(YAFFS_TRACE_ALWAYS, "device already mounted");
4711                 return YAFFS_FAIL;
4712         }
4713
4714         /* Finished with most checks. Further checks happen later on too. */
4715
4716         dev->is_mounted = 1;
4717
4718         /* OK now calculate a few things for the device */
4719
4720         /*
4721          *  Calculate all the chunk size manipulation numbers:
4722          */
4723         x = dev->data_bytes_per_chunk;
4724         /* We always use dev->chunk_shift and dev->chunk_div */
4725         dev->chunk_shift = calc_shifts(x);
4726         x >>= dev->chunk_shift;
4727         dev->chunk_div = x;
4728         /* We only use chunk mask if chunk_div is 1 */
4729         dev->chunk_mask = (1 << dev->chunk_shift) - 1;
4730
4731         /*
4732          * Calculate chunk_grp_bits.
4733          * We need to find the next power of 2 > than internal_end_block
4734          */
4735
4736         x = dev->param.chunks_per_block * (dev->internal_end_block + 1);
4737
4738         bits = calc_shifts_ceiling(x);
4739
4740         /* Set up tnode width if wide tnodes are enabled. */
4741         if (!dev->param.wide_tnodes_disabled) {
4742                 /* bits must be even so that we end up with 32-bit words */
4743                 if (bits & 1)
4744                         bits++;
4745                 if (bits < 16)
4746                         dev->tnode_width = 16;
4747                 else
4748                         dev->tnode_width = bits;
4749         } else {
4750                 dev->tnode_width = 16;
4751         }
4752
4753         dev->tnode_mask = (1 << dev->tnode_width) - 1;
4754
4755         /* Level0 Tnodes are 16 bits or wider (if wide tnodes are enabled),
4756          * so if the bitwidth of the
4757          * chunk range we're using is greater than 16 we need
4758          * to figure out chunk shift and chunk_grp_size
4759          */
4760
4761         if (bits <= dev->tnode_width)
4762                 dev->chunk_grp_bits = 0;
4763         else
4764                 dev->chunk_grp_bits = bits - dev->tnode_width;
4765
4766         dev->tnode_size = (dev->tnode_width * YAFFS_NTNODES_LEVEL0) / 8;
4767         if (dev->tnode_size < sizeof(struct yaffs_tnode))
4768                 dev->tnode_size = sizeof(struct yaffs_tnode);
4769
4770         dev->chunk_grp_size = 1 << dev->chunk_grp_bits;
4771
4772         if (dev->param.chunks_per_block < dev->chunk_grp_size) {
4773                 /* We have a problem because the soft delete won't work if
4774                  * the chunk group size > chunks per block.
4775                  * This can be remedied by using larger "virtual blocks".
4776                  */
4777                 yaffs_trace(YAFFS_TRACE_ALWAYS, "chunk group too large");
4778
4779                 return YAFFS_FAIL;
4780         }
4781
4782         /* Finished verifying the device, continue with initialisation */
4783
4784         /* More device initialisation */
4785         dev->all_gcs = 0;
4786         dev->passive_gc_count = 0;
4787         dev->oldest_dirty_gc_count = 0;
4788         dev->bg_gcs = 0;
4789         dev->gc_block_finder = 0;
4790         dev->buffered_block = -1;
4791         dev->doing_buffered_block_rewrite = 0;
4792         dev->n_deleted_files = 0;
4793         dev->n_bg_deletions = 0;
4794         dev->n_unlinked_files = 0;
4795         dev->n_ecc_fixed = 0;
4796         dev->n_ecc_unfixed = 0;
4797         dev->n_tags_ecc_fixed = 0;
4798         dev->n_tags_ecc_unfixed = 0;
4799         dev->n_erase_failures = 0;
4800         dev->n_erased_blocks = 0;
4801         dev->gc_disable = 0;
4802         dev->has_pending_prioritised_gc = 1;
4803                 /* Assume the worst for now, will get fixed on first GC */
4804         INIT_LIST_HEAD(&dev->dirty_dirs);
4805         dev->oldest_dirty_seq = 0;
4806         dev->oldest_dirty_block = 0;
4807
4808         /* Initialise temporary buffers and caches. */
4809         if (!yaffs_init_tmp_buffers(dev))
4810                 init_failed = 1;
4811
4812         dev->cache = NULL;
4813         dev->gc_cleanup_list = NULL;
4814
4815         if (!init_failed && dev->param.n_caches > 0) {
4816                 int i;
4817                 void *buf;
4818                 int cache_bytes =
4819                     dev->param.n_caches * sizeof(struct yaffs_cache);
4820
4821                 if (dev->param.n_caches > YAFFS_MAX_SHORT_OP_CACHES)
4822                         dev->param.n_caches = YAFFS_MAX_SHORT_OP_CACHES;
4823
4824                 dev->cache = kmalloc(cache_bytes, GFP_NOFS);
4825
4826                 buf = (u8 *) dev->cache;
4827
4828                 if (dev->cache)
4829                         memset(dev->cache, 0, cache_bytes);
4830
4831                 for (i = 0; i < dev->param.n_caches && buf; i++) {
4832                         dev->cache[i].object = NULL;
4833                         dev->cache[i].last_use = 0;
4834                         dev->cache[i].dirty = 0;
4835                         dev->cache[i].data = buf =
4836                             kmalloc(dev->param.total_bytes_per_chunk, GFP_NOFS);
4837                 }
4838                 if (!buf)
4839                         init_failed = 1;
4840
4841                 dev->cache_last_use = 0;
4842         }
4843
4844         dev->cache_hits = 0;
4845
4846         if (!init_failed) {
4847                 dev->gc_cleanup_list =
4848                     kmalloc(dev->param.chunks_per_block * sizeof(u32),
4849                                         GFP_NOFS);
4850                 if (!dev->gc_cleanup_list)
4851                         init_failed = 1;
4852         }
4853
4854         if (dev->param.is_yaffs2)
4855                 dev->param.use_header_file_size = 1;
4856
4857         if (!init_failed && !yaffs_init_blocks(dev))
4858                 init_failed = 1;
4859
4860         yaffs_init_tnodes_and_objs(dev);
4861
4862         if (!init_failed && !yaffs_create_initial_dir(dev))
4863                 init_failed = 1;
4864
4865         if (!init_failed) {
4866                 /* Now scan the flash. */
4867                 if (dev->param.is_yaffs2) {
4868                         if (yaffs2_checkpt_restore(dev)) {
4869                                 yaffs_check_obj_details_loaded(dev->root_dir);
4870                                 yaffs_trace(YAFFS_TRACE_CHECKPOINT |
4871                                         YAFFS_TRACE_MOUNT,
4872                                         "yaffs: restored from checkpoint"
4873                                         );
4874                         } else {
4875
4876                                 /* Clean up the mess caused by an aborted
4877                                  * checkpoint load then scan backwards.
4878                                  */
4879                                 yaffs_deinit_blocks(dev);
4880
4881                                 yaffs_deinit_tnodes_and_objs(dev);
4882
4883                                 dev->n_erased_blocks = 0;
4884                                 dev->n_free_chunks = 0;
4885                                 dev->alloc_block = -1;
4886                                 dev->alloc_page = -1;
4887                                 dev->n_deleted_files = 0;
4888                                 dev->n_unlinked_files = 0;
4889                                 dev->n_bg_deletions = 0;
4890
4891                                 if (!init_failed && !yaffs_init_blocks(dev))
4892                                         init_failed = 1;
4893
4894                                 yaffs_init_tnodes_and_objs(dev);
4895
4896                                 if (!init_failed
4897                                     && !yaffs_create_initial_dir(dev))
4898                                         init_failed = 1;
4899
4900                                 if (!init_failed && !yaffs2_scan_backwards(dev))
4901                                         init_failed = 1;
4902                         }
4903                 } else if (!yaffs1_scan(dev)) {
4904                         init_failed = 1;
4905                 }
4906
4907                 yaffs_strip_deleted_objs(dev);
4908                 yaffs_fix_hanging_objs(dev);
4909                 if (dev->param.empty_lost_n_found)
4910                         yaffs_empty_l_n_f(dev);
4911         }
4912
4913         if (init_failed) {
4914                 /* Clean up the mess */
4915                 yaffs_trace(YAFFS_TRACE_TRACING,
4916                   "yaffs: yaffs_guts_initialise() aborted.");
4917
4918                 yaffs_deinitialise(dev);
4919                 return YAFFS_FAIL;
4920         }
4921
4922         /* Zero out stats */
4923         dev->n_page_reads = 0;
4924         dev->n_page_writes = 0;
4925         dev->n_erasures = 0;
4926         dev->n_gc_copies = 0;
4927         dev->n_retired_writes = 0;
4928
4929         dev->n_retired_blocks = 0;
4930
4931         yaffs_verify_free_chunks(dev);
4932         yaffs_verify_blocks(dev);
4933
4934         /* Clean up any aborted checkpoint data */
4935         if (!dev->is_checkpointed && dev->blocks_in_checkpt > 0)
4936                 yaffs2_checkpt_invalidate(dev);
4937
4938         yaffs_trace(YAFFS_TRACE_TRACING,
4939           "yaffs: yaffs_guts_initialise() done.");
4940         return YAFFS_OK;
4941 }
4942
4943 void yaffs_deinitialise(struct yaffs_dev *dev)
4944 {
4945         if (dev->is_mounted) {
4946                 int i;
4947
4948                 yaffs_deinit_blocks(dev);
4949                 yaffs_deinit_tnodes_and_objs(dev);
4950                 if (dev->param.n_caches > 0 && dev->cache) {
4951
4952                         for (i = 0; i < dev->param.n_caches; i++) {
4953                                 kfree(dev->cache[i].data);
4954                                 dev->cache[i].data = NULL;
4955                         }
4956
4957                         kfree(dev->cache);
4958                         dev->cache = NULL;
4959                 }
4960
4961                 kfree(dev->gc_cleanup_list);
4962
4963                 for (i = 0; i < YAFFS_N_TEMP_BUFFERS; i++)
4964                         kfree(dev->temp_buffer[i].buffer);
4965
4966                 dev->is_mounted = 0;
4967
4968                 if (dev->param.deinitialise_flash_fn)
4969                         dev->param.deinitialise_flash_fn(dev);
4970         }
4971 }
4972
4973 int yaffs_count_free_chunks(struct yaffs_dev *dev)
4974 {
4975         int n_free = 0;
4976         int b;
4977         struct yaffs_block_info *blk;
4978
4979         blk = dev->block_info;
4980         for (b = dev->internal_start_block; b <= dev->internal_end_block; b++) {
4981                 switch (blk->block_state) {
4982                 case YAFFS_BLOCK_STATE_EMPTY:
4983                 case YAFFS_BLOCK_STATE_ALLOCATING:
4984                 case YAFFS_BLOCK_STATE_COLLECTING:
4985                 case YAFFS_BLOCK_STATE_FULL:
4986                         n_free +=
4987                             (dev->param.chunks_per_block - blk->pages_in_use +
4988                              blk->soft_del_pages);
4989                         break;
4990                 default:
4991                         break;
4992                 }
4993                 blk++;
4994         }
4995         return n_free;
4996 }
4997
4998 int yaffs_get_n_free_chunks(struct yaffs_dev *dev)
4999 {
5000         /* This is what we report to the outside world */
5001         int n_free;
5002         int n_dirty_caches;
5003         int blocks_for_checkpt;
5004         int i;
5005
5006         n_free = dev->n_free_chunks;
5007         n_free += dev->n_deleted_files;
5008
5009         /* Now count and subtract the number of dirty chunks in the cache. */
5010
5011         for (n_dirty_caches = 0, i = 0; i < dev->param.n_caches; i++) {
5012                 if (dev->cache[i].dirty)
5013                         n_dirty_caches++;
5014         }
5015
5016         n_free -= n_dirty_caches;
5017
5018         n_free -=
5019             ((dev->param.n_reserved_blocks + 1) * dev->param.chunks_per_block);
5020
5021         /* Now figure checkpoint space and report that... */
5022         blocks_for_checkpt = yaffs_calc_checkpt_blocks_required(dev);
5023
5024         n_free -= (blocks_for_checkpt * dev->param.chunks_per_block);
5025
5026         if (n_free < 0)
5027                 n_free = 0;
5028
5029         return n_free;
5030 }