yaffs_lstat(str,&s);
- printf("%s ino %d length %d mode %X ",de->d_name,(int)s.st_ino,(int)s.st_size,s.st_mode);
+ printf("%s ino %lld length %d mode %X ",de->d_name,(int)s.st_ino,s.st_size,s.st_mode);
switch(s.st_mode & S_IFMT)
{
case S_IFREG: printf("data file"); break;
yaffs_lstat(str,&s);
- printf("%s inode %d obj %x length %d mode %X ",str,s.st_ino,de->d_dont_use,(int)s.st_size,s.st_mode);
+ printf("%s inode %d obj %x length %lld mode %X ",
+ str,s.st_ino,de->d_dont_use, s.st_size,s.st_mode);
switch(s.st_mode & S_IFMT)
{
case S_IFREG: printf("data file"); break;
}
+void max_files_test(const char *mountpt)
+{
+ char fn[100];
+ char sn[100];
+ char hn[100];
+ int result;
+ int h;
+ int i;
+
+ yaffs_trace_mask = 0;
+
+ yaffs_start_up();
+
+ yaffs_mount(mountpt);
+
+ for(i = 0; i < 5000; i++) {
+ sprintf(fn,"%s/file%d", mountpt, i);
+ yaffs_unlink(fn);
+ h = yaffs_open(fn,O_CREAT| O_RDWR, S_IREAD | S_IWRITE);
+ if(h < 0)
+ printf("File %s not created\n", fn);
+ yaffs_write(h,fn,100);
+ result = yaffs_close(h);
+ }
+ for(i = 0; i < 5; i++){
+ sprintf(fn,"%s/file%d",mountpt, i);
+ yaffs_unlink(fn);
+ }
+
+ for(i = 1000; i < 1010; i++){
+ sprintf(fn,"%s/file%d",mountpt, i);
+ h = yaffs_open(fn,O_CREAT| O_RDWR, S_IREAD | S_IWRITE);
+ yaffs_write(h,fn,100);
+ if(h < 0)
+ printf("File %s not created\n", fn);
+ result = yaffs_close(h);
+ }
+
+ h =yaffs_open(hn,O_RDWR,0);
+
+}
+
+void start_twice(const char *mountpt)
+{
+ printf("About to do first yaffs_start\n");
+ yaffs_start_up();
+ printf("started\n");
+ printf("First mount returns %d\n", yaffs_mount(mountpt));
+ printf("About to do second yaffs_start\n");
+ yaffs_start_up();
+ printf("started\n");
+ printf("Second mount returns %d\n", yaffs_mount(mountpt));
+}
+ #define N_WRITES 2000
+ #define STRIDE 2000
+
+ #define BUFFER_N 1100
+ unsigned xxbuffer[BUFFER_N];
+
+
+ void set_buffer(int n)
+ {
+ int i;
+ for(i = 0; i < BUFFER_N; i++)
+ xxbuffer[i] = i + n;
+ }
+
+ void write_big_sparse_file(int h)
+ {
+ int i;
+ loff_t offset = 0;
+ loff_t pos;
+ int n = sizeof(xxbuffer);
+ int wrote;
+
+ for(i = 0; i < N_WRITES; i++) {
+ printf("writing at %lld\n", offset);
+ set_buffer(i);
+ pos = yaffs_lseek(h, offset, SEEK_SET);
+ if(pos != offset) {
+ printf("mismatched seek pos %lld offset %lld\n",
+ pos, offset);
+ perror("lseek64");
+ exit(1);
+ }
+ wrote = yaffs_write(h, xxbuffer, n);
+
+ if(wrote != n) {
+ printf("mismatched write wrote %d n %d\n", wrote, n);
+ exit(1);
+ }
+
+ offset += (STRIDE * sizeof(xxbuffer));
+ }
+
+ yaffs_ftruncate(h, offset);
+
+ }
+
+
+
+
+ void verify_big_sparse_file(int h)
+ {
+ unsigned check_buffer[BUFFER_N];
+ int i;
+ loff_t offset = 0;
+ loff_t pos;
+ int n = sizeof(check_buffer);
+ int result;
+ const char * check_type;
+ int checks_failed = 0;
+ int checks_passed = 0;
+
+ for(i = 0; i < N_WRITES * STRIDE; i++) {
+ if(i % STRIDE) {
+ check_type = "zero";
+ memset(xxbuffer,0, n);
+ } else {
+ check_type = "buffer";
+ set_buffer(i/STRIDE);
+ }
+ //printf("%s checking %lld\n", check_type, offset);
+ pos = yaffs_lseek(h, offset, SEEK_SET);
+ if(pos != offset) {
+ printf("mismatched seek pos %lld offset %lld\n",
+ pos, offset);
+ perror("lseek64");
+ exit(1);
+ }
+ result = yaffs_read(h, check_buffer, n);
+
+ if(result != n) {
+ printf("mismatched read result %d n %d\n", result, n);
+ exit(1);
+ }
+
+
+
+
+ if(memcmp(xxbuffer, check_buffer, n)) {
+ int j;
+
+ printf("buffer at %lld mismatches\n", pos);
+ printf("xxbuffer ");
+ for(j = 0; j < 20; j++)
+ printf(" %d",xxbuffer[j]);
+ printf("\n");
+ printf("check_buffer ");
+ for(j = 0; j < 20; j++)
+ printf(" %d",check_buffer[j]);
+ printf("\n");
+
+ checks_failed++;
+ } else {
+ checks_passed++;
+ }
+
+ offset += sizeof(xxbuffer);
+ }
+
+ printf("%d checks passed, %d checks failed\n", checks_passed, checks_failed);
+
+ }
+
+
+ void large_file_test(const char *mountpt)
+ {
+ int handle;
+ char fullname[100];
+
+ yaffs_trace_mask = 0;
+
+ yaffs_start_up();
+
+ yaffs_mount(mountpt);
+ printf("mounted\n");
+ dumpDir(mountpt);
+
+ sprintf(fullname, "%s/%s", mountpt, "big-test-file");
+
+ handle = yaffs_open(fullname, O_RDONLY, 0);
+
+ handle = yaffs_open(fullname, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE);
+
+ if(handle < 0) {
+ perror("opening file");
+ exit(1);
+ }
+
+ write_big_sparse_file(handle);
+ verify_big_sparse_file(handle);
+
+ yaffs_close(handle);
+
+ printf("Job done\n");
+ yaffs_unmount(mountpt);
+
+ yaffs_mount(mountpt);
+ printf("mounted again\n");
+ dumpDir(mountpt);
+ handle = yaffs_open(fullname, O_RDONLY, 0);
+ verify_big_sparse_file(handle);
+ yaffs_unmount(mountpt);
+
+
+ yaffs_mount_common(mountpt, 0, 1);
+ printf("mounted with no checkpt\n");
+ dumpDir(mountpt);
+ handle = yaffs_open(fullname, O_RDONLY, 0);
+ verify_big_sparse_file(handle);
+ yaffs_unmount(mountpt);
+
+ }
+
+
int random_seed;
int simulate_power_failure;
//checkpoint_upgrade_test("/flash/flash",20);
//small_overwrite_test("/flash/flash",1000);
//checkpoint_fill_test("/flash/flash",20);
- // random_small_file_test("/flash/flash",10000);
+ //random_small_file_test("/flash/flash",10000);
// huge_array_test("/flash/flash",10);
//test_flash_traffic("yaffs2");
// link_follow_test("/yaffs2");
+ //basic_utime_test("/yaffs2");
+
+ //max_files_test("/yaffs2");
+
+ start_twice("/yaffs2");
- large_file_test("/yaffs2");
++ //large_file_test("/yaffs2");
+
+ //basic_utime_test("/yaffs2");
return 0;
u8 shareWrite:1;
int inodeId:12; /* Index to corresponding yaffsfs_Inode */
int handleCount:10; /* Number of handles for this fd */
- u32 position; /* current position in file */
+ loff_t position; /* current position in file */
}yaffsfs_FileDes;
typedef struct {
static yaffsfs_Handle *yaffsfs_HandleToPointer(int h)
{
- if(h >= 0 && h <= YAFFSFS_N_HANDLES)
+ if(h >= 0 && h < YAFFSFS_N_HANDLES)
return &yaffsfs_handle[h];
return NULL;
}
}
+static int yaffsfs_TooManyObjects(struct yaffs_dev *dev)
+{
+ int current_objects = dev->n_obj - dev->n_deleted_files;
+ if(dev->param.max_objects && current_objects > dev->param.max_objects)
+ return 1;
+ else
+ return 0;
+}
int yaffs_open_sharing(const YCHAR *path, int oflag, int mode, int sharing)
{
if(dir->my_dev->read_only){
yaffsfs_SetError(-EROFS);
errorReported = 1;
+ } else if(yaffsfs_TooManyObjects(dir->my_dev)) {
+ yaffsfs_SetError(-ENFILE);
+ errorReported = 1;
} else
obj = yaffs_create_file(dir,name,mode,0,0);
- int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte, int isPread, int offset)
+ int yaffsfs_do_read(int handle, void *vbuf, unsigned int nbyte, int isPread, loff_t offset)
{
yaffsfs_FileDes *fd = NULL;
struct yaffs_obj *obj = NULL;
- int pos = 0;
- int startPos = 0;
- int endPos = 0;
+ loff_t pos = 0;
+ loff_t startPos = 0;
+ loff_t endPos = 0;
int nRead = 0;
int nToRead = 0;
int totalRead = 0;
- unsigned int maxRead;
+ loff_t maxRead;
u8 *buf = (u8 *)vbuf;
if(!vbuf){
return yaffsfs_do_read(handle, buf, nbyte, 0, 0);
}
- int yaffs_pread(int handle, void *buf, unsigned int nbyte, unsigned int offset)
+ int yaffs_pread(int handle, void *buf, unsigned int nbyte, loff_t offset)
{
return yaffsfs_do_read(handle, buf, nbyte, 1, offset);
}
- int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte, int isPwrite, int offset)
+ int yaffsfs_do_write(int handle, const void *vbuf, unsigned int nbyte, int isPwrite, loff_t offset)
{
yaffsfs_FileDes *fd = NULL;
struct yaffs_obj *obj = NULL;
- int pos = 0;
- int startPos = 0;
- int endPos;
+ loff_t pos = 0;
+ loff_t startPos = 0;
+ loff_t endPos;
int nWritten = 0;
int totalWritten = 0;
int write_trhrough = 0;
return yaffsfs_do_write(fd, buf, nbyte, 0, 0);
}
- int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, unsigned int offset)
+ int yaffs_pwrite(int fd, const void *buf, unsigned int nbyte, loff_t offset)
{
return yaffsfs_do_write(fd, buf, nbyte, 1, offset);
}
- int yaffs_truncate(const YCHAR *path,off_t new_size)
+ int yaffs_truncate(const YCHAR *path,loff_t new_size)
{
struct yaffs_obj *obj = NULL;
struct yaffs_obj *dir = NULL;
else if(new_size < 0 || new_size > YAFFS_MAX_FILE_SIZE)
yaffsfs_SetError(-EINVAL);
else
- result = yaffs_resize_file(obj,new_size);
+ result = yaffs_resize_file(obj, new_size);
yaffsfs_Unlock();
return (result) ? 0 : -1;
}
- int yaffs_ftruncate(int handle, off_t new_size)
+ int yaffs_ftruncate(int handle, loff_t new_size)
{
yaffsfs_FileDes *fd = NULL;
struct yaffs_obj *obj = NULL;
yaffsfs_SetError(-EINVAL);
else
/* resize the file */
- result = yaffs_resize_file(obj,new_size);
+ result = yaffs_resize_file(obj, new_size);
yaffsfs_Unlock();
return (result) ? 0 : -1;
}
- off_t yaffs_lseek(int handle, off_t offset, int whence)
+ loff_t yaffs_lseek(int handle, loff_t offset, int whence)
{
yaffsfs_FileDes *fd = NULL;
struct yaffs_obj *obj = NULL;
- int pos = -1;
- int fSize = -1;
+ loff_t pos = -1;
+ loff_t fSize = -1;
yaffsfs_Lock();
fd = yaffsfs_HandleToFileDes(handle);
yaffsfs_SetError(-ELOOP);
else if(!parent)
yaffsfs_SetError(-ENOENT);
+ else if(yaffsfs_TooManyObjects(parent->my_dev))
+ yaffsfs_SetError(-ENFILE);
else if(strnlen(name,5) == 0){
/* Trying to make the root itself */
yaffsfs_SetError(-EEXIST);
return (void *)dev;
}
- int yaffs_mount2(const YCHAR *path,int read_only)
+ int yaffs_mount_common(const YCHAR *path,int read_only, int skip_checkpt)
{
int retVal=-1;
int result=YAFFS_FAIL;
if(dev){
if(!dev->is_mounted){
dev->read_only = read_only ? 1 : 0;
- result = yaffs_guts_initialise(dev);
+ if(skip_checkpt) {
+ u8 skip = dev->param.skip_checkpt_rd;
+ dev->param.skip_checkpt_rd = 1;
+ result = yaffs_guts_initialise(dev);
+ dev->param.skip_checkpt_rd = skip;
+ } else {
+ result = yaffs_guts_initialise(dev);
+ }
+
if(result == YAFFS_FAIL)
yaffsfs_SetError(-ENOMEM);
retVal = result ? 0 : -1;
}
+ int yaffs_mount2(const YCHAR *path, int readonly)
+ {
+ return yaffs_mount_common(path, readonly, 0);
+ }
int yaffs_mount(const YCHAR *path)
{
- return yaffs_mount2(path,0);
+ return yaffs_mount_common(path, 0, 0);
}
int yaffs_sync(const YCHAR *path)
void yaffs_add_device(struct yaffs_dev *dev)
{
+ struct list_head *cfg;
+ /* First check that the device is not in the list. */
+
+ list_for_each(cfg, &yaffsfs_deviceList){
+ if(dev == list_entry(cfg, struct yaffs_dev, dev_list))
+ return;
+ }
+
dev->is_mounted = 0;
dev->param.remove_obj_fn = yaffsfs_RemoveObjectCallback;
yaffsfs_SetError(-ELOOP);
else if( !parent || strnlen(name,5) < 1)
yaffsfs_SetError(-ENOENT);
+ else if(yaffsfs_TooManyObjects(parent->my_dev))
+ yaffsfs_SetError(-ENFILE);
else if(parent->my_dev->read_only)
yaffsfs_SetError(-EROFS);
else if(parent){
yaffsfs_SetError(-ENOENT);
else if(obj->my_dev->read_only)
yaffsfs_SetError(-EROFS);
+ else if(yaffsfs_TooManyObjects(obj->my_dev))
+ yaffsfs_SetError(-ENFILE);
else if(lnk)
yaffsfs_SetError(-EEXIST);
else if(lnk_dir->my_dev != obj->my_dev)
*/
#define YAFFS_MAGIC 0x5941ff53
+ /*
+ * Tnodes form a tree with the tnodes in "levels"
+ * Levels greater than 0 hold 8 slots which point to other tnodes.
+ * Those at level 0 hold 16 slots which point to chunks in NAND.
+ *
+ * A maximum level of 8 thust supports files of size up to:
+ *
+ * 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.
+ */
#define YAFFS_NTNODES_LEVEL0 16
#define YAFFS_TNODES_LEVEL0_BITS 4
#define YAFFS_TNODES_LEVEL0_MASK 0xf
#define YAFFS_NTNODES_INTERNAL (YAFFS_NTNODES_LEVEL0 / 2)
#define YAFFS_TNODES_INTERNAL_BITS (YAFFS_TNODES_LEVEL0_BITS - 1)
#define YAFFS_TNODES_INTERNAL_MASK 0x7
- #define YAFFS_TNODES_MAX_LEVEL 6
-
+ #define YAFFS_TNODES_MAX_LEVEL 8
+ #define YAFFS_TNODES_MAX_BITS (YAFFS_TNODES_LEVEL0_BITS + \
+ YAFFS_TNODES_INTERNAL_BITS * \
+ YAFFS_TNODES_MAX_LEVEL)
+ #define YAFFS_MAX_CHUNK_ID ((1 << YAFFS_TNODES_MAX_BITS) - 1)
/* Constants for YAFFS1 mode */
#define YAFFS_BYTES_PER_SPARE 16
#define YAFFS_MIN_YAFFS2_CHUNK_SIZE 1024
#define YAFFS_MIN_YAFFS2_SPARE_SIZE 32
- #define YAFFS_MAX_CHUNK_ID 0x000fffff
+
#define YAFFS_ALLOCATION_NOBJECTS 100
#define YAFFS_ALLOCATION_NTNODES 100
#define YAFFS_OBJECT_SPACE 0x40000
#define YAFFS_MAX_OBJECT_ID (YAFFS_OBJECT_SPACE - 1)
- #define YAFFS_CHECKPOINT_VERSION 4
+ #define YAFFS_CHECKPOINT_VERSION 5
#ifdef CONFIG_YAFFS_UNICODE
#define YAFFS_MAX_NAME_LENGTH 127
enum yaffs_obj_type extra_obj_type; /* What object type? */
- unsigned extra_length; /* Length if it is a file */
+ loff_t extra_file_size; /* Length if it is a file */
unsigned extra_equiv_id; /* Equivalent object for a hard link */
};
u32 yst_ctime;
/* File size applies to files only */
- int file_size;
+ u32 file_size_low;
/* Equivalent object id applies to hard links only. */
int equiv_id;
u32 inband_shadowed_obj_id;
u32 inband_is_shrink;
- u32 reserved[2];
+ u32 file_size_high;
+ u32 reserved[1];
int shadows_obj; /* This object header shadows the
specified object if > 0 */
*/
struct yaffs_file_var {
- u32 file_size;
- u32 scanned_size;
- u32 shrink_size;
+ loff_t file_size;
+ loff_t scanned_size;
+ loff_t shrink_size;
int top_level;
struct yaffs_tnode *top;
};
u8 unlink_allowed:1;
u8 serial;
int n_data_chunks;
- u32 size_or_equiv_obj;
+ loff_t size_or_equiv_obj;
};
/*--------------------- Temporary buffers ----------------
int always_check_erased; /* Force chunk erased check always on */
int disable_summary;
+
+ int max_objects; /*
+ * Set to limit the number of objects created.
+ * 0 = no limit.
+ */
};
struct yaffs_dev {
int yaffs_del_obj(struct yaffs_obj *obj);
int yaffs_get_obj_name(struct yaffs_obj *obj, YCHAR * name, int buffer_size);
- int yaffs_get_obj_length(struct yaffs_obj *obj);
+ loff_t yaffs_get_obj_length(struct yaffs_obj *obj);
int yaffs_get_obj_inode(struct yaffs_obj *obj);
unsigned yaffs_get_obj_type(struct yaffs_obj *obj);
int yaffs_get_obj_link_count(struct yaffs_obj *obj);
unsigned pos);
int yaffs_is_non_empty_dir(struct yaffs_obj *obj);
+
+ 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
+ * 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);
+ loff_t yaffs_max_file_size(struct yaffs_dev *dev);
+
+
#endif
#define YAFFS_USE_WRITE_BEGIN_END 0
#endif
+
+
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define set_nlink(inode, count) do { (inode)->i_nlink = (count); } while(0)
+#endif
+
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28))
static uint32_t YCALCBLOCKS(uint64_t partition_size, uint32_t block_size)
{
struct yaffs_obj *obj;
unsigned char *pg_buf;
int ret;
+ loff_t pos = ((loff_t) pg->index) << PAGE_CACHE_SHIFT;
struct yaffs_dev *dev;
yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_readpage_nolock at %08x, size %08x",
- (unsigned)(pg->index << PAGE_CACHE_SHIFT),
- (unsigned)PAGE_CACHE_SIZE);
+ "yaffs_readpage_nolock at %lld, size %08x",
+ (long long)pos,
+ (unsigned)PAGE_CACHE_SIZE);
obj = yaffs_dentry_to_obj(f->f_dentry);
yaffs_gross_lock(dev);
- ret = yaffs_file_rd(obj, pg_buf,
- pg->index << PAGE_CACHE_SHIFT, PAGE_CACHE_SIZE);
+ ret = yaffs_file_rd(obj, pg_buf, pos, PAGE_CACHE_SIZE);
yaffs_gross_unlock(dev);
if (page->index > end_index || !n_bytes) {
yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_writepage at %08x, inode size = %08x!!",
- (unsigned)(page->index << PAGE_CACHE_SHIFT),
- (unsigned)inode->i_size);
+ "yaffs_writepage at %lld, inode size = %lld!!",
+ ((loff_t)page->index) << PAGE_CACHE_SHIFT,
+ inode->i_size);
yaffs_trace(YAFFS_TRACE_OS,
" -> don't care!!");
yaffs_gross_lock(dev);
yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_writepage at %08x, size %08x",
- (unsigned)(page->index << PAGE_CACHE_SHIFT), n_bytes);
+ "yaffs_writepage at %lld, size %08x",
+ ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes);
yaffs_trace(YAFFS_TRACE_OS,
- "writepag0: obj = %05x, ino = %05x",
- (int)obj->variant.file_variant.file_size, (int)inode->i_size);
+ "writepag0: obj = %lld, ino = %lld",
+ obj->variant.file_variant.file_size, inode->i_size);
n_written = yaffs_wr_file(obj, buffer,
- page->index << PAGE_CACHE_SHIFT, n_bytes, 0);
+ ((loff_t)page->index) << PAGE_CACHE_SHIFT, n_bytes, 0);
yaffs_touch_super(dev);
yaffs_trace(YAFFS_TRACE_OS,
- "writepag1: obj = %05x, ino = %05x",
- (int)obj->variant.file_variant.file_size, (int)inode->i_size);
+ "writepag1: obj = %lld, ino = %lld",
+ obj->variant.file_variant.file_size, inode->i_size);
yaffs_gross_unlock(dev);
addr = kva + offset_into_page;
yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_write_end addr %p pos %x n_bytes %d",
- addr, (unsigned)pos, copied);
+ "yaffs_write_end addr %p pos %lld n_bytes %d",
+ addr, pos, copied);
ret = yaffs_file_write(filp, addr, copied, &pos);
int n_bytes = to - offset;
int n_written;
- unsigned spos = pos;
- unsigned saddr;
-
kva = kmap(pg);
addr = kva + offset;
- saddr = (unsigned)addr;
-
yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_commit_write addr %x pos %x n_bytes %d",
- saddr, spos, n_bytes);
+ "yaffs_commit_write addr %p pos %lld n_bytes %d",
+ addr, pos, n_bytes);
n_written = yaffs_file_write(f, addr, n_bytes, &pos);
inode->i_size = yaffs_get_obj_length(obj);
inode->i_blocks = (inode->i_size + 511) >> 9;
- inode->i_nlink = yaffs_get_obj_link_count(obj);
+ set_nlink(inode, yaffs_get_obj_link_count(obj));
yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_fill_inode mode %x uid %d gid %d size %d count %d",
+ "yaffs_fill_inode mode %x uid %d gid %d size %lld count %d",
inode->i_mode, inode->i_uid, inode->i_gid,
- (int)inode->i_size, atomic_read(&inode->i_count));
+ inode->i_size, atomic_read(&inode->i_count));
switch (obj->yst_mode & S_IFMT) {
default: /* fifo, device or socket */
loff_t * pos)
{
struct yaffs_obj *obj;
- int n_written, ipos;
+ int n_written;
+ loff_t ipos;
struct inode *inode;
struct yaffs_dev *dev;
ipos = *pos;
yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_file_write about to write writing %u(%x) bytes to object %d at %d(%x)",
- (unsigned)n, (unsigned)n, obj->obj_id, ipos, ipos);
+ "yaffs_file_write about to write writing %u(%x) bytes to object %d at %lld",
+ (unsigned)n, (unsigned)n, obj->obj_id, ipos);
n_written = yaffs_wr_file(obj, buf, ipos, n, 0);
inode->i_blocks = (ipos + 511) >> 9;
yaffs_trace(YAFFS_TRACE_OS,
- "yaffs_file_write size updated to %d bytes, %d blocks",
+ "yaffs_file_write size updated to %lld bytes, %d blocks",
ipos, (int)(inode->i_blocks));
}
ret_val = yaffs_unlinker(obj, dentry->d_name.name);
if (ret_val == YAFFS_OK) {
- dentry->d_inode->i_nlink--;
+ inode_dec_link_count(dentry->d_inode);
dir->i_version++;
yaffs_gross_unlock(dev);
- mark_inode_dirty(dentry->d_inode);
update_dir_time(dir);
return 0;
}
obj);
if (link) {
- old_dentry->d_inode->i_nlink = yaffs_get_obj_link_count(obj);
+ set_nlink(old_dentry->d_inode, yaffs_get_obj_link_count(obj));
d_instantiate(dentry, old_dentry->d_inode);
atomic_inc(&old_dentry->d_inode->i_count);
yaffs_trace(YAFFS_TRACE_OS,
yaffs_trace(YAFFS_TRACE_OS, "yaffs_symlink");
+ if (strnlen(dentry->d_name.name, YAFFS_MAX_NAME_LENGTH + 1) >
+ YAFFS_MAX_NAME_LENGTH)
+ return -ENAMETOOLONG;
+
+ if (strnlen(symname, YAFFS_MAX_ALIAS_LENGTH + 1) >
+ YAFFS_MAX_ALIAS_LENGTH)
+ return -ENAMETOOLONG;
+
dev = yaffs_inode_to_obj(dir)->my_dev;
yaffs_gross_lock(dev);
obj = yaffs_create_symlink(yaffs_inode_to_obj(dir), dentry->d_name.name,
yaffs_gross_unlock(dev);
if (ret_val == YAFFS_OK) {
- if (target) {
- new_dentry->d_inode->i_nlink--;
- mark_inode_dirty(new_dentry->d_inode);
- }
+ if (target)
+ inode_dec_link_count(new_dentry->d_inode);
update_dir_time(old_dir);
if (old_dir != new_dir)
yaffs_trace(YAFFS_TRACE_OS,
"yaffs_setattr of object %d",
yaffs_inode_to_obj(inode)->obj_id);
-
+ #if 0
/* Fail if a requested resize >= 2GB */
if (attr->ia_valid & ATTR_SIZE && (attr->ia_size >> 31))
error = -EINVAL;
+ #endif
if (error == 0)
error = inode_change_ok(inode, attr);
sb->u.generic_sbp = dev;
#endif
+
dev->driver_context = mtd;
param->name = mtd->name;
if (!context->bg_thread)
param->defered_dir_update = 0;
+ sb->s_maxbytes = yaffs_max_file_size(dev);
+
/* Release lock before yaffs_get_inode() */
yaffs_gross_unlock(dev);
static char *yaffs_dump_dev_part1(char *buf, struct yaffs_dev *dev)
{
+ buf += sprintf(buf, "max file size....... %lld\n",
+ (long long) yaffs_max_file_size(dev));
buf += sprintf(buf, "data_bytes_per_chunk. %d\n",
dev->data_bytes_per_chunk);
buf += sprintf(buf, "chunk_grp_bits....... %d\n", dev->chunk_grp_bits);