*.pyc
DEADJOE
*.mod.c
+*.order
+/Module.symvers
+/.tmp_versions
+
+#
+# cscope files
+#
+cscope.*
ifdef YAFFS_CURRENT
YAFFS_O := yaffs2.o
+ EXTRA_CFLAGS += -DYAFFS_CURRENT
else
YAFFS_O := yaffs2multi.o
endif
}
+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
//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");
#include <errno.h>
-unsigned yaffs_trace_mask =
+unsigned yaffs_trace_mask =
- YAFFS_TRACE_SCAN |
+ YAFFS_TRACE_SCAN |
YAFFS_TRACE_GC |
- YAFFS_TRACE_ERASE |
- YAFFS_TRACE_ERROR |
- YAFFS_TRACE_TRACING |
- YAFFS_TRACE_ALLOCATE |
+ YAFFS_TRACE_ERASE |
+ YAFFS_TRACE_ERROR |
+ YAFFS_TRACE_TRACING |
+ YAFFS_TRACE_ALLOCATE |
YAFFS_TRACE_BAD_BLOCKS |
- YAFFS_TRACE_VERIFY |
-
+ YAFFS_TRACE_VERIFY |
+
0;
-
+
// Configuration
int yaffs_start_up(void)
{
+ static int start_up_called = 0;
+
+ if(start_up_called)
+ return;
+ start_up_called = 1;
+
// Stuff to configure YAFFS
// Stuff to initialise anything special (eg lock semaphore).
yaffsfs_OSInitialisation();
-
+
// Set up devices
// /ram1 ram, yaffs1
memset(&ram1Dev,0,sizeof(ram1Dev));
ram1Dev.param.chunks_per_block = 32;
ram1Dev.param.n_reserved_blocks = 2; // Set this smaller for RAM
ram1Dev.param.start_block = 0; // Can use block 0
- ram1Dev.param.end_block = 127; // Last block in 2MB.
+ ram1Dev.param.end_block = 127; // Last block in 2MB.
//ram1Dev.param.use_nand_ecc = 1;
ram1Dev.param.n_caches = 0; // Disable caching on this device.
ram1Dev.driver_context = (void *) 0; // Used to identify the device in fstat.
ram1Dev.param.read_chunk_tags_fn = yramdisk_rd_chunk;
ram1Dev.param.erase_fn = yramdisk_erase;
ram1Dev.param.initialise_flash_fn = yramdisk_initialise;
-
+
yaffs_add_device(&ram1Dev);
// /M18-1 yaffs1 on M18 nor sim
yaffs_add_device(&flashDev);
// todo yaffs_initialise(yaffsfs_config);
-
+
return 0;
}
yaffs_yaffs1.o \
yaffs_yaffs2.o \
yaffs_verify.o \
- yaffs_error.o
+ yaffs_error.o \
+ yaffs_summary.o
# yaffs_checkptrwtest.o\
yaffs_yaffs1.c yaffs_yaffs1.h \
yaffs_yaffs2.c yaffs_yaffs2.h \
yaffs_bitmap.c yaffs_bitmap.h \
- yaffs_verify.c yaffs_verify.h
+ yaffs_verify.c yaffs_verify.h \
+ yaffs_summary.c yaffs_summary.h
YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
yaffsfs.h ydirectenv.h \
--- /dev/null
+handle_tests.c opens and closes random handles, in an effot to stress test yaffs.
+
+Command line options:
+ No commands.
+
+compile command: make
+run command: ./handle_test
--- /dev/null
+# Makefile for YAFFS direct stress tests
+#
+#
+# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
+#
+# Copyright (C) 2003-2010 Aleph One Ltd.
+#
+#
+# Created by Charles Manning <charles@aleph1.co.uk>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# NB Warning this Makefile does not include header dependencies.
+#
+# $Id: Makefile,v 1.7 2010-02-25 22:34:47 charles Exp $
+
+#EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
+
+CFLAGS = -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_YAFFS2
+CFLAGS += -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES
+CFLAGS += -Wall -g $(EXTRA_COMPILE_FLAGS) -Wstrict-aliasing
+#CFLAGS += -fno-strict-aliasing
+CFLAGS += -O0
+CFLAGS += -Wextra -Wpointer-arith
+#CFLAGS += -DCONFIG_YAFFS_VALGRIND_TEST
+
+#CFLAGS+= -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
+#CFLAGS+= -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
+
+
+COMMONTESTOBJS = yaffscfg2k.o yaffs_osglue.o yaffs_hweight.o \
+ yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \
+ yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \
+ yaffs_tagscompat.o yaffs_packedtags2.o yaffs_nand.o \
+ yaffs_checkptrw.o yaffs_qsort.o\
+ yaffs_nameval.o yaffs_attribs.o \
+ yaffs_norif1.o ynorsim.o \
+ yaffs_allocator.o \
+ yaffs_bitmap.o \
+ yaffs_yaffs1.o \
+ yaffs_yaffs2.o \
+ yaffs_verify.o \
+ yaffs_error.o \
+ yaffs_summary.o
+
+# yaffs_checkptrwtest.o\
+
+TESTFILES = test_1_yaffs_mount.o
+
+
+
+
+YAFFSTESTOBJS = $(COMMONTESTOBJS) $(TESTFILES)
+
+
+ALLOBJS = $(sort $(YAFFSTESTOBJS)) $(PYTHONOBJS)
+
+YAFFSSYMLINKS = yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffs_tagscompat.c yaffs_tagscompat.h \
+ yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h \
+ yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \
+ yaffs_checkptrw.h yaffs_checkptrw.c \
+ yaffs_nameval.c yaffs_nameval.h \
+ yaffs_trace.h yaffs_attribs.h \
+ yaffs_allocator.c yaffs_allocator.h \
+ yaffs_yaffs1.c yaffs_yaffs1.h \
+ yaffs_yaffs2.c yaffs_yaffs2.h \
+ yaffs_bitmap.c yaffs_bitmap.h \
+ yaffs_verify.c yaffs_verify.h \
+ yaffs_summary.c yaffs_summary.h
+
+YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
+ yaffsfs.h ydirectenv.h \
+ yaffs_flashif.c yaffscfg.h yaffs_qsort.c \
+ yaffs_nandemul2k.h yaffs_list.h \
+ yaffs_attribs.c yaffs_osglue.h \
+ yaffs_nandif.c yaffs_nandif.h yportenv.h \
+ yaffs_hweight.h yaffs_hweight.c \
+ yaffs_error.c
+
+
+DIRECTEXTRASYMLINKS = yaffscfg2k.c yaffs_fileem2k.c yaffs_fileem2k.h\
+ yaffs_fileem.c yaffs_norif1.c yaffs_norif1.h \
+ yaffs_ramdisk.c yaffs_ramdisk.h yaffs_ramem2k.c \
+ ynorsim.h ynorsim.c yaffs_osglue.c
+
+SYMLINKS = $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) $(DIRECTEXTRASYMLINKS) $(PYTONOSYMLINKS)
+#all: directtest2k boottest
+
+all: test_1_yaffs_mount
+
+$(ALLOBJS): %.o: %.c
+ gcc -c $(CFLAGS) -o $@ $<
+
+$(PYTONOSYMLINKS):
+ ln -s ../../python/$@ $@
+
+$(YAFFSSYMLINKS):
+ ln -s ../../../$@ $@
+
+$(YAFFSDIRECTSYMLINKS):
+ ln -s ../../$@ $@
+
+$(DIRECTEXTRASYMLINKS):
+ ln -s ../../basic-test/$@ $@
+
+
+test_1_yaffs_mount: $(SYMLINKS) $(ALLOBJS)
+ gcc $(CFLLAG) -o $@ $(ALLOBJS)
+
+
+
+clean:
+ rm -f test_1_yaffs_mount $(ALLOBJS) core $(SYMLINKS)
--- /dev/null
+is_yaffs_working_tests folder contains the very simple tests to check that yaffs has been installed properly.
+
+test_1_yaffs_mount.c mounts yaffs, creates a file, unmounts and then mounts yaffs and checks that the file is still there.
+
+
+
+compile command: make
+run command: ./test_1_yaffs_mount
+
+command line options:
+ No commands.
--- /dev/null
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2011 Aleph One Ltd.
+ * for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Timothy Manning <timothy@yaffs.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+
+#include "yaffsfs.h"
+#define YAFFS_MOUNT_POINT "/yaffs2/"
+#define FILE_PATH "/yaffs2/foo.txt"
+
+int random_seed;
+int simulate_power_failure = 0;
+
+
+int main()
+{
+ int output = 0;
+ int output2 = 0;
+ yaffs_start_up();
+
+ printf("\n\n starting test\n");
+ yaffs_set_trace(0);
+ output = yaffs_mount(YAFFS_MOUNT_POINT);
+
+ if (output>=0){
+ printf("yaffs mounted: %s\n",YAFFS_MOUNT_POINT);
+ } else {
+ printf("error\n yaffs failed to mount: %s\nerror\n",YAFFS_MOUNT_POINT);
+ return (0);
+ }
+ //now create a file.
+ output = yaffs_open(FILE_PATH,O_CREAT | O_RDWR, S_IREAD | S_IWRITE);
+ if (output>=0){
+ printf("file created: %s\n",FILE_PATH);
+ } else {
+ printf("error\n yaffs failed to create the file: %s\nerror\n",FILE_PATH);
+ return (0);
+ }
+ output2 = yaffs_close(output);
+ if (output2>=0){
+ printf("file closed: %s\n",FILE_PATH);
+ } else {
+ printf("error\n yaffs failed to close the file: %s\nerror\n",FILE_PATH);
+ return (0);
+ }
+ //unmount and remount the mount point.
+ output = yaffs_unmount(YAFFS_MOUNT_POINT);
+ if (output>=0){
+ printf("yaffs unmounted: %s\n",YAFFS_MOUNT_POINT);
+ } else {
+ printf("error\n yaffs failed to unmount: %s\nerror\n",YAFFS_MOUNT_POINT);
+ return (0);
+ }
+ output = yaffs_mount(YAFFS_MOUNT_POINT);
+ if (output>=0){
+ printf("yaffs mounted: %s\n",YAFFS_MOUNT_POINT);
+ } else {
+ printf("error\n yaffs failed to mount: %s\nerror\n",YAFFS_MOUNT_POINT);
+ return (0);
+ }
+ //now open the existing file.
+ output = yaffs_open(FILE_PATH, O_RDWR, S_IREAD | S_IWRITE);
+ if (output>=0){
+ printf("file created: %s\n",FILE_PATH);
+ } else {
+ printf("error\n yaffs failed to create the file: %s\nerror\n",FILE_PATH);
+ return (0);
+ }
+ //close the file.
+ output2 = yaffs_close(output);
+ if (output2>=0){
+ printf("file closed: %s\n",FILE_PATH);
+ } else {
+ printf("error\n yaffs failed to close the file: %s\nerror\n",FILE_PATH);
+ return (0);
+ }
+
+ //unmount the mount point.
+ output = yaffs_unmount(YAFFS_MOUNT_POINT);
+ if (output>=0){
+ printf("yaffs unmounted: %s\n",YAFFS_MOUNT_POINT);
+ } else {
+ printf("error\n yaffs failed to unmount: %s\nerror\n",YAFFS_MOUNT_POINT);
+ return (0);
+ }
+
+ printf("test passed. yay!\n");
+
+}
--- /dev/null
+# Makefile for YAFFS direct stress tests
+#
+#
+# YAFFS: Yet another Flash File System. A NAND-flash specific file system.
+#
+# Copyright (C) 2003-2010 Aleph One Ltd.
+#
+#
+# Created by Charles Manning <charles@aleph1.co.uk>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# NB Warning this Makefile does not include header dependencies.
+#
+# $Id: Makefile,v 1.7 2010-02-25 22:34:47 charles Exp $
+
+#EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC
+
+CFLAGS = -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_YAFFS2
+CFLAGS += -DCONFIG_YAFFS_PROVIDE_DEFS -DCONFIG_YAFFSFS_PROVIDE_VALUES
+CFLAGS += -Wall -g $(EXTRA_COMPILE_FLAGS) -Wstrict-aliasing
+#CFLAGS += -fno-strict-aliasing
+CFLAGS += -O0
+CFLAGS += -Wextra -Wpointer-arith
+#CFLAGS += -DCONFIG_YAFFS_VALGRIND_TEST
+
+#CFLAGS+= -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations
+#CFLAGS+= -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline
+
+
+COMMONTESTOBJS = yaffscfg2k.o yaffs_osglue.o yaffs_hweight.o \
+ yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \
+ yaffs_packedtags1.o yaffs_ramdisk.o yaffs_ramem2k.o \
+ yaffs_tagscompat.o yaffs_packedtags2.o yaffs_nand.o \
+ yaffs_checkptrw.o yaffs_qsort.o \
+ yaffs_nameval.o yaffs_attribs.o \
+ yaffs_norif1.o ynorsim.o \
+ yaffs_allocator.o \
+ yaffs_bitmap.o \
+ yaffs_yaffs1.o \
+ yaffs_yaffs2.o \
+ yaffs_verify.o \
+ yaffs_error.o \
+ yaffs_summary.o
+# yaffs_tagsvalidity.o
+# yaffs_checkptrwtest.o\
+
+TESTFILES = linux_test.o lib.o
+
+
+
+
+YAFFSTESTOBJS = $(COMMONTESTOBJS) $(TESTFILES)
+
+
+ALLOBJS = $(sort $(YAFFSTESTOBJS)) $(PYTHONOBJS)
+
+YAFFSSYMLINKS = yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffs_tagscompat.c yaffs_tagscompat.h \
+ yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h \
+ yaffs_nand.c yaffs_nand.h yaffs_getblockinfo.h \
+ yaffs_checkptrw.h yaffs_checkptrw.c \
+ yaffs_nameval.c yaffs_nameval.h \
+ yaffs_trace.h yaffs_attribs.h \
+ yaffs_allocator.c yaffs_allocator.h \
+ yaffs_yaffs1.c yaffs_yaffs1.h \
+ yaffs_yaffs2.c yaffs_yaffs2.h \
+ yaffs_bitmap.c yaffs_bitmap.h \
+ yaffs_verify.c yaffs_verify.h \
+ yaffs_summary.c yaffs_summary.h
+#yaffs_tagsvalidity.c yaffs_tagsvalidity.h
+
+YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
+ yaffsfs.h ydirectenv.h \
+ yaffs_flashif.c yaffscfg.h yaffs_qsort.c \
+ yaffs_nandemul2k.h yaffs_list.h \
+ yaffs_attribs.c yaffs_osglue.h \
+ yaffs_nandif.c yaffs_nandif.h yportenv.h \
+ yaffs_hweight.h yaffs_hweight.c \
+ yaffs_error.c
+
+
+DIRECTEXTRASYMLINKS = yaffscfg2k.c yaffs_fileem2k.c yaffs_fileem2k.h\
+ yaffs_fileem.c yaffs_norif1.c yaffs_norif1.h \
+ yaffs_ramdisk.c yaffs_ramdisk.h yaffs_ramem2k.c \
+ ynorsim.h ynorsim.c yaffs_osglue.c
+
+SYMLINKS = $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) $(DIRECTEXTRASYMLINKS) $(PYTONOSYMLINKS)
+#all: directtest2k boottest
+
+all: linux_test
+
+$(ALLOBJS): %.o: %.c
+ gcc -c $(CFLAGS) -o $@ $<
+
+$(PYTONOSYMLINKS):
+ ln -s ../../python/$@ $@
+
+$(YAFFSSYMLINKS):
+ ln -s ../../../$@ $@
+
+$(YAFFSDIRECTSYMLINKS):
+ ln -s ../../$@ $@
+
+$(DIRECTEXTRASYMLINKS):
+ ln -s ../../basic-test/$@ $@
+
+
+linux_test: $(SYMLINKS) $(ALLOBJS)
+ gcc $(CFLLAG) -o $@ $(ALLOBJS)
+
+
+
+clean:
+ rm -f linux_test $(ALLOBJS) core $(SYMLINKS)
--- /dev/null
+
+linux_test.c tests yaffs running under linux using the nandsim generator.
+
+
+If a segmentation fault happens during the test then check that
+the nandsim has been initilised properly.
+
+How to initilise the nandsim
+
+$ make
+
+$ sudo -s
+...password..
+# now you have a root shell
+$ ./linux-tests/initnandsim 128MiB-2048
+$ insmod yaffs2multi.ko
+$ mkdir /mnt/y
+$ mount -t yaffs2 /dev/mtdblock0 /mnt/y
+
+
+
+How to change the permissions on the nandsim partition
+
+$ sudo chmod a+wr /mnt/y/
+#check the permission change
+$ touch /mnt/y/test_file
+
+How to clean the folder
+
+$ rm -rf /mnt/y
+
+
+The test must be run in sudo to work to allow the files to be
+created in the root folders.
+
+compile command: make
+run command: sudo ./linux_test
+
+command line options:
+ -h display the command line options.
+ -s [number] seeds the rand with the number.
+ -p [number] sets the print level to the number.
+ the higher the number the more low level commands are printed.
+ the number should be between 0 and 5.
+ -v verbose mode. everything is printed.
+ -q quite mode. nothing is printed.
+
+
--- /dev/null
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2010 Aleph One Ltd.
+ * for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Timothy Manning <timothy@yaffs.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "lib.h"
+static char message[200];
+static int PRINT_LEVEL = 3;
+static int exit_on_error_val =1;
+char string[FILE_NAME_LENGTH+1];
+
+
+int get_exit_on_error(void)
+{
+ return exit_on_error_val;
+}
+
+void set_exit_on_error(int val)
+{
+ exit_on_error_val=val;
+}
+
+node * linked_list_add_node(int pos,node *head_node)
+{
+ node *new_node=NULL;
+ if (pos==HEAD){
+ new_node=malloc(sizeof(node));
+ memset(new_node, 0, sizeof(node));
+ new_node->string=NULL;
+ new_node->next=head_node;
+ return new_node;
+ }
+ return NULL;
+}
+
+void node_print_pointers(node *current_node)
+{
+ while (current_node != NULL){
+ sprintf(message,"current_node: %p, string: %s next_node: %p\n",current_node,current_node->string,current_node->next);
+ print_message(3,message);
+ current_node=current_node->next;
+ }
+}
+
+int delete_linked_list(node *head_node)
+{
+ node *next_node=NULL;
+ node *current_node=head_node;
+
+ while (current_node != NULL){
+ next_node=current_node->next;
+ free(current_node);
+ current_node=next_node;
+ }
+
+ return 1;
+}
+
+char * generate_random_string(unsigned int length)
+{
+
+ unsigned int x;
+ for (x=0;x<(length-1);x++)
+ {
+ string[x]=(rand() % NAME_RANGE)+65;
+ }
+ string[x]='\0';
+ return string;
+}
+
+void set_print_level(int new_level)
+{
+ PRINT_LEVEL=new_level;
+}
+int get_print_level(void)
+{
+ return PRINT_LEVEL;
+}
+void print_message(char print_level,char *message)
+{
+ if (print_level <= PRINT_LEVEL){
+ printf("%s",message);
+ }
+}
+int random_int(void)
+{
+ return (random()%1000000);
+}
+
+void check_function(int output)
+{
+ if (output>=0){
+ print_message(3,"test_passed\n");
+ } else {
+ print_message(3,"test_failed\n");
+ get_error_linux();
+ }
+}
+
+void get_error_linux(void)
+{
+ int error_code=0;
+ char message[30];
+ message[0]='\0';
+
+ error_code=errno;
+ sprintf(message,"linux_error code %d\n",error_code);
+ print_message(1,message);
+
+ strcpy(message,"error is");
+ perror(message);
+// sprintf(message,"error is : %s\n",yaffs_error_to_str(error_code));
+ //perror(message);
+ //print_message(1,message);
+}
--- /dev/null
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2010 Aleph One Ltd.
+ * for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Timothy Manning <timothy@yaffs.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+#ifndef __lib_h__
+#define __lib_h__
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#define NAME_RANGE 10
+#define ROOT_PATH "/mnt/y/"
+#define FILE_NAME_LENGTH 3
+#define HEAD 0
+#define TAIL 1
+
+typedef struct node_temp{
+ char *string;
+ struct node_temp *next;
+}node;
+
+int get_exit_on_error(void);
+void set_exit_on_error(int val);
+int delete_linked_list(node *head_node);
+node * linked_list_add_node(int pos,node *head_node);
+int random_int(void);
+char * generate_random_string(unsigned int length);
+void get_error_linux(void);
+void check_function(int output);
+void print_message(char print_level, char *message);
+void set_print_level(int new_level);
+int get_print_level(void);
+void node_print_pointers(node *current_node);
+#endif
--- /dev/null
+/*
+ * YAFFS: Yet another FFS. A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2010 Aleph One Ltd.
+ * for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Timothy Manning <timothy@yaffs.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include "linux_test.h"
+
+int random_seed;
+int simulate_power_failure = 1;
+
+char message[400]; //this is used for storing print messages.
+
+
+
+const struct option long_options[]={
+ {"help", 0,NULL,'h'},
+
+
+ {"print_level", 1,NULL,'p'},
+ {"quiet", 0,NULL,'q'},
+
+ {"seed", 1,NULL,'s'},
+
+ {"verbose", 0,NULL,'v'}
+};
+
+const char short_options[]="hp:qs:v";
+
+
+void init(int argc, char *argv[])
+{
+ char dir[200];
+ dir[0]='\0';
+ int x=-1;
+ char message[100];
+ int new_option;
+
+ x=(unsigned)time(NULL);
+ sprintf(message,"seeding srand with: %d\n",x);
+ print_message(2,message);
+ srand(x);
+
+
+
+ do {
+ new_option=getopt_long(argc,argv,short_options,long_options,NULL);
+ if (new_option=='h'){
+ printf("mirror_tests help\n");
+ printf("arguments:\n");
+ printf("\t-p [NUMBER] //sets the print level for mirror_tests.\n");
+ printf("\t-v //verbose mode everything is printed\n");
+ printf("\t-q //quiet mode nothing is printed.\n");
+ printf("\t-s [number] //seeds rand with the number\n");
+
+ exit(0);
+
+ } else if (new_option=='p'){
+ set_print_level(atoi(optarg));
+ } else if (new_option=='v'){
+ set_print_level(5);
+ } else if (new_option=='q'){
+ set_print_level(-1);
+ } else if (new_option=='s'){
+ srand(atoi(argv[x+1]));
+
+ } else if (new_option==-1){
+
+ } else if (new_option=='?') {
+ printf("bad argument\n");
+ exit(0);
+ }
+ }while(new_option!=-1);
+}
+
+int main(int argc, char *argv[])
+{
+ dir_struct *scanned_dir=NULL;
+ int output=0;
+ int break_bool=0;
+ int x=5;
+
+ init(argc,argv);
+ while( 1){
+ while (break_bool!=1){
+ //printf("x %d\n",x);
+ x--;
+ if (x<0 &&(break_bool!=1)){
+ output=mkdir_test();
+ break_bool=1;
+ }
+ x--;
+ if (x<0 &&(break_bool!=1)){
+ output=rmdir_test();
+ break_bool=1;
+ }
+ x--;
+ if (x<0 &&(break_bool!=1)){
+ output=mknod_test();
+ break_bool=1;
+ }
+ x--;
+ if (x<0 &&(break_bool!=1)){
+ output=symlink_test();
+ break_bool=1;
+ }
+ x--;
+ if (x<0 &&(break_bool!=1)){
+ output=link_test();
+ break_bool=1;
+ }
+ x--;
+ if (x<0 &&(break_bool!=1)){
+ output=rename_test();
+ break_bool=1;
+ }
+ x--;
+ if (x<0 &&(break_bool!=1)){
+ scanned_dir=scan_dir();
+
+ output=remount_test();
+ check_dir(scanned_dir);
+ scanned_dir=NULL; //the scanned dir has been freed in check_dir.
+ break_bool=1;
+ }
+ }
+ //printf("resetting x\n");
+ check_function(output);
+ break_bool=0;
+ x=(rand()% 99);
+ }
+ return 0;
+}
+
+dir_struct * scan_dir(void)
+{
+ struct dirent *dir_data;
+ dir_struct *dir=NULL;
+ dir=malloc(sizeof(dir_struct));
+ memset(dir, 0, sizeof(dir_struct));
+ DIR *open_dir=NULL;
+
+
+ open_dir=opendir(ROOT_PATH);
+ if (open_dir < 0){
+ sprintf(message,"failed to find the directory: %s",ROOT_PATH);
+ print_message(1,message);
+ }
+ dir_data=readdir(open_dir);
+ while(dir_data){
+ dir->path_list=linked_list_add_node(HEAD,dir->path_list);
+ dir->path_list->string=malloc(strlen(dir_data->d_name)+1);
+ strcpy(dir->path_list->string,dir_data->d_name);
+ sprintf(message,"opened file: %s\n",dir->path_list->string);
+ print_message(5,message);
+ dir_data=readdir(open_dir);
+ }
+ closedir(open_dir);
+ //node_print_pointers(dir->path_list);
+ return dir;
+}
+
+int check_dir(dir_struct *old_dir)
+{
+ print_message(3,"scanning new dir\n");
+ dir_struct *new_dir=scan_dir();
+ node *new_list=new_dir->path_list;
+ node *old_list=old_dir->path_list;
+ int exit_loop=0,error=0;
+ print_message(3,"checking dir\n");
+ for (;old_list!= NULL;old_list=old_list->next){
+ //sprintf(message,"new_list=!NULL= %d, exit_loop !=1 = %d\n",(new_list!=NULL),(exit_loop !=1));
+ //print_message(3,message);
+ for (;(new_list!=NULL) && (exit_loop !=1);new_list=new_list->next){
+ //sprintf(message,"comparing %s and %s\n",old_list->string,new_list->string);
+ //print_message(3,message);
+ if (strcmp( new_list->string ,old_list->string)==0){
+ //files match -now compare the modes and contents of the files.
+ //and set the paths to NULL.
+ exit_loop=1;
+ }
+ /*if (new_list->next==NULL){
+ print_message(3,"next is null\n");
+
+ }*/
+ }
+ if (exit_loop !=1){
+ //failed to find a matching file
+ sprintf(message,"a file has disappeared: %s\n",old_list->string);
+ print_message(3,message);
+ error=1;
+
+ }
+ new_list=new_dir->path_list;
+ exit_loop=0;
+ }
+ //now check if there are any old unmatched files
+
+ //free both data structs
+ delete_linked_list(old_dir->path_list);
+ delete_linked_list(new_dir->path_list);
+ new_dir->path_list=NULL;
+ old_dir->path_list=NULL;
+ free(old_dir);
+ free(new_dir);
+ if (error ==1){
+ print_message(3,"checking dir failed\n");
+ if (get_exit_on_error()==1){
+ print_message(3,"exiting_program\n");
+ exit(0);
+ }
+ }
+
+ else if (error !=1){
+ print_message(3,"checking dir passed\n");
+ }
+ return error;
+}
+
+int remount_test(void)
+{
+ int output;
+ print_message(3,"\nunmounting\n");
+ output=umount2("/mnt/y",1);
+ check_function(output);
+ print_message(3,"mounting\n");
+ mount("/dev/mtdblock0","/mnt/y","yaffs2",0,NULL);
+ check_function(output);
+ return output;
+}
+
+int mkdir_test(void)
+{
+
+ char string[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ int mode=0,output=0;
+ strcpy(string,ROOT_PATH);
+ strcat(string,generate_random_string(FILE_NAME_LENGTH));
+ mode = ((S_IREAD|S_IWRITE)&random_int());
+ sprintf(message,"\nmaking directory: %s, with mode %d\n",string,mode);
+ print_message(3,message);
+ output= mkdir(string,mode);
+ return output;
+}
+
+int rmdir_test(void)
+{
+ char string[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ int output=0;
+ strcpy(string,ROOT_PATH);
+ strcat(string,generate_random_string(FILE_NAME_LENGTH));
+
+ sprintf(message,"\nremoving directory: %s\n",string);
+ print_message(3,message);
+ output= rmdir(string);
+ return output;
+}
+int symlink_test(void)
+{
+ char string[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ char string2[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ int output;
+ strcpy(string,ROOT_PATH);
+ strcat(string,generate_random_string(FILE_NAME_LENGTH));
+ strcpy(string2,ROOT_PATH);
+ strcat(string2,generate_random_string(FILE_NAME_LENGTH));
+ sprintf(message,"\nsymlink from: %s, to %s\n",string,string2);
+ print_message(3,message);
+ output= symlink(string,string2);
+ return output;
+}
+int rename_test(void)
+{
+ char string[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ char string2[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ int output;
+ strcpy(string,ROOT_PATH);
+ strcat(string,generate_random_string(FILE_NAME_LENGTH));
+ strcpy(string2,ROOT_PATH);
+ strcat(string2,generate_random_string(FILE_NAME_LENGTH));
+ sprintf(message,"\nrenaming from: %s, to %s\n",string,string2);
+ print_message(3,message);
+ output= rename(string,string2);
+ return output;
+}
+int link_test(void)
+{
+ char string[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ char string2[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ int output=0;
+ strcpy(string,ROOT_PATH);
+ strcat(string,generate_random_string(FILE_NAME_LENGTH));
+ strcpy(string2,ROOT_PATH);
+ strcat(string2,generate_random_string(FILE_NAME_LENGTH));
+ sprintf(message,"\nlink from: %s, to %s\n",string,string2);
+ print_message(3,message);
+ output= link(string,string2);
+ return output;
+}
+int mknod_test(void)
+{
+ char string[FILE_NAME_LENGTH+strlen(ROOT_PATH)];
+ int mode=0,dev=0,output=0;
+ strcpy(string,ROOT_PATH);
+ strcat(string,generate_random_string(FILE_NAME_LENGTH));
+ mode = ((S_IREAD|S_IWRITE)&random_int());
+ dev = random_int();
+ sprintf(message,"\nmaking node: %s, with mode %d, dev %d\n",string,mode,dev);
+ print_message(3,message);
+ output= mknod(string,mode,dev);
+ return output;
+}
--- /dev/null
+/*
+ * YAFFS: Yet another Flash File System . A NAND-flash specific file system.
+ *
+ * Copyright (C) 2002-2010 Aleph One Ltd.
+ * for Toby Churchill Ltd and Brightstar Engineering
+ *
+ * Created by Timothy Manning <timothy@yaffs.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+#ifndef __linux_test_h__
+#define __linux_test_h__
+#include <stdio.h>
+#include <stdlib.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <sys/mount.h>
+#include "lib.h"
+#include <fcntl.h>
+#include <time.h>
+#include <getopt.h>
+
+typedef struct dir_struct_temp{
+ node *path_list;
+ int number_of_items;
+}dir_struct;
+
+int check_dir(dir_struct *old_dir);
+dir_struct * scan_dir(void);
+int link_test(void);
+int symlink_test(void);
+int mknod_test(void);
+int mkdir_test(void);
+int rename_test(void);
+int rmdir_test(void);
+int remount_test(void);
+#endif
+++ /dev/null
-#include <stdio.h>
-#include <errno.h>
-
-
-int main()
-{
- int output=0;
- int error_code =0 ;
- output =symlink("timothy/home/tests/new_dir" "timothy/home/test/new_dir_link");
- output=mkdir("timothy/home/test/new_dir_link" );
- printf("output %d\n",output);
- if (output <0 ) {
- error_code = errno;
- printf("error code %d\n",error_code);
- printf("Error description is : %s\n",strerror(errno));
- }
- return 0;
-}
+++ /dev/null
-#include <stdio.h>
-#include <errno.h>
-
-
-int main()
-{
- int output=0;
- int error_code =0 ;
- output=rename( "/home/timothy/test/cat/","/home/timothy/test/dog/");
- printf("output %d\n",output);
- if (output <0 ) {
- error_code = errno;
- printf("error code %d\n",error_code);
- printf("Error description is : %s\n",strerror(errno));
- }
- return 0;
-}
+++ /dev/null
-
-BUGS
- NO Bugs.
-
-
yaffs_yaffs1.o \
yaffs_yaffs2.o \
yaffs_verify.o \
- yaffs_error.o
-
+ yaffs_error.o \
+ yaffs_summary.o
# yaffs_checkptrwtest.o\
TESTFILES = quick_tests.o lib.o \
test_yaffs_lstat.o test_yaffs_lstat_ENOENT.o test_yaffs_lstat_ENOTDIR.o test_yaffs_lstat_ENAMETOOLONG.o \
test_yaffs_lstat_NULL.o \
test_yaffs_flush.o test_yaffs_flush_EBADF.o test_yaffs_flush_EROFS.o \
- test_yaffs_dup.o test_yaffs_dup_EBADF.o
+ test_yaffs_dup.o test_yaffs_dup_EBADF.o
+
yaffs_yaffs1.c yaffs_yaffs1.h \
yaffs_yaffs2.c yaffs_yaffs2.h \
yaffs_bitmap.c yaffs_bitmap.h \
- yaffs_verify.c yaffs_verify.h
+ yaffs_verify.c yaffs_verify.h \
+ yaffs_summary.c yaffs_summary.h
YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
yaffsfs.h ydirectenv.h \
-
Made by Timothy Manning <timothy@yaffs.net> on 04/11/2010
+This test is designed to test the response and error handling of the yaffs functions.
+
+compile command: make
+run command: ./quick_tests
+
+command line options:
+ -h prints the available command line options.
+ -c tests will continue even if a test fails, rather than exiting the test.
+ -v verbose mode. will print all messages.
+ -q quiet mode. will not print any messages.
+ -t [number] sets the yaffs_trace() function to the number.
+ -n [number] sets the number of randomly selected tests to run after the test has run through
+ after running all of listed tests.
+
+############################# development infomation ####################################################################
Tests made
+++ /dev/null
-
-Made by Timothy Manning <timothy@yaffs.net> on 08/11/2010
-
-
-Current BUGS
-
-
-Current WARNINGS
-
- WARNING- If yaffs is unmounted then most of yaffs' functions return ENODIR.
- But some function return EBADF instead.
- Functions which return ENOTDIR: open, close, access, unlink, lseek, write, read
-
- Functions which return ENOENT: access, stat
-
-
-
- WARNING-the function yaffs_open does not check the mode passed to it.
- This means that yaffs open does not return EINVAL if a bad mode is passed to it.
- However this causes the error EEXIST to happen instead, because both O_CREAT and O_EXCL flags are set.
-
- WARNING- yaffs_open will work with either of the two mode set to 255.
- However there are only 4 or 5 flags that can be set for each of the modes.
- This means that the programmer may not be setting the flags properly.
-
- WARNING- When mounting a non-existing mount point the error ENODEV is returned.
- The quick tests have been altered to accommodate this error code.
- With standard access function in linux the error returned is ENOENT.
yaffs_bitmap.o \
yaffs_yaffs1.o \
yaffs_yaffs2.o \
- yaffs_verify.o
+ yaffs_verify.o \
+ yaffs_summary.o
SSCOMMONTESTOBJS = yaffscfg2k.o yaffs_ecc.o yaffs_fileem.o yaffs_fileem2k.o yaffsfs.o yaffs_guts.o \
yaffs_yaffs1.c yaffs_yaffs1.h \
yaffs_yaffs2.c yaffs_yaffs2.h \
yaffs_bitmap.c yaffs_bitmap.h \
- yaffs_verify.c yaffs_verify.h
+ yaffs_verify.c yaffs_verify.h \
+ yaffs_summary.c yaffs_summary.h
YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
yaffsfs.h yaffs_osglue.h ydirectenv.h \
--- /dev/null
+The stress_tester program opens and closes files at random in an effort to break yaffs.
+
+compile command: make
+run command: ./yaffs_tester
+
+command line options:
+ -seed [number] sets the random seed generator to the number.
+
{
generate_random_string(name,MAX_FILE_NAME_SIZE);
printf("before %d %d %d\n",strlen(yaffs_test_dir),strlen(name),strlen(path));
- join_paths(yaffs_test_dir,name,path);//bug###################### here
+ join_paths(yaffs_test_dir,name,path);
printf("after %d %d %d\n",strlen(yaffs_test_dir),strlen(name),strlen(path));
add_to_buffer(&message_buffer,"trying to open file: ",MESSAGE_LEVEL_BASIC_TASKS,NPRINT);
append_to_buffer(&message_buffer,path,MESSAGE_LEVEL_BASIC_TASKS,PRINT);
P_open_handles_array->number_of_open_handles++;
}
- else close_random_file(P_open_handles_array);
+ else close_random_file(P_open_handles_array);
}
int x=0;
int output=0;
int start=0;
+ printf("trying to clear handle");
if (P_open_handles_array->number_of_open_handles>0){
start=rand() % (MAX_NUMBER_OF_OPENED_HANDLES-1);
- for (x=start;P_open_handles_array->handle[x] !=-3 &&(x+1>start ||x<start);){
+
+ for (x=start;(x+1>start ||x<start);){
x++;
- if (x>MAX_NUMBER_OF_OPENED_HANDLES-1) x=0;
+ if (x>MAX_NUMBER_OF_OPENED_HANDLES-1) x=0;
+ if (P_open_handles_array->handle[x] !=-3 ){
+ //the handle is open, so try to close it.
+ break;
+ }
}
if (P_open_handles_array->handle[x]!=-3)
open_handles_array.path[x][0]='\0';
}
+
while(1)
{
+
x=rand() % 3;
+ printf("running test: %d",x);
switch(x){
case 0 :open_random_file(yaffs_test_dir,&open_handles_array);break;
- //case 1 :write_to_random_file(&open_handles_array);break;
- case 2 :close_random_file(&open_handles_array);break;
- case 3 :truncate_random_file(&open_handles_array);break;
+ case 3 :write_to_random_file(&open_handles_array);break;
+// case 1 :close_random_file(&open_handles_array);break;
+ case 2 :truncate_random_file(&open_handles_array);break;
}
}
}
#include "message_buffer.h"
#include "error_handler.h"
-#define MAX_NUMBER_OF_OPENED_HANDLES 50
+#define MAX_NUMBER_OF_OPENED_HANDLES 70
#define MAX_FILE_NAME_SIZE 51
typedef struct handle_regster_template{
yaffs_yaffs1.o \
yaffs_yaffs2.o \
yaffs_verify.o \
- yaffs_error.o
+ yaffs_error.o \
+ yaffs_summary.o
# yaffs_checkptrwtest.o\
yaffs_yaffs1.c yaffs_yaffs1.h \
yaffs_yaffs2.c yaffs_yaffs2.h \
yaffs_bitmap.c yaffs_bitmap.h \
- yaffs_verify.c yaffs_verify.h
+ yaffs_verify.c yaffs_verify.h \
+ yaffs_summary.c yaffs_summary.h
YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
yaffsfs.h ydirectenv.h \
--- /dev/null
+Created by Timothy Manning <timothy@yaffs.net> on 7/01/11
+
+This test is designed to test the locking ability of yaffs functions.
+
+compile command: make
+run command: ./threading
+
+
+command line arguments are:
+ -h displays the help contents
+ -t sets the number of threads
+
yaffs_yaffs1.o \
yaffs_yaffs2.o \
yaffs_verify.o \
- yaffs_error.o
+ yaffs_error.o \
+ yaffs_summary.o
# yaffs_checkptrwtest.o\
yaffs_yaffs1.c yaffs_yaffs1.h \
yaffs_yaffs2.c yaffs_yaffs2.h \
yaffs_bitmap.c yaffs_bitmap.h \
- yaffs_verify.c yaffs_verify.h
+ yaffs_verify.c yaffs_verify.h \
+ yaffs_summary.c yaffs_summary.h
YAFFSDIRECTSYMLINKS = yaffsfs.c yaffs_flashif.h yaffs_flashif2.h\
yaffsfs.h ydirectenv.h \
-Made by Timothy Manning on 24/12/10 <timothy@yaffs.net>
+Made by Timothy Manning on 24/12/2010 <timothy@yaffs.net>
mirror_tests is designed to check that yaffs behaves the same way as linux.
rm test/*;rmdir test/;./mirror_tests -n 100 -v
+compile command: make
+run command: mirror_tests
+
Command line arguments
- -yaffs_path [PATH] //sets the path for yaffs.
- -linux_path [PATH] //sets the path for linux.
- -p [NUMBER] //sets the print level for mirror_tests.
- -v //verbose mode everything is printed
- -q //quiet mode nothing is printed.
- -n [number] //sets the number of random tests to run.
- -s [number] //seeds rand with the number
- -t [number] //sets yaffs_trace to the number
- -clean //removes emfile and test dir
+ -yaffs_path [PATH] sets the path for yaffs.
+ -linux_path [PATH] sets the path for linux.
+ -p [NUMBER] sets the print level for mirror_tests.
+ -v verbose mode everything is printed
+ -q quiet mode nothing is printed.
+ -n [number] sets the number of random tests to run.
+ -s [number] seeds rand with the number
+ -t [number] sets yaffs_trace to the number
+ -clean removes emfile and test dir
#define __YAFFS_LIST_H__
-#include "yportenv.h"
-
/*
* This is a simple doubly linked list implementation that matches the
* way the Linux kernel doubly linked list implementation works.
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);
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);
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)
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 {
#include "linux/types.h"
#include "linux/mtd/mtd.h"
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
+#endif
+
+
/* Don't compile this module if we don't have MTD's mtd_oob_ops interface */
#if (MTD_VERSION_CODE > MTD_VERSION(2, 6, 17))
}
memset(&ops, 0, sizeof(ops));
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = (u8 *) data;
int deleted;
memset(&ops, 0, sizeof(ops));
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = data;
}
memset(&ops, 0, sizeof(ops));
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = (u8 *) data;
int deleted;
memset(&ops, 0, sizeof(ops));
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.len = (data) ? chunk_bytes : 0;
ops.ooblen = dev->param.tags_9bytes ? 9 : 8;
ops.datbuf = data;
*
* Returns YAFFS_OK or YAFFS_FAIL.
*/
-static int nandmtd1_test_prerequists(struct mtd_info *mtd)
+static int nandmtd1_test_prerequists(struct yaffs_dev *dev, struct mtd_info *mtd)
{
/* 2.6.18 has mtd->ecclayout->oobavail */
/* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */
if (oobavail < (dev->param.tags_9bytes ? 9 : 8)) {
yaffs_trace(YAFFS_TRACE_ERROR,
"mtd device has only %d bytes for tags, need %d",
- oobavail, (dev->param.tags_9bytes ? 9 : 8);
+ oobavail, (dev->param.tags_9bytes ? 9 : 8));
return YAFFS_FAIL;
}
return YAFFS_OK;
/* We don't yet have a good place to test for MTD config prerequists.
* Do it here as we are called during the initial scan.
*/
- if (nandmtd1_test_prerequists(mtd) != YAFFS_OK)
+ if (nandmtd1_test_prerequists(dev, mtd) != YAFFS_OK)
return YAFFS_FAIL;
retval = nandmtd1_read_chunk_tags(dev, chunk_num, NULL, &etags);
#include "yaffs_linux.h"
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 2, 0))
+#define MTD_OPS_AUTO_OOB MTD_OOB_AUTO
+#endif
+
+
+
/* NB For use with inband tags....
* We assume that the data buffer is of size total_bytes_per_chunk so
* that we can also use it to load the tags.
}
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 17))
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
ops.len = dev->param.total_bytes_per_chunk;
ops.ooboffs = 0;
retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
&dummy, data);
else if (tags) {
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.ooblen = packed_tags_size;
ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
ops.ooboffs = 0;
#include "linux/mtd/mtd.h"
#include "linux/types.h"
#include "linux/time.h"
+#include "mtd/mtd-abi.h"
/* NB For use with inband tags....
yaffs_pack_tags2(&pt, tags, !dev->param.no_tags_ecc);
}
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.ooblen = (dev->param.inband_tags) ? 0 : packed_tags_size;
ops.len = dev->param.total_bytes_per_chunk;
ops.ooboffs = 0;
retval = mtd->read(mtd, addr, dev->param.total_bytes_per_chunk,
&dummy, data);
} else if (tags) {
- ops.mode = MTD_OOB_AUTO;
+ ops.mode = MTD_OPS_AUTO_OOB;
ops.ooblen = packed_tags_size;
ops.len = data ? dev->data_bytes_per_chunk : packed_tags_size;
ops.ooboffs = 0;
#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)
{
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 %lld count %d",
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)
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
-#include <linux/smp_lock.h>
#include <linux/pagemap.h>
#include <linux/mtd/mtd.h>
#include <linux/interrupt.h>
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,
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;
}
return -ENOTEMPTY;
}
-static int yaffs_sync_object(struct file *file, int datasync)
+static int yaffs_sync_object(struct file *file, loff_t start, loff_t end, int datasync)
{
struct yaffs_obj *obj;
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)
inode->i_ctime.tv_nsec = 0;
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",
inode->i_mode, inode->i_uid, inode->i_gid,
return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL;
}
-static int yaffs_read_super(struct file_system_type *fs,
+static struct dentry *yaffs_mount(struct file_system_type *fs,
int flags, const char *dev_name,
- void *data, struct vfsmount *mnt)
+ void *data)
{
-
- return get_sb_bdev(fs, flags, dev_name, data,
- yaffs_internal_read_super_mtd, mnt);
+ return mount_bdev(fs, flags, dev_name, data,
+ yaffs_internal_read_super_mtd);
}
static struct file_system_type yaffs_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs",
- .get_sb = yaffs_read_super,
+ .mount = yaffs_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL;
}
-static int yaffs2_read_super(struct file_system_type *fs,
- int flags, const char *dev_name, void *data,
- struct vfsmount *mnt)
+static struct dentry *yaffs2_mount(struct file_system_type *fs,
+ int flags, const char *dev_name, void *data)
{
- return get_sb_bdev(fs, flags, dev_name, data,
- yaffs2_internal_read_super_mtd, mnt);
+ return mount_bdev(fs, flags, dev_name, data,
+ yaffs2_internal_read_super_mtd);
}
static struct file_system_type yaffs2_fs_type = {
.owner = THIS_MODULE,
.name = "yaffs2",
- .get_sb = yaffs2_read_super,
+ .mount = yaffs2_mount,
.kill_sb = kill_block_super,
.fs_flags = FS_REQUIRES_DEV,
};
--- /dev/null
+/*
+ * 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
+ *
+ * Created by Waldemar Rymarkiewicz <waldemar.rymarkiewicz@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1 as
+ * published by the Free Software Foundation.
+ *
+ * Note: Only YAFFS headers are LGPL, YAFFS C code is covered by GPL.
+ */
+
+#ifdef YAFFS_CURRENT
+ #include "yportenv_single.h"
+#else
+ #include "yportenv_multi.h"
+#endif