1 --- a/fs/yaffs2/devextras.h
2 +++ b/fs/yaffs2/devextras.h
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
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.
20 -#define __inline__ __inline
24 -#if !(defined __KERNEL__) || (defined WIN32)
26 -/* User space defines */
27 +#if !(defined __KERNEL__)
29 +/* Definition of types */
30 typedef unsigned char __u8;
31 typedef unsigned short __u16;
32 typedef unsigned __u32;
37 - * Simple doubly linked list implementation.
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.
48 -#define prefetch(x) 1
51 - struct list_head *next, *prev;
53 + struct ylist_head *next; /* next in chain */
54 + struct ylist_head *prev; /* previous in chain */
57 -#define LIST_HEAD_INIT(name) { &(name), &(name) }
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)}
66 -#define INIT_LIST_HEAD(ptr) do { \
67 - (ptr)->next = (ptr); (ptr)->prev = (ptr); \
69 +/* Initialise a list head to an empty list */
70 +#define YINIT_LIST_HEAD(p) \
77 - * Insert a new entry between two known consecutive entries.
79 - * This is only for internal list manipulation where we know
80 - * the prev/next entries already!
82 -static __inline__ void __list_add(struct list_head *new,
83 - struct list_head *prev,
84 - struct list_head *next)
93 - * list_add - add a new entry
94 - * @new: new entry to be added
95 - * @head: list head to add it after
97 - * Insert a new entry after the specified head.
98 - * This is good for implementing stacks.
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)
105 - __list_add(new, head, head->next);
107 + struct ylist_head *listNext = list->next;
109 + list->next = newEntry;
110 + newEntry->prev = list;
111 + newEntry->next = listNext;
112 + listNext->prev = newEntry;
115 - * list_add_tail - add a new entry
116 - * @new: new entry to be added
117 - * @head: list head to add it before
119 - * Insert a new entry before the specified head.
120 - * This is useful for implementing queues.
122 -static __inline__ void list_add_tail(struct list_head *new,
123 - struct list_head *head)
125 - __list_add(new, head->prev, head);
129 - * Delete a list entry by making the prev/next entries
130 - * point to each other.
132 - * This is only for internal list manipulation where we know
133 - * the prev/next entries already!
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)
142 + struct ylist_head *listPrev = list->prev;
144 + list->prev = newEntry;
145 + newEntry->next = list;
146 + newEntry->prev = listPrev;
147 + listPrev->next = newEntry;
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.
157 -static __inline__ void list_del(struct list_head *entry)
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)
163 - __list_del(entry->prev, entry->next);
164 + struct ylist_head *listNext = entry->next;
165 + struct ylist_head *listPrev = entry->prev;
167 + listNext->prev = listPrev;
168 + listPrev->next = listNext;
173 - * list_del_init - deletes entry from list and reinitialize it.
174 - * @entry: the element to delete from the list.
176 -static __inline__ void list_del_init(struct list_head *entry)
177 +static __inline__ void ylist_del_init(struct ylist_head *entry)
179 - __list_del(entry->prev, entry->next);
180 - INIT_LIST_HEAD(entry);
182 + entry->next = entry->prev = entry;
186 - * list_empty - tests whether a list is empty
187 - * @head: the list to test.
189 -static __inline__ int list_empty(struct list_head *head)
191 +/* Test if the list is empty */
192 +static __inline__ int ylist_empty(struct ylist_head *entry)
194 - return head->next == head;
195 + return (entry->next == entry);
199 - * list_splice - join two lists
200 - * @list: the new list to add.
201 - * @head: the place to add it in the first list.
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.
206 -static __inline__ void list_splice(struct list_head *list,
207 - struct list_head *head)
209 - struct list_head *first = list->next;
211 - if (first != list) {
212 - struct list_head *last = list->prev;
213 - struct list_head *at = head->next;
215 - first->prev = head;
216 - head->next = first;
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.
229 -#define list_entry(ptr, type, member) \
230 - ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
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.
237 -#define list_for_each(pos, head) \
238 - for (pos = (head)->next, prefetch(pos->next); pos != (head); \
239 - pos = pos->next, prefetch(pos->next))
242 - * list_for_each_safe - iterate over a list safe against removal
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.
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)))
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
261 +#define ylist_for_each(itervar, list) \
262 + for (itervar = (list)->next; itervar != (list); itervar = itervar->next)
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)
269 +#if !(defined __KERNEL__)
273 +#include <sys/stat.h>
277 +#ifdef CONFIG_YAFFS_PROVIDE_DEFS
284 @@ -212,6 +153,7 @@ static __inline__ void list_splice(struc
290 #include <sys/stat.h>
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
302 unsigned int ia_valid;
303 @@ -244,21 +182,15 @@ struct iattr {
304 unsigned int ia_attr_flags;
313 #include <linux/types.h>
314 -#include <linux/list.h>
315 #include <linux/fs.h>
316 #include <linux/stat.h>
326 --- a/fs/yaffs2/Kconfig
327 +++ b/fs/yaffs2/Kconfig
330 tristate "YAFFS2 file system support"
333 + depends on MTD_BLOCK
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
347 @@ -109,26 +110,6 @@ config YAFFS_DISABLE_LAZY_LOAD
351 -config YAFFS_CHECKPOINT_RESERVED_BLOCKS
352 - int "Reserved blocks for checkpointing"
353 - depends on YAFFS_YAFFS2
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
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.
372 config YAFFS_DISABLE_WIDE_TNODES
373 bool "Turn off wide tnodes"
374 --- a/fs/yaffs2/Makefile
375 +++ b/fs/yaffs2/Makefile
377 obj-$(CONFIG_YAFFS_FS) += yaffs.o
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
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 */
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 */
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
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
408 +MTD versions in yaffs_mtdif1.c.
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 */
415 #endif /* YAFFS_OUT_OF_TREE */
417 --- a/fs/yaffs2/yaffs_checkptrw.c
418 +++ b/fs/yaffs2/yaffs_checkptrw.c
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 $";
427 #include "yaffs_checkptrw.h"
429 +#include "yaffs_getblockinfo.h"
431 static int yaffs_CheckpointSpaceOk(yaffs_Device *dev)
434 int blocksAvailable = dev->nErasedBlocks - dev->nReservedBlocks;
436 T(YAFFS_TRACE_CHECKPOINT,
437 (TSTR("checkpt blocks available = %d" TENDSTR),
441 return (blocksAvailable <= 0) ? 0 : 1;
445 static int yaffs_CheckpointErase(yaffs_Device *dev)
451 - if(!dev->eraseBlockInNAND)
452 + if (!dev->eraseBlockInNAND)
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));
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;
474 - dev->markNANDBlockBad(dev,i);
476 + dev->markNANDBlockBad(dev, i);
477 bi->blockState = YAFFS_BLOCK_STATE_DEAD;
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));
487 - if(dev->checkpointNextBlock >= 0 &&
488 - dev->checkpointNextBlock <= dev->internalEndBlock &&
489 - blocksAvailable > 0){
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) {
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));
509 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("out of checkpt blocks"TENDSTR)));
510 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("out of checkpt blocks"TENDSTR)));
512 dev->checkpointNextBlock = -1;
513 dev->checkpointCurrentBlock = -1;
514 @@ -98,30 +93,31 @@ static void yaffs_CheckpointFindNextChec
516 yaffs_ExtendedTags tags;
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));
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;
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,
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));
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));
550 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("found no more checkpt blocks"TENDSTR)));
551 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("found no more checkpt blocks"TENDSTR)));
553 dev->checkpointNextBlock = -1;
554 dev->checkpointCurrentBlock = -1;
555 @@ -133,17 +129,17 @@ int yaffs_CheckpointOpen(yaffs_Device *d
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)
567 - if(forWriting && !yaffs_CheckpointSpaceOk(dev))
568 + if (forWriting && !yaffs_CheckpointSpaceOk(dev))
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)
580 @@ -159,12 +155,10 @@ int yaffs_CheckpointOpen(yaffs_Device *d
581 dev->checkpointNextBlock = dev->internalStartBlock;
583 /* Erase all the blocks in the checkpoint area */
585 - memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
587 + memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
588 dev->checkpointByteOffset = 0;
589 return yaffs_CheckpointErase(dev);
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;
604 @@ -191,18 +185,17 @@ int yaffs_GetCheckpointSum(yaffs_Device
606 static int yaffs_CheckpointFlushBuffer(yaffs_Device *dev)
612 yaffs_ExtendedTags tags;
614 - if(dev->checkpointCurrentBlock < 0){
615 + if (dev->checkpointCurrentBlock < 0) {
616 yaffs_CheckpointFindNextErasedBlock(dev);
617 dev->checkpointCurrentChunk = 0;
620 - if(dev->checkpointCurrentBlock < 0)
621 + if (dev->checkpointCurrentBlock < 0)
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
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++;
638 @@ -221,28 +214,29 @@ static int yaffs_CheckpointFlushBuffer(y
639 chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock + dev->checkpointCurrentChunk;
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));
647 realignedChunk = chunk - dev->chunkOffset;
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;
660 - memset(dev->checkpointBuffer,0,dev->nDataBytesPerChunk);
661 + memset(dev->checkpointBuffer, 0, dev->nDataBytesPerChunk);
667 -int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes)
668 +int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes)
675 @@ -250,17 +244,14 @@ int yaffs_CheckpointWrite(yaffs_Device *
679 - if(!dev->checkpointBuffer)
680 + if (!dev->checkpointBuffer)
683 - if(!dev->checkpointOpenForWrite)
684 + if (!dev->checkpointOpenForWrite)
687 - while(i < nBytes && ok) {
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;
697 @@ -270,18 +261,17 @@ int yaffs_CheckpointWrite(yaffs_Device *
698 dev->checkpointByteCount++;
701 - if(dev->checkpointByteOffset < 0 ||
702 + if (dev->checkpointByteOffset < 0 ||
703 dev->checkpointByteOffset >= dev->nDataBytesPerChunk)
704 ok = yaffs_CheckpointFlushBuffer(dev);
712 int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes)
717 yaffs_ExtendedTags tags;
719 @@ -291,52 +281,54 @@ int yaffs_CheckpointRead(yaffs_Device *d
721 __u8 *dataBytes = (__u8 *)data;
723 - if(!dev->checkpointBuffer)
724 + if (!dev->checkpointBuffer)
727 - if(dev->checkpointOpenForWrite)
728 + if (dev->checkpointOpenForWrite)
731 - while(i < nBytes && ok) {
732 + while (i < nBytes && ok) {
735 - if(dev->checkpointByteOffset < 0 ||
736 - dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
737 + if (dev->checkpointByteOffset < 0 ||
738 + dev->checkpointByteOffset >= dev->nDataBytesPerChunk) {
740 - if(dev->checkpointCurrentBlock < 0){
741 + if (dev->checkpointCurrentBlock < 0) {
742 yaffs_CheckpointFindNextCheckpointBlock(dev);
743 dev->checkpointCurrentChunk = 0;
746 - if(dev->checkpointCurrentBlock < 0)
747 + if (dev->checkpointCurrentBlock < 0)
751 - chunk = dev->checkpointCurrentBlock * dev->nChunksPerBlock +
752 - dev->checkpointCurrentChunk;
753 + chunk = dev->checkpointCurrentBlock *
754 + dev->nChunksPerBlock +
755 + dev->checkpointCurrentChunk;
757 realignedChunk = chunk - dev->chunkOffset;
759 - /* read in the next chunk */
760 - /* printf("read checkpoint page %d\n",dev->checkpointPage); */
761 - dev->readChunkWithTagsFromNAND(dev, realignedChunk,
762 - dev->checkpointBuffer,
765 - if(tags.chunkId != (dev->checkpointPageSequence + 1) ||
766 - tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
768 + /* read in the next chunk */
769 + /* printf("read checkpoint page %d\n",dev->checkpointPage); */
770 + dev->readChunkWithTagsFromNAND(dev,
772 + dev->checkpointBuffer,
775 + if (tags.chunkId != (dev->checkpointPageSequence + 1) ||
776 + tags.eccResult > YAFFS_ECC_RESULT_FIXED ||
777 + tags.sequenceNumber != YAFFS_SEQUENCE_CHECKPOINT_DATA)
780 dev->checkpointByteOffset = 0;
781 dev->checkpointPageSequence++;
782 dev->checkpointCurrentChunk++;
784 - if(dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
785 + if (dev->checkpointCurrentChunk >= dev->nChunksPerBlock)
786 dev->checkpointCurrentBlock = -1;
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)
799 - if(dev->checkpointOpenForWrite){
800 - if(dev->checkpointByteOffset != 0)
801 + if (dev->checkpointOpenForWrite) {
802 + if (dev->checkpointByteOffset != 0)
803 yaffs_CheckpointFlushBuffer(dev);
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;
814 - // Todo this looks odd...
815 + /* Todo this looks odd... */
818 YFREE(dev->checkpointBlockList);
819 @@ -374,27 +366,25 @@ int yaffs_CheckpointClose(yaffs_Device *
820 dev->nErasedBlocks -= dev->blocksInCheckpoint;
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));
827 - if(dev->checkpointBuffer){
828 + if (dev->checkpointBuffer) {
829 /* free the buffer */
830 YFREE(dev->checkpointBuffer);
831 dev->checkpointBuffer = NULL;
840 int yaffs_CheckpointInvalidateStream(yaffs_Device *dev)
842 /* Erase the first checksum block */
844 - T(YAFFS_TRACE_CHECKPOINT,(TSTR("checkpoint invalidate"TENDSTR)));
845 + T(YAFFS_TRACE_CHECKPOINT, (TSTR("checkpoint invalidate"TENDSTR)));
847 - if(!yaffs_CheckpointSpaceOk(dev))
848 + if (!yaffs_CheckpointSpaceOk(dev))
851 return yaffs_CheckpointErase(dev);
852 --- a/fs/yaffs2/yaffs_checkptrw.h
853 +++ b/fs/yaffs2/yaffs_checkptrw.h
856 int yaffs_CheckpointOpen(yaffs_Device *dev, int forWriting);
858 -int yaffs_CheckpointWrite(yaffs_Device *dev,const void *data, int nBytes);
859 +int yaffs_CheckpointWrite(yaffs_Device *dev, const void *data, int nBytes);
861 -int yaffs_CheckpointRead(yaffs_Device *dev,void *data, int nBytes);
862 +int yaffs_CheckpointRead(yaffs_Device *dev, void *data, int nBytes);
864 int yaffs_GetCheckpointSum(yaffs_Device *dev, __u32 *sum);
866 --- a/fs/yaffs2/yaffs_ecc.c
867 +++ b/fs/yaffs2/yaffs_ecc.c
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 $";
875 #include "yportenv.h"
877 @@ -109,12 +109,10 @@ void yaffs_ECCCalculate(const unsigned c
878 b = column_parity_table[*data++];
881 - if (b & 0x01) // odd number of bits in the byte
883 + if (b & 0x01) { /* odd number of bits in the byte */
885 line_parity_prime ^= ~i;
890 ecc[2] = (~col_parity) | 0x03;
891 @@ -158,7 +156,7 @@ void yaffs_ECCCalculate(const unsigned c
894 #ifdef CONFIG_YAFFS_ECC_WRONG_ORDER
895 - // Swap the bytes into the wrong order
896 + /* Swap the bytes into the wrong order */
900 @@ -189,7 +187,7 @@ int yaffs_ECCCorrect(unsigned char *data
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 */
909 @@ -251,7 +249,7 @@ int yaffs_ECCCorrect(unsigned char *data
910 * ECCxxxOther does ECC calcs on arbitrary n bytes of data
912 void yaffs_ECCCalculateOther(const unsigned char *data, unsigned nBytes,
913 - yaffs_ECCOther * eccOther)
914 + yaffs_ECCOther *eccOther)
918 @@ -278,8 +276,8 @@ void yaffs_ECCCalculateOther(const unsig
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)
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 */
932 if (lDelta == ~lDeltaPrime &&
933 - (((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15))
935 + (((cDelta ^ (cDelta >> 1)) & 0x15) == 0x15)) {
936 /* Single bit (recoverable) error in data */
939 @@ -307,7 +304,7 @@ int yaffs_ECCCorrectOther(unsigned char
943 - if(lDelta >= nBytes)
944 + if (lDelta >= nBytes)
947 data[lDelta] ^= (1 << bit);
948 @@ -316,7 +313,7 @@ int yaffs_ECCCorrectOther(unsigned char
951 if ((yaffs_CountBits32(lDelta) + yaffs_CountBits32(lDeltaPrime) +
952 - yaffs_CountBits(cDelta)) == 1) {
953 + yaffs_CountBits(cDelta)) == 1) {
954 /* Reccoverable error in ecc */
956 *read_ecc = *test_ecc;
957 @@ -326,6 +323,4 @@ int yaffs_ECCCorrectOther(unsigned char
958 /* Unrecoverable error */
964 --- a/fs/yaffs2/yaffs_ecc.h
965 +++ b/fs/yaffs2/yaffs_ecc.h
967 * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
971 - * This code implements the ECC algorithm used in SmartMedia.
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.
980 + * This code implements the ECC algorithm used in SmartMedia.
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.
989 #ifndef __YAFFS_ECC_H__
990 #define __YAFFS_ECC_H__
991 @@ -34,11 +34,11 @@ typedef struct {
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);
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);
1007 --- a/fs/yaffs2/yaffs_fs.c
1008 +++ b/fs/yaffs2/yaffs_fs.c
1011 * YAFFS: Yet Another Flash File System. A NAND-flash specific file system.
1013 - * Copyright (C) 2002-2007 Aleph One Ltd.
1014 + * Copyright (C) 2002-2009 Aleph One Ltd.
1015 * for Toby Churchill Ltd and Brightstar Engineering
1017 * Created by Charles Manning <charles@aleph1.co.uk>
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;
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>
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>
1043 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1044 +#include "asm/div64.h"
1046 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
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)
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)
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 */
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)
1070 +#define YPROC_ROOT NULL
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)
1078 #define WRITE_SIZE_STR "oobblock"
1079 -#define WRITE_SIZE(mtd) (mtd)->oobblock
1080 +#define WRITE_SIZE(mtd) ((mtd)->oobblock)
1083 -#include <asm/uaccess.h>
1084 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 27))
1085 +#define YAFFS_USE_WRITE_BEGIN_END 1
1087 +#define YAFFS_USE_WRITE_BEGIN_END 0
1090 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
1091 +static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
1093 + uint64_t result = partition_size;
1094 + do_div(result, block_size);
1095 + return (uint32_t)result;
1098 +#define YCALCBLOCKS(s, b) ((s)/(b))
1101 +#include <linux/uaccess.h>
1103 #include "yportenv.h"
1104 #include "yaffs_guts.h"
1105 @@ -96,28 +120,44 @@ extern const char *yaffs_guts_c_version;
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;
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);
1120 +MODULE_PARM(yaffs_traceMask, "i");
1121 +MODULE_PARM(yaffs_wr_attempts, "i");
1122 +MODULE_PARM(yaffs_auto_checkpoint, "i");
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);
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))
1137 +static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino);
1140 /*#define T(x) printk x */
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)
1147 -#define yaffs_InodeToObjectLV(iptr) (iptr)->u.generic_ip
1148 +#define yaffs_InodeToObjectLV(iptr) ((iptr)->u.generic_ip)
1151 #define yaffs_InodeToObject(iptr) ((yaffs_Object *)(yaffs_InodeToObjectLV(iptr)))
1152 #define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode)
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)
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);
1162 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
1165 +static ssize_t yaffs_hold_space(struct file *f);
1166 +static void yaffs_release_space(struct file *f);
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);
1172 static int yaffs_file_flush(struct file *file);
1175 static int yaffs_sync_object(struct file *file, struct dentry *dentry,
1179 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir);
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);
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);
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);
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,
1207 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
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);
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);
1220 @@ -174,33 +216,47 @@ static int yaffs_sync_fs(struct super_bl
1221 static int yaffs_write_super(struct super_block *sb);
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);
1231 static int yaffs_statfs(struct super_block *sb, struct statfs *buf);
1233 -static void yaffs_read_inode(struct inode *inode);
1235 +#ifdef YAFFS_HAS_PUT_INODE
1236 static void yaffs_put_inode(struct inode *inode);
1239 static void yaffs_delete_inode(struct inode *);
1240 static void yaffs_clear_inode(struct inode *);
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);
1247 static int yaffs_writepage(struct page *page);
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);
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,
1266 -static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
1268 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13))
1271 +static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
1273 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 13))
1274 static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd);
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,
1285 .prepare_write = yaffs_prepare_write,
1286 .commit_write = yaffs_commit_write,
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,
1304 -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18))
1305 +#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 18))
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
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,
1330 -static struct inode_operations yaffs_file_inode_operations = {
1331 +static const struct inode_operations yaffs_file_inode_operations = {
1332 .setattr = yaffs_setattr,
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,
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,
1347 @@ -276,16 +338,21 @@ static struct inode_operations yaffs_dir
1348 .setattr = yaffs_setattr,
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,
1358 -static struct super_operations yaffs_super_ops = {
1359 +static const struct super_operations yaffs_super_ops = {
1360 .statfs = yaffs_statfs,
1362 +#ifndef YAFFS_USE_OWN_IGET
1363 .read_inode = yaffs_read_inode,
1365 +#ifdef YAFFS_HAS_PUT_INODE
1366 .put_inode = yaffs_put_inode,
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,
1375 -static void yaffs_GrossLock(yaffs_Device * dev)
1376 +static void yaffs_GrossLock(yaffs_Device *dev)
1378 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs locking\n"));
1380 + T(YAFFS_TRACE_OS, ("yaffs locking %p\n", current));
1381 down(&dev->grossLock);
1382 + T(YAFFS_TRACE_OS, ("yaffs locked %p\n", current));
1385 -static void yaffs_GrossUnlock(yaffs_Device * dev)
1386 +static void yaffs_GrossUnlock(yaffs_Device *dev)
1388 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs unlocking\n"));
1389 + T(YAFFS_TRACE_OS, ("yaffs unlocking %p\n", current));
1390 up(&dev->grossLock);
1394 -static int yaffs_readlink(struct dentry *dentry, char __user * buffer,
1396 +static int yaffs_readlink(struct dentry *dentry, char __user *buffer,
1399 unsigned char *alias;
1401 @@ -329,7 +395,7 @@ static int yaffs_readlink(struct dentry
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)
1409 static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd)
1410 @@ -345,32 +411,31 @@ static int yaffs_follow_link(struct dent
1412 yaffs_GrossUnlock(dev);
1422 ret = vfs_follow_link(nd, alias);
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);
1434 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
1435 - yaffs_Object * obj);
1436 + yaffs_Object *obj);
1439 * Lookup is used to find objects in the fs
1441 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1442 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
1444 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry,
1445 - struct nameidata *n)
1446 + struct nameidata *n)
1448 static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry)
1450 @@ -383,12 +448,11 @@ static struct dentry *yaffs_lookup(struc
1451 yaffs_GrossLock(dev);
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));
1460 - yaffs_FindObjectByName(yaffs_InodeToObject(dir),
1461 - dentry->d_name.name);
1462 + obj = yaffs_FindObjectByName(yaffs_InodeToObject(dir),
1463 + dentry->d_name.name);
1465 obj = yaffs_GetEquivalentObject(obj); /* in case it was a hardlink */
1467 @@ -397,13 +461,13 @@ static struct dentry *yaffs_lookup(struc
1471 - (KERN_DEBUG "yaffs_lookup found %d\n", obj->objectId));
1472 + ("yaffs_lookup found %d\n", obj->objectId));
1474 inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
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 */
1483 @@ -416,7 +480,7 @@ static struct dentry *yaffs_lookup(struc
1487 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_lookup not found\n"));
1488 + T(YAFFS_TRACE_OS, ("yaffs_lookup not found\n"));
1492 @@ -425,20 +489,22 @@ static struct dentry *yaffs_lookup(struc
1493 d_add(dentry, inode);
1496 - /* return (ERR_PTR(-EIO)); */
1501 +#ifdef YAFFS_HAS_PUT_INODE
1503 /* For now put inode is just for debugging
1504 * Put inode is called when the inode **structure** is put.
1506 static void yaffs_put_inode(struct inode *inode)
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)));
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);
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"));
1532 @@ -486,23 +552,23 @@ static void yaffs_delete_inode(struct in
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"));
1545 yaffs_GrossLock(dev);
1546 - yaffs_DeleteFile(obj);
1547 + yaffs_DeleteObject(obj);
1548 yaffs_GrossUnlock(dev);
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);
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)
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;
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"));
1572 yaffs_GrossLock(dev);
1574 @@ -535,15 +601,15 @@ static int yaffs_readpage_nolock(struct
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));
1585 obj = yaffs_DentryToObject(f->f_dentry);
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));
1593 if (!PageLocked(pg))
1594 @@ -555,9 +621,9 @@ static int yaffs_readpage_nolock(struct
1596 yaffs_GrossLock(dev);
1599 - yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT,
1601 + ret = yaffs_ReadDataFromFile(obj, pg_buf,
1602 + pg->index << PAGE_CACHE_SHIFT,
1605 yaffs_GrossUnlock(dev);
1607 @@ -575,7 +641,7 @@ static int yaffs_readpage_nolock(struct
1608 flush_dcache_page(pg);
1611 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage done\n"));
1612 + T(YAFFS_TRACE_OS, ("yaffs_readpage done\n"));
1616 @@ -593,7 +659,7 @@ static int yaffs_readpage(struct file *f
1618 /* writepage inspired by/stolen from smbfs */
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)
1624 static int yaffs_writepage(struct page *page)
1625 @@ -616,12 +682,11 @@ static int yaffs_writepage(struct page *
1627 if (offset > inode->i_size) {
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));
1637 - (KERN_DEBUG " -> don't care!!\n"));
1638 + (" -> don't care!!\n"));
1642 @@ -629,11 +694,10 @@ static int yaffs_writepage(struct page *
1643 end_index = inode->i_size >> PAGE_CACHE_SHIFT;
1646 - if (page->index < end_index) {
1647 + if (page->index < end_index)
1648 nBytes = PAGE_CACHE_SIZE;
1651 nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1);
1656 @@ -643,19 +707,18 @@ static int yaffs_writepage(struct page *
1657 yaffs_GrossLock(obj->myDev);
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));
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));
1671 - yaffs_WriteDataToFile(obj, buffer, page->index << PAGE_CACHE_SHIFT,
1673 + nWritten = yaffs_WriteDataToFile(obj, buffer,
1674 + page->index << PAGE_CACHE_SHIFT, nBytes, 0);
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));
1682 yaffs_GrossUnlock(obj->myDev);
1684 @@ -667,100 +730,207 @@ static int yaffs_writepage(struct page *
1685 return (nWritten == nBytes) ? 0 : -ENOSPC;
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)
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;
1700 + int space_held = 0;
1702 + T(YAFFS_TRACE_OS, ("start yaffs_write_begin\n"));
1704 +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28)
1705 + pg = grab_cache_page_write_begin(mapping, index, flags);
1707 + pg = __grab_cache_page(mapping, index);
1715 + /* Get fs space */
1716 + space_held = yaffs_hold_space(filp);
1718 + if (!space_held) {
1723 + /* Update page if required */
1725 + if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE))
1726 + ret = yaffs_readpage_nolock(filp, pg);
1731 + /* Happy path return */
1732 + T(YAFFS_TRACE_OS, ("end yaffs_write_begin - ok\n"));
1737 + T(YAFFS_TRACE_OS, ("end yaffs_write_begin fail returning %d\n", ret));
1739 + yaffs_release_space(filp);
1742 + page_cache_release(pg);
1749 static int yaffs_prepare_write(struct file *f, struct page *pg,
1750 - unsigned offset, unsigned to)
1751 + unsigned offset, unsigned to)
1753 + T(YAFFS_TRACE_OS, ("yaffs_prepair_write\n"));
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);
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)
1770 + uint32_t offset_into_page = pos & (PAGE_CACHE_SIZE - 1);
1773 + addr = kva + offset_into_page;
1776 + ("yaffs_write_end addr %x pos %x nBytes %d\n",
1778 + (int)pos, copied));
1780 + ret = yaffs_file_write(filp, addr, copied, &pos);
1782 + if (ret != copied) {
1784 + ("yaffs_write_end not same size ret %d copied %d\n",
1787 + ClearPageUptodate(pg);
1789 + SetPageUptodate(pg);
1794 + yaffs_release_space(filp);
1796 + page_cache_release(pg);
1801 static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset,
1807 - void *addr = page_address(pg) + offset;
1808 loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset;
1809 int nBytes = to - offset;
1812 unsigned spos = pos;
1813 - unsigned saddr = (unsigned)addr;
1817 + addr = kva + offset;
1819 + saddr = (unsigned) addr;
1822 - (KERN_DEBUG "yaffs_commit_write addr %x pos %x nBytes %d\n", saddr,
1824 + ("yaffs_commit_write addr %x pos %x nBytes %d\n",
1825 + saddr, spos, nBytes));
1827 nWritten = yaffs_file_write(f, addr, nBytes, &pos);
1829 if (nWritten != nBytes) {
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));
1837 ClearPageUptodate(pg);
1839 SetPageUptodate(pg);
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));
1850 return nWritten == nBytes ? 0 : nWritten;
1856 -static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj)
1857 +static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj)
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;
1872 - case YAFFS_OBJECT_TYPE_SYMLINK :
1873 - if( ! S_ISLNK(mode) ){
1874 - obj->yst_mode &= ~S_IFMT;
1875 - obj->yst_mode |= S_IFLNK;
1879 - case YAFFS_OBJECT_TYPE_DIRECTORY :
1880 - if( ! S_ISDIR(mode) ){
1881 - obj->yst_mode &= ~S_IFMT;
1882 - obj->yst_mode |= S_IFDIR;
1886 - case YAFFS_OBJECT_TYPE_UNKNOWN :
1887 - case YAFFS_OBJECT_TYPE_HARDLINK :
1888 - case YAFFS_OBJECT_TYPE_SPECIAL :
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;
1902 + case YAFFS_OBJECT_TYPE_SYMLINK:
1903 + if (!S_ISLNK(mode)) {
1904 + obj->yst_mode &= ~S_IFMT;
1905 + obj->yst_mode |= S_IFLNK;
1909 + case YAFFS_OBJECT_TYPE_DIRECTORY:
1910 + if (!S_ISDIR(mode)) {
1911 + obj->yst_mode &= ~S_IFMT;
1912 + obj->yst_mode |= S_IFDIR;
1916 + case YAFFS_OBJECT_TYPE_UNKNOWN:
1917 + case YAFFS_OBJECT_TYPE_HARDLINK:
1918 + case YAFFS_OBJECT_TYPE_SPECIAL:
1924 + inode->i_flags |= S_NOATIME;
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;
1934 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
1935 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
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);
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)));
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));
1959 init_special_inode(inode, obj->yst_mode,
1960 - (dev_t) (obj->yst_rdev));
1961 + (dev_t) (obj->yst_rdev));
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;
1971 case S_IFDIR: /* directory */
1972 inode->i_op = &yaffs_dir_inode_operations;
1973 @@ -817,34 +986,36 @@ static void yaffs_FillInodeFromObject(st
1977 - (KERN_DEBUG "yaffs_FileInode invalid parameters\n"));
1978 + ("yaffs_FileInode invalid parameters\n"));
1983 struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev,
1984 - yaffs_Object * obj)
1985 + yaffs_Object *obj)
1987 struct inode *inode;
1991 - (KERN_DEBUG "yaffs_get_inode for NULL super_block!!\n"));
1992 + ("yaffs_get_inode for NULL super_block!!\n"));
1999 - (KERN_DEBUG "yaffs_get_inode for NULL object!!\n"));
2000 + ("yaffs_get_inode for NULL object!!\n"));
2006 - (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId));
2007 + ("yaffs_get_inode for object %d\n", obj->objectId));
2009 - inode = iget(sb, obj->objectId);
2010 + inode = Y_IGET(sb, obj->objectId);
2011 + if (IS_ERR(inode))
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
2019 static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
2025 @@ -869,28 +1040,26 @@ static ssize_t yaffs_file_write(struct f
2027 inode = f->f_dentry->d_inode;
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;
2040 - (KERN_DEBUG "yaffs_file_write: hey obj is null!\n"));
2042 + ("yaffs_file_write: hey obj is null!\n"));
2046 - "yaffs_file_write about to write writing %d bytes"
2047 - "to object %d at %d\n",
2048 - n, obj->objectId, ipos));
2050 + ("yaffs_file_write about to write writing %zu bytes"
2051 + "to object %d at %d\n",
2052 + n, obj->objectId, ipos));
2054 nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0);
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));
2065 @@ -899,10 +1068,9 @@ static ssize_t yaffs_file_write(struct f
2066 inode->i_blocks = (ipos + 511) >> 9;
2070 - "yaffs_file_write size updated to %d bytes, "
2072 - ipos, (int)(inode->i_blocks)));
2073 + ("yaffs_file_write size updated to %d bytes, "
2075 + ipos, (int)(inode->i_blocks)));
2079 @@ -910,13 +1078,54 @@ static ssize_t yaffs_file_write(struct f
2080 return nWritten == 0 ? -ENOSPC : nWritten;
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 */
2087 +static ssize_t yaffs_hold_space(struct file *f)
2089 + yaffs_Object *obj;
2090 + yaffs_Device *dev;
2095 + obj = yaffs_DentryToObject(f->f_dentry);
2099 + yaffs_GrossLock(dev);
2101 + nFreeChunks = yaffs_GetNumberOfFreeChunks(dev);
2103 + yaffs_GrossUnlock(dev);
2105 + return (nFreeChunks > 20) ? 1 : 0;
2108 +static void yaffs_release_space(struct file *f)
2110 + yaffs_Object *obj;
2111 + yaffs_Device *dev;
2114 + obj = yaffs_DentryToObject(f->f_dentry);
2118 + yaffs_GrossLock(dev);
2121 + yaffs_GrossUnlock(dev);
2124 static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir)
2128 struct inode *inode = f->f_dentry->d_inode;
2129 unsigned long offset, curoffs;
2130 - struct list_head *i;
2131 + struct ylist_head *i;
2134 char name[YAFFS_MAX_NAME_LENGTH + 1];
2135 @@ -932,24 +1141,20 @@ static int yaffs_readdir(struct file *f,
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)
2143 + ("yaffs_readdir: entry . ino %d \n",
2144 + (int)inode->i_ino));
2145 + if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) < 0)
2153 - (KERN_DEBUG "yaffs_readdir: entry .. ino %d \n",
2154 - (int)f->f_dentry->d_parent->d_inode->i_ino));
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)
2167 @@ -965,35 +1170,32 @@ static int yaffs_readdir(struct file *f,
2168 f->f_version = inode->i_version;
2171 - list_for_each(i, &obj->variant.directoryVariant.children) {
2172 + ylist_for_each(i, &obj->variant.directoryVariant.children) {
2174 if (curoffs >= offset) {
2175 - l = list_entry(i, yaffs_Object, siblings);
2176 + l = ylist_entry(i, yaffs_Object, siblings);
2178 yaffs_GetObjectName(l, name,
2179 YAFFS_MAX_NAME_LENGTH + 1);
2181 - (KERN_DEBUG "yaffs_readdir: %s inode %d\n", name,
2182 + ("yaffs_readdir: %s inode %d\n", name,
2183 yaffs_GetObjectInode(l)));
2189 - yaffs_GetObjectInode(l),
2190 - yaffs_GetObjectType(l))
2195 + yaffs_GetObjectInode(l),
2196 + yaffs_GetObjectType(l)) < 0)
2210 yaffs_GrossUnlock(dev);
2213 @@ -1002,12 +1204,19 @@ static int yaffs_readdir(struct file *f,
2215 * File creation. Allocate an inode, and we're done..
2217 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
2219 +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 29)
2222 +#define YCRED(x) (x->cred)
2225 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 5, 0))
2226 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
2230 static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode,
2235 struct inode *inode;
2236 @@ -1018,25 +1227,25 @@ static int yaffs_mknod(struct inode *dir
2237 yaffs_Object *parent = yaffs_InodeToObject(dir);
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;
2245 - if((dir->i_mode & S_ISGID) && S_ISDIR(mode))
2246 + if ((dir->i_mode & S_ISGID) && S_ISDIR(mode))
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));
2257 - (KERN_DEBUG "yaffs_mknod: could not get parent object\n"));
2258 + ("yaffs_mknod: could not get parent object\n"));
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));
2268 dev = parent->myDev;
2270 @@ -1045,33 +1254,28 @@ static int yaffs_mknod(struct inode *dir
2271 switch (mode & S_IFMT) {
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))
2278 - yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
2279 - gid, old_encode_dev(rdev));
2282 - yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
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));
2289 + obj = yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid,
2293 case S_IFREG: /* file */
2294 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n"));
2296 - yaffs_MknodFile(parent, dentry->d_name.name, mode, uid,
2298 + T(YAFFS_TRACE_OS, ("yaffs_mknod: making file\n"));
2299 + obj = yaffs_MknodFile(parent, dentry->d_name.name, mode, uid,
2302 case S_IFDIR: /* directory */
2304 - (KERN_DEBUG "yaffs_mknod: making directory\n"));
2306 - yaffs_MknodDirectory(parent, dentry->d_name.name, mode,
2308 + ("yaffs_mknod: making directory\n"));
2309 + obj = yaffs_MknodDirectory(parent, dentry->d_name.name, mode,
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? */
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);
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)));
2329 - (KERN_DEBUG "yaffs_mknod failed making object\n"));
2330 + ("yaffs_mknod failed making object\n"));
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)
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);
2342 - /* attempt to fix dir bug - didn't work */
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)
2355 static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode)
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);
2363 @@ -1127,8 +1325,8 @@ static int yaffs_unlink(struct inode *di
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));
2372 dev = yaffs_InodeToObject(dir)->myDev;
2374 @@ -1151,82 +1349,74 @@ static int yaffs_unlink(struct inode *di
2377 static int yaffs_link(struct dentry *old_dentry, struct inode *dir,
2378 - struct dentry *dentry)
2379 + struct dentry *dentry)
2381 struct inode *inode = old_dentry->d_inode;
2382 yaffs_Object *obj = NULL;
2383 yaffs_Object *link = NULL;
2386 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_link\n"));
2387 + T(YAFFS_TRACE_OS, ("yaffs_link\n"));
2389 obj = yaffs_InodeToObject(inode);
2392 yaffs_GrossLock(dev);
2394 - if (!S_ISDIR(inode->i_mode)) /* Don't link directories */
2397 - yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name,
2400 + if (!S_ISDIR(inode->i_mode)) /* Don't link directories */
2401 + link = yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name,
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);
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)));
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)));
2418 yaffs_GrossUnlock(dev);
2429 static int yaffs_symlink(struct inode *dir, struct dentry *dentry,
2430 - const char *symname)
2431 + const char *symname)
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;
2440 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_symlink\n"));
2441 + T(YAFFS_TRACE_OS, ("yaffs_symlink\n"));
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);
2452 struct inode *inode;
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"));
2460 - T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink not created\n"));
2462 + T(YAFFS_TRACE_OS, ("symlink not created\n"));
2468 static int yaffs_sync_object(struct file *file, struct dentry *dentry,
2474 @@ -1236,7 +1426,7 @@ static int yaffs_sync_object(struct file
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;
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;
2491 yaffs_GrossLock(dev);
2493 /* Check if the target is an existing directory that is not empty. */
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);
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)) {
2508 - T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n"));
2509 + T(YAFFS_TRACE_OS, ("target is non-empty dir\n"));
2511 retVal = YAFFS_FAIL;
2514 /* Now does unlinking internally using shadowing mechanism */
2515 - T(YAFFS_TRACE_OS, (KERN_DEBUG "calling yaffs_RenameObject\n"));
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"));
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);
2529 yaffs_GrossUnlock(dev);
2531 if (retVal == YAFFS_OK) {
2534 new_dentry->d_inode->i_nlink--;
2535 mark_inode_dirty(new_dentry->d_inode);
2537 @@ -1298,7 +1483,6 @@ static int yaffs_rename(struct inode *ol
2544 static int yaffs_setattr(struct dentry *dentry, struct iattr *attr)
2545 @@ -1308,15 +1492,15 @@ static int yaffs_setattr(struct dentry *
2549 - (KERN_DEBUG "yaffs_setattr of object %d\n",
2550 - yaffs_InodeToObject(inode)->objectId));
2552 - if ((error = inode_change_ok(inode, attr)) == 0) {
2553 + ("yaffs_setattr of object %d\n",
2554 + yaffs_InodeToObject(inode)->objectId));
2556 + error = inode_change_ok(inode, attr);
2558 dev = yaffs_InodeToObject(inode)->myDev;
2559 yaffs_GrossLock(dev);
2560 if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) ==
2566 @@ -1328,12 +1512,12 @@ static int yaffs_setattr(struct dentry *
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)
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)
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);
2585 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_statfs\n"));
2586 + T(YAFFS_TRACE_OS, ("yaffs_statfs\n"));
2588 yaffs_GrossLock(dev);
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) {
2595 + if (dev->nDataBytesPerChunk & (dev->nDataBytesPerChunk - 1)) {
2596 + /* Do this if chunk size is not a power of 2 */
2598 + uint64_t bytesInDev;
2599 + uint64_t bytesFree;
2601 + bytesInDev = ((uint64_t)((dev->endBlock - dev->startBlock + 1))) *
2602 + ((uint64_t)(dev->nChunksPerBlock * dev->nDataBytesPerChunk));
2604 + do_div(bytesInDev, sb->s_blocksize); /* bytesInDev becomes the number of blocks */
2605 + buf->f_blocks = bytesInDev;
2607 + bytesFree = ((uint64_t)(yaffs_GetNumberOfFreeChunks(dev))) *
2608 + ((uint64_t)(dev->nDataBytesPerChunk));
2610 + do_div(bytesFree, sb->s_blocksize);
2612 + buf->f_bfree = bytesFree;
2614 + } else if (sb->s_blocksize > dev->nDataBytesPerChunk) {
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);
2624 - yaffs_GetNumberOfFreeChunks(dev) / (sb->s_blocksize /
2625 - dev->nDataBytesPerChunk);
2626 + yaffs_GetNumberOfFreeChunks(dev) /
2627 + (sb->s_blocksize / dev->nDataBytesPerChunk);
2631 - (dev->endBlock - dev->startBlock +
2632 - 1) * dev->nChunksPerBlock * (dev->nDataBytesPerChunk /
2634 + (dev->endBlock - dev->startBlock + 1) *
2635 + dev->nChunksPerBlock *
2636 + (dev->nDataBytesPerChunk / sb->s_blocksize);
2639 - yaffs_GetNumberOfFreeChunks(dev) * (dev->nDataBytesPerChunk /
2641 + yaffs_GetNumberOfFreeChunks(dev) *
2642 + (dev->nDataBytesPerChunk / sb->s_blocksize);
2647 buf->f_bavail = buf->f_bfree;
2648 @@ -1378,18 +1583,19 @@ static int yaffs_statfs(struct super_blo
2653 static int yaffs_do_sync_fs(struct super_block *sb)
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"));
2662 yaffs_GrossLock(dev);
2666 + yaffs_FlushEntireDeviceCache(dev);
2667 yaffs_CheckpointSave(dev);
2670 yaffs_GrossUnlock(dev);
2672 @@ -1397,35 +1603,73 @@ static int yaffs_do_sync_fs(struct super
2678 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
2680 +#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
2681 static void yaffs_write_super(struct super_block *sb)
2683 static int yaffs_write_super(struct super_block *sb)
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))
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)
2703 static int yaffs_sync_fs(struct super_block *sb)
2706 + T(YAFFS_TRACE_OS, ("yaffs_sync_fs\n"));
2708 + if (yaffs_auto_checkpoint >= 1)
2709 + yaffs_do_sync_fs(sb);
2714 +#ifdef YAFFS_USE_OWN_IGET
2716 +static struct inode *yaffs_iget(struct super_block *sb, unsigned long ino)
2718 + struct inode *inode;
2719 + yaffs_Object *obj;
2720 + yaffs_Device *dev = yaffs_SuperToDevice(sb);
2723 + ("yaffs_iget for %lu\n", ino));
2725 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n"));
2726 + inode = iget_locked(sb, ino);
2728 + return ERR_PTR(-ENOMEM);
2729 + if (!(inode->i_state & I_NEW))
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.
2737 - return 0; /* yaffs_do_sync_fs(sb);*/
2738 + yaffs_GrossLock(dev);
2740 + obj = yaffs_FindObjectByNumber(dev, inode->i_ino);
2742 + yaffs_FillInodeFromObject(inode, obj);
2744 + yaffs_GrossUnlock(dev);
2746 + unlock_new_inode(inode);
2752 static void yaffs_read_inode(struct inode *inode)
2754 @@ -1438,7 +1682,7 @@ static void yaffs_read_inode(struct inod
2755 yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb);
2758 - (KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino));
2759 + ("yaffs_read_inode for %d\n", (int)inode->i_ino));
2761 yaffs_GrossLock(dev);
2763 @@ -1449,18 +1693,20 @@ static void yaffs_read_inode(struct inod
2764 yaffs_GrossUnlock(dev);
2767 -static LIST_HEAD(yaffs_dev_list);
2770 +static YLIST_HEAD(yaffs_dev_list);
2773 +#if 0 /* not used */
2774 static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data)
2776 yaffs_Device *dev = yaffs_SuperToDevice(sb);
2778 - if( *flags & MS_RDONLY ) {
2779 + if (*flags & MS_RDONLY) {
2780 struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
2783 - (KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name ));
2784 + ("yaffs_remount_fs: %s: RO\n", dev->name));
2786 yaffs_GrossLock(dev);
2788 @@ -1472,10 +1718,9 @@ static int yaffs_remount_fs(struct super
2791 yaffs_GrossUnlock(dev);
2796 - (KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name ));
2797 + ("yaffs_remount_fs: %s: RW\n", dev->name));
2801 @@ -1486,7 +1731,7 @@ static void yaffs_put_super(struct super
2803 yaffs_Device *dev = yaffs_SuperToDevice(sb);
2805 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n"));
2806 + T(YAFFS_TRACE_OS, ("yaffs_put_super\n"));
2808 yaffs_GrossLock(dev);
2810 @@ -1494,18 +1739,17 @@ static void yaffs_put_super(struct super
2812 yaffs_CheckpointSave(dev);
2814 - if (dev->putSuperFunc) {
2815 + if (dev->putSuperFunc)
2816 dev->putSuperFunc(sb);
2819 yaffs_Deinitialise(dev);
2821 yaffs_GrossUnlock(dev);
2823 /* we assume this is protected by lock_kernel() in mount/umount */
2824 - list_del(&dev->devList);
2825 + ylist_del(&dev->devList);
2827 - if(dev->spareBuffer){
2828 + if (dev->spareBuffer) {
2829 YFREE(dev->spareBuffer);
2830 dev->spareBuffer = NULL;
2832 @@ -1516,12 +1760,10 @@ static void yaffs_put_super(struct super
2834 static void yaffs_MTDPutSuper(struct super_block *sb)
2837 struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice;
2844 put_mtd_device(mtd);
2846 @@ -1531,9 +1773,9 @@ static void yaffs_MarkSuperBlockDirty(vo
2848 struct super_block *sb = (struct super_block *)vsb;
2850 - T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_MarkSuperBlockDirty() sb = %p\n",sb));
2853 + T(YAFFS_TRACE_OS, ("yaffs_MarkSuperBlockDirty() sb = %p\n", sb));
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)
2863 - char cur_opt[MAX_OPT_LEN+1];
2864 + char cur_opt[MAX_OPT_LEN + 1];
2868 /* Parse through the options which is a comma seperated list */
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);
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;
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;
2903 - printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",cur_opt);
2904 + printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",
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)
2921 struct inode *inode = NULL;
2922 @@ -1602,6 +1844,7 @@ static struct super_block *yaffs_interna
2924 sb->s_magic = YAFFS_MAGIC;
2925 sb->s_op = &yaffs_super_ops;
2926 + sb->s_flags |= MS_NOATIME;
2929 printk(KERN_INFO "yaffs: sb is NULL\n");
2930 @@ -1614,14 +1857,14 @@ static struct super_block *yaffs_interna
2932 yaffs_devname(sb, devname_buf));
2938 - printk(KERN_INFO "yaffs: passed flags \"%s\"\n",data_str);
2939 + printk(KERN_INFO "yaffs: passed flags \"%s\"\n", data_str);
2941 - memset(&options,0,sizeof(options));
2942 + memset(&options, 0, sizeof(options));
2944 - if(yaffs_parse_options(&options,data_str)){
2945 + if (yaffs_parse_options(&options, data_str)) {
2946 /* Option parsing failed */
2949 @@ -1645,9 +1888,9 @@ static struct super_block *yaffs_interna
2950 yaffs_devname(sb, devname_buf)));
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 */
2958 /* Get the device */
2959 mtd = get_mtd_device(NULL, MINOR(sb->s_dev));
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));
2969 + T(YAFFS_TRACE_OS, (" size %lld\n", mtd->size));
2972 #ifdef CONFIG_YAFFS_AUTO_YAFFS2
2974 - if (yaffsVersion == 1 &&
2975 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
2976 - mtd->writesize >= 2048) {
2978 - mtd->oobblock >= 2048) {
2980 - T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n"));
2982 + if (yaffsVersion == 1 && WRITE_SIZE(mtd) >= 2048) {
2983 + T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs2\n"));
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) {
2992 - mtd->oobblock == 512) {
2994 - T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n"));
2996 + if (yaffsVersion == 2 && !options.inband_tags && WRITE_SIZE(mtd) == 512) {
2997 + T(YAFFS_TRACE_ALWAYS, ("yaffs: auto selecting yaffs1\n"));
3002 @@ -1707,7 +1944,7 @@ static struct super_block *yaffs_interna
3003 !mtd->block_markbad ||
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) {
3011 @@ -1719,12 +1956,9 @@ static struct super_block *yaffs_interna
3015 -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17))
3016 - if (mtd->writesize < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
3018 - if (mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
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
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) {
3036 @@ -1761,7 +1995,7 @@ static struct super_block *yaffs_interna
3037 * Set the yaffs_Device up for mtd
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);
3044 sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL);
3045 @@ -1780,13 +2014,15 @@ static struct super_block *yaffs_interna
3047 /* Set up the memory size parameters.... */
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));
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;
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);
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;
3073 - dev->nDataBytesPerChunk = mtd->oobblock;
3074 + dev->totalBytesPerChunk = mtd->oobblock;
3075 dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
3077 - nBlocks = mtd->size / mtd->erasesize;
3078 + nBlocks = YCALCBLOCKS(mtd->size, mtd->erasesize);
3080 - dev->nCheckpointReservedBlocks = CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS;
3081 dev->startBlock = 0;
3082 dev->endBlock = nBlocks - 1;
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;
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);
3096 init_MUTEX(&dev->grossLock);
3098 @@ -1884,20 +2119,23 @@ static struct super_block *yaffs_interna
3102 + sb->s_dirt = !dev->isCheckpointed;
3103 + T(YAFFS_TRACE_ALWAYS,
3104 + ("yaffs_read_super: isCheckpointed %d\n", dev->isCheckpointed));
3106 T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n"));
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,
3116 return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
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
3126 #ifdef CONFIG_YAFFS_YAFFS2
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,
3133 return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
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
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);
3160 - sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections);
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);
3176 @@ -2033,7 +2270,7 @@ static int yaffs_proc_read(char *page,
3178 off_t offset, int count, int *eof, void *data)
3180 - struct list_head *item;
3181 + struct ylist_head *item;
3185 @@ -2057,8 +2294,8 @@ static int yaffs_proc_read(char *page,
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);
3196 @@ -2119,7 +2356,7 @@ static int yaffs_proc_write(struct file
3200 - char substring[MAX_MASK_NAME_LENGTH+1];
3201 + char substring[MAX_MASK_NAME_LENGTH + 1];
3205 @@ -2129,9 +2366,8 @@ static int yaffs_proc_write(struct file
3207 while (!done && (pos < count)) {
3209 - while ((pos < count) && isspace(buf[pos])) {
3210 + while ((pos < count) && isspace(buf[pos]))
3216 @@ -2148,20 +2384,21 @@ static int yaffs_proc_write(struct file
3219 mask_bitfield = simple_strtoul(buf + pos, &end, 0);
3221 if (end > buf + pos) {
3222 mask_name = "numeral";
3223 len = end - (buf + pos);
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';
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;
3243 @@ -2172,7 +2409,7 @@ static int yaffs_proc_write(struct file
3245 if (mask_name != NULL) {
3250 rg &= ~mask_bitfield;
3252 @@ -2191,13 +2428,13 @@ static int yaffs_proc_write(struct file
3254 yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS;
3256 - printk("new trace = 0x%08X\n",yaffs_traceMask);
3257 + printk(KERN_DEBUG "new trace = 0x%08X\n", yaffs_traceMask);
3259 if (rg & YAFFS_TRACE_ALWAYS) {
3260 for (i = 0; mask_flags[i].mask_name != NULL; i++) {
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);
3268 @@ -2211,12 +2448,8 @@ struct file_system_to_install {
3271 static struct file_system_to_install fs_to_install[] = {
3272 -//#ifdef CONFIG_YAFFS_YAFFS1
3273 {&yaffs_fs_type, 0},
3275 -//#ifdef CONFIG_YAFFS_YAFFS2
3276 {&yaffs2_fs_type, 0},
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",
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;
3297 /* Now add the file system entries */
3299 @@ -2247,9 +2479,8 @@ static int __init init_yaffs_fs(void)
3301 while (fsinst->fst && !error) {
3302 error = register_filesystem(fsinst->fst);
3305 fsinst->installed = 1;
3310 @@ -2277,7 +2508,7 @@ static void __exit exit_yaffs_fs(void)
3311 T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__
3314 - remove_proc_entry("yaffs", &proc_root);
3315 + remove_proc_entry("yaffs", YPROC_ROOT);
3317 fsinst = fs_to_install;
3319 @@ -2288,7 +2519,6 @@ static void __exit exit_yaffs_fs(void)
3326 module_init(init_yaffs_fs)
3328 +++ b/fs/yaffs2/yaffs_getblockinfo.h
3331 + * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
3333 + * Copyright (C) 2002-2007 Aleph One Ltd.
3334 + * for Toby Churchill Ltd and Brightstar Engineering
3336 + * Created by Charles Manning <charles@aleph1.co.uk>
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.
3342 + * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
3345 +#ifndef __YAFFS_GETBLOCKINFO_H__
3346 +#define __YAFFS_GETBLOCKINFO_H__
3348 +#include "yaffs_guts.h"
3350 +/* Function to manipulate block info */
3351 +static Y_INLINE yaffs_BlockInfo *yaffs_GetBlockInfo(yaffs_Device * dev, int blk)
3353 + if (blk < dev->internalStartBlock || blk > dev->internalEndBlock) {
3354 + T(YAFFS_TRACE_ERROR,
3356 + ("**>> yaffs: getBlockInfo block %d is not valid" TENDSTR),