/* Function to calculate chunk and offset */
-static inline void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
- int *chunk_out, u32 *offset_out)
+void yaffs_addr_to_chunk(struct yaffs_dev *dev, loff_t addr,
+ int *chunk_out, u32 *offset_out)
{
int chunk;
u32 offset;
if (buffer) {
/* assume it is an unmanaged one. */
- yaffs_trace(YAFFS_TRACE_BUFFERS, "Releasing unmanaged temp buffer");
+ yaffs_trace(YAFFS_TRACE_BUFFERS,
+ "Releasing unmanaged temp buffer");
kfree(buffer);
dev->unmanaged_buffer_deallocs++;
}
static inline int yaffs_hash_fn(int n)
{
- n = abs(n);
+ if (n < 0)
+ n = -n;
return n % YAFFS_NOBJECT_BUCKETS;
}
yaffs_trace(YAFFS_TRACE_ERROR,
"**>> yaffs write required %d attempts",
attempts);
- dev->n_retired_writes += (attempts - 1);
+ dev->n_retried_writes += (attempts - 1);
}
return chunk;
#endif
}
+loff_t yaffs_max_file_size(struct yaffs_dev *dev)
+{
+ return ((loff_t) YAFFS_MAX_CHUNK_ID) * dev->data_bytes_per_chunk;
+}
+
/*-------------------- TNODES -------------------
* List of spare tnodes
case YAFFS_OBJECT_TYPE_FILE:
the_obj->variant.file_variant.file_size = 0;
the_obj->variant.file_variant.scanned_size = 0;
- the_obj->variant.file_variant.shrink_size = ~0; /* max */
+ the_obj->variant.file_variant.shrink_size =
+ yaffs_max_file_size(dev);
the_obj->variant.file_variant.top_level = 0;
the_obj->variant.file_variant.top = tn;
break;
bi->has_shrink_hdr = 0;
bi->skip_erased_check = 1; /* Clean, so no need to check */
bi->gc_prioritise = 0;
- bi->has_summary=0;
+ bi->has_summary = 0;
yaffs_clear_chunk_bits(dev, block_no);
/* Update file size */
if (object->variant_type == YAFFS_OBJECT_TYPE_FILE) {
- oh->file_size =
+ yaffs_oh_size_load(oh,
+ object->variant.file_variant.file_size);
+ tags.extra_file_size =
object->variant.file_variant.file_size;
- tags.extra_length = oh->file_size;
}
yaffs_verify_oh(object, oh, &tags, 1);
}
} else {
#else
+ dev = dev;
{
#endif
strncpy(name, oh_name, buff_size - 1);
}
} else {
#else
+ dev = dev;
{
#endif
strncpy(oh_name, name, YAFFS_MAX_NAME_LENGTH - 1);
u8 *buffer = NULL;
YCHAR old_name[YAFFS_MAX_NAME_LENGTH + 1];
struct yaffs_obj_hdr *oh = NULL;
+ loff_t file_size = 0;
strcpy(old_name, _Y("silly old name"));
/* Should not happen */
break;
case YAFFS_OBJECT_TYPE_FILE:
- oh->file_size =
- (oh->parent_obj_id == YAFFS_OBJECTID_DELETED ||
- oh->parent_obj_id == YAFFS_OBJECTID_UNLINKED) ?
- 0 : in->variant.file_variant.file_size;
+ if (oh->parent_obj_id != YAFFS_OBJECTID_DELETED &&
+ oh->parent_obj_id != YAFFS_OBJECTID_UNLINKED)
+ file_size = in->variant.file_variant.file_size;
+ yaffs_oh_size_load(oh, file_size);
break;
case YAFFS_OBJECT_TYPE_HARDLINK:
oh->equiv_id = in->variant.hardlink_variant.equiv_id;
/* Add extra info for file header */
new_tags.extra_available = 1;
new_tags.extra_parent_id = oh->parent_obj_id;
- new_tags.extra_length = oh->file_size;
+ new_tags.extra_file_size = file_size;
new_tags.extra_is_shrink = oh->is_shrink;
new_tags.extra_equiv_id = oh->equiv_id;
new_tags.extra_shadows = (oh->shadows_obj > 0) ? 1 : 0;
}
int yaffs_do_file_wr(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
- int n_bytes, int write_trhrough)
+ int n_bytes, int write_through)
{
int chunk;
int n = n_bytes;
int n_done = 0;
int n_writeback;
- int start_write = offset;
+ loff_t start_write = offset;
int chunk_written = 0;
u32 n_bytes_read;
- u32 chunk_start;
+ loff_t chunk_start;
struct yaffs_dev *dev;
dev = in->my_dev;
while (n > 0 && chunk_written >= 0) {
yaffs_addr_to_chunk(dev, offset, &chunk, &start);
- if (chunk * dev->data_bytes_per_chunk + start != offset ||
+ if (((loff_t)chunk) *
+ dev->data_bytes_per_chunk + start != offset ||
start >= dev->data_bytes_per_chunk) {
yaffs_trace(YAFFS_TRACE_ERROR,
- "AddrToChunk of offset %d gives chunk %d start %d",
- (int)offset, chunk, start);
+ "AddrToChunk of offset %lld gives chunk %d start %d",
+ offset, chunk, start);
}
chunk++; /* File pos to chunk in file offset */
* before.
*/
- chunk_start = ((chunk - 1) * dev->data_bytes_per_chunk);
+ chunk_start = (((loff_t)(chunk - 1)) *
+ dev->data_bytes_per_chunk);
if (chunk_start > in->variant.file_variant.file_size)
n_bytes_read = 0; /* Past end of file */
cache->locked = 0;
cache->n_bytes = n_writeback;
- if (write_trhrough) {
+ if (write_through) {
chunk_written =
yaffs_wr_data_obj
(cache->object,
}
int yaffs_wr_file(struct yaffs_obj *in, const u8 *buffer, loff_t offset,
- int n_bytes, int write_trhrough)
+ int n_bytes, int write_through)
{
yaffs2_handle_hole(in, offset);
- return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_trhrough);
+ return yaffs_do_file_wr(in, buffer, offset, n_bytes, write_through);
}
/* ---------------------- File resizing stuff ------------------ */
-static void yaffs_prune_chunks(struct yaffs_obj *in, int new_size)
+static void yaffs_prune_chunks(struct yaffs_obj *in, loff_t new_size)
{
struct yaffs_dev *dev = in->my_dev;
- int old_size = in->variant.file_variant.file_size;
+ loff_t old_size = in->variant.file_variant.file_size;
int i;
int chunk_id;
- int last_del = 1 + (old_size - 1) / dev->data_bytes_per_chunk;
- int start_del = 1 + (new_size + dev->data_bytes_per_chunk - 1) /
- dev->data_bytes_per_chunk;
+ u32 dummy;
+ int last_del;
+ int start_del;
+ if (old_size > 0)
+ yaffs_addr_to_chunk(dev, old_size - 1, &last_del, &dummy);
+ else
+ last_del = 0;
+
+ yaffs_addr_to_chunk(dev, new_size + dev->data_bytes_per_chunk - 1,
+ &start_del, &dummy);
+ last_del++;
+ start_del++;
/* Delete backwards so that we don't end up with holes if
* power is lost part-way through the operation.
int yaffs_resize_file(struct yaffs_obj *in, loff_t new_size)
{
struct yaffs_dev *dev = in->my_dev;
- int old_size = in->variant.file_variant.file_size;
+ loff_t old_size = in->variant.file_variant.file_size;
yaffs_flush_file_cache(in);
yaffs_invalidate_whole_cache(in);
*/
yaffs_get_obj_name(l, buffer,
YAFFS_MAX_NAME_LENGTH + 1);
- if (strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH) == 0)
+ if (!strncmp(name, buffer, YAFFS_MAX_NAME_LENGTH))
return l;
}
}
return strnlen(name, YAFFS_MAX_NAME_LENGTH);
}
-int yaffs_get_obj_length(struct yaffs_obj *obj)
+loff_t yaffs_get_obj_length(struct yaffs_obj *obj)
{
/* Dereference any hard linking */
obj = yaffs_get_equivalent_obj(obj);
if (!init_failed && !yaffs_create_initial_dir(dev))
init_failed = 1;
- if(!init_failed && dev->param.is_yaffs2 &&
+ if (!init_failed && dev->param.is_yaffs2 &&
!dev->param.disable_summary &&
!yaffs_summary_init(dev))
init_failed = 1;
dev->n_page_writes = 0;
dev->n_erasures = 0;
dev->n_gc_copies = 0;
- dev->n_retired_writes = 0;
+ dev->n_retried_writes = 0;
dev->n_retired_blocks = 0;
return n_free;
}
+
+/*\
+ * Marshalling functions to get loff_t file sizes into aand out of
+ * object headers.
+ */
+void yaffs_oh_size_load(struct yaffs_obj_hdr *oh, loff_t fsize)
+{
+ oh->file_size_low = (fsize & 0xFFFFFFFF);
+ oh->file_size_high = ((fsize >> 32) & 0xFFFFFFFF);
+}
+
+loff_t yaffs_oh_to_size(struct yaffs_obj_hdr *oh)
+{
+ loff_t retval;
+
+ if (~(oh->file_size_high))
+ retval = (((loff_t) oh->file_size_high) << 32) |
+ (((loff_t) oh->file_size_low) & 0xFFFFFFFF);
+ else
+ retval = (loff_t) oh->file_size_low;
+
+ return retval;
+}