rename target/linux/generic-2.6 to generic
[openwrt/svn-archive/archive.git] / target / linux / generic / patches-2.6.32 / 511-yaffs-cvs-2009-04-24.patch
1 --- a/fs/yaffs2/devextras.h
2 +++ b/fs/yaffs2/devextras.h
3 @@ -14,194 +14,135 @@
4 */
5
6 /*
7 - * This file is just holds extra declarations used during development.
8 - * Most of these are from kernel includes placed here so we can use them in
9 - * applications.
10 + * This file is just holds extra declarations of macros that would normally
11 + * be providesd in the Linux kernel. These macros have been written from
12 + * scratch but are functionally equivalent to the Linux ones.
13 *
14 */
15
16 #ifndef __EXTRAS_H__
17 #define __EXTRAS_H__
18
19 -#if defined WIN32
20 -#define __inline__ __inline
21 -#define new newHack
22 -#endif
23 -
24 -#if !(defined __KERNEL__) || (defined WIN32)
25
26 -/* User space defines */
27 +#if !(defined __KERNEL__)
28
29 +/* Definition of types */
30 typedef unsigned char __u8;
31 typedef unsigned short __u16;
32 typedef unsigned __u32;
33
34 +#endif
35 +
36 /*
37 - * Simple doubly linked list implementation.
38 - *
39 - * Some of the internal functions ("__xxx") are useful when
40 - * manipulating whole lists rather than single entries, as
41 - * sometimes we already know the next/prev entries and we can
42 - * generate better code by using them directly rather than
43 - * using the generic single-entry routines.
44 + * This is a simple doubly linked list implementation that matches the
45 + * way the Linux kernel doubly linked list implementation works.
46 */
47
48 -#define prefetch(x) 1
49 -
50 -struct list_head {
51 - struct list_head *next, *prev;
52 +struct ylist_head {
53 + struct ylist_head *next; /* next in chain */
54 + struct ylist_head *prev; /* previous in chain */
55 };
56
57 -#define LIST_HEAD_INIT(name) { &(name), &(name) }
58
59 -#define LIST_HEAD(name) \
60 - struct list_head name = LIST_HEAD_INIT(name)
61 +/* Initialise a static list */
62 +#define YLIST_HEAD(name) \
63 +struct ylist_head name = { &(name), &(name)}
64 +
65
66 -#define INIT_LIST_HEAD(ptr) do { \
67 - (ptr)->next = (ptr); (ptr)->prev = (ptr); \
68 +
69 +/* Initialise a list head to an empty list */
70 +#define YINIT_LIST_HEAD(p) \
71 +do { \
72 + (p)->next = (p);\
73 + (p)->prev = (p); \
74 } while (0)
75
76 -/*
77 - * Insert a new entry between two known consecutive entries.
78 - *
79 - * This is only for internal list manipulation where we know
80 - * the prev/next entries already!
81 - */
82 -static __inline__ void __list_add(struct list_head *new,
83 - struct list_head *prev,
84 - struct list_head *next)
85 -{
86 - next->prev = new;
87 - new->next = next;
88 - new->prev = prev;
89 - prev->next = new;
90 -}
91
92 -/**
93 - * list_add - add a new entry
94 - * @new: new entry to be added
95 - * @head: list head to add it after
96 - *
97 - * Insert a new entry after the specified head.
98 - * This is good for implementing stacks.
99 - */
100 -static __inline__ void list_add(struct list_head *new, struct list_head *head)
101 +/* Add an element to a list */
102 +static __inline__ void ylist_add(struct ylist_head *newEntry,
103 + struct ylist_head *list)
104 {
105 - __list_add(new, head, head->next);
106 -}
107 + struct ylist_head *listNext = list->next;
108 +
109 + list->next = newEntry;
110 + newEntry->prev = list;
111 + newEntry->next = listNext;
112 + listNext->prev = newEntry;
113
114 -/**
115 - * list_add_tail - add a new entry
116 - * @new: new entry to be added
117 - * @head: list head to add it before
118 - *
119 - * Insert a new entry before the specified head.
120 - * This is useful for implementing queues.
121 - */
122 -static __inline__ void list_add_tail(struct list_head *new,
123 - struct list_head *head)
124 -{
125 - __list_add(new, head->prev, head);
126 }
127
128 -/*
129 - * Delete a list entry by making the prev/next entries
130 - * point to each other.
131 - *
132 - * This is only for internal list manipulation where we know
133 - * the prev/next entries already!
134 - */
135 -static __inline__ void __list_del(struct list_head *prev,
136 - struct list_head *next)
137 +static __inline__ void ylist_add_tail(struct ylist_head *newEntry,
138 + struct ylist_head *list)
139 {
140 - next->prev = prev;
141 - prev->next = next;
142 + struct ylist_head *listPrev = list->prev;
143 +
144 + list->prev = newEntry;
145 + newEntry->next = list;
146 + newEntry->prev = listPrev;
147 + listPrev->next = newEntry;
148 +
149 }
150
151 -/**
152 - * list_del - deletes entry from list.
153 - * @entry: the element to delete from the list.
154 - * Note: list_empty on entry does not return true after this, the entry is
155 - * in an undefined state.
156 - */
157 -static __inline__ void list_del(struct list_head *entry)
158 +
159 +/* Take an element out of its current list, with or without
160 + * reinitialising the links.of the entry*/
161 +static __inline__ void ylist_del(struct ylist_head *entry)
162 {
163 - __list_del(entry->prev, entry->next);
164 + struct ylist_head *listNext = entry->next;
165 + struct ylist_head *listPrev = entry->prev;
166 +
167 + listNext->prev = listPrev;
168 + listPrev->next = listNext;
169 +
170 }
171
172 -/**
173 - * list_del_init - deletes entry from list and reinitialize it.
174 - * @entry: the element to delete from the list.
175 - */
176 -static __inline__ void list_del_init(struct list_head *entry)
177 +static __inline__ void ylist_del_init(struct ylist_head *entry)
178 {
179 - __list_del(entry->prev, entry->next);
180 - INIT_LIST_HEAD(entry);
181 + ylist_del(entry);
182 + entry->next = entry->prev = entry;
183 }
184
185 -/**
186 - * list_empty - tests whether a list is empty
187 - * @head: the list to test.
188 - */
189 -static __inline__ int list_empty(struct list_head *head)
190 +
191 +/* Test if the list is empty */
192 +static __inline__ int ylist_empty(struct ylist_head *entry)
193 {
194 - return head->next == head;
195 + return (entry->next == entry);
196 }
197
198 -/**
199 - * list_splice - join two lists
200 - * @list: the new list to add.
201 - * @head: the place to add it in the first list.
202 +
203 +/* ylist_entry takes a pointer to a list entry and offsets it to that
204 + * we can find a pointer to the object it is embedded in.
205 */
206 -static __inline__ void list_splice(struct list_head *list,
207 - struct list_head *head)
208 -{
209 - struct list_head *first = list->next;
210
211 - if (first != list) {
212 - struct list_head *last = list->prev;
213 - struct list_head *at = head->next;
214 -
215 - first->prev = head;
216 - head->next = first;
217 -
218 - last->next = at;
219 - at->prev = last;
220 - }
221 -}
222
223 -/**
224 - * list_entry - get the struct for this entry
225 - * @ptr: the &struct list_head pointer.
226 - * @type: the type of the struct this is embedded in.
227 - * @member: the name of the list_struct within the struct.
228 - */
229 -#define list_entry(ptr, type, member) \
230 - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
231 -
232 -/**
233 - * list_for_each - iterate over a list
234 - * @pos: the &struct list_head to use as a loop counter.
235 - * @head: the head for your list.
236 - */
237 -#define list_for_each(pos, head) \
238 - for (pos = (head)->next, prefetch(pos->next); pos != (head); \
239 - pos = pos->next, prefetch(pos->next))
240 -
241 -/**
242 - * list_for_each_safe - iterate over a list safe against removal
243 - * of list entry
244 - * @pos: the &struct list_head to use as a loop counter.
245 - * @n: another &struct list_head to use as temporary storage
246 - * @head: the head for your list.
247 - */
248 -#define list_for_each_safe(pos, n, head) \
249 - for (pos = (head)->next, n = pos->next; pos != (head); \
250 - pos = n, n = pos->next)
251 +#define ylist_entry(entry, type, member) \
252 + ((type *)((char *)(entry)-(unsigned long)(&((type *)NULL)->member)))
253
254 -/*
255 - * File types
256 +
257 +/* ylist_for_each and list_for_each_safe iterate over lists.
258 + * ylist_for_each_safe uses temporary storage to make the list delete safe
259 */
260 +
261 +#define ylist_for_each(itervar, list) \
262 + for (itervar = (list)->next; itervar != (list); itervar = itervar->next)
263 +
264 +#define ylist_for_each_safe(itervar, saveVar, list) \
265 + for (itervar = (list)->next, saveVar = (list)->next->next; \
266 + itervar != (list); itervar = saveVar, saveVar = saveVar->next)
267 +
268 +
269 +#if !(defined __KERNEL__)
270 +
271 +
272 +#ifndef WIN32
273 +#include <sys/stat.h>
274 +#endif
275 +
276 +
277 +#ifdef CONFIG_YAFFS_PROVIDE_DEFS
278 +/* File types */
279 +
280 +
281 #define DT_UNKNOWN 0
282 #define DT_FIFO 1
283 #define DT_CHR 2
284 @@ -212,6 +153,7 @@ static __inline__ void list_splice(struc
285 #define DT_SOCK 12
286 #define DT_WHT 14
287
288 +
289 #ifndef WIN32
290 #include <sys/stat.h>
291 #endif
292 @@ -227,10 +169,6 @@ static __inline__ void list_splice(struc
293 #define ATTR_ATIME 16
294 #define ATTR_MTIME 32
295 #define ATTR_CTIME 64
296 -#define ATTR_ATIME_SET 128
297 -#define ATTR_MTIME_SET 256
298 -#define ATTR_FORCE 512 /* Not a change, but a change it */
299 -#define ATTR_ATTR_FLAG 1024
300
301 struct iattr {
302 unsigned int ia_valid;
303 @@ -244,21 +182,15 @@ struct iattr {
304 unsigned int ia_attr_flags;
305 };
306
307 -#define KERN_DEBUG
308 +#endif
309
310 #else
311
312 -#ifndef WIN32
313 #include <linux/types.h>
314 -#include <linux/list.h>
315 #include <linux/fs.h>
316 #include <linux/stat.h>
317 -#endif
318
319 #endif
320
321 -#if defined WIN32
322 -#undef new
323 -#endif
324
325 #endif
326 --- a/fs/yaffs2/Kconfig
327 +++ b/fs/yaffs2/Kconfig
328 @@ -5,7 +5,7 @@
329 config YAFFS_FS
330 tristate "YAFFS2 file system support"
331 default n
332 - depends on MTD
333 + depends on MTD_BLOCK
334 select YAFFS_YAFFS1
335 select YAFFS_YAFFS2
336 help
337 @@ -43,7 +43,8 @@ config YAFFS_9BYTE_TAGS
338 format that you need to continue to support. New data written
339 also uses the older-style format. Note: Use of this option
340 generally requires that MTD's oob layout be adjusted to use the
341 - older-style format. See notes on tags formats and MTD versions.
342 + older-style format. See notes on tags formats and MTD versions
343 + in yaffs_mtdif1.c.
344
345 If unsure, say N.
346
347 @@ -109,26 +110,6 @@ config YAFFS_DISABLE_LAZY_LOAD
348
349 If unsure, say N.
350
351 -config YAFFS_CHECKPOINT_RESERVED_BLOCKS
352 - int "Reserved blocks for checkpointing"
353 - depends on YAFFS_YAFFS2
354 - default 10
355 - help
356 - Give the number of Blocks to reserve for checkpointing.
357 - Checkpointing saves the state at unmount so that mounting is
358 - much faster as a scan of all the flash to regenerate this state
359 - is not needed. These Blocks are reserved per partition, so if
360 - you have very small partitions the default (10) may be a mess
361 - for you. You can set this value to 0, but that does not mean
362 - checkpointing is disabled at all. There only won't be any
363 - specially reserved blocks for checkpointing, so if there is
364 - enough free space on the filesystem, it will be used for
365 - checkpointing.
366 -
367 - If unsure, leave at default (10), but don't wonder if there are
368 - always 2MB used on your large page device partition (10 x 2k
369 - pagesize). When using small partitions or when being very small
370 - on space, you probably want to set this to zero.
371
372 config YAFFS_DISABLE_WIDE_TNODES
373 bool "Turn off wide tnodes"
374 --- a/fs/yaffs2/Makefile
375 +++ b/fs/yaffs2/Makefile
376 @@ -5,7 +5,6 @@
377 obj-$(CONFIG_YAFFS_FS) += yaffs.o
378
379 yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o
380 -yaffs-y += yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
381 +yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o
382 yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o
383 -yaffs-y += yaffs_mtdif1.o yaffs_packedtags1.o
384 -yaffs-y += yaffs_mtdif.o yaffs_mtdif2.o
385 +yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o
386 --- a/fs/yaffs2/moduleconfig.h
387 +++ b/fs/yaffs2/moduleconfig.h
388 @@ -27,12 +27,12 @@
389
390 /* Default: Not selected */
391 /* Meaning: Yaffs does its own ECC, rather than using MTD ECC */
392 -//#define CONFIG_YAFFS_DOES_ECC
393 +/* #define CONFIG_YAFFS_DOES_ECC */
394
395 /* Default: Not selected */
396 /* Meaning: ECC byte order is 'wrong'. Only meaningful if */
397 /* CONFIG_YAFFS_DOES_ECC is set */
398 -//#define CONFIG_YAFFS_ECC_WRONG_ORDER
399 +/* #define CONFIG_YAFFS_ECC_WRONG_ORDER */
400
401 /* Default: Selected */
402 /* Meaning: Disables testing whether chunks are erased before writing to them*/
403 @@ -54,11 +54,11 @@ that you need to continue to support. N
404 older-style format.
405 Note: Use of this option generally requires that MTD's oob layout be
406 adjusted to use the older-style format. See notes on tags formats and
407 -MTD versions.
408 +MTD versions in yaffs_mtdif1.c.
409 */
410 /* Default: Not selected */
411 /* Meaning: Use older-style on-NAND data format with pageStatus byte */
412 -#define CONFIG_YAFFS_9BYTE_TAGS
413 +/* #define CONFIG_YAFFS_9BYTE_TAGS */
414
415 #endif /* YAFFS_OUT_OF_TREE */
416
417 --- a/fs/yaffs2/yaffs_checkptrw.c
418 +++ b/fs/yaffs2/yaffs_checkptrw.c
419 @@ -12,48 +12,43 @@
420 */
421
422 const char *yaffs_checkptrw_c_version =
423 - "$Id: yaffs_checkptrw.c,v 1.14 2007-05-15 20:07:40 charles Exp $";
424 + "$Id: yaffs_checkptrw.c,v 1.18 2009-03-06 17:20:49 wookey Exp $";
425
426
427 #include "yaffs_checkptrw.h"
428 -
429 +#include "yaffs_getblockinfo.h"
430
431 static int yaffs_CheckpointSpaceOk(yaffs_Device *dev)
432 {
433 -
434 int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
435
436 T(YAFFS_TRACE_CHECKPOINT,
437 (TSTR("checkpt blocks available = %d" TENDSTR),
438 blocksAvailable));
439
440 -
441 return (blocksAvailable <= 0) ? 0 : 1;
442 }
443
444
445 static int yaffs_CheckpointErase(yaffs_Device *dev)
446 {
447 -
448 int i;
449
450 -
451 - if(!dev->eraseBlockInNAND)
452 + if (!dev->eraseBlockInNAND)
453 return 0;
454 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("checking blocks %d to %d"TENDSTR),
455 - dev->internalStartBlock,dev->internalEndBlock));
456 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("checking blocks %d to %d"TENDSTR),
457 + dev->internalStartBlock, dev->internalEndBlock));
458
459 - for(i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
460 - yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
461 - if(bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT){
462 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("erasing checkpt block %d"TENDSTR),i));
463 - if(dev->eraseBlockInNAND(dev,i- dev->blockOffset /* realign */)){
464 + for (i = dev->internalStartBlock; i <= dev->internalEndBlock; i++) {
465 + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
466 + if (bi->blockState == YAFFS_BLOCK_STATE_CHECKPOINT) {
467 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("erasing checkpt block %d"TENDSTR), i));
468 + if (dev->eraseBlockInNAND(dev, i - dev->blockOffset /* realign */)) {
469 bi->blockState = YAFFS_BLOCK_STATE_EMPTY;
470 dev->nErasedBlocks++;
471 dev->nFreeChunks += dev->nChunksPerBlock;
472 - }
473 - else {
474 - dev->markNANDBlockBad(dev,i);
475 + } else {
476 + dev->markNANDBlockBad(dev, i);
477 bi->blockState = YAFFS_BLOCK_STATE_DEAD;
478 }
479 }
480 @@ -71,23 +66,23 @@ static void yaffs_CheckpointFindNextEras
481 int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
482 T(YAFFS_TRACE_CHECKPOINT,
483 (TSTR("allocating checkpt block: erased %d reserved %d avail %d next %d "TENDSTR),
484 - dev->nErasedBlocks,dev->nReservedBlocks,blocksAvailable,dev->checkpointNextBlock));
485 + dev->nErasedBlocks, dev->nReservedBlocks, blocksAvailable, dev->checkpointNextBlock));
486
487 - if(dev->checkpointNextBlock >= 0 &&
488 - dev->checkpointNextBlock <= dev->internalEndBlock &&
489 - blocksAvailable > 0){
490 -
491 - for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){
492 - yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,i);
493 - if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY){
494 + if (dev->checkpointNextBlock >= 0 &&
495 + dev->checkpointNextBlock <= dev->internalEndBlock &&
496 + blocksAvailable > 0) {
497 +
498 + for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
499 + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, i);
500 + if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY) {
501 dev->checkpointNextBlock = i + 1;
502 dev->checkpointCurrentBlock = i;
503 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("allocating checkpt block %d"TENDSTR),i));
504 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("allocating checkpt block %d"TENDSTR), i));
505 return;
506 }
507 }
508 }
509 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("out of checkpt blocks"TENDSTR)));
510 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("out of checkpt blocks"TENDSTR)));
511
512 dev->checkpointNextBlock = -1;
513 dev->checkpointCurrentBlock = -1;
514 @@ -98,30 +93,31 @@ static void yaffs_CheckpointFindNextChec
515 int i;
516 yaffs_ExtendedTags tags;
517
518 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: start: blocks %d next %d" TENDSTR),
519 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: start: blocks %d next %d" TENDSTR),
520 dev->blocksInCheckpoint, dev->checkpointNextBlock));
521
522 - if(dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
523 - for(i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++){
524 + if (dev->blocksInCheckpoint < dev->checkpointMaxBlocks)
525 + for (i = dev->checkpointNextBlock; i <= dev->internalEndBlock; i++) {
526 int chunk = i * dev->nChunksPerBlock;
527 int realignedChunk = chunk - dev->chunkOffset;
528
529 - dev->readChunkWithTagsFromNAND(dev,realignedChunk,NULL,&tags);
530 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR),
531 - i, tags.objectId,tags.sequenceNumber,tags.eccResult));
532 + dev->readChunkWithTagsFromNAND(dev, realignedChunk,
533 + NULL, &tags);
534 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("find next checkpt block: search: block %d oid %d seq %d eccr %d" TENDSTR),
535 + i, tags.objectId, tags.sequenceNumber, tags.eccResult));
536
537 - if(tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA){
538 + if (tags.sequenceNumber == YAFFS_SEQUENCE_CHECKPOINT_DATA) {
539 /* Right kind of block */
540 dev->checkpointNextBlock = tags.objectId;
541 dev->checkpointCurrentBlock = i;
542 dev->checkpointBlockList[dev->blocksInCheckpoint] = i;
543 dev->blocksInCheckpoint++;
544 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("found checkpt block %d"TENDSTR),i));
545 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("found checkpt block %d"TENDSTR), i));
546 return;
547 }
548 }
549
550 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("found no more checkpt blocks"TENDSTR)));
551 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("found no more checkpt blocks"TENDSTR)));
552
553 dev->checkpointNextBlock = -1;
554 dev->checkpointCurrentBlock = -1;
555 @@ -133,17 +129,17 @@ int yaffs_CheckpointOpen(yaffs_Device *d
556
557 /* Got the functions we need? */
558 if (!dev->writeChunkWithTagsToNAND ||
559 - !dev->readChunkWithTagsFromNAND ||
560 - !dev->eraseBlockInNAND ||
561 - !dev->markNANDBlockBad)
562 + !dev->readChunkWithTagsFromNAND ||
563 + !dev->eraseBlockInNAND ||
564 + !dev->markNANDBlockBad)
565 return 0;
566
567 - if(forWriting && !yaffs_CheckpointSpaceOk(dev))
568 + if (forWriting && !yaffs_CheckpointSpaceOk(dev))
569 return 0;
570
571 - if(!dev->checkpointBuffer)
572 - dev->checkpointBuffer = YMALLOC_DMA(dev->nDataBytesPerChunk);
573 - if(!dev->checkpointBuffer)
574 + if (!dev->checkpointBuffer)
575 + dev->checkpointBuffer = YMALLOC_DMA(dev->totalBytesPerChunk);
576 + if (!dev->checkpointBuffer)
577 return 0;
578
579
580 @@ -159,12 +155,10 @@ int yaffs_CheckpointOpen(yaffs_Device *d
581 dev->checkpointNextBlock = dev->internalStartBlock;
582
583 /* Erase all the blocks in the checkpoint area */
584 - if(forWriting){
585 - memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
586 + if (forWriting) {
587 + memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
588 dev->checkpointByteOffset = 0;
589 return yaffs_CheckpointErase(dev);
590 -
591 -
592 } else {
593 int i;
594 /* Set to a value that will kick off a read */
595 @@ -174,7 +168,7 @@ int yaffs_CheckpointOpen(yaffs_Device *d
596 dev->blocksInCheckpoint = 0;
597 dev->checkpointMaxBlocks = (dev->internalEndBlock - dev->internalStartBlock)/16 + 2;
598 dev->checkpointBlockList = YMALLOC(sizeof(int) * dev->checkpointMaxBlocks);
599 - for(i = 0; i < dev->checkpointMaxBlocks; i++)
600 + for (i = 0; i < dev->checkpointMaxBlocks; i++)
601 dev->checkpointBlockList[i] = -1;
602 }
603
604 @@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device
605
606 static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
607 {
608 -
609 int chunk;
610 int realignedChunk;
611
612 yaffs_ExtendedTags tags;
613
614 - if(dev->checkpointCurrentBlock < 0){
615 + if (dev->checkpointCurrentBlock < 0) {
616 yaffs_CheckpointFindNextErasedBlock(dev);
617 dev->checkpointCurrentChunk = 0;
618 }
619
620 - if(dev->checkpointCurrentBlock < 0)
621 + if (dev->checkpointCurrentBlock < 0)
622 return 0;
623
624 tags.chunkDeleted = 0;
625 @@ -210,10 +203,10 @@ static int yaffs_CheckpointFlushBuffer(y
626 tags.chunkId = dev->checkpointPageSequence + 1;
627 tags.sequenceNumber = YAFFS_SEQUENCE_CHECKPOINT_DATA;
628 tags.byteCount = dev->nDataBytesPerChunk;
629 - if(dev->checkpointCurrentChunk == 0){
630 + if (dev->checkpointCurrentChunk == 0) {
631 /* First chunk we write for the block? Set block state to
632 checkpoint */
633 - yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointCurrentBlock);
634 + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointCurrentBlock);
635 bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
636 dev->blocksInCheckpoint++;
637 }
638 @@ -221,28 +214,29 @@ static int yaffs_CheckpointFlushBuffer(y
639 chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk;
640
641
642 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
643 - chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk,tags.objectId,tags.chunkId));
644 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint wite buffer nand %d(%d:%d) objid %d chId %d" TENDSTR),
645 + chunk, dev->checkpointCurrentBlock, dev->checkpointCurrentChunk, tags.objectId, tags.chunkId));
646
647 realignedChunk = chunk - dev->chunkOffset;
648
649 - dev->writeChunkWithTagsToNAND(dev,realignedChunk,dev->checkpointBuffer,&tags);
650 + dev->writeChunkWithTagsToNAND(dev, realignedChunk,
651 + dev->checkpointBuffer, &tags);
652 dev->checkpointByteOffset = 0;
653 dev->checkpointPageSequence++;
654 dev->checkpointCurrentChunk++;
655 - if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock){
656 + if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock) {
657 dev->checkpointCurrentChunk = 0;
658 dev->checkpointCurrentBlock = -1;
659 }
660 - memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
661 + memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
662
663 return 1;
664 }
665
666
667 -int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
668 +int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes)
669 {
670 - int i=0;
671 + int i = 0;
672 int ok = 1;
673
674
675 @@ -250,17 +244,14 @@ int yaffs_CheckpointWrite(yaffs_Device *
676
677
678
679 - if(!dev->checkpointBuffer)
680 + if (!dev->checkpointBuffer)
681 return 0;
682
683 - if(!dev->checkpointOpenForWrite)
684 + if (!dev->checkpointOpenForWrite)
685 return -1;
686
687 - while(i < nBytes && ok) {
688 -
689 -
690 -
691 - dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes ;
692 + while (i < nBytes && ok) {
693 + dev->checkpointBuffer[dev->checkpointByteOffset] = *dataBytes;
694 dev->checkpointSum += *dataBytes;
695 dev->checkpointXor ^= *dataBytes;
696
697 @@ -270,18 +261,17 @@ int yaffs_CheckpointWrite(yaffs_Device *
698 dev->checkpointByteCount++;
699
700
701 - if(dev->checkpointByteOffset < 0 ||
702 + if (dev->checkpointByteOffset < 0 ||
703 dev->checkpointByteOffset >= dev->nDataBytesPerChunk)
704 ok = yaffs_CheckpointFlushBuffer(dev);
705 -
706 }
707
708 - return i;
709 + return i;
710 }
711
712 int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
713 {
714 - int i=0;
715 + int i = 0;
716 int ok = 1;
717 yaffs_ExtendedTags tags;
718
719 @@ -291,52 +281,54 @@ int yaffs_CheckpointRead(yaffs_Device *d
720
721 __u8 *dataBytes = (__u8 *)data;
722
723 - if(!dev->checkpointBuffer)
724 + if (!dev->checkpointBuffer)
725 return 0;
726
727 - if(dev->checkpointOpenForWrite)
728 + if (dev->checkpointOpenForWrite)
729 return -1;
730
731 - while(i < nBytes && ok) {
732 + while (i < nBytes && ok) {
733
734
735 - if(dev->checkpointByteOffset < 0 ||
736 - dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
737 + if (dev->checkpointByteOffset < 0 ||
738 + dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
739
740 - if(dev->checkpointCurrentBlock < 0){
741 + if (dev->checkpointCurrentBlock < 0) {
742 yaffs_CheckpointFindNextCheckpointBlock(dev);
743 dev->checkpointCurrentChunk = 0;
744 }
745
746 - if(dev->checkpointCurrentBlock < 0)
747 + if (dev->checkpointCurrentBlock < 0)
748 ok = 0;
749 else {
750 -
751 - chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock +
752 - dev->checkpointCurrentChunk;
753 + chunk = dev->checkpointCurrentBlock *
754 + dev->nChunksPerBlock +
755 + dev->checkpointCurrentChunk;
756
757 realignedChunk = chunk - dev->chunkOffset;
758
759 - /* read in the next chunk */
760 - /* printf("read checkpoint page %d\n",dev->checkpointPage); */
761 - dev->readChunkWithTagsFromNAND(dev, realignedChunk,
762 - dev->checkpointBuffer,
763 - &tags);
764 -
765 - if(tags.chunkId != (dev->checkpointPageSequence + 1) ||
766 - tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
767 - ok = 0;
768 + /* read in the next chunk */
769 + /* printf("read checkpoint page %d\n",dev->checkpointPage); */
770 + dev->readChunkWithTagsFromNAND(dev,
771 + realignedChunk,
772 + dev->checkpointBuffer,
773 + &tags);
774 +
775 + if (tags.chunkId != (dev->checkpointPageSequence + 1) ||
776 + tags.eccResult > YAFFS_ECC_RESULT_FIXED ||
777 + tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
778 + ok = 0;
779
780 dev->checkpointByteOffset = 0;
781 dev->checkpointPageSequence++;
782 dev->checkpointCurrentChunk++;
783
784 - if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
785 + if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
786 dev->checkpointCurrentBlock = -1;
787 }
788 }
789
790 - if(ok){
791 + if (ok) {
792 *dataBytes = dev->checkpointBuffer[dev->checkpointByteOffset];
793 dev->checkpointSum += *dataBytes;
794 dev->checkpointXor ^= *dataBytes;
795 @@ -353,17 +345,17 @@ int yaffs_CheckpointRead(yaffs_Device *d
796 int yaffs_CheckpointClose(yaffs_Device *dev)
797 {
798
799 - if(dev->checkpointOpenForWrite){
800 - if(dev->checkpointByteOffset != 0)
801 + if (dev->checkpointOpenForWrite) {
802 + if (dev->checkpointByteOffset != 0)
803 yaffs_CheckpointFlushBuffer(dev);
804 } else {
805 int i;
806 - for(i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++){
807 - yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev,dev->checkpointBlockList[i]);
808 - if(bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
809 + for (i = 0; i < dev->blocksInCheckpoint && dev->checkpointBlockList[i] >= 0; i++) {
810 + yaffs_BlockInfo *bi = yaffs_GetBlockInfo(dev, dev->checkpointBlockList[i]);
811 + if (bi->blockState == YAFFS_BLOCK_STATE_EMPTY)
812 bi->blockState = YAFFS_BLOCK_STATE_CHECKPOINT;
813 else {
814 - // Todo this looks odd...
815 + /* Todo this looks odd... */
816 }
817 }
818 YFREE(dev->checkpointBlockList);
819 @@ -374,27 +366,25 @@ int yaffs_CheckpointClose(yaffs_Device *
820 dev->nErasedBlocks -= dev->blocksInCheckpoint;
821
822
823 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint byte count %d" TENDSTR),
824 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint byte count %d" TENDSTR),
825 dev->checkpointByteCount));
826
827 - if(dev->checkpointBuffer){
828 + if (dev->checkpointBuffer) {
829 /* free the buffer */
830 YFREE(dev->checkpointBuffer);
831 dev->checkpointBuffer = NULL;
832 return 1;
833 - }
834 - else
835 + } else
836 return 0;
837 -
838 }
839
840 int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
841 {
842 /* Erase the first checksum block */
843
844 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint invalidate"TENDSTR)));
845 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate"TENDSTR)));
846
847 - if(!yaffs_CheckpointSpaceOk(dev))
848 + if (!yaffs_CheckpointSpaceOk(dev))
849 return 0;
850
851 return yaffs_CheckpointErase(dev);
852 --- a/fs/yaffs2/yaffs_checkptrw.h
853 +++ b/fs/yaffs2/yaffs_checkptrw.h
854 @@ -20,9 +20,9 @@
855
856 int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting);
857
858 -int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes);
859 +int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes);
860
861 -int yaffs_CheckpointRead(yaffs_Device *dev,void *data, int nBytes);
862 +int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes);
863
864 int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum);
865
866 --- a/fs/yaffs2/yaffs_ecc.c
867 +++ b/fs/yaffs2/yaffs_ecc.c
868 @@ -29,7 +29,7 @@
869 */
870
871 const char *yaffs_ecc_c_version =
872 - "$Id: yaffs_ecc.c,v 1.9 2007-02-14 01:09:06 wookey Exp $";
873 + "$Id: yaffs_ecc.c,v 1.11 2009-03-06 17:20:50 wookey Exp $";
874
875 #include "yportenv.h"
876
877 @@ -109,12 +109,10 @@ void yaffs_ECCCalculate(const unsigned c
878 b = column_parity_table[*data++];
879 col_parity ^= b;
880
881 - if (b & 0x01) // odd number of bits in the byte
882 - {
883 + if (b & 0x01) { /* odd number of bits in the byte */
884 line_parity ^= i;
885 line_parity_prime ^= ~i;
886 }
887 -
888 }
889
890 ecc[2] = (~col_parity) | 0x03;
891 @@ -158,7 +156,7 @@ void yaffs_ECCCalculate(const unsigned c
892 ecc[0] = ~t;
893
894 #ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
895 - // Swap the bytes into the wrong order
896 + /* Swap the bytes into the wrong order */
897 t = ecc[0];
898 ecc[0] = ecc[1];
899 ecc[1] = t;
900 @@ -189,7 +187,7 @@ int yaffs_ECCCorrect(unsigned char *data
901 unsigned bit;
902
903 #ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
904 - // swap the bytes to correct for the wrong order
905 + /* swap the bytes to correct for the wrong order */
906 unsigned char t;
907
908 t = d0;
909 @@ -251,7 +249,7 @@ int yaffs_ECCCorrect(unsigned char *data
910 * ECCxxxOther does ECC calcs on arbitrary n bytes of data
911 */
912 void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
913 - yaffs_ECCOther * eccOther)
914 + yaffs_ECCOther *eccOther)
915 {
916 unsigned int i;
917
918 @@ -278,8 +276,8 @@ void yaffs_ECCCalculateOther(const unsig
919 }
920
921 int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
922 - yaffs_ECCOther * read_ecc,
923 - const yaffs_ECCOther * test_ecc)
924 + yaffs_ECCOther *read_ecc,
925 + const yaffs_ECCOther *test_ecc)
926 {
927 unsigned char cDelta; /* column parity delta */
928 unsigned lDelta; /* line parity delta */
929 @@ -294,8 +292,7 @@ int yaffs_ECCCorrectOther(unsigned char
930 return 0; /* no error */
931
932 if (lDelta == ~lDeltaPrime &&
933 - (((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15))
934 - {
935 + (((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15)) {
936 /* Single bit (recoverable) error in data */
937
938 bit = 0;
939 @@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char
940 if (cDelta & 0x02)
941 bit |= 0x01;
942
943 - if(lDelta >= nBytes)
944 + if (lDelta >= nBytes)
945 return -1;
946
947 data[lDelta] ^= (1 << bit);
948 @@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char
949 }
950
951 if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
952 - yaffs_CountBits(cDelta)) == 1) {
953 + yaffs_CountBits(cDelta)) == 1) {
954 /* Reccoverable error in ecc */
955
956 *read_ecc = *test_ecc;
957 @@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char
958 /* Unrecoverable error */
959
960 return -1;
961 -
962 }
963 -
964 --- a/fs/yaffs2/yaffs_ecc.h
965 +++ b/fs/yaffs2/yaffs_ecc.h
966 @@ -13,15 +13,15 @@
967 * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
968 */
969
970 - /*
971 - * This code implements the ECC algorithm used in SmartMedia.
972 - *
973 - * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
974 - * The two unused bit are set to 1.
975 - * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
976 - * blocks are used on a 512-byte NAND page.
977 - *
978 - */
979 +/*
980 + * This code implements the ECC algorithm used in SmartMedia.
981 + *
982 + * The ECC comprises 22 bits of parity information and is stuffed into 3 bytes.
983 + * The two unused bit are set to 1.
984 + * The ECC can correct single bit errors in a 256-byte page of data. Thus, two such ECC
985 + * blocks are used on a 512-byte NAND page.
986 + *
987 + */
988
989 #ifndef __YAFFS_ECC_H__
990 #define __YAFFS_ECC_H__
991 @@ -34,11 +34,11 @@ typedef struct {
992
993 void yaffs_ECCCalculate(const unsigned char *data, unsigned char *ecc);
994 int yaffs_ECCCorrect(unsigned char *data, unsigned char *read_ecc,
995 - const unsigned char *test_ecc);
996 + const unsigned char *test_ecc);
997
998 void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
999 - yaffs_ECCOther * ecc);
1000 + yaffs_ECCOther *ecc);
1001 int yaffs_ECCCorrectOther(unsigned char *data, unsigned nBytes,
1002 - yaffs_ECCOther * read_ecc,
1003 - const yaffs_ECCOther * test_ecc);
1004 + yaffs_ECCOther *read_ecc,
1005 + const yaffs_ECCOther *test_ecc);
1006 #endif
1007 --- a/fs/yaffs2/yaffs_fs.c
1008 +++ b/fs/yaffs2/yaffs_fs.c
1009 @@ -1,7 +1,7 @@
1010 /*
1011 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
1012 *
1013 - * Copyright (C) 2002-2007 Aleph One Ltd.
1014 + * Copyright (C) 2002-2009 Aleph One Ltd.
1015 * for Toby Churchill Ltd and Brightstar Engineering
1016 *
1017 * Created by Charles Manning <charles@aleph1.co.uk>
1018 @@ -32,18 +32,17 @@
1019 */
1020
1021 const char *yaffs_fs_c_version =
1022 - "$Id: yaffs_fs.c,v 1.63 2007-09-19 20:35:40 imcd Exp $";
1023 + "$Id: yaffs_fs.c,v 1.79 2009-03-17 01:12:00 wookey Exp $";
1024 extern const char *yaffs_guts_c_version;
1025
1026 #include <linux/version.h>
1027 -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
1028 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
1029 #include <linux/config.h>
1030 #endif
1031 #include <linux/kernel.h>
1032 #include <linux/module.h>
1033 #include <linux/slab.h>
1034 #include <linux/init.h>
1035 -#include <linux/list.h>
1036 #include <linux/fs.h>
1037 #include <linux/proc_fs.h>
1038 #include <linux/smp_lock.h>
1039 @@ -53,10 +52,12 @@ extern const char *yaffs_guts_c_version;
1040 #include <linux/string.h>
1041 #include <linux/ctype.h>
1042
1043 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1044 +#include "asm/div64.h"
1045 +
1046 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1047
1048 #include <linux/statfs.h> /* Added NCB 15-8-2003 */
1049 -#include <asm/statfs.h>
1050 +#include <linux/statfs.h>
1051 #define UnlockPage(p) unlock_page(p)
1052 #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags)
1053
1054 @@ -69,22 +70,45 @@ extern const char *yaffs_guts_c_version;
1055 #define BDEVNAME_SIZE 0
1056 #define yaffs_devname(sb, buf) kdevname(sb->s_dev)
1057
1058 -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1059 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0))
1060 /* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */
1061 #define __user
1062 #endif
1063
1064 #endif
1065
1066 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
1067 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 26))
1068 +#define YPROC_ROOT (&proc_root)
1069 +#else
1070 +#define YPROC_ROOT NULL
1071 +#endif
1072 +
1073 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
1074 #define WRITE_SIZE_STR "writesize"
1075 -#define WRITE_SIZE(mtd) (mtd)->writesize
1076 +#define WRITE_SIZE(mtd) ((mtd)->writesize)
1077 #else
1078 #define WRITE_SIZE_STR "oobblock"
1079 -#define WRITE_SIZE(mtd) (mtd)->oobblock
1080 +#define WRITE_SIZE(mtd) ((mtd)->oobblock)
1081 #endif
1082
1083 -#include <asm/uaccess.h>
1084 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
1085 +#define YAFFS_USE_WRITE_BEGIN_END 1
1086 +#else
1087 +#define YAFFS_USE_WRITE_BEGIN_END 0
1088 +#endif
1089 +
1090 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
1091 +static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
1092 +{
1093 + uint64_t result = partition_size;
1094 + do_div(result, block_size);
1095 + return (uint32_t)result;
1096 +}
1097 +#else
1098 +#define YCALCBLOCKS(s, b) ((s)/(b))
1099 +#endif
1100 +
1101 +#include <linux/uaccess.h>
1102
1103 #include "yportenv.h"
1104 #include "yaffs_guts.h"
1105 @@ -96,28 +120,44 @@ extern const char *yaffs_guts_c_version;
1106
1107 unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS;
1108 unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS;
1109 +unsigned int yaffs_auto_checkpoint = 1;
1110
1111 /* Module Parameters */
1112 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1113 -module_param(yaffs_traceMask,uint,0644);
1114 -module_param(yaffs_wr_attempts,uint,0644);
1115 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1116 +module_param(yaffs_traceMask, uint, 0644);
1117 +module_param(yaffs_wr_attempts, uint, 0644);
1118 +module_param(yaffs_auto_checkpoint, uint, 0644);
1119 +#else
1120 +MODULE_PARM(yaffs_traceMask, "i");
1121 +MODULE_PARM(yaffs_wr_attempts, "i");
1122 +MODULE_PARM(yaffs_auto_checkpoint, "i");
1123 +#endif
1124 +
1125 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 25))
1126 +/* use iget and read_inode */
1127 +#define Y_IGET(sb, inum) iget((sb), (inum))
1128 +static void yaffs_read_inode(struct inode *inode);
1129 +
1130 #else
1131 -MODULE_PARM(yaffs_traceMask,"i");
1132 -MODULE_PARM(yaffs_wr_attempts,"i");
1133 +/* Call local equivalent */
1134 +#define YAFFS_USE_OWN_IGET
1135 +#define Y_IGET(sb, inum) yaffs_iget((sb), (inum))
1136 +
1137 +static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino);
1138 #endif
1139
1140 /*#define T(x) printk x */
1141
1142 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
1143 -#define yaffs_InodeToObjectLV(iptr) (iptr)->i_private
1144 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
1145 +#define yaffs_InodeToObjectLV(iptr) ((iptr)->i_private)
1146 #else
1147 -#define yaffs_InodeToObjectLV(iptr) (iptr)->u.generic_ip
1148 +#define yaffs_InodeToObjectLV(iptr) ((iptr)->u.generic_ip)
1149 #endif
1150
1151 #define yaffs_InodeToObject(iptr) ((yaffs_Object *)(yaffs_InodeToObjectLV(iptr)))
1152 #define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode)
1153
1154 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1155 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1156 #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->s_fs_info)
1157 #else
1158 #define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp)
1159 @@ -126,47 +166,49 @@ MODULE_PARM(yaffs_wr_attempts,"i");
1160 static void yaffs_put_super(struct super_block *sb);
1161
1162 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
1163 - loff_t * pos);
1164 + loff_t *pos);
1165 +static ssize_t yaffs_hold_space(struct file *f);
1166 +static void yaffs_release_space(struct file *f);
1167
1168 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
1169 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
1170 static int yaffs_file_flush(struct file *file, fl_owner_t id);
1171 #else
1172 static int yaffs_file_flush(struct file *file);
1173 #endif
1174
1175 static int yaffs_sync_object(struct file *file, struct dentry *dentry,
1176 - int datasync);
1177 + int datasync);
1178
1179 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir);
1180
1181 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1182 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1183 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
1184 struct nameidata *n);
1185 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
1186 - struct nameidata *n);
1187 + struct nameidata *n);
1188 #else
1189 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode);
1190 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry);
1191 #endif
1192 static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
1193 - struct dentry *dentry);
1194 + struct dentry *dentry);
1195 static int yaffs_unlink(struct inode *dir, struct dentry *dentry);
1196 static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
1197 - const char *symname);
1198 + const char *symname);
1199 static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode);
1200
1201 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1202 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1203 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
1204 - dev_t dev);
1205 + dev_t dev);
1206 #else
1207 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
1208 - int dev);
1209 + int dev);
1210 #endif
1211 static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry,
1212 struct inode *new_dir, struct dentry *new_dentry);
1213 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);
1214
1215 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
1216 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
1217 static int yaffs_sync_fs(struct super_block *sb, int wait);
1218 static void yaffs_write_super(struct super_block *sb);
1219 #else
1220 @@ -174,33 +216,47 @@ static int yaffs_sync_fs(struct super_bl
1221 static int yaffs_write_super(struct super_block *sb);
1222 #endif
1223
1224 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
1225 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
1226 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf);
1227 -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1228 +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1229 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
1230 #else
1231 static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
1232 #endif
1233 -static void yaffs_read_inode(struct inode *inode);
1234
1235 +#ifdef YAFFS_HAS_PUT_INODE
1236 static void yaffs_put_inode(struct inode *inode);
1237 +#endif
1238 +
1239 static void yaffs_delete_inode(struct inode *);
1240 static void yaffs_clear_inode(struct inode *);
1241
1242 static int yaffs_readpage(struct file *file, struct page *page);
1243 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1244 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1245 static int yaffs_writepage(struct page *page, struct writeback_control *wbc);
1246 #else
1247 static int yaffs_writepage(struct page *page);
1248 #endif
1249 +
1250 +
1251 +#if (YAFFS_USE_WRITE_BEGIN_END != 0)
1252 +static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
1253 + loff_t pos, unsigned len, unsigned flags,
1254 + struct page **pagep, void **fsdata);
1255 +static int yaffs_write_end(struct file *filp, struct address_space *mapping,
1256 + loff_t pos, unsigned len, unsigned copied,
1257 + struct page *pg, void *fsdadata);
1258 +#else
1259 static int yaffs_prepare_write(struct file *f, struct page *pg,
1260 - unsigned offset, unsigned to);
1261 + unsigned offset, unsigned to);
1262 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
1263 - unsigned to);
1264 + unsigned to);
1265
1266 -static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
1267 - int buflen);
1268 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
1269 +#endif
1270 +
1271 +static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
1272 + int buflen);
1273 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
1274 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
1275 #else
1276 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
1277 @@ -209,12 +265,17 @@ static int yaffs_follow_link(struct dent
1278 static struct address_space_operations yaffs_file_address_operations = {
1279 .readpage = yaffs_readpage,
1280 .writepage = yaffs_writepage,
1281 +#if (YAFFS_USE_WRITE_BEGIN_END > 0)
1282 + .write_begin = yaffs_write_begin,
1283 + .write_end = yaffs_write_end,
1284 +#else
1285 .prepare_write = yaffs_prepare_write,
1286 .commit_write = yaffs_commit_write,
1287 +#endif
1288 };
1289
1290 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22))
1291 -static struct file_operations yaffs_file_operations = {
1292 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 22))
1293 +static const struct file_operations yaffs_file_operations = {
1294 .read = do_sync_read,
1295 .write = do_sync_write,
1296 .aio_read = generic_file_aio_read,
1297 @@ -224,11 +285,12 @@ static struct file_operations yaffs_file
1298 .fsync = yaffs_sync_object,
1299 .splice_read = generic_file_splice_read,
1300 .splice_write = generic_file_splice_write,
1301 + .llseek = generic_file_llseek,
1302 };
1303
1304 -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
1305 +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
1306
1307 -static struct file_operations yaffs_file_operations = {
1308 +static const struct file_operations yaffs_file_operations = {
1309 .read = do_sync_read,
1310 .write = do_sync_write,
1311 .aio_read = generic_file_aio_read,
1312 @@ -241,29 +303,29 @@ static struct file_operations yaffs_file
1313
1314 #else
1315
1316 -static struct file_operations yaffs_file_operations = {
1317 +static const struct file_operations yaffs_file_operations = {
1318 .read = generic_file_read,
1319 .write = generic_file_write,
1320 .mmap = generic_file_mmap,
1321 .flush = yaffs_file_flush,
1322 .fsync = yaffs_sync_object,
1323 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1324 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1325 .sendfile = generic_file_sendfile,
1326 #endif
1327 };
1328 #endif
1329
1330 -static struct inode_operations yaffs_file_inode_operations = {
1331 +static const struct inode_operations yaffs_file_inode_operations = {
1332 .setattr = yaffs_setattr,
1333 };
1334
1335 -static struct inode_operations yaffs_symlink_inode_operations = {
1336 +static const struct inode_operations yaffs_symlink_inode_operations = {
1337 .readlink = yaffs_readlink,
1338 .follow_link = yaffs_follow_link,
1339 .setattr = yaffs_setattr,
1340 };
1341
1342 -static struct inode_operations yaffs_dir_inode_operations = {
1343 +static const struct inode_operations yaffs_dir_inode_operations = {
1344 .create = yaffs_create,
1345 .lookup = yaffs_lookup,
1346 .link = yaffs_link,
1347 @@ -276,16 +338,21 @@ static struct inode_operations yaffs_dir
1348 .setattr = yaffs_setattr,
1349 };
1350
1351 -static struct file_operations yaffs_dir_operations = {
1352 +static const struct file_operations yaffs_dir_operations = {
1353 .read = generic_read_dir,
1354 .readdir = yaffs_readdir,
1355 .fsync = yaffs_sync_object,
1356 };
1357
1358 -static struct super_operations yaffs_super_ops = {
1359 +static const struct super_operations yaffs_super_ops = {
1360 .statfs = yaffs_statfs,
1361 +
1362 +#ifndef YAFFS_USE_OWN_IGET
1363 .read_inode = yaffs_read_inode,
1364 +#endif
1365 +#ifdef YAFFS_HAS_PUT_INODE
1366 .put_inode = yaffs_put_inode,
1367 +#endif
1368 .put_super = yaffs_put_super,
1369 .delete_inode = yaffs_delete_inode,
1370 .clear_inode = yaffs_clear_inode,
1371 @@ -293,22 +360,21 @@ static struct super_operations yaffs_sup
1372 .write_super = yaffs_write_super,
1373 };
1374
1375 -static void yaffs_GrossLock(yaffs_Device * dev)
1376 +static void yaffs_GrossLock(yaffs_Device *dev)
1377 {
1378 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs locking\n"));
1379 -
1380 + T(YAFFS_TRACE_OS, ("yaffs locking %p\n", current));
1381 down(&dev->grossLock);
1382 + T(YAFFS_TRACE_OS, ("yaffs locked %p\n", current));
1383 }
1384
1385 -static void yaffs_GrossUnlock(yaffs_Device * dev)
1386 +static void yaffs_GrossUnlock(yaffs_Device *dev)
1387 {
1388 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs unlocking\n"));
1389 + T(YAFFS_TRACE_OS, ("yaffs unlocking %p\n", current));
1390 up(&dev->grossLock);
1391 -
1392 }
1393
1394 -static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
1395 - int buflen)
1396 +static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
1397 + int buflen)
1398 {
1399 unsigned char *alias;
1400 int ret;
1401 @@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry
1402 return ret;
1403 }
1404
1405 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
1406 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
1407 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
1408 #else
1409 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
1410 @@ -345,32 +411,31 @@ static int yaffs_follow_link(struct dent
1411
1412 yaffs_GrossUnlock(dev);
1413
1414 - if (!alias)
1415 - {
1416 + if (!alias) {
1417 ret = -ENOMEM;
1418 goto out;
1419 - }
1420 + }
1421
1422 ret = vfs_follow_link(nd, alias);
1423 kfree(alias);
1424 out:
1425 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
1426 - return ERR_PTR (ret);
1427 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
1428 + return ERR_PTR(ret);
1429 #else
1430 return ret;
1431 #endif
1432 }
1433
1434 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
1435 - yaffs_Object * obj);
1436 + yaffs_Object *obj);
1437
1438 /*
1439 * Lookup is used to find objects in the fs
1440 */
1441 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1442 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1443
1444 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
1445 - struct nameidata *n)
1446 + struct nameidata *n)
1447 #else
1448 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
1449 #endif
1450 @@ -383,12 +448,11 @@ static struct dentry *yaffs_lookup(struc
1451 yaffs_GrossLock(dev);
1452
1453 T(YAFFS_TRACE_OS,
1454 - (KERN_DEBUG "yaffs_lookup for %d:%s\n",
1455 - yaffs_InodeToObject(dir)->objectId, dentry->d_name.name));
1456 + ("yaffs_lookup for %d:%s\n",
1457 + yaffs_InodeToObject(dir)->objectId, dentry->d_name.name));
1458
1459 - obj =
1460 - yaffs_FindObjectByName(yaffs_InodeToObject(dir),
1461 - dentry->d_name.name);
1462 + obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),
1463 + dentry->d_name.name);
1464
1465 obj = yaffs_GetEquivalentObject(obj); /* in case it was a hardlink */
1466
1467 @@ -397,13 +461,13 @@ static struct dentry *yaffs_lookup(struc
1468
1469 if (obj) {
1470 T(YAFFS_TRACE_OS,
1471 - (KERN_DEBUG "yaffs_lookup found %d\n", obj->objectId));
1472 + ("yaffs_lookup found %d\n", obj->objectId));
1473
1474 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
1475
1476 if (inode) {
1477 T(YAFFS_TRACE_OS,
1478 - (KERN_DEBUG "yaffs_loookup dentry \n"));
1479 + ("yaffs_loookup dentry \n"));
1480 /* #if 0 asserted by NCB for 2.5/6 compatability - falls through to
1481 * d_add even if NULL inode */
1482 #if 0
1483 @@ -416,7 +480,7 @@ static struct dentry *yaffs_lookup(struc
1484 }
1485
1486 } else {
1487 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_lookup not found\n"));
1488 + T(YAFFS_TRACE_OS, ("yaffs_lookup not found\n"));
1489
1490 }
1491
1492 @@ -425,20 +489,22 @@ static struct dentry *yaffs_lookup(struc
1493 d_add(dentry, inode);
1494
1495 return NULL;
1496 - /* return (ERR_PTR(-EIO)); */
1497 -
1498 }
1499
1500 +
1501 +#ifdef YAFFS_HAS_PUT_INODE
1502 +
1503 /* For now put inode is just for debugging
1504 * Put inode is called when the inode **structure** is put.
1505 */
1506 static void yaffs_put_inode(struct inode *inode)
1507 {
1508 T(YAFFS_TRACE_OS,
1509 - ("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino,
1510 - atomic_read(&inode->i_count)));
1511 + ("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino,
1512 + atomic_read(&inode->i_count)));
1513
1514 }
1515 +#endif
1516
1517 /* clear is called to tell the fs to release any per-inode data it holds */
1518 static void yaffs_clear_inode(struct inode *inode)
1519 @@ -449,9 +515,9 @@ static void yaffs_clear_inode(struct ino
1520 obj = yaffs_InodeToObject(inode);
1521
1522 T(YAFFS_TRACE_OS,
1523 - ("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino,
1524 - atomic_read(&inode->i_count),
1525 - obj ? "object exists" : "null object"));
1526 + ("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino,
1527 + atomic_read(&inode->i_count),
1528 + obj ? "object exists" : "null object"));
1529
1530 if (obj) {
1531 dev = obj->myDev;
1532 @@ -486,23 +552,23 @@ static void yaffs_delete_inode(struct in
1533 yaffs_Device *dev;
1534
1535 T(YAFFS_TRACE_OS,
1536 - ("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino,
1537 - atomic_read(&inode->i_count),
1538 - obj ? "object exists" : "null object"));
1539 + ("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino,
1540 + atomic_read(&inode->i_count),
1541 + obj ? "object exists" : "null object"));
1542
1543 if (obj) {
1544 dev = obj->myDev;
1545 yaffs_GrossLock(dev);
1546 - yaffs_DeleteFile(obj);
1547 + yaffs_DeleteObject(obj);
1548 yaffs_GrossUnlock(dev);
1549 }
1550 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
1551 - truncate_inode_pages (&inode->i_data, 0);
1552 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
1553 + truncate_inode_pages(&inode->i_data, 0);
1554 #endif
1555 clear_inode(inode);
1556 }
1557
1558 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
1559 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
1560 static int yaffs_file_flush(struct file *file, fl_owner_t id)
1561 #else
1562 static int yaffs_file_flush(struct file *file)
1563 @@ -513,8 +579,8 @@ static int yaffs_file_flush(struct file
1564 yaffs_Device *dev = obj->myDev;
1565
1566 T(YAFFS_TRACE_OS,
1567 - (KERN_DEBUG "yaffs_file_flush object %d (%s)\n", obj->objectId,
1568 - obj->dirty ? "dirty" : "clean"));
1569 + ("yaffs_file_flush object %d (%s)\n", obj->objectId,
1570 + obj->dirty ? "dirty" : "clean"));
1571
1572 yaffs_GrossLock(dev);
1573
1574 @@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct
1575
1576 yaffs_Device *dev;
1577
1578 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage at %08x, size %08x\n",
1579 - (unsigned)(pg->index << PAGE_CACHE_SHIFT),
1580 - (unsigned)PAGE_CACHE_SIZE));
1581 + T(YAFFS_TRACE_OS, ("yaffs_readpage at %08x, size %08x\n",
1582 + (unsigned)(pg->index << PAGE_CACHE_SHIFT),
1583 + (unsigned)PAGE_CACHE_SIZE));
1584
1585 obj = yaffs_DentryToObject(f->f_dentry);
1586
1587 dev = obj->myDev;
1588
1589 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1590 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1591 BUG_ON(!PageLocked(pg));
1592 #else
1593 if (!PageLocked(pg))
1594 @@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct
1595
1596 yaffs_GrossLock(dev);
1597
1598 - ret =
1599 - yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT,
1600 - PAGE_CACHE_SIZE);
1601 + ret = yaffs_ReadDataFromFile(obj, pg_buf,
1602 + pg->index << PAGE_CACHE_SHIFT,
1603 + PAGE_CACHE_SIZE);
1604
1605 yaffs_GrossUnlock(dev);
1606
1607 @@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct
1608 flush_dcache_page(pg);
1609 kunmap(pg);
1610
1611 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage done\n"));
1612 + T(YAFFS_TRACE_OS, ("yaffs_readpage done\n"));
1613 return ret;
1614 }
1615
1616 @@ -593,7 +659,7 @@ static int yaffs_readpage(struct file *f
1617
1618 /* writepage inspired by/stolen from smbfs */
1619
1620 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1621 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1622 static int yaffs_writepage(struct page *page, struct writeback_control *wbc)
1623 #else
1624 static int yaffs_writepage(struct page *page)
1625 @@ -616,12 +682,11 @@ static int yaffs_writepage(struct page *
1626
1627 if (offset > inode->i_size) {
1628 T(YAFFS_TRACE_OS,
1629 - (KERN_DEBUG
1630 - "yaffs_writepage at %08x, inode size = %08x!!!\n",
1631 - (unsigned)(page->index << PAGE_CACHE_SHIFT),
1632 - (unsigned)inode->i_size));
1633 + ("yaffs_writepage at %08x, inode size = %08x!!!\n",
1634 + (unsigned)(page->index << PAGE_CACHE_SHIFT),
1635 + (unsigned)inode->i_size));
1636 T(YAFFS_TRACE_OS,
1637 - (KERN_DEBUG " -> don't care!!\n"));
1638 + (" -> don't care!!\n"));
1639 unlock_page(page);
1640 return 0;
1641 }
1642 @@ -629,11 +694,10 @@ static int yaffs_writepage(struct page *
1643 end_index = inode->i_size >> PAGE_CACHE_SHIFT;
1644
1645 /* easy case */
1646 - if (page->index < end_index) {
1647 + if (page->index < end_index)
1648 nBytes = PAGE_CACHE_SIZE;
1649 - } else {
1650 + else
1651 nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1);
1652 - }
1653
1654 get_page(page);
1655
1656 @@ -643,19 +707,18 @@ static int yaffs_writepage(struct page *
1657 yaffs_GrossLock(obj->myDev);
1658
1659 T(YAFFS_TRACE_OS,
1660 - (KERN_DEBUG "yaffs_writepage at %08x, size %08x\n",
1661 - (unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes));
1662 + ("yaffs_writepage at %08x, size %08x\n",
1663 + (unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes));
1664 T(YAFFS_TRACE_OS,
1665 - (KERN_DEBUG "writepag0: obj = %05x, ino = %05x\n",
1666 - (int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
1667 + ("writepag0: obj = %05x, ino = %05x\n",
1668 + (int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
1669
1670 - nWritten =
1671 - yaffs_WriteDataToFile(obj, buffer, page->index << PAGE_CACHE_SHIFT,
1672 - nBytes, 0);
1673 + nWritten = yaffs_WriteDataToFile(obj, buffer,
1674 + page->index << PAGE_CACHE_SHIFT, nBytes, 0);
1675
1676 T(YAFFS_TRACE_OS,
1677 - (KERN_DEBUG "writepag1: obj = %05x, ino = %05x\n",
1678 - (int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
1679 + ("writepag1: obj = %05x, ino = %05x\n",
1680 + (int)obj->variant.fileVariant.fileSize, (int)inode->i_size));
1681
1682 yaffs_GrossUnlock(obj->myDev);
1683
1684 @@ -667,100 +730,207 @@ static int yaffs_writepage(struct page *
1685 return (nWritten == nBytes) ? 0 : -ENOSPC;
1686 }
1687
1688 +
1689 +#if (YAFFS_USE_WRITE_BEGIN_END > 0)
1690 +static int yaffs_write_begin(struct file *filp, struct address_space *mapping,
1691 + loff_t pos, unsigned len, unsigned flags,
1692 + struct page **pagep, void **fsdata)
1693 +{
1694 + struct page *pg = NULL;
1695 + pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1696 + uint32_t offset = pos & (PAGE_CACHE_SIZE - 1);
1697 + uint32_t to = offset + len;
1698 +
1699 + int ret = 0;
1700 + int space_held = 0;
1701 +
1702 + T(YAFFS_TRACE_OS, ("start yaffs_write_begin\n"));
1703 + /* Get a page */
1704 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28)
1705 + pg = grab_cache_page_write_begin(mapping, index, flags);
1706 +#else
1707 + pg = __grab_cache_page(mapping, index);
1708 +#endif
1709 +
1710 + *pagep = pg;
1711 + if (!pg) {
1712 + ret = -ENOMEM;
1713 + goto out;
1714 + }
1715 + /* Get fs space */
1716 + space_held = yaffs_hold_space(filp);
1717 +
1718 + if (!space_held) {
1719 + ret = -ENOSPC;
1720 + goto out;
1721 + }
1722 +
1723 + /* Update page if required */
1724 +
1725 + if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
1726 + ret = yaffs_readpage_nolock(filp, pg);
1727 +
1728 + if (ret)
1729 + goto out;
1730 +
1731 + /* Happy path return */
1732 + T(YAFFS_TRACE_OS, ("end yaffs_write_begin - ok\n"));
1733 +
1734 + return 0;
1735 +
1736 +out:
1737 + T(YAFFS_TRACE_OS, ("end yaffs_write_begin fail returning %d\n", ret));
1738 + if (space_held)
1739 + yaffs_release_space(filp);
1740 + if (pg) {
1741 + unlock_page(pg);
1742 + page_cache_release(pg);
1743 + }
1744 + return ret;
1745 +}
1746 +
1747 +#else
1748 +
1749 static int yaffs_prepare_write(struct file *f, struct page *pg,
1750 - unsigned offset, unsigned to)
1751 + unsigned offset, unsigned to)
1752 {
1753 + T(YAFFS_TRACE_OS, ("yaffs_prepair_write\n"));
1754
1755 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_prepair_write\n"));
1756 if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
1757 return yaffs_readpage_nolock(f, pg);
1758 -
1759 return 0;
1760 +}
1761 +#endif
1762 +
1763 +#if (YAFFS_USE_WRITE_BEGIN_END > 0)
1764 +static int yaffs_write_end(struct file *filp, struct address_space *mapping,
1765 + loff_t pos, unsigned len, unsigned copied,
1766 + struct page *pg, void *fsdadata)
1767 +{
1768 + int ret = 0;
1769 + void *addr, *kva;
1770 + uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);
1771 +
1772 + kva = kmap(pg);
1773 + addr = kva + offset_into_page;
1774 +
1775 + T(YAFFS_TRACE_OS,
1776 + ("yaffs_write_end addr %x pos %x nBytes %d\n",
1777 + (unsigned) addr,
1778 + (int)pos, copied));
1779 +
1780 + ret = yaffs_file_write(filp, addr, copied, &pos);
1781 +
1782 + if (ret != copied) {
1783 + T(YAFFS_TRACE_OS,
1784 + ("yaffs_write_end not same size ret %d copied %d\n",
1785 + ret, copied));
1786 + SetPageError(pg);
1787 + ClearPageUptodate(pg);
1788 + } else {
1789 + SetPageUptodate(pg);
1790 + }
1791 +
1792 + kunmap(pg);
1793
1794 + yaffs_release_space(filp);
1795 + unlock_page(pg);
1796 + page_cache_release(pg);
1797 + return ret;
1798 }
1799 +#else
1800
1801 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
1802 - unsigned to)
1803 + unsigned to)
1804 {
1805 + void *addr, *kva;
1806
1807 - void *addr = page_address(pg) + offset;
1808 loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;
1809 int nBytes = to - offset;
1810 int nWritten;
1811
1812 unsigned spos = pos;
1813 - unsigned saddr = (unsigned)addr;
1814 + unsigned saddr;
1815 +
1816 + kva = kmap(pg);
1817 + addr = kva + offset;
1818 +
1819 + saddr = (unsigned) addr;
1820
1821 T(YAFFS_TRACE_OS,
1822 - (KERN_DEBUG "yaffs_commit_write addr %x pos %x nBytes %d\n", saddr,
1823 - spos, nBytes));
1824 + ("yaffs_commit_write addr %x pos %x nBytes %d\n",
1825 + saddr, spos, nBytes));
1826
1827 nWritten = yaffs_file_write(f, addr, nBytes, &pos);
1828
1829 if (nWritten != nBytes) {
1830 T(YAFFS_TRACE_OS,
1831 - (KERN_DEBUG
1832 - "yaffs_commit_write not same size nWritten %d nBytes %d\n",
1833 - nWritten, nBytes));
1834 + ("yaffs_commit_write not same size nWritten %d nBytes %d\n",
1835 + nWritten, nBytes));
1836 SetPageError(pg);
1837 ClearPageUptodate(pg);
1838 } else {
1839 SetPageUptodate(pg);
1840 }
1841
1842 + kunmap(pg);
1843 +
1844 T(YAFFS_TRACE_OS,
1845 - (KERN_DEBUG "yaffs_commit_write returning %d\n",
1846 - nWritten == nBytes ? 0 : nWritten));
1847 + ("yaffs_commit_write returning %d\n",
1848 + nWritten == nBytes ? 0 : nWritten));
1849
1850 return nWritten == nBytes ? 0 : nWritten;
1851 -
1852 }
1853 +#endif
1854 +
1855
1856 -static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj)
1857 +static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
1858 {
1859 if (inode && obj) {
1860
1861
1862 /* Check mode against the variant type and attempt to repair if broken. */
1863 - __u32 mode = obj->yst_mode;
1864 - switch( obj->variantType ){
1865 - case YAFFS_OBJECT_TYPE_FILE :
1866 - if( ! S_ISREG(mode) ){
1867 - obj->yst_mode &= ~S_IFMT;
1868 - obj->yst_mode |= S_IFREG;
1869 - }
1870 -
1871 - break;
1872 - case YAFFS_OBJECT_TYPE_SYMLINK :
1873 - if( ! S_ISLNK(mode) ){
1874 - obj->yst_mode &= ~S_IFMT;
1875 - obj->yst_mode |= S_IFLNK;
1876 - }
1877 -
1878 - break;
1879 - case YAFFS_OBJECT_TYPE_DIRECTORY :
1880 - if( ! S_ISDIR(mode) ){
1881 - obj->yst_mode &= ~S_IFMT;
1882 - obj->yst_mode |= S_IFDIR;
1883 - }
1884 -
1885 - break;
1886 - case YAFFS_OBJECT_TYPE_UNKNOWN :
1887 - case YAFFS_OBJECT_TYPE_HARDLINK :
1888 - case YAFFS_OBJECT_TYPE_SPECIAL :
1889 - default:
1890 - /* TODO? */
1891 - break;
1892 - }
1893 + __u32 mode = obj->yst_mode;
1894 + switch (obj->variantType) {
1895 + case YAFFS_OBJECT_TYPE_FILE:
1896 + if (!S_ISREG(mode)) {
1897 + obj->yst_mode &= ~S_IFMT;
1898 + obj->yst_mode |= S_IFREG;
1899 + }
1900 +
1901 + break;
1902 + case YAFFS_OBJECT_TYPE_SYMLINK:
1903 + if (!S_ISLNK(mode)) {
1904 + obj->yst_mode &= ~S_IFMT;
1905 + obj->yst_mode |= S_IFLNK;
1906 + }
1907 +
1908 + break;
1909 + case YAFFS_OBJECT_TYPE_DIRECTORY:
1910 + if (!S_ISDIR(mode)) {
1911 + obj->yst_mode &= ~S_IFMT;
1912 + obj->yst_mode |= S_IFDIR;
1913 + }
1914 +
1915 + break;
1916 + case YAFFS_OBJECT_TYPE_UNKNOWN:
1917 + case YAFFS_OBJECT_TYPE_HARDLINK:
1918 + case YAFFS_OBJECT_TYPE_SPECIAL:
1919 + default:
1920 + /* TODO? */
1921 + break;
1922 + }
1923 +
1924 + inode->i_flags |= S_NOATIME;
1925
1926 inode->i_ino = obj->objectId;
1927 inode->i_mode = obj->yst_mode;
1928 inode->i_uid = obj->yst_uid;
1929 inode->i_gid = obj->yst_gid;
1930 -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
1931 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 19))
1932 inode->i_blksize = inode->i_sb->s_blocksize;
1933 #endif
1934 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1935 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1936
1937 inode->i_rdev = old_decode_dev(obj->yst_rdev);
1938 inode->i_atime.tv_sec = (time_t) (obj->yst_atime);
1939 @@ -781,26 +951,25 @@ static void yaffs_FillInodeFromObject(st
1940 inode->i_nlink = yaffs_GetObjectLinkCount(obj);
1941
1942 T(YAFFS_TRACE_OS,
1943 - (KERN_DEBUG
1944 - "yaffs_FillInode mode %x uid %d gid %d size %d count %d\n",
1945 - inode->i_mode, inode->i_uid, inode->i_gid,
1946 - (int)inode->i_size, atomic_read(&inode->i_count)));
1947 + ("yaffs_FillInode mode %x uid %d gid %d size %d count %d\n",
1948 + inode->i_mode, inode->i_uid, inode->i_gid,
1949 + (int)inode->i_size, atomic_read(&inode->i_count)));
1950
1951 switch (obj->yst_mode & S_IFMT) {
1952 default: /* fifo, device or socket */
1953 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1954 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1955 init_special_inode(inode, obj->yst_mode,
1956 - old_decode_dev(obj->yst_rdev));
1957 + old_decode_dev(obj->yst_rdev));
1958 #else
1959 init_special_inode(inode, obj->yst_mode,
1960 - (dev_t) (obj->yst_rdev));
1961 + (dev_t) (obj->yst_rdev));
1962 #endif
1963 break;
1964 case S_IFREG: /* file */
1965 inode->i_op = &yaffs_file_inode_operations;
1966 inode->i_fop = &yaffs_file_operations;
1967 inode->i_mapping->a_ops =
1968 - &yaffs_file_address_operations;
1969 + &yaffs_file_address_operations;
1970 break;
1971 case S_IFDIR: /* directory */
1972 inode->i_op = &yaffs_dir_inode_operations;
1973 @@ -817,34 +986,36 @@ static void yaffs_FillInodeFromObject(st
1974
1975 } else {
1976 T(YAFFS_TRACE_OS,
1977 - (KERN_DEBUG "yaffs_FileInode invalid parameters\n"));
1978 + ("yaffs_FileInode invalid parameters\n"));
1979 }
1980
1981 }
1982
1983 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
1984 - yaffs_Object * obj)
1985 + yaffs_Object *obj)
1986 {
1987 struct inode *inode;
1988
1989 if (!sb) {
1990 T(YAFFS_TRACE_OS,
1991 - (KERN_DEBUG "yaffs_get_inode for NULL super_block!!\n"));
1992 + ("yaffs_get_inode for NULL super_block!!\n"));
1993 return NULL;
1994
1995 }
1996
1997 if (!obj) {
1998 T(YAFFS_TRACE_OS,
1999 - (KERN_DEBUG "yaffs_get_inode for NULL object!!\n"));
2000 + ("yaffs_get_inode for NULL object!!\n"));
2001 return NULL;
2002
2003 }
2004
2005 T(YAFFS_TRACE_OS,
2006 - (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId));
2007 + ("yaffs_get_inode for object %d\n", obj->objectId));
2008
2009 - inode = iget(sb, obj->objectId);
2010 + inode = Y_IGET(sb, obj->objectId);
2011 + if (IS_ERR(inode))
2012 + return NULL;
2013
2014 /* NB Side effect: iget calls back to yaffs_read_inode(). */
2015 /* iget also increments the inode's i_count */
2016 @@ -854,7 +1025,7 @@ struct inode *yaffs_get_inode(struct sup
2017 }
2018
2019 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
2020 - loff_t * pos)
2021 + loff_t *pos)
2022 {
2023 yaffs_Object *obj;
2024 int nWritten, ipos;
2025 @@ -869,28 +1040,26 @@ static ssize_t yaffs_file_write(struct f
2026
2027 inode = f->f_dentry->d_inode;
2028
2029 - if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) {
2030 + if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND)
2031 ipos = inode->i_size;
2032 - } else {
2033 + else
2034 ipos = *pos;
2035 - }
2036
2037 - if (!obj) {
2038 + if (!obj)
2039 T(YAFFS_TRACE_OS,
2040 - (KERN_DEBUG "yaffs_file_write: hey obj is null!\n"));
2041 - } else {
2042 + ("yaffs_file_write: hey obj is null!\n"));
2043 + else
2044 T(YAFFS_TRACE_OS,
2045 - (KERN_DEBUG
2046 - "yaffs_file_write about to write writing %d bytes"
2047 - "to object %d at %d\n",
2048 - n, obj->objectId, ipos));
2049 - }
2050 + ("yaffs_file_write about to write writing %zu bytes"
2051 + "to object %d at %d\n",
2052 + n, obj->objectId, ipos));
2053
2054 nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0);
2055
2056 T(YAFFS_TRACE_OS,
2057 - (KERN_DEBUG "yaffs_file_write writing %d bytes, %d written at %d\n",
2058 - n, nWritten, ipos));
2059 + ("yaffs_file_write writing %zu bytes, %d written at %d\n",
2060 + n, nWritten, ipos));
2061 +
2062 if (nWritten > 0) {
2063 ipos += nWritten;
2064 *pos = ipos;
2065 @@ -899,10 +1068,9 @@ static ssize_t yaffs_file_write(struct f
2066 inode->i_blocks = (ipos + 511) >> 9;
2067
2068 T(YAFFS_TRACE_OS,
2069 - (KERN_DEBUG
2070 - "yaffs_file_write size updated to %d bytes, "
2071 - "%d blocks\n",
2072 - ipos, (int)(inode->i_blocks)));
2073 + ("yaffs_file_write size updated to %d bytes, "
2074 + "%d blocks\n",
2075 + ipos, (int)(inode->i_blocks)));
2076 }
2077
2078 }
2079 @@ -910,13 +1078,54 @@ static ssize_t yaffs_file_write(struct f
2080 return nWritten == 0 ? -ENOSPC : nWritten;
2081 }
2082
2083 +/* Space holding and freeing is done to ensure we have space available for write_begin/end */
2084 +/* For now we just assume few parallel writes and check against a small number. */
2085 +/* Todo: need to do this with a counter to handle parallel reads better */
2086 +
2087 +static ssize_t yaffs_hold_space(struct file *f)
2088 +{
2089 + yaffs_Object *obj;
2090 + yaffs_Device *dev;
2091 +
2092 + int nFreeChunks;
2093 +
2094 +
2095 + obj = yaffs_DentryToObject(f->f_dentry);
2096 +
2097 + dev = obj->myDev;
2098 +
2099 + yaffs_GrossLock(dev);
2100 +
2101 + nFreeChunks = yaffs_GetNumberOfFreeChunks(dev);
2102 +
2103 + yaffs_GrossUnlock(dev);
2104 +
2105 + return (nFreeChunks > 20) ? 1 : 0;
2106 +}
2107 +
2108 +static void yaffs_release_space(struct file *f)
2109 +{
2110 + yaffs_Object *obj;
2111 + yaffs_Device *dev;
2112 +
2113 +
2114 + obj = yaffs_DentryToObject(f->f_dentry);
2115 +
2116 + dev = obj->myDev;
2117 +
2118 + yaffs_GrossLock(dev);
2119 +
2120 +
2121 + yaffs_GrossUnlock(dev);
2122 +}
2123 +
2124 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
2125 {
2126 yaffs_Object *obj;
2127 yaffs_Device *dev;
2128 struct inode *inode = f->f_dentry->d_inode;
2129 unsigned long offset, curoffs;
2130 - struct list_head *i;
2131 + struct ylist_head *i;
2132 yaffs_Object *l;
2133
2134 char name[YAFFS_MAX_NAME_LENGTH + 1];
2135 @@ -932,24 +1141,20 @@ static int yaffs_readdir(struct file *f,
2136
2137 if (offset == 0) {
2138 T(YAFFS_TRACE_OS,
2139 - (KERN_DEBUG "yaffs_readdir: entry . ino %d \n",
2140 - (int)inode->i_ino));
2141 - if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR)
2142 - < 0) {
2143 + ("yaffs_readdir: entry . ino %d \n",
2144 + (int)inode->i_ino));
2145 + if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0)
2146 goto out;
2147 - }
2148 offset++;
2149 f->f_pos++;
2150 }
2151 if (offset == 1) {
2152 T(YAFFS_TRACE_OS,
2153 - (KERN_DEBUG "yaffs_readdir: entry .. ino %d \n",
2154 - (int)f->f_dentry->d_parent->d_inode->i_ino));
2155 - if (filldir
2156 - (dirent, "..", 2, offset,
2157 - f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) {
2158 + ("yaffs_readdir: entry .. ino %d \n",
2159 + (int)f->f_dentry->d_parent->d_inode->i_ino));
2160 + if (filldir(dirent, "..", 2, offset,
2161 + f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0)
2162 goto out;
2163 - }
2164 offset++;
2165 f->f_pos++;
2166 }
2167 @@ -965,35 +1170,32 @@ static int yaffs_readdir(struct file *f,
2168 f->f_version = inode->i_version;
2169 }
2170
2171 - list_for_each(i, &obj->variant.directoryVariant.children) {
2172 + ylist_for_each(i, &obj->variant.directoryVariant.children) {
2173 curoffs++;
2174 if (curoffs >= offset) {
2175 - l = list_entry(i, yaffs_Object, siblings);
2176 + l = ylist_entry(i, yaffs_Object, siblings);
2177
2178 yaffs_GetObjectName(l, name,
2179 YAFFS_MAX_NAME_LENGTH + 1);
2180 T(YAFFS_TRACE_OS,
2181 - (KERN_DEBUG "yaffs_readdir: %s inode %d\n", name,
2182 + ("yaffs_readdir: %s inode %d\n", name,
2183 yaffs_GetObjectInode(l)));
2184
2185 if (filldir(dirent,
2186 - name,
2187 - strlen(name),
2188 - offset,
2189 - yaffs_GetObjectInode(l),
2190 - yaffs_GetObjectType(l))
2191 - < 0) {
2192 + name,
2193 + strlen(name),
2194 + offset,
2195 + yaffs_GetObjectInode(l),
2196 + yaffs_GetObjectType(l)) < 0)
2197 goto up_and_out;
2198 - }
2199
2200 offset++;
2201 f->f_pos++;
2202 }
2203 }
2204
2205 - up_and_out:
2206 - out:
2207 -
2208 +up_and_out:
2209 +out:
2210 yaffs_GrossUnlock(dev);
2211
2212 return 0;
2213 @@ -1002,12 +1204,19 @@ static int yaffs_readdir(struct file *f,
2214 /*
2215 * File creation. Allocate an inode, and we're done..
2216 */
2217 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
2218 +
2219 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
2220 +#define YCRED(x) x
2221 +#else
2222 +#define YCRED(x) (x->cred)
2223 +#endif
2224 +
2225 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2226 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
2227 - dev_t rdev)
2228 + dev_t rdev)
2229 #else
2230 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
2231 - int rdev)
2232 + int rdev)
2233 #endif
2234 {
2235 struct inode *inode;
2236 @@ -1018,25 +1227,25 @@ static int yaffs_mknod(struct inode *dir
2237 yaffs_Object *parent = yaffs_InodeToObject(dir);
2238
2239 int error = -ENOSPC;
2240 - uid_t uid = current->fsuid;
2241 - gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
2242 + uid_t uid = YCRED(current)->fsuid;
2243 + gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
2244
2245 - if((dir->i_mode & S_ISGID) && S_ISDIR(mode))
2246 + if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
2247 mode |= S_ISGID;
2248
2249 if (parent) {
2250 T(YAFFS_TRACE_OS,
2251 - (KERN_DEBUG "yaffs_mknod: parent object %d type %d\n",
2252 - parent->objectId, parent->variantType));
2253 + ("yaffs_mknod: parent object %d type %d\n",
2254 + parent->objectId, parent->variantType));
2255 } else {
2256 T(YAFFS_TRACE_OS,
2257 - (KERN_DEBUG "yaffs_mknod: could not get parent object\n"));
2258 + ("yaffs_mknod: could not get parent object\n"));
2259 return -EPERM;
2260 }
2261
2262 T(YAFFS_TRACE_OS, ("yaffs_mknod: making oject for %s, "
2263 - "mode %x dev %x\n",
2264 - dentry->d_name.name, mode, rdev));
2265 + "mode %x dev %x\n",
2266 + dentry->d_name.name, mode, rdev));
2267
2268 dev = parent->myDev;
2269
2270 @@ -1045,33 +1254,28 @@ static int yaffs_mknod(struct inode *dir
2271 switch (mode & S_IFMT) {
2272 default:
2273 /* Special (socket, fifo, device...) */
2274 - T(YAFFS_TRACE_OS, (KERN_DEBUG
2275 - "yaffs_mknod: making special\n"));
2276 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
2277 - obj =
2278 - yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
2279 - gid, old_encode_dev(rdev));
2280 -#else
2281 - obj =
2282 - yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
2283 - gid, rdev);
2284 + T(YAFFS_TRACE_OS, ("yaffs_mknod: making special\n"));
2285 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2286 + obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
2287 + gid, old_encode_dev(rdev));
2288 +#else
2289 + obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
2290 + gid, rdev);
2291 #endif
2292 break;
2293 case S_IFREG: /* file */
2294 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n"));
2295 - obj =
2296 - yaffs_MknodFile(parent, dentry->d_name.name, mode, uid,
2297 - gid);
2298 + T(YAFFS_TRACE_OS, ("yaffs_mknod: making file\n"));
2299 + obj = yaffs_MknodFile(parent, dentry->d_name.name, mode, uid,
2300 + gid);
2301 break;
2302 case S_IFDIR: /* directory */
2303 T(YAFFS_TRACE_OS,
2304 - (KERN_DEBUG "yaffs_mknod: making directory\n"));
2305 - obj =
2306 - yaffs_MknodDirectory(parent, dentry->d_name.name, mode,
2307 - uid, gid);
2308 + ("yaffs_mknod: making directory\n"));
2309 + obj = yaffs_MknodDirectory(parent, dentry->d_name.name, mode,
2310 + uid, gid);
2311 break;
2312 case S_IFLNK: /* symlink */
2313 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n"));
2314 + T(YAFFS_TRACE_OS, ("yaffs_mknod: making symlink\n"));
2315 obj = NULL; /* Do we ever get here? */
2316 break;
2317 }
2318 @@ -1083,12 +1287,12 @@ static int yaffs_mknod(struct inode *dir
2319 inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
2320 d_instantiate(dentry, inode);
2321 T(YAFFS_TRACE_OS,
2322 - (KERN_DEBUG "yaffs_mknod created object %d count = %d\n",
2323 - obj->objectId, atomic_read(&inode->i_count)));
2324 + ("yaffs_mknod created object %d count = %d\n",
2325 + obj->objectId, atomic_read(&inode->i_count)));
2326 error = 0;
2327 } else {
2328 T(YAFFS_TRACE_OS,
2329 - (KERN_DEBUG "yaffs_mknod failed making object\n"));
2330 + ("yaffs_mknod failed making object\n"));
2331 error = -ENOMEM;
2332 }
2333
2334 @@ -1098,25 +1302,19 @@ static int yaffs_mknod(struct inode *dir
2335 static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
2336 {
2337 int retVal;
2338 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mkdir\n"));
2339 + T(YAFFS_TRACE_OS, ("yaffs_mkdir\n"));
2340 retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0);
2341 -#if 0
2342 - /* attempt to fix dir bug - didn't work */
2343 - if (!retVal) {
2344 - dget(dentry);
2345 - }
2346 -#endif
2347 return retVal;
2348 }
2349
2350 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
2351 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2352 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode,
2353 struct nameidata *n)
2354 #else
2355 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
2356 #endif
2357 {
2358 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_create\n"));
2359 + T(YAFFS_TRACE_OS, ("yaffs_create\n"));
2360 return yaffs_mknod(dir, dentry, mode | S_IFREG, 0);
2361 }
2362
2363 @@ -1127,8 +1325,8 @@ static int yaffs_unlink(struct inode *di
2364 yaffs_Device *dev;
2365
2366 T(YAFFS_TRACE_OS,
2367 - (KERN_DEBUG "yaffs_unlink %d:%s\n", (int)(dir->i_ino),
2368 - dentry->d_name.name));
2369 + ("yaffs_unlink %d:%s\n", (int)(dir->i_ino),
2370 + dentry->d_name.name));
2371
2372 dev = yaffs_InodeToObject(dir)->myDev;
2373
2374 @@ -1151,82 +1349,74 @@ static int yaffs_unlink(struct inode *di
2375 * Create a link...
2376 */
2377 static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
2378 - struct dentry *dentry)
2379 + struct dentry *dentry)
2380 {
2381 struct inode *inode = old_dentry->d_inode;
2382 yaffs_Object *obj = NULL;
2383 yaffs_Object *link = NULL;
2384 yaffs_Device *dev;
2385
2386 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_link\n"));
2387 + T(YAFFS_TRACE_OS, ("yaffs_link\n"));
2388
2389 obj = yaffs_InodeToObject(inode);
2390 dev = obj->myDev;
2391
2392 yaffs_GrossLock(dev);
2393
2394 - if (!S_ISDIR(inode->i_mode)) /* Don't link directories */
2395 - {
2396 - link =
2397 - yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name,
2398 - obj);
2399 - }
2400 + if (!S_ISDIR(inode->i_mode)) /* Don't link directories */
2401 + link = yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name,
2402 + obj);
2403
2404 if (link) {
2405 old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj);
2406 d_instantiate(dentry, old_dentry->d_inode);
2407 atomic_inc(&old_dentry->d_inode->i_count);
2408 T(YAFFS_TRACE_OS,
2409 - (KERN_DEBUG "yaffs_link link count %d i_count %d\n",
2410 - old_dentry->d_inode->i_nlink,
2411 - atomic_read(&old_dentry->d_inode->i_count)));
2412 -
2413 + ("yaffs_link link count %d i_count %d\n",
2414 + old_dentry->d_inode->i_nlink,
2415 + atomic_read(&old_dentry->d_inode->i_count)));
2416 }
2417
2418 yaffs_GrossUnlock(dev);
2419
2420 - if (link) {
2421 -
2422 + if (link)
2423 return 0;
2424 - }
2425
2426 return -EPERM;
2427 }
2428
2429 static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
2430 - const char *symname)
2431 + const char *symname)
2432 {
2433 yaffs_Object *obj;
2434 yaffs_Device *dev;
2435 - uid_t uid = current->fsuid;
2436 - gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid;
2437 + uid_t uid = YCRED(current)->fsuid;
2438 + gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : YCRED(current)->fsgid;
2439
2440 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_symlink\n"));
2441 + T(YAFFS_TRACE_OS, ("yaffs_symlink\n"));
2442
2443 dev = yaffs_InodeToObject(dir)->myDev;
2444 yaffs_GrossLock(dev);
2445 obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name,
2446 - S_IFLNK | S_IRWXUGO, uid, gid, symname);
2447 + S_IFLNK | S_IRWXUGO, uid, gid, symname);
2448 yaffs_GrossUnlock(dev);
2449
2450 if (obj) {
2451 -
2452 struct inode *inode;
2453
2454 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
2455 d_instantiate(dentry, inode);
2456 - T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink created OK\n"));
2457 + T(YAFFS_TRACE_OS, ("symlink created OK\n"));
2458 return 0;
2459 } else {
2460 - T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink not created\n"));
2461 -
2462 + T(YAFFS_TRACE_OS, ("symlink not created\n"));
2463 }
2464
2465 return -ENOMEM;
2466 }
2467
2468 static int yaffs_sync_object(struct file *file, struct dentry *dentry,
2469 - int datasync)
2470 + int datasync)
2471 {
2472
2473 yaffs_Object *obj;
2474 @@ -1236,7 +1426,7 @@ static int yaffs_sync_object(struct file
2475
2476 dev = obj->myDev;
2477
2478 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_object\n"));
2479 + T(YAFFS_TRACE_OS, ("yaffs_sync_object\n"));
2480 yaffs_GrossLock(dev);
2481 yaffs_FlushFile(obj, 1);
2482 yaffs_GrossUnlock(dev);
2483 @@ -1255,41 +1445,36 @@ static int yaffs_rename(struct inode *ol
2484 int retVal = YAFFS_FAIL;
2485 yaffs_Object *target;
2486
2487 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_rename\n"));
2488 + T(YAFFS_TRACE_OS, ("yaffs_rename\n"));
2489 dev = yaffs_InodeToObject(old_dir)->myDev;
2490
2491 yaffs_GrossLock(dev);
2492
2493 /* Check if the target is an existing directory that is not empty. */
2494 - target =
2495 - yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),
2496 - new_dentry->d_name.name);
2497 + target = yaffs_FindObjectByName(yaffs_InodeToObject(new_dir),
2498 + new_dentry->d_name.name);
2499
2500
2501
2502 - if (target &&
2503 - target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
2504 - !list_empty(&target->variant.directoryVariant.children)) {
2505 + if (target && target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY &&
2506 + !ylist_empty(&target->variant.directoryVariant.children)) {
2507
2508 - T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n"));
2509 + T(YAFFS_TRACE_OS, ("target is non-empty dir\n"));
2510
2511 retVal = YAFFS_FAIL;
2512 } else {
2513 -
2514 /* Now does unlinking internally using shadowing mechanism */
2515 - T(YAFFS_TRACE_OS, (KERN_DEBUG "calling yaffs_RenameObject\n"));
2516 -
2517 - retVal =
2518 - yaffs_RenameObject(yaffs_InodeToObject(old_dir),
2519 - old_dentry->d_name.name,
2520 - yaffs_InodeToObject(new_dir),
2521 - new_dentry->d_name.name);
2522 + T(YAFFS_TRACE_OS, ("calling yaffs_RenameObject\n"));
2523
2524 + retVal = yaffs_RenameObject(yaffs_InodeToObject(old_dir),
2525 + old_dentry->d_name.name,
2526 + yaffs_InodeToObject(new_dir),
2527 + new_dentry->d_name.name);
2528 }
2529 yaffs_GrossUnlock(dev);
2530
2531 if (retVal == YAFFS_OK) {
2532 - if(target) {
2533 + if (target) {
2534 new_dentry->d_inode->i_nlink--;
2535 mark_inode_dirty(new_dentry->d_inode);
2536 }
2537 @@ -1298,7 +1483,6 @@ static int yaffs_rename(struct inode *ol
2538 } else {
2539 return -ENOTEMPTY;
2540 }
2541 -
2542 }
2543
2544 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
2545 @@ -1308,15 +1492,15 @@ static int yaffs_setattr(struct dentry *
2546 yaffs_Device *dev;
2547
2548 T(YAFFS_TRACE_OS,
2549 - (KERN_DEBUG "yaffs_setattr of object %d\n",
2550 - yaffs_InodeToObject(inode)->objectId));
2551 -
2552 - if ((error = inode_change_ok(inode, attr)) == 0) {
2553 + ("yaffs_setattr of object %d\n",
2554 + yaffs_InodeToObject(inode)->objectId));
2555
2556 + error = inode_change_ok(inode, attr);
2557 + if (error == 0) {
2558 dev = yaffs_InodeToObject(inode)->myDev;
2559 yaffs_GrossLock(dev);
2560 if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) ==
2561 - YAFFS_OK) {
2562 + YAFFS_OK) {
2563 error = 0;
2564 } else {
2565 error = -EPERM;
2566 @@ -1328,12 +1512,12 @@ static int yaffs_setattr(struct dentry *
2567 return error;
2568 }
2569
2570 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
2571 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2572 static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf)
2573 {
2574 yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev;
2575 struct super_block *sb = dentry->d_sb;
2576 -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
2577 +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2578 static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf)
2579 {
2580 yaffs_Device *dev = yaffs_SuperToDevice(sb);
2581 @@ -1343,32 +1527,53 @@ static int yaffs_statfs(struct super_blo
2582 yaffs_Device *dev = yaffs_SuperToDevice(sb);
2583 #endif
2584
2585 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_statfs\n"));
2586 + T(YAFFS_TRACE_OS, ("yaffs_statfs\n"));
2587
2588 yaffs_GrossLock(dev);
2589
2590 buf->f_type = YAFFS_MAGIC;
2591 buf->f_bsize = sb->s_blocksize;
2592 buf->f_namelen = 255;
2593 - if (sb->s_blocksize > dev->nDataBytesPerChunk) {
2594 +
2595 + if (dev->nDataBytesPerChunk & (dev->nDataBytesPerChunk - 1)) {
2596 + /* Do this if chunk size is not a power of 2 */
2597 +
2598 + uint64_t bytesInDev;
2599 + uint64_t bytesFree;
2600 +
2601 + bytesInDev = ((uint64_t)((dev->endBlock - dev->startBlock + 1))) *
2602 + ((uint64_t)(dev->nChunksPerBlock * dev->nDataBytesPerChunk));
2603 +
2604 + do_div(bytesInDev, sb->s_blocksize); /* bytesInDev becomes the number of blocks */
2605 + buf->f_blocks = bytesInDev;
2606 +
2607 + bytesFree = ((uint64_t)(yaffs_GetNumberOfFreeChunks(dev))) *
2608 + ((uint64_t)(dev->nDataBytesPerChunk));
2609 +
2610 + do_div(bytesFree, sb->s_blocksize);
2611 +
2612 + buf->f_bfree = bytesFree;
2613 +
2614 + } else if (sb->s_blocksize > dev->nDataBytesPerChunk) {
2615
2616 buf->f_blocks =
2617 - (dev->endBlock - dev->startBlock +
2618 - 1) * dev->nChunksPerBlock / (sb->s_blocksize /
2619 - dev->nDataBytesPerChunk);
2620 + (dev->endBlock - dev->startBlock + 1) *
2621 + dev->nChunksPerBlock /
2622 + (sb->s_blocksize / dev->nDataBytesPerChunk);
2623 buf->f_bfree =
2624 - yaffs_GetNumberOfFreeChunks(dev) / (sb->s_blocksize /
2625 - dev->nDataBytesPerChunk);
2626 + yaffs_GetNumberOfFreeChunks(dev) /
2627 + (sb->s_blocksize / dev->nDataBytesPerChunk);
2628 } else {
2629 -
2630 buf->f_blocks =
2631 - (dev->endBlock - dev->startBlock +
2632 - 1) * dev->nChunksPerBlock * (dev->nDataBytesPerChunk /
2633 - sb->s_blocksize);
2634 + (dev->endBlock - dev->startBlock + 1) *
2635 + dev->nChunksPerBlock *
2636 + (dev->nDataBytesPerChunk / sb->s_blocksize);
2637 +
2638 buf->f_bfree =
2639 - yaffs_GetNumberOfFreeChunks(dev) * (dev->nDataBytesPerChunk /
2640 - sb->s_blocksize);
2641 + yaffs_GetNumberOfFreeChunks(dev) *
2642 + (dev->nDataBytesPerChunk / sb->s_blocksize);
2643 }
2644 +
2645 buf->f_files = 0;
2646 buf->f_ffree = 0;
2647 buf->f_bavail = buf->f_bfree;
2648 @@ -1378,18 +1583,19 @@ static int yaffs_statfs(struct super_blo
2649 }
2650
2651
2652 -/**
2653 static int yaffs_do_sync_fs(struct super_block *sb)
2654 {
2655
2656 yaffs_Device *dev = yaffs_SuperToDevice(sb);
2657 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_do_sync_fs\n"));
2658 + T(YAFFS_TRACE_OS, ("yaffs_do_sync_fs\n"));
2659
2660 - if(sb->s_dirt) {
2661 + if (sb->s_dirt) {
2662 yaffs_GrossLock(dev);
2663
2664 - if(dev)
2665 + if (dev) {
2666 + yaffs_FlushEntireDeviceCache(dev);
2667 yaffs_CheckpointSave(dev);
2668 + }
2669
2670 yaffs_GrossUnlock(dev);
2671
2672 @@ -1397,35 +1603,73 @@ static int yaffs_do_sync_fs(struct super
2673 }
2674 return 0;
2675 }
2676 -**/
2677
2678 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
2679 +
2680 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2681 static void yaffs_write_super(struct super_block *sb)
2682 #else
2683 static int yaffs_write_super(struct super_block *sb)
2684 #endif
2685 {
2686
2687 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n"));
2688 -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
2689 - return 0; /* yaffs_do_sync_fs(sb);*/
2690 + T(YAFFS_TRACE_OS, ("yaffs_write_super\n"));
2691 + if (yaffs_auto_checkpoint >= 2)
2692 + yaffs_do_sync_fs(sb);
2693 +#if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
2694 + return 0;
2695 #endif
2696 }
2697
2698
2699 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
2700 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2701 static int yaffs_sync_fs(struct super_block *sb, int wait)
2702 #else
2703 static int yaffs_sync_fs(struct super_block *sb)
2704 #endif
2705 {
2706 + T(YAFFS_TRACE_OS, ("yaffs_sync_fs\n"));
2707 +
2708 + if (yaffs_auto_checkpoint >= 1)
2709 + yaffs_do_sync_fs(sb);
2710 +
2711 + return 0;
2712 +}
2713 +
2714 +#ifdef YAFFS_USE_OWN_IGET
2715 +
2716 +static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino)
2717 +{
2718 + struct inode *inode;
2719 + yaffs_Object *obj;
2720 + yaffs_Device *dev = yaffs_SuperToDevice(sb);
2721 +
2722 + T(YAFFS_TRACE_OS,
2723 + ("yaffs_iget for %lu\n", ino));
2724
2725 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n"));
2726 + inode = iget_locked(sb, ino);
2727 + if (!inode)
2728 + return ERR_PTR(-ENOMEM);
2729 + if (!(inode->i_state & I_NEW))
2730 + return inode;
2731 +
2732 + /* NB This is called as a side effect of other functions, but
2733 + * we had to release the lock to prevent deadlocks, so
2734 + * need to lock again.
2735 + */
2736
2737 - return 0; /* yaffs_do_sync_fs(sb);*/
2738 + yaffs_GrossLock(dev);
2739
2740 + obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
2741 +
2742 + yaffs_FillInodeFromObject(inode, obj);
2743 +
2744 + yaffs_GrossUnlock(dev);
2745 +
2746 + unlock_new_inode(inode);
2747 + return inode;
2748 }
2749
2750 +#else
2751
2752 static void yaffs_read_inode(struct inode *inode)
2753 {
2754 @@ -1438,7 +1682,7 @@ static void yaffs_read_inode(struct inod
2755 yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb);
2756
2757 T(YAFFS_TRACE_OS,
2758 - (KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino));
2759 + ("yaffs_read_inode for %d\n", (int)inode->i_ino));
2760
2761 yaffs_GrossLock(dev);
2762
2763 @@ -1449,18 +1693,20 @@ static void yaffs_read_inode(struct inod
2764 yaffs_GrossUnlock(dev);
2765 }
2766
2767 -static LIST_HEAD(yaffs_dev_list);
2768 +#endif
2769 +
2770 +static YLIST_HEAD(yaffs_dev_list);
2771
2772 -#if 0 // not used
2773 +#if 0 /* not used */
2774 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
2775 {
2776 yaffs_Device *dev = yaffs_SuperToDevice(sb);
2777
2778 - if( *flags & MS_RDONLY ) {
2779 + if (*flags & MS_RDONLY) {
2780 struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
2781
2782 T(YAFFS_TRACE_OS,
2783 - (KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name ));
2784 + ("yaffs_remount_fs: %s: RO\n", dev->name));
2785
2786 yaffs_GrossLock(dev);
2787
2788 @@ -1472,10 +1718,9 @@ static int yaffs_remount_fs(struct super
2789 mtd->sync(mtd);
2790
2791 yaffs_GrossUnlock(dev);
2792 - }
2793 - else {
2794 + } else {
2795 T(YAFFS_TRACE_OS,
2796 - (KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name ));
2797 + ("yaffs_remount_fs: %s: RW\n", dev->name));
2798 }
2799
2800 return 0;
2801 @@ -1486,7 +1731,7 @@ static void yaffs_put_super(struct super
2802 {
2803 yaffs_Device *dev = yaffs_SuperToDevice(sb);
2804
2805 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n"));
2806 + T(YAFFS_TRACE_OS, ("yaffs_put_super\n"));
2807
2808 yaffs_GrossLock(dev);
2809
2810 @@ -1494,18 +1739,17 @@ static void yaffs_put_super(struct super
2811
2812 yaffs_CheckpointSave(dev);
2813
2814 - if (dev->putSuperFunc) {
2815 + if (dev->putSuperFunc)
2816 dev->putSuperFunc(sb);
2817 - }
2818
2819 yaffs_Deinitialise(dev);
2820
2821 yaffs_GrossUnlock(dev);
2822
2823 /* we assume this is protected by lock_kernel() in mount/umount */
2824 - list_del(&dev->devList);
2825 + ylist_del(&dev->devList);
2826
2827 - if(dev->spareBuffer){
2828 + if (dev->spareBuffer) {
2829 YFREE(dev->spareBuffer);
2830 dev->spareBuffer = NULL;
2831 }
2832 @@ -1516,12 +1760,10 @@ static void yaffs_put_super(struct super
2833
2834 static void yaffs_MTDPutSuper(struct super_block *sb)
2835 {
2836 -
2837 struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
2838
2839 - if (mtd->sync) {
2840 + if (mtd->sync)
2841 mtd->sync(mtd);
2842 - }
2843
2844 put_mtd_device(mtd);
2845 }
2846 @@ -1531,9 +1773,9 @@ static void yaffs_MarkSuperBlockDirty(vo
2847 {
2848 struct super_block *sb = (struct super_block *)vsb;
2849
2850 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_MarkSuperBlockDirty() sb = %p\n",sb));
2851 -// if(sb)
2852 -// sb->s_dirt = 1;
2853 + T(YAFFS_TRACE_OS, ("yaffs_MarkSuperBlockDirty() sb = %p\n", sb));
2854 + if (sb)
2855 + sb->s_dirt = 1;
2856 }
2857
2858 typedef struct {
2859 @@ -1546,48 +1788,48 @@ typedef struct {
2860 #define MAX_OPT_LEN 20
2861 static int yaffs_parse_options(yaffs_options *options, const char *options_str)
2862 {
2863 - char cur_opt[MAX_OPT_LEN+1];
2864 + char cur_opt[MAX_OPT_LEN + 1];
2865 int p;
2866 int error = 0;
2867
2868 /* Parse through the options which is a comma seperated list */
2869
2870 - while(options_str && *options_str && !error){
2871 - memset(cur_opt,0,MAX_OPT_LEN+1);
2872 + while (options_str && *options_str && !error) {
2873 + memset(cur_opt, 0, MAX_OPT_LEN + 1);
2874 p = 0;
2875
2876 - while(*options_str && *options_str != ','){
2877 - if(p < MAX_OPT_LEN){
2878 + while (*options_str && *options_str != ',') {
2879 + if (p < MAX_OPT_LEN) {
2880 cur_opt[p] = *options_str;
2881 p++;
2882 }
2883 options_str++;
2884 }
2885
2886 - if(!strcmp(cur_opt,"inband-tags"))
2887 + if (!strcmp(cur_opt, "inband-tags"))
2888 options->inband_tags = 1;
2889 - else if(!strcmp(cur_opt,"no-cache"))
2890 + else if (!strcmp(cur_opt, "no-cache"))
2891 options->no_cache = 1;
2892 - else if(!strcmp(cur_opt,"no-checkpoint-read"))
2893 + else if (!strcmp(cur_opt, "no-checkpoint-read"))
2894 options->skip_checkpoint_read = 1;
2895 - else if(!strcmp(cur_opt,"no-checkpoint-write"))
2896 + else if (!strcmp(cur_opt, "no-checkpoint-write"))
2897 options->skip_checkpoint_write = 1;
2898 - else if(!strcmp(cur_opt,"no-checkpoint")){
2899 + else if (!strcmp(cur_opt, "no-checkpoint")) {
2900 options->skip_checkpoint_read = 1;
2901 options->skip_checkpoint_write = 1;
2902 } else {
2903 - printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",cur_opt);
2904 + printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
2905 + cur_opt);
2906 error = 1;
2907 }
2908 -
2909 }
2910
2911 return error;
2912 }
2913
2914 static struct super_block *yaffs_internal_read_super(int yaffsVersion,
2915 - struct super_block *sb,
2916 - void *data, int silent)
2917 + struct super_block *sb,
2918 + void *data, int silent)
2919 {
2920 int nBlocks;
2921 struct inode *inode = NULL;
2922 @@ -1602,6 +1844,7 @@ static struct super_block *yaffs_interna
2923
2924 sb->s_magic = YAFFS_MAGIC;
2925 sb->s_op = &yaffs_super_ops;
2926 + sb->s_flags |= MS_NOATIME;
2927
2928 if (!sb)
2929 printk(KERN_INFO "yaffs: sb is NULL\n");
2930 @@ -1614,14 +1857,14 @@ static struct super_block *yaffs_interna
2931 sb->s_dev,
2932 yaffs_devname(sb, devname_buf));
2933
2934 - if(!data_str)
2935 + if (!data_str)
2936 data_str = "";
2937
2938 - printk(KERN_INFO "yaffs: passed flags \"%s\"\n",data_str);
2939 + printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
2940
2941 - memset(&options,0,sizeof(options));
2942 + memset(&options, 0, sizeof(options));
2943
2944 - if(yaffs_parse_options(&options,data_str)){
2945 + if (yaffs_parse_options(&options, data_str)) {
2946 /* Option parsing failed */
2947 return NULL;
2948 }
2949 @@ -1645,9 +1888,9 @@ static struct super_block *yaffs_interna
2950 yaffs_devname(sb, devname_buf)));
2951
2952 /* Check it's an mtd device..... */
2953 - if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) {
2954 + if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR)
2955 return NULL; /* This isn't an mtd device */
2956 - }
2957 +
2958 /* Get the device */
2959 mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
2960 if (!mtd) {
2961 @@ -1673,29 +1916,23 @@ static struct super_block *yaffs_interna
2962 T(YAFFS_TRACE_OS, (" %s %d\n", WRITE_SIZE_STR, WRITE_SIZE(mtd)));
2963 T(YAFFS_TRACE_OS, (" oobsize %d\n", mtd->oobsize));
2964 T(YAFFS_TRACE_OS, (" erasesize %d\n", mtd->erasesize));
2965 - T(YAFFS_TRACE_OS, (" size %d\n", mtd->size));
2966 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
2967 + T(YAFFS_TRACE_OS, (" size %u\n", mtd->size));
2968 +#else
2969 + T(YAFFS_TRACE_OS, (" size %lld\n", mtd->size));
2970 +#endif
2971
2972 #ifdef CONFIG_YAFFS_AUTO_YAFFS2
2973
2974 - if (yaffsVersion == 1 &&
2975 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
2976 - mtd->writesize >= 2048) {
2977 -#else
2978 - mtd->oobblock >= 2048) {
2979 -#endif
2980 - T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n"));
2981 - yaffsVersion = 2;
2982 + if (yaffsVersion == 1 && WRITE_SIZE(mtd) >= 2048) {
2983 + T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs2\n"));
2984 + yaffsVersion = 2;
2985 }
2986
2987 /* Added NCB 26/5/2006 for completeness */
2988 - if (yaffsVersion == 2 &&
2989 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
2990 - mtd->writesize == 512) {
2991 -#else
2992 - mtd->oobblock == 512) {
2993 -#endif
2994 - T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n"));
2995 - yaffsVersion = 1;
2996 + if (yaffsVersion == 2 && !options.inband_tags && WRITE_SIZE(mtd) == 512) {
2997 + T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs1\n"));
2998 + yaffsVersion = 1;
2999 }
3000
3001 #endif
3002 @@ -1707,7 +1944,7 @@ static struct super_block *yaffs_interna
3003 !mtd->block_markbad ||
3004 !mtd->read ||
3005 !mtd->write ||
3006 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
3007 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3008 !mtd->read_oob || !mtd->write_oob) {
3009 #else
3010 !mtd->write_ecc ||
3011 @@ -1719,12 +1956,9 @@ static struct super_block *yaffs_interna
3012 return NULL;
3013 }
3014
3015 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
3016 - if (mtd->writesize < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
3017 -#else
3018 - if (mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
3019 -#endif
3020 - mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) {
3021 + if ((WRITE_SIZE(mtd) < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
3022 + mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) &&
3023 + !options.inband_tags) {
3024 T(YAFFS_TRACE_ALWAYS,
3025 ("yaffs: MTD device does not have the "
3026 "right page sizes\n"));
3027 @@ -1735,7 +1969,7 @@ static struct super_block *yaffs_interna
3028 if (!mtd->erase ||
3029 !mtd->read ||
3030 !mtd->write ||
3031 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
3032 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3033 !mtd->read_oob || !mtd->write_oob) {
3034 #else
3035 !mtd->write_ecc ||
3036 @@ -1761,7 +1995,7 @@ static struct super_block *yaffs_interna
3037 * Set the yaffs_Device up for mtd
3038 */
3039
3040 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3041 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3042 sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
3043 #else
3044 sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
3045 @@ -1780,13 +2014,15 @@ static struct super_block *yaffs_interna
3046
3047 /* Set up the memory size parameters.... */
3048
3049 - nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK);
3050 + nBlocks = YCALCBLOCKS(mtd->size, (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK));
3051 +
3052 dev->startBlock = 0;
3053 dev->endBlock = nBlocks - 1;
3054 dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK;
3055 - dev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
3056 + dev->totalBytesPerChunk = YAFFS_BYTES_PER_CHUNK;
3057 dev->nReservedBlocks = 5;
3058 dev->nShortOpCaches = (options.no_cache) ? 0 : 10;
3059 + dev->inbandTags = options.inband_tags;
3060
3061 /* ... and the functions. */
3062 if (yaffsVersion == 2) {
3063 @@ -1798,20 +2034,19 @@ static struct super_block *yaffs_interna
3064 dev->queryNANDBlock = nandmtd2_QueryNANDBlock;
3065 dev->spareBuffer = YMALLOC(mtd->oobsize);
3066 dev->isYaffs2 = 1;
3067 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
3068 - dev->nDataBytesPerChunk = mtd->writesize;
3069 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3070 + dev->totalBytesPerChunk = mtd->writesize;
3071 dev->nChunksPerBlock = mtd->erasesize / mtd->writesize;
3072 #else
3073 - dev->nDataBytesPerChunk = mtd->oobblock;
3074 + dev->totalBytesPerChunk = mtd->oobblock;
3075 dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
3076 #endif
3077 - nBlocks = mtd->size / mtd->erasesize;
3078 + nBlocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
3079
3080 - dev->nCheckpointReservedBlocks = CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS;
3081 dev->startBlock = 0;
3082 dev->endBlock = nBlocks - 1;
3083 } else {
3084 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
3085 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3086 /* use the MTD interface in yaffs_mtdif1.c */
3087 dev->writeChunkWithTagsToNAND =
3088 nandmtd1_WriteChunkWithTagsToNAND;
3089 @@ -1847,7 +2082,7 @@ static struct super_block *yaffs_interna
3090 dev->skipCheckpointWrite = options.skip_checkpoint_write;
3091
3092 /* we assume this is protected by lock_kernel() in mount/umount */
3093 - list_add_tail(&dev->devList, &yaffs_dev_list);
3094 + ylist_add_tail(&dev->devList, &yaffs_dev_list);
3095
3096 init_MUTEX(&dev->grossLock);
3097
3098 @@ -1884,20 +2119,23 @@ static struct super_block *yaffs_interna
3099 return NULL;
3100 }
3101 sb->s_root = root;
3102 + sb->s_dirt = !dev->isCheckpointed;
3103 + T(YAFFS_TRACE_ALWAYS,
3104 + ("yaffs_read_super: isCheckpointed %d\n", dev->isCheckpointed));
3105
3106 T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n"));
3107 return sb;
3108 }
3109
3110
3111 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3112 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3113 static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data,
3114 int silent)
3115 {
3116 return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
3117 }
3118
3119 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
3120 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3121 static int yaffs_read_super(struct file_system_type *fs,
3122 int flags, const char *dev_name,
3123 void *data, struct vfsmount *mnt)
3124 @@ -1938,14 +2176,14 @@ static DECLARE_FSTYPE(yaffs_fs_type, "ya
3125
3126 #ifdef CONFIG_YAFFS_YAFFS2
3127
3128 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
3129 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
3130 static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data,
3131 int silent)
3132 {
3133 return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
3134 }
3135
3136 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
3137 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
3138 static int yaffs2_read_super(struct file_system_type *fs,
3139 int flags, const char *dev_name, void *data,
3140 struct vfsmount *mnt)
3141 @@ -1990,12 +2228,12 @@ static char *yaffs_dump_dev(char *buf, y
3142 {
3143 buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock);
3144 buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock);
3145 + buf += sprintf(buf, "totalBytesPerChunk. %d\n", dev->totalBytesPerChunk);
3146 buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk);
3147 buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits);
3148 buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize);
3149 buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks);
3150 buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks);
3151 - buf += sprintf(buf, "nCheckptResBlocks.. %d\n", dev->nCheckpointReservedBlocks);
3152 buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint);
3153 buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated);
3154 buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes);
3155 @@ -2006,10 +2244,8 @@ static char *yaffs_dump_dev(char *buf, y
3156 buf += sprintf(buf, "nPageReads......... %d\n", dev->nPageReads);
3157 buf += sprintf(buf, "nBlockErasures..... %d\n", dev->nBlockErasures);
3158 buf += sprintf(buf, "nGCCopies.......... %d\n", dev->nGCCopies);
3159 - buf +=
3160 - sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);
3161 - buf +=
3162 - sprintf(buf, "passiveGCs......... %d\n",
3163 + buf += sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);
3164 + buf += sprintf(buf, "passiveGCs......... %d\n",
3165 dev->passiveGarbageCollections);
3166 buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites);
3167 buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches);
3168 @@ -2025,6 +2261,7 @@ static char *yaffs_dump_dev(char *buf, y
3169 sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions);
3170 buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC);
3171 buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2);
3172 + buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags);
3173
3174 return buf;
3175 }
3176 @@ -2033,7 +2270,7 @@ static int yaffs_proc_read(char *page,
3177 char **start,
3178 off_t offset, int count, int *eof, void *data)
3179 {
3180 - struct list_head *item;
3181 + struct ylist_head *item;
3182 char *buf = page;
3183 int step = offset;
3184 int n = 0;
3185 @@ -2057,8 +2294,8 @@ static int yaffs_proc_read(char *page,
3186 lock_kernel();
3187
3188 /* Locate and print the Nth entry. Order N-squared but N is small. */
3189 - list_for_each(item, &yaffs_dev_list) {
3190 - yaffs_Device *dev = list_entry(item, yaffs_Device, devList);
3191 + ylist_for_each(item, &yaffs_dev_list) {
3192 + yaffs_Device *dev = ylist_entry(item, yaffs_Device, devList);
3193 if (n < step) {
3194 n++;
3195 continue;
3196 @@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file
3197 char *end;
3198 char *mask_name;
3199 const char *x;
3200 - char substring[MAX_MASK_NAME_LENGTH+1];
3201 + char substring[MAX_MASK_NAME_LENGTH + 1];
3202 int i;
3203 int done = 0;
3204 int add, len = 0;
3205 @@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file
3206
3207 while (!done && (pos < count)) {
3208 done = 1;
3209 - while ((pos < count) && isspace(buf[pos])) {
3210 + while ((pos < count) && isspace(buf[pos]))
3211 pos++;
3212 - }
3213
3214 switch (buf[pos]) {
3215 case '+':
3216 @@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file
3217 mask_name = NULL;
3218
3219 mask_bitfield = simple_strtoul(buf + pos, &end, 0);
3220 +
3221 if (end > buf + pos) {
3222 mask_name = "numeral";
3223 len = end - (buf + pos);
3224 pos += len;
3225 done = 0;
3226 } else {
3227 - for(x = buf + pos, i = 0;
3228 - (*x == '_' || (*x >='a' && *x <= 'z')) &&
3229 - i <MAX_MASK_NAME_LENGTH; x++, i++, pos++)
3230 - substring[i] = *x;
3231 + for (x = buf + pos, i = 0;
3232 + (*x == '_' || (*x >= 'a' && *x <= 'z')) &&
3233 + i < MAX_MASK_NAME_LENGTH; x++, i++, pos++)
3234 + substring[i] = *x;
3235 substring[i] = '\0';
3236
3237 for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3238 - if(strcmp(substring,mask_flags[i].mask_name) == 0){
3239 + if (strcmp(substring, mask_flags[i].mask_name) == 0) {
3240 mask_name = mask_flags[i].mask_name;
3241 mask_bitfield = mask_flags[i].mask_bitfield;
3242 done = 0;
3243 @@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file
3244
3245 if (mask_name != NULL) {
3246 done = 0;
3247 - switch(add) {
3248 + switch (add) {
3249 case '-':
3250 rg &= ~mask_bitfield;
3251 break;
3252 @@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file
3253
3254 yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
3255
3256 - printk("new trace = 0x%08X\n",yaffs_traceMask);
3257 + printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_traceMask);
3258
3259 if (rg & YAFFS_TRACE_ALWAYS) {
3260 for (i = 0; mask_flags[i].mask_name != NULL; i++) {
3261 char flag;
3262 flag = ((rg & mask_flags[i].mask_bitfield) == mask_flags[i].mask_bitfield) ? '+' : '-';
3263 - printk("%c%s\n", flag, mask_flags[i].mask_name);
3264 + printk(KERN_DEBUG "%c%s\n", flag, mask_flags[i].mask_name);
3265 }
3266 }
3267
3268 @@ -2211,12 +2448,8 @@ struct file_system_to_install {
3269 };
3270
3271 static struct file_system_to_install fs_to_install[] = {
3272 -//#ifdef CONFIG_YAFFS_YAFFS1
3273 {&yaffs_fs_type, 0},
3274 -//#endif
3275 -//#ifdef CONFIG_YAFFS_YAFFS2
3276 {&yaffs2_fs_type, 0},
3277 -//#endif
3278 {NULL, 0}
3279 };
3280
3281 @@ -2231,15 +2464,14 @@ static int __init init_yaffs_fs(void)
3282 /* Install the proc_fs entry */
3283 my_proc_entry = create_proc_entry("yaffs",
3284 S_IRUGO | S_IFREG,
3285 - &proc_root);
3286 + YPROC_ROOT);
3287
3288 if (my_proc_entry) {
3289 my_proc_entry->write_proc = yaffs_proc_write;
3290 my_proc_entry->read_proc = yaffs_proc_read;
3291 my_proc_entry->data = NULL;
3292 - } else {
3293 + } else
3294 return -ENOMEM;
3295 - }
3296
3297 /* Now add the file system entries */
3298
3299 @@ -2247,9 +2479,8 @@ static int __init init_yaffs_fs(void)
3300
3301 while (fsinst->fst && !error) {
3302 error = register_filesystem(fsinst->fst);
3303 - if (!error) {
3304 + if (!error)
3305 fsinst->installed = 1;
3306 - }
3307 fsinst++;
3308 }
3309
3310 @@ -2277,7 +2508,7 @@ static void __exit exit_yaffs_fs(void)
3311 T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__
3312 " removing. \n"));
3313
3314 - remove_proc_entry("yaffs", &proc_root);
3315 + remove_proc_entry("yaffs", YPROC_ROOT);
3316
3317 fsinst = fs_to_install;
3318
3319 @@ -2288,7 +2519,6 @@ static void __exit exit_yaffs_fs(void)
3320 }
3321 fsinst++;
3322 }
3323 -
3324 }
3325
3326 module_init(init_yaffs_fs)
3327 --- /dev/null
3328 +++ b/fs/yaffs2/yaffs_getblockinfo.h
3329 @@ -0,0 +1,34 @@
3330 +/*
3331 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
3332 + *
3333 + * Copyright (C) 2002-2007 Aleph One Ltd.
3334 + * for Toby Churchill Ltd and Brightstar Engineering
3335 + *
3336 + * Created by Charles Manning <charles@aleph1.co.uk>
3337 + *
3338 + * This program is free software; you can redistribute it and/or modify
3339 + * it under the terms of the GNU Lesser General Public License version 2.1 as
3340 + * published by the Free Software Foundation.
3341 + *
3342 + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
3343 + */
3344 +
3345 +#ifndef __YAFFS_GETBLOCKINFO_H__
3346 +#define __YAFFS_GETBLOCKINFO_H__
3347 +
3348 +#include "yaffs_guts.h"
3349 +
3350 +/* Function to manipulate block info */
3351 +static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
3352 +{
3353 + if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
3354 + T(YAFFS_TRACE_ERROR,
3355 + (TSTR
3356 + ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),
3357 + blk));