/*
* YAFFS: Yet another Flash File System . A NAND-flash specific file system.
*
- * Copyright (C) 2002-2011 Aleph One Ltd.
- * for Toby Churchill Ltd and Brightstar Engineering
+ * Copyright (C) 2002-2018 Aleph One Ltd.
*
* Created by Charles Manning <charles@aleph1.co.uk>
*
* 2^(3*MAX_LEVEL+4)
*
* Thus a max level of 8 supports files with up to 2^^28 chunks which gives
- * a maximum file size of arounf 51Gbytees with 2k chunks.
+ * a maximum file size of around 512Gbytees with 2k chunks.
*/
#define YAFFS_NTNODES_LEVEL0 16
#define YAFFS_TNODES_LEVEL0_BITS 4
/* Binary data version stamps */
#define YAFFS_SUMMARY_VERSION 1
-#define YAFFS_CHECKPOINT_VERSION 7
#ifdef CONFIG_YAFFS_UNICODE
#define YAFFS_MAX_NAME_LENGTH 127
*/
struct yaffs_tags {
- unsigned chunk_id:20;
- unsigned serial_number:2;
- unsigned n_bytes_lsb:10;
- unsigned obj_id:18;
- unsigned ecc:12;
- unsigned n_bytes_msb:2;
+ u32 chunk_id:20;
+ u32 serial_number:2;
+ u32 n_bytes_lsb:10;
+ u32 obj_id:18;
+ u32 ecc:12;
+ u32 n_bytes_msb:2;
};
union yaffs_tags_union {
struct yaffs_tags as_tags;
- u8 as_bytes[8];
+ u8 as_bytes[8];
+ u32 as_u32[2];
};
YAFFS_ECC_RESULT_UNFIXED
};
+/*
+ * Object type enum:
+ * When this is stored in flash we store it as a u32 instead
+ * to prevent any alignment change issues as compiler variants change.
+ */
+
enum yaffs_obj_type {
YAFFS_OBJECT_TYPE_UNKNOWN,
YAFFS_OBJECT_TYPE_FILE,
struct yaffs_block_info {
- int soft_del_pages:10; /* number of soft deleted pages */
- int pages_in_use:10; /* number of pages in use */
- unsigned block_state:4; /* One of the above block states. */
+ s32 soft_del_pages:10; /* number of soft deleted pages */
+ s32 pages_in_use:10; /* number of pages in use */
+ u32 block_state:4; /* One of the above block states. */
/* NB use unsigned because enum is sometimes
* an int */
u32 needs_retiring:1; /* Data has failed on this block, */
};
+union yaffs_block_info_union {
+ struct yaffs_block_info bi;
+ u32 as_u32[2];
+};
+
/* -------------------------- Object structure -------------------------------*/
/* This is the object structure as stored on NAND */
struct yaffs_obj_hdr {
- enum yaffs_obj_type type;
+ u32 type; /* enum yaffs_obj_type */
/* Apply to everything */
- int parent_obj_id;
+ u32 parent_obj_id;
u16 sum_no_longer_used; /* checksum of name. No longer used */
YCHAR name[YAFFS_MAX_NAME_LENGTH + 1];
* - a hard link
*/
+/* The file variant has three file sizes:
+ * - file_size : size of file as written into Yaffs - including data in cache.
+ * - stored_size - size of file as stored on media.
+ * - shrink_size - size of file that has been shrunk back to.
+ *
+ * The stored_size and file_size might be different because the data written
+ * into the cache will increase the file_size but the stored_size will only
+ * change when the data is actually stored.
+ *
+ */
struct yaffs_file_var {
loff_t file_size;
- loff_t scanned_size;
+ loff_t stored_size;
loff_t shrink_size;
int top_level;
struct yaffs_tnode *top;
void *my_inode;
- enum yaffs_obj_type variant_type;
+ u32 variant_type; /* enum yaffs_object_type */
union yaffs_obj_var variant;
int count;
};
-/* yaffs_checkpt_obj holds the definition of an object as dumped
- * by checkpointing.
- */
-
-struct yaffs_checkpt_obj {
- int struct_type;
- u32 obj_id;
- u32 parent_id;
- int hdr_chunk;
- enum yaffs_obj_type variant_type:3;
- u8 deleted:1;
- u8 soft_del:1;
- u8 unlinked:1;
- u8 fake:1;
- u8 rename_allowed:1;
- u8 unlink_allowed:1;
- u8 serial;
- int n_data_chunks;
- loff_t size_or_equiv_obj;
-};
/*--------------------- Temporary buffers ----------------
*
int inband_tags; /* Use unband tags */
u32 total_bytes_per_chunk; /* Should be >= 512, does not need to
be a power of 2 */
- int chunks_per_block; /* does not need to be a power of 2 */
- int spare_bytes_per_chunk; /* spare area size */
- int start_block; /* Start block we're allowed to use */
- int end_block; /* End block we're allowed to use */
- int n_reserved_blocks; /* Tuneable so that we can reduce
+ u32 chunks_per_block; /* does not need to be a power of 2 */
+ u32 spare_bytes_per_chunk; /* spare area size */
+ u32 start_block; /* Start block we're allowed to use */
+ u32 end_block; /* End block we're allowed to use */
+ u32 n_reserved_blocks; /* Tuneable so that we can reduce
* reserved blocks on NOR and RAM. */
- int n_caches; /* If <= 0, then short op caching is disabled,
+ u32 n_caches; /* If == 0, then short op caching is disabled,
* else the number of short op caches.
*/
int cache_bypass_aligned; /* If non-zero then bypass the cache for
* 0 = no limit.
*/
+ int hide_lost_n_found; /* Set non-zero to hide the lost-n-found dir. */
+
+ int stored_endian; /* 0=cpu endian, 1=little endian, 2=big endian */
+
/* The remove_obj_fn function must be supplied by OS flavours that
* need it.
* yaffs direct uses it to implement the faster readdir.
int always_check_erased; /* Force chunk erased check always on */
int disable_summary;
+ int disable_bad_block_marking;
};
struct list_head dev_list;
+ int ll_init;
/* Runtime parameters. Set up by YAFFS. */
- int data_bytes_per_chunk;
+ u32 data_bytes_per_chunk;
/* Non-wide tnode stuff */
u16 chunk_grp_bits; /* Number of bits that need to be resolved if
*/
u16 chunk_grp_size; /* == 2^^chunk_grp_bits */
+ struct yaffs_tnode *tn_swap_buffer;
+
/* Stuff to support wide tnodes */
u32 tnode_width;
u32 tnode_mask;
int is_mounted;
int read_only;
int is_checkpointed;
+ int swap_endian; /* Stored endian needs endian swap. */
/* Stuff to support block offsetting to support start block zero */
- int internal_start_block;
- int internal_end_block;
+ u32 internal_start_block;
+ u32 internal_end_block;
int block_offset;
int chunk_offset;
int checkpt_byte_offs;
u8 *checkpt_buffer;
int checkpt_open_write;
- int blocks_in_checkpt;
+ u32 blocks_in_checkpt;
int checkpt_cur_chunk;
int checkpt_cur_block;
int checkpt_next_block;
int *checkpt_block_list;
- int checkpt_max_blocks;
+ u32 checkpt_max_blocks;
u32 checkpt_sum;
u32 checkpt_xor;
/* Block Info */
struct yaffs_block_info *block_info;
u8 *chunk_bits; /* bitmap of chunks in use */
- unsigned block_info_alt:1; /* allocated using alternative alloc */
- unsigned chunk_bits_alt:1; /* allocated using alternative alloc */
+ u8 block_info_alt:1; /* allocated using alternative alloc */
+ u8 chunk_bits_alt:1; /* allocated using alternative alloc */
int chunk_bit_stride; /* Number of bytes of chunk_bits per block.
* Must be consistent with chunks_per_block.
*/
u32 n_page_writes;
u32 n_page_reads;
u32 n_erasures;
+ u32 n_bad_queries;
u32 n_bad_markings;
u32 n_erase_failures;
u32 n_gc_copies;
};
+/*
+ * Checkpointing definitions.
+ */
+
+#define YAFFS_CHECKPOINT_VERSION 8
+
+/* yaffs_checkpt_obj holds the definition of an object as dumped
+ * by checkpointing.
+ */
+
+
+/* Checkpint object bits in bitfield: offset, length */
+#define CHECKPOINT_VARIANT_BITS 0, 3
+#define CHECKPOINT_DELETED_BITS 3, 1
+#define CHECKPOINT_SOFT_DEL_BITS 4, 1
+#define CHECKPOINT_UNLINKED_BITS 5, 1
+#define CHECKPOINT_FAKE_BITS 6, 1
+#define CHECKPOINT_RENAME_ALLOWED_BITS 7, 1
+#define CHECKPOINT_UNLINK_ALLOWED_BITS 8, 1
+#define CHECKPOINT_SERIAL_BITS 9, 8
+
+struct yaffs_checkpt_obj {
+ int struct_type;
+ u32 obj_id;
+ u32 parent_id;
+ int hdr_chunk;
+ u32 bit_field;
+ int n_data_chunks;
+ loff_t size_or_equiv_obj;
+};
+
/* The CheckpointDevice structure holds the device information that changes
*at runtime and must be preserved over unmount/mount cycles.
*/
int yaffs_rename_obj(struct yaffs_obj *old_dir, const YCHAR * old_name,
struct yaffs_obj *new_dir, const YCHAR * new_name);
+int yaffs_unlink_obj(struct yaffs_obj *obj);
+
int yaffs_unlinker(struct yaffs_obj *dir, const YCHAR * name);
int yaffs_del_obj(struct yaffs_obj *obj);
+struct yaffs_obj *yaffs_retype_obj(struct yaffs_obj *obj,
+ enum yaffs_obj_type type);
+
int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR * name, int buffer_size);
loff_t yaffs_get_obj_length(struct yaffs_obj *obj);
const YCHAR *name, u32 mode, u32 uid,
u32 gid);
-int yaffs_flush_file(struct yaffs_obj *obj, int update_time, int data_sync);
+int yaffs_flush_file(struct yaffs_obj *in,
+ int update_time,
+ int data_sync,
+ int discard_cache);
/* Flushing and checkpointing */
-void yaffs_flush_whole_cache(struct yaffs_dev *dev);
+void yaffs_flush_whole_cache(struct yaffs_dev *dev, int discard);
int yaffs_checkpoint_save(struct yaffs_dev *dev);
int yaffs_checkpoint_restore(struct yaffs_dev *dev);
int yaffs_dump_obj(struct yaffs_obj *obj);
void yaffs_guts_test(struct yaffs_dev *dev);
+int yaffs_guts_ll_init(struct yaffs_dev *dev);
+
/* A few useful functions to be used within the core files*/
void yaffs_chunk_del(struct yaffs_dev *dev, int chunk_id, int mark_flash,
int yaffs_is_non_empty_dir(struct yaffs_obj *obj);
-int yaffs_format_dev(struct yaffs_dev *dev);
+int yaffs_guts_format_dev(struct yaffs_dev *dev);
void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
int *chunk_out, u32 *offset_out);
/*
- * Marshalling functions to get loff_t file sizes into aand out of
+ * Marshalling functions to get loff_t file sizes into and out of
* object headers.
*/
-void yaffs_oh_size_load(struct yaffs_obj_hdr *oh, loff_t fsize);
-loff_t yaffs_oh_to_size(struct yaffs_obj_hdr *oh);
+void yaffs_oh_size_load(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh,
+ loff_t fsize, int do_endian);
+loff_t yaffs_oh_to_size(struct yaffs_dev *dev, struct yaffs_obj_hdr *oh,
+ int do_endian);
loff_t yaffs_max_file_size(struct yaffs_dev *dev);
+/*
+ * Debug function to count number of blocks in each state
+ * NB Needs to be called with correct number of integers
+ */
+
+void yaffs_count_blocks_by_state(struct yaffs_dev *dev, int bs[10]);
+
+int yaffs_find_chunk_in_file(struct yaffs_obj *in, int inode_chunk,
+ struct yaffs_ext_tags *tags);
+
+/*
+ * Define LOFF_T_32_BIT if a 32-bit LOFF_T is being used.
+ * Not serious if you get this wrong - you might just get some warnings.
+*/
+
+#ifdef LOFF_T_32_BIT
+#define FSIZE_LOW(fsize) (fsize)
+#define FSIZE_HIGH(fsize) 0
+#define FSIZE_COMBINE(high, low) (low)
+#else
+#define FSIZE_LOW(fsize) ((fsize) & 0xffffffff)
+#define FSIZE_HIGH(fsize)(((fsize) >> 32) & 0xffffffff)
+#define FSIZE_COMBINE(high, low) ((((loff_t) (high)) << 32) | \
+ (((loff_t) (low)) & 0xFFFFFFFF))
+#endif
+
#endif