#include "yaffs_getblockinfo.h"
#include "yaffs_verify.h"
#include "yaffs_attribs.h"
+#include "yaffs_summary.h"
/*
* Checkpoints are really no benefit on very small partitions.
}
/* Dump end of list */
- memset(&cp, 0xFF, sizeof(struct yaffs_checkpt_obj));
+ memset(&cp, 0xff, sizeof(struct yaffs_checkpt_obj));
cp.struct_type = sizeof(cp);
if (ok)
* of hole marker.
*/
loff_t old_file_size;
- int increase;
+ loff_t increase;
int small_hole;
int result = YAFFS_OK;
struct yaffs_dev *dev = NULL;
small_hole = 0;
if (small_hole)
- local_buffer = yaffs_get_temp_buffer(dev, __LINE__);
+ local_buffer = yaffs_get_temp_buffer(dev);
if (local_buffer) {
/* fill hole with zero bytes */
- int pos = old_file_size;
+ loff_t pos = old_file_size;
int this_write;
int written;
memset(local_buffer, 0, dev->data_bytes_per_chunk);
}
}
- yaffs_release_temp_buffer(dev, local_buffer, __LINE__);
+ yaffs_release_temp_buffer(dev, local_buffer);
/* If out of space then reverse any chunks we've added */
if (!small_increase_ok)
int blk, int chunk_in_block,
int *found_chunks,
u8 *chunk_data,
- struct list_head *hard_list)
+ struct list_head *hard_list,
+ int summary_available)
{
struct yaffs_obj_hdr *oh;
struct yaffs_obj *in;
struct yaffs_obj *parent;
int equiv_id;
- int file_size;
+ loff_t file_size;
int is_shrink;
int is_unlinked;
struct yaffs_ext_tags tags;
struct yaffs_hardlink_var *hl_var;
struct yaffs_symlink_var *sl_var;
- result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL, &tags);
+ if (summary_available) {
+ result = yaffs_summary_fetch(dev, &tags, chunk_in_block);
+ tags.seq_number = bi->seq_number;
+ }
+
+ if (!summary_available || tags.obj_id == 0) {
+ result = yaffs_rd_chunk_tags_nand(dev, chunk, NULL, &tags);
+ dev->tags_used++;
+ } else {
+ dev->summary_used++;
+ }
/* Let's have a good look at this chunk... */
dev->n_free_chunks++;
} else if (tags.obj_id > YAFFS_MAX_OBJECT_ID ||
tags.chunk_id > YAFFS_MAX_CHUNK_ID ||
+ tags.obj_id == YAFFS_OBJECTID_SUMMARY ||
(tags.chunk_id > 0 &&
tags.n_bytes > dev->data_bytes_per_chunk) ||
tags.seq_number != bi->seq_number) {
dev->n_free_chunks++;
} else if (tags.chunk_id > 0) {
/* chunk_id > 0 so it is a data chunk... */
- unsigned int endpos;
- u32 chunk_base = (tags.chunk_id - 1) *
+ loff_t endpos;
+ loff_t chunk_base = (tags.chunk_id - 1) *
dev->data_bytes_per_chunk;
*found_chunks = 1;
(tags.extra_available &&
tags.extra_obj_type == YAFFS_OBJECT_TYPE_FILE)
)) {
- u32 this_size = (oh) ?
- oh->file_size :
- tags.extra_length;
+ loff_t this_size = (oh) ?
+ yaffs_oh_to_size(oh) :
+ tags.extra_file_size;
u32 parent_obj_id = (oh) ?
oh->parent_obj_id :
tags.extra_parent_id;
}
if (!in->valid && in->variant_type !=
- (oh ? oh->type : tags.extra_obj_type))
+ (oh ? oh->type : tags.extra_obj_type)) {
yaffs_trace(YAFFS_TRACE_ERROR,
- "yaffs tragedy: Bad object type, %d != %d, for object %d at chunk %d during scan",
+ "yaffs tragedy: Bad type, %d != %d, for object %d at chunk %d during scan",
oh ? oh->type : tags.extra_obj_type,
in->variant_type, tags.obj_id,
chunk);
+ in = yaffs_retype_obj(in, oh ? oh->type : tags.extra_obj_type);
+ }
if (!in->valid &&
(tags.obj_id == YAFFS_OBJECTID_ROOT ||
parent = yaffs_find_or_create_by_number(dev,
oh->parent_obj_id,
YAFFS_OBJECT_TYPE_DIRECTORY);
- file_size = oh->file_size;
+ file_size = yaffs_oh_to_size(oh);
is_shrink = oh->is_shrink;
equiv_id = oh->equiv_id;
} else {
parent = yaffs_find_or_create_by_number(dev,
tags.extra_parent_id,
YAFFS_OBJECT_TYPE_DIRECTORY);
- file_size = tags.extra_length;
+ file_size = tags.extra_file_size;
is_shrink = tags.extra_is_shrink;
equiv_id = tags.extra_equiv_id;
in->lazy_loaded = 1;
int alloc_failed = 0;
struct yaffs_block_index *block_index = NULL;
int alt_block_index = 0;
+ int summary_available;
yaffs_trace(YAFFS_TRACE_SCAN,
"yaffs2_scan_backwards starts intstartblk %d intendblk %d...",
dev->blocks_in_checkpt = 0;
- chunk_data = yaffs_get_temp_buffer(dev, __LINE__);
+ chunk_data = yaffs_get_temp_buffer(dev);
/* Scan all the blocks to determine their state */
bi = dev->block_info;
bi++;
}
- yaffs_trace(YAFFS_TRACE_SCAN, "%d blocks to be sorted...", n_to_scan);
+ yaffs_trace(YAFFS_TRACE_ALWAYS, "%d blocks to be sorted...", n_to_scan);
cond_resched();
bi = yaffs_get_block_info(dev, blk);
deleted = 0;
+ summary_available = yaffs_summary_read(dev, dev->sum_tags, blk);
+
/* For each chunk in each block that needs scanning.... */
found_chunks = 0;
- for (c = dev->param.chunks_per_block - 1;
+ if (summary_available)
+ c = dev->chunks_per_summary - 1;
+ else
+ c = dev->param.chunks_per_block - 1;
+
+ for (/* c is already initialised */;
!alloc_failed && c >= 0 &&
(bi->block_state == YAFFS_BLOCK_STATE_NEEDS_SCAN ||
- bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING); c--) {
+ bi->block_state == YAFFS_BLOCK_STATE_ALLOCATING);
+ c--) {
/* Scan backwards...
* Read the tags and decide what to do
*/
if (yaffs2_scan_chunk(dev, bi, blk, c,
&found_chunks, chunk_data,
- &hard_list) == YAFFS_FAIL)
+ &hard_list, summary_available) ==
+ YAFFS_FAIL)
alloc_failed = 1;
}
*/
yaffs_link_fixup(dev, &hard_list);
- yaffs_release_temp_buffer(dev, chunk_data, __LINE__);
+ yaffs_release_temp_buffer(dev, chunk_data);
if (alloc_failed)
return YAFFS_FAIL;