YAFFS2

Summary

The original motivation for YAFFS 2 was to add support for the new NAND with 2kB pages instead of 512-byte pages and strictly sequential page writing order.

To achieve this, a new design is used which also realises the following benefits:

Most of YAFFS and YAFFS2 code is common, therefore the code will likely be kept common with YAFFS vs YAFFS2 being run-time selected.

Method

The main philosophical difference between YAFFS and YAFFS2 is how discarded status is tracked. Since we can't do any re-writing, we can't use the "discarded" flags in YAFFS2.

Instead YAFFS2 uses two mechanisms to resolve data state.



This changes erasure slightly:

This makes erasure & garbage collection more expensive (by adding reads), but remember that ion YAFFS2 we don't need to do page deletions which are much more expensive operations. Thus, all-up YAFFS2 wins.

Resize Handling

In YAFFS, soft deletion is ued for everything but resizing (shrinking) a file which has some particularly ugly cases that can complicate garbage collection.

As mentioned before, we write a new ObjectHeader to indicate the shrinking. However, it is important that this ObjectHeader does not get destroyed (erased) before the data chunks that were discarded during the shrink are destroyed (erased). If this precaution is not taken then it is possible that the deleted chunks might be brought back to life.

The modification to the garbage collector is as follows:





Tag structure

Each chunk in YAFFS2 has the following information:

Field

Comment

Size for 1kb chunks

Size for 2kB chunks

blockState

Block state. non-0xFF for bad block

1 byte

1 byte

chunkId

32-bit chunk Id

4 bytes

4 bytes

objectId

32-bit object Id

4 bytes

4 bytes

nBytes

Number of data bytes in this chunk

2 bytes

2 bytes

blockSequence

sequence number for this block

4 bytes

4 bytes

tagsEcc

ECC on tags area

3 bytes

3 bytes

ecc

ECC, 3 bytes/256 bytes of data

12 bytes

24 bytes

Total


30 bytes

42 bytes



To get enough spare bytes for this tagging structure requires a chunk-size of at least 1kB. YAFFS1 is still used for 512-byte chunk sizes.

The blockSequence increments each time a block is allocated. (ie. the first block allocated is block 1, and so on).

Scanning

The only reason we need to keep track of data status on NAND is to be able to recreate the file system state during scanning. Since we no longer have chunk deletion status flags we use a slightly different process for scanning a YAFFS2 system.

In effect, YAFFS2 recreates its state by "replaying the tape". ie. it scans the chunks in their allocation order (block sequence Id order) rather than in their order on the media. This implies that at start up, the blocks must be read and their block sequence determined.

Performance

These numbers are indicative of relative performance. These only apply to the NAND data transfer and do not include other overheads.

As an example, read/write cycle times of 100nS are used (though NAND can typically do 50nS), "seek time" of 10uS and program time of 200uS. Mileage will vary.

NB x16 means using a 16-bit bus. Clearly this cuts down on data transfer time relative to an 8-bit bus.

Times for 2kB read(units of 1uS).

Operation

YAFFS1

YAFFS2 (512b pages)

YAFFS2 (2kB pages)

YAFFS2(2kB pages, x16)

Seek

40

40

10

10

Read

220

220

220

110

Total

260

260

230

120

MB/s

7.6

7.6

8.7

16.7

Relative speed

1

1

1.1

2.2



Times for 2kB writes(units of 1uS).

Operation

YAFFS1

YAFFS2 (512b pages)

YAFFS2 (2kB pages)

YAFFS2(2kB pages, x16)

Seek

40

40

10

10

Program

800

800

200

200

Seek

40

40

10

10

Read

220

220

220

110

Total

1320

1320

660

440

MB/s

1.5

1.5

3

4.5

Relative speed

1

1

2

3



Times for 1MB delete (units of 1uS).

Operation

YAFFS1

YAFFS2 (512b pages)

YAFFS2 (2kB pages)

YAFFS2(2kB pages, x16)

Seek

20480

0

0

0

Program

409600

0

0

0

Erase

128000

128000

16000

16000

Total

558080

128000

16000

16000

MB/s

1.8

7.8

62.5

62.5

Relative speed

1

4

34

34



Times for 1MB of garbage collection at 50% dirty (units of 1uS).

Operation

YAFFS1

YAFFS2 (512b pages)

YAFFS2 (2kB pages)

YAFFS2(2kB pages, x16)

Delete 1MB

558080

128000

16000

16000

Write 0.5MB

337920

337920

168960

112640

Total

896000

465920

184960

128640

MB/s

1.1

2.1

5.4

7.7

Relative speed

1

1.9

4.9

7



MTD Interface

As mentioned before, YAFFS2 requires a chunk-size of at least 1kB to get a large enough spare area to support the increased size of the tags. This is not really a disadvantage, but should rather be viewed as an opportunity to exploit the NAND hardware more effectively. In particular:

To this end, yaffs_guts is being re-crafted to support arbitrary chunk size (power of 2, >= 1024), with arbitrary block size.

Currently, YAFFS also makes some other assumptions which will need to be changed:

Some of these differences can be absorbed in the yaffs_mtd layer. Some will need to be handles inside the mtd itself.

$Id: yaffs2.html,v 1.3 2003-09-16 06:48:38 charles Exp $