diff options
Diffstat (limited to 'fs')
27 files changed, 0 insertions, 10446 deletions
| diff --git a/fs/yaffs2/Kconfig b/fs/yaffs2/Kconfig deleted file mode 100644 index 272df7221..000000000 --- a/fs/yaffs2/Kconfig +++ /dev/null @@ -1,176 +0,0 @@ -# -# YAFFS file system configurations -# - -config YAFFS_FS -	tristate "YAFFS2 file system support" -	default n -	depends on MTD -	select YAFFS_YAFFS1 -	select YAFFS_YAFFS2 -	help -	  YAFFS2, or Yet Another Flash Filing System, is a filing system -	  optimised for NAND Flash chips. - -	  To compile the YAFFS2 file system support as a module, choose M -	  here: the module will be called yaffs2. - -	  If unsure, say N. - -	  Further information on YAFFS2 is available at -	  <http://www.aleph1.co.uk/yaffs/>. - -config YAFFS_YAFFS1 -	bool "512 byte / page devices" -	depends on YAFFS_FS -	default y -	help -	  Enable YAFFS1 support -- yaffs for 512 byte / page devices -	   -	  Not needed for 2K-page devices. - -	  If unsure, say Y. - -config YAFFS_9BYTE_TAGS -	bool "Use older-style on-NAND data format with pageStatus byte" -	depends on YAFFS_YAFFS1 -	default n -	help - -	  Older-style on-NAND data format has a "pageStatus" byte to record -	  chunk/page state.  This byte is zero when the page is discarded. -	  Choose this option if you have existing on-NAND data using this -	  format that you need to continue to support.  New data written -	  also uses the older-style format.  Note: Use of this option -	  generally requires that MTD's oob layout be adjusted to use the -	  older-style format.  See notes on tags formats and MTD versions -	  in yaffs_mtdif1.c. - -	  If unsure, say N. - -config YAFFS_DOES_ECC -	bool "Lets Yaffs do its own ECC" -	depends on YAFFS_FS && YAFFS_YAFFS1 && !YAFFS_9BYTE_TAGS -	default n -	help -	  This enables Yaffs to use its own ECC functions instead of using -	  the ones from the generic MTD-NAND driver. - -	  If unsure, say N. - -config YAFFS_ECC_WRONG_ORDER -	bool "Use the same ecc byte order as Steven Hill's nand_ecc.c" -	depends on YAFFS_FS && YAFFS_DOES_ECC && !YAFFS_9BYTE_TAGS -	default n -	help -	  This makes yaffs_ecc.c use the same ecc byte order as Steven -	  Hill's nand_ecc.c. If not set, then you get the same ecc byte -	  order as SmartMedia. - -	  If unsure, say N. - -config YAFFS_YAFFS2 -	bool "2048 byte (or larger) / page devices" -	depends on YAFFS_FS -	default y -	help -	  Enable YAFFS2 support -- yaffs for >= 2K bytes per page devices - -	  If unsure, say Y. - -config YAFFS_AUTO_YAFFS2 -	bool "Autoselect yaffs2 format" -	depends on YAFFS_YAFFS2 -	default y -	help -	  Without this, you need to explicitely use yaffs2 as the file -	  system type. With this, you can say "yaffs" and yaffs or yaffs2 -	  will be used depending on the device page size (yaffs on -	  512-byte page devices, yaffs2 on 2K page devices). - -	  If unsure, say Y. - -config YAFFS_DISABLE_LAZY_LOAD -	bool "Disable lazy loading" -	depends on YAFFS_YAFFS2 -	default n -	help -	  "Lazy loading" defers loading file details until they are -	  required. This saves mount time, but makes the first look-up -	  a bit longer. - -	  Lazy loading will only happen if enabled by this option being 'n' -	  and if the appropriate tags are available, else yaffs2 will -	  automatically fall back to immediate loading and do the right -	  thing. - -	  Lazy laoding will be required by checkpointing. - -	  Setting this to 'y' will disable lazy loading. - -	  If unsure, say N. - -config YAFFS_CHECKPOINT_RESERVED_BLOCKS -	int "Reserved blocks for checkpointing" -	depends on YAFFS_YAFFS2 -	default 10 -	help -          Give the number of Blocks to reserve for checkpointing. -	  Checkpointing saves the state at unmount so that mounting is -	  much faster as a scan of all the flash to regenerate this state -	  is not needed.  These Blocks are reserved per partition, so if -	  you have very small partitions the default (10) may be a mess -	  for you.  You can set this value to 0, but that does not mean -	  checkpointing is disabled at all. There only won't be any -	  specially reserved blocks for checkpointing, so if there is -	  enough free space on the filesystem, it will be used for -	  checkpointing. - -	  If unsure, leave at default (10), but don't wonder if there are -	  always 2MB used on your large page device partition (10 x 2k -	  pagesize). When using small partitions or when being very small -	  on space, you probably want to set this to zero. - -config YAFFS_DISABLE_WIDE_TNODES -	bool "Turn off wide tnodes" -	depends on YAFFS_FS -	default n -	help -	  Wide tnodes are only used for NAND arrays >=32MB for 512-byte -	  page devices and >=128MB for 2k page devices. They use slightly -	  more RAM but are faster since they eliminate chunk group -	  searching. - -	  Setting this to 'y' will force tnode width to 16 bits and save -	  memory but make large arrays slower. - -	  If unsure, say N. - -config YAFFS_ALWAYS_CHECK_CHUNK_ERASED -	bool "Force chunk erase check" -	depends on YAFFS_FS -	default n -	help -          Normally YAFFS only checks chunks before writing until an erased -	  chunk is found. This helps to detect any partially written -	  chunks that might have happened due to power loss. - -	  Enabling this forces on the test that chunks are erased in flash -	  before writing to them. This takes more time but is potentially -	  a bit more secure. -  -	  Suggest setting Y during development and ironing out driver -	  issues etc. Suggest setting to N if you want faster writing.   - -	  If unsure, say Y. - -config YAFFS_SHORT_NAMES_IN_RAM -	bool "Cache short names in RAM" -	depends on YAFFS_FS -	default y -	help -	  If this config is set, then short names are stored with the -	  yaffs_Object.  This costs an extra 16 bytes of RAM per object, -	  but makes look-ups faster. - -	  If unsure, say Y. diff --git a/fs/yaffs2/Makefile b/fs/yaffs2/Makefile deleted file mode 100644 index 538aec420..000000000 --- a/fs/yaffs2/Makefile +++ /dev/null @@ -1,40 +0,0 @@ -# Main Makefile for YAFFS -# -# -# YAFFS: Yet Another Flash File System. A NAND-flash specific file system. -#  -# Copyright (C) 2002-2007 Aleph One Ltd. -#   for Toby Churchill Ltd and Brightstar Engineering -#  -# 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. - - -ifneq ($(KERNELRELEASE),) -	EXTRA_CFLAGS += -DYAFFS_OUT_OF_TREE - -	obj-m := yaffs2.o - -	yaffs2-objs := yaffs_mtdif.o yaffs_mtdif2.o -	yaffs2-objs += yaffs_mtdif1.o yaffs_packedtags1.o -	yaffs2-objs += yaffs_ecc.o yaffs_fs.o yaffs_guts.o -	yaffs2-objs += yaffs_packedtags2.o yaffs_qsort.o -	yaffs2-objs += yaffs_tagscompat.o yaffs_tagsvalidity.o -	yaffs2-objs += yaffs_checkptrw.o yaffs_nand.o - -else -	KERNELDIR ?= /lib/modules/$(shell uname -r)/build -	PWD := $(shell pwd) - -modules default: -	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules - -mi modules_install: -	$(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install - -clean: -	$(MAKE) -C $(KERNELDIR) M=$(PWD) clean -endif diff --git a/fs/yaffs2/Makefile.kernel b/fs/yaffs2/Makefile.kernel deleted file mode 100644 index 382ee6142..000000000 --- a/fs/yaffs2/Makefile.kernel +++ /dev/null @@ -1,10 +0,0 @@ -# -# Makefile for the linux YAFFS filesystem routines. -# - -obj-$(CONFIG_YAFFS_FS) += yaffs.o - -yaffs-y := yaffs_ecc.o yaffs_fs.o yaffs_guts.o yaffs_checkptrw.o -yaffs-y += yaffs_packedtags1.o yaffs_packedtags2.o yaffs_nand.o yaffs_qsort.o -yaffs-y += yaffs_tagscompat.o yaffs_tagsvalidity.o -yaffs-y += yaffs_mtdif.o yaffs_mtdif1.o yaffs_mtdif2.o diff --git a/fs/yaffs2/README-linux-patch b/fs/yaffs2/README-linux-patch deleted file mode 100644 index 3bdf26cc8..000000000 --- a/fs/yaffs2/README-linux-patch +++ /dev/null @@ -1,20 +0,0 @@ -To build YAFFS in the Linux kernel tree you need to run the patch-ker.sh -script from the yaffs source directory, giving your choice as to whether -you wish to copy (c) or link (l) the code and the path to your kernel -sources, e.g: - -./patch-ker.sh c /usr/src/linux - -This will copy the yaffs files into fs/yaffs2 and modify the Kconfig -and Makefiles in the fs directory. - -./patch-ker.sh l /usr/src/linux - -This does the same as the above but makes symbolic links instead. - -After you've run the script, go back to your normal kernel making procedure -and configure the yaffs settings you want. - -Prolems? Contact the yaffs mailing list: - -http://www.aleph1.co.uk/mailman/listinfo/yaffs diff --git a/fs/yaffs2/direct/dtest.c b/fs/yaffs2/direct/dtest.c deleted file mode 100644 index a9156ca19..000000000 --- a/fs/yaffs2/direct/dtest.c +++ /dev/null @@ -1,2282 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* -* Test code for the "direct" interface.  -*/ - -/* XXX U-BOOT XXX */ -#include <common.h> - -#include <stdio.h> -#include <string.h> -#include <unistd.h> -#include <fcntl.h> - -#include "yaffsfs.h" - -void dumpDir(const char *dname); - -char xx[600]; - -void copy_in_a_file(char *yaffsName,char *inName) -{ -	int inh,outh; -	unsigned char buffer[100]; -	int ni,no; -	inh = open(inName,O_RDONLY); -	outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); -	 -	while((ni = read(inh,buffer,100)) > 0) -	{ -		no = yaffs_write(outh,buffer,ni); -		if(ni != no) -		{ -			printf("problem writing yaffs file\n"); -		} -		 -	} -	 -	yaffs_close(outh); -	close(inh); -} - -void make_a_file(char *yaffsName,char bval,int sizeOfFile) -{ -	int outh; -	int i; -	unsigned char buffer[100]; - -	outh = yaffs_open(yaffsName, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); -	 -	memset(buffer,bval,100); -	 -	do{ -		i = sizeOfFile; -		if(i > 100) i = 100; -		sizeOfFile -= i; -		 -		yaffs_write(outh,buffer,i); -		 -	} while (sizeOfFile > 0); -	 -		 -	yaffs_close(outh); - -} - -void make_pattern_file(char *fn,int size) -{ -	int outh; -	int marker; -	int i; -	outh = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); -	yaffs_lseek(outh,size-1,SEEK_SET); -	yaffs_write(outh,"A",1); -	 -	for(i = 0; i < size; i+=256) -	{ -		marker = ~i; -		yaffs_lseek(outh,i,SEEK_SET); -		yaffs_write(outh,&marker,sizeof(marker)); -	} -	yaffs_close(outh); -	 -} - -int check_pattern_file(char *fn) -{ -	int h; -	int marker; -	int i; -	int size; -	int ok = 1; -	 -	h = yaffs_open(fn, O_RDWR,0); -	size = yaffs_lseek(h,0,SEEK_END); -		 -	for(i = 0; i < size; i+=256) -	{ -		yaffs_lseek(h,i,SEEK_SET); -		yaffs_read(h,&marker,sizeof(marker)); -		ok = (marker == ~i); -		if(!ok) -		{ -		   printf("pattern check failed on file %s, size %d at position %d. Got %x instead of %x\n", -					fn,size,i,marker,~i); -		} -	} -	yaffs_close(h); -	return ok; -} - - - - - -int dump_file_data(char *fn) -{ -	int h; -	int marker; -	int i = 0; -	int size; -	int ok = 1; -	unsigned char b; -	 -	h = yaffs_open(fn, O_RDWR,0); - -				 -	printf("%s\n",fn); -	while(yaffs_read(h,&b,1)> 0) -	{ -		printf("%02x",b); -		i++; -		if(i > 32)  -		{ -		   printf("\n"); -		   i = 0;; -		 } -	} -	printf("\n"); -	yaffs_close(h); -	return ok; -} - - - -void dump_file(const char *fn) -{ -	int i; -	int size; -	int h; -	 -	h = yaffs_open(fn,O_RDONLY,0); -	if(h < 0) -	{ -		printf("*****\nDump file %s does not exist\n",fn); -	} -	else -	{ -		size = yaffs_lseek(h,0,SEEK_SET); -		printf("*****\nDump file %s size %d\n",fn,size); -		for(i = 0; i < size; i++) -		{ -			 -		} -	} -} - -void create_file_of_size(const char *fn,int syze) -{ -	int h; -	int n; -	 -	char xx[200]; -	 -	int iterations = (syze + strlen(fn) -1)/ strlen(fn); -	 -	h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); -		 -	while (iterations > 0) -	{ -		sprintf(xx,"%s %8d",fn,iterations); -		yaffs_write(h,xx,strlen(xx)); -		iterations--; -	} -	yaffs_close (h); -} - -void verify_file_of_size(const char *fn,int syze) -{ -	int h; -	int n; -	 -	char xx[200]; -	char yy[200]; -	int l; -	 -	int iterations = (syze + strlen(fn) -1)/ strlen(fn); -	 -	h = yaffs_open(fn, O_RDONLY, S_IREAD | S_IWRITE); -		 -	while (iterations > 0) -	{ -		sprintf(xx,"%s %8d",fn,iterations); -		l = strlen(xx); -		 -		yaffs_read(h,yy,l); -		yy[l] = 0; -		 -		if(strcmp(xx,yy)){ -			printf("=====>>>>> verification of file %s failed near position %d\n",fn,yaffs_lseek(h,0,SEEK_CUR)); -		} -		iterations--; -	} -	yaffs_close (h); -} - -void create_resized_file_of_size(const char *fn,int syze1,int reSyze, int syze2) -{ -	int h; -	int n; -	 -	 -	int iterations; -	 -	h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); -		 -	iterations = (syze1 + strlen(fn) -1)/ strlen(fn); -	while (iterations > 0) -	{ -		yaffs_write(h,fn,strlen(fn)); -		iterations--; -	} -	 -	yaffs_truncate(h,reSyze); -	 -	yaffs_lseek(h,0,SEEK_SET); -	iterations = (syze2 + strlen(fn) -1)/ strlen(fn); -	while (iterations > 0) -	{ -		yaffs_write(h,fn,strlen(fn)); -		iterations--; -	} -	 -	yaffs_close (h); -} - - -void do_some_file_stuff(const char *path) -{ - -	char fn[100]; - -	sprintf(fn,"%s/%s",path,"f1"); -	create_file_of_size(fn,10000); - -	sprintf(fn,"%s/%s",path,"fdel"); -	create_file_of_size(fn,10000); -	yaffs_unlink(fn); - -	sprintf(fn,"%s/%s",path,"f2"); -	 -	create_resized_file_of_size(fn,10000,3000,4000); -} - -void yaffs_backward_scan_test(const char *path) -{ -	char fn[100]; -	 -	yaffs_StartUp();	 -	 -	yaffs_mount(path); -	 -	do_some_file_stuff(path); -	 -	sprintf(fn,"%s/ddd",path); -	 -	yaffs_mkdir(fn,0); -	 -	do_some_file_stuff(fn); -	 -	yaffs_unmount(path); -	 -	yaffs_mount(path); -} - -char xxzz[2000]; - - -void yaffs_device_flush_test(const char *path) -{ -	char fn[100]; -	int h; -	int i; -	 -	yaffs_StartUp();	 -	 -	yaffs_mount(path); -	 -	do_some_file_stuff(path); -	 -	// Open and add some data to a few files -	for(i = 0; i < 10; i++) { -	 -		sprintf(fn,"%s/ff%d",path,i); - -		h = yaffs_open(fn, O_CREAT | O_RDWR | O_TRUNC, S_IWRITE | S_IREAD); -		yaffs_write(h,xxzz,2000); -		yaffs_write(h,xxzz,2000); -	} -	yaffs_unmount(path); -	 -	yaffs_mount(path); -} - - - -void short_scan_test(const char *path, int fsize, int niterations) -{ -	int i; -	char fn[100]; -	 -	sprintf(fn,"%s/%s",path,"f1"); -	 -	yaffs_StartUp(); -	for(i = 0; i < niterations; i++) -	{ -		printf("\n*****************\nIteration %d\n",i); -		yaffs_mount(path); -		printf("\nmount: Directory look-up of %s\n",path); -		dumpDir(path); -		make_a_file(fn,1,fsize); -		yaffs_unmount(path); -	} -} - - - -void scan_pattern_test(const char *path, int fsize, int niterations) -{ -	int i; -	int j; -	char fn[3][100]; -	int result; -	 -	sprintf(fn[0],"%s/%s",path,"f0"); -	sprintf(fn[1],"%s/%s",path,"f1"); -	sprintf(fn[2],"%s/%s",path,"f2"); -	 -	yaffs_StartUp(); -	 -	for(i = 0; i < niterations; i++) -	{ -		printf("\n*****************\nIteration %d\n",i); -		yaffs_mount(path); -		printf("\nmount: Directory look-up of %s\n",path); -		dumpDir(path); -		for(j = 0; j < 3; j++) -		{ -			result = dump_file_data(fn[j]); -			result = check_pattern_file(fn[j]); -			make_pattern_file(fn[j],fsize);  -			result = dump_file_data(fn[j]); -			result = check_pattern_file(fn[j]); -		} -		yaffs_unmount(path); -	} -} - -void fill_disk(char *path,int nfiles) -{ -	int h; -	int n; -	int result; -	int f; -	 -	char str[50]; -	 -	for(n = 0; n < nfiles; n++) -	{ -		sprintf(str,"%s/%d",path,n); -		 -		h = yaffs_open(str, O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); -		 -		printf("writing file %s handle %d ",str, h); -		 -		while ((result = yaffs_write(h,xx,600)) == 600) -		{ -			f = yaffs_freespace(path); -		} -		result = yaffs_close(h); -		printf(" close %d\n",result); -	} -} - -void fill_disk_and_delete(char *path, int nfiles, int ncycles) -{ -	int i,j; -	char str[50]; -	int result; -	 -	for(i = 0; i < ncycles; i++) -	{ -		printf("@@@@@@@@@@@@@@ cycle %d\n",i); -		fill_disk(path,nfiles); -		 -		for(j = 0; j < nfiles; j++) -		{ -			sprintf(str,"%s/%d",path,j); -			result = yaffs_unlink(str); -			printf("unlinking file %s, result %d\n",str,result); -		} -	} -} - - -void fill_files(char *path,int flags, int maxIterations,int siz) -{ -	int i; -	int j; -	char str[50]; -	int h; -	 -	i = 0; -	 -	do{ -		sprintf(str,"%s/%d",path,i); -		h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE); -		yaffs_close(h); - -		if(h >= 0) -		{ -			for(j = 0; j < siz; j++) -			{ -				yaffs_write(h,str,1); -			} -		} -		 -		if( flags & 1) -		{ -			yaffs_unlink(str); -		} -		i++; -	} while(h >= 0 && i < maxIterations); -	 -	if(flags & 2) -	{ -		i = 0; -		do{ -			sprintf(str,"%s/%d",path,i); -			printf("unlink %s\n",str); -			i++; -		} while(yaffs_unlink(str) >= 0); -	} -} - -void leave_unlinked_file(char *path,int maxIterations,int siz) -{ -	int i; -	char str[50]; -	int h; -	 -	i = 0; -	 -	do{ -		sprintf(str,"%s/%d",path,i); -		printf("create %s\n",str); -		h = yaffs_open(str, O_CREAT | O_TRUNC | O_RDWR,S_IREAD | S_IWRITE); -		if(h >= 0) -		{ -			yaffs_unlink(str); -		} -		i++; -	} while(h < 0 && i < maxIterations); -	 -	if(h >= 0) -	{ -		for(i = 0; i < siz; i++) -		{ -			yaffs_write(h,str,1); -		} -	} -	 -	printf("Leaving file %s open\n",str); - -} - -void dumpDirFollow(const char *dname) -{ -	yaffs_DIR *d; -	yaffs_dirent *de; -	struct yaffs_stat s; -	char str[100]; -			 -	d = yaffs_opendir(dname); -	 -	if(!d) -	{ -		printf("opendir failed\n"); -	} -	else -	{ -		while((de = yaffs_readdir(d)) != NULL) -		{ -			sprintf(str,"%s/%s",dname,de->d_name); -			 -			yaffs_stat(str,&s); -			 -			printf("%s length %d mode %X ",de->d_name,(int)s.st_size,s.st_mode); -			switch(s.st_mode & S_IFMT) -			{ -				case S_IFREG: printf("data file"); break; -				case S_IFDIR: printf("directory"); break; -				case S_IFLNK: printf("symlink -->"); -							  if(yaffs_readlink(str,str,100) < 0) -								printf("no alias"); -							  else -								printf("\"%s\"",str);     -							  break; -				default: printf("unknown"); break; -			} -			 -			printf("\n");            -		} -		 -		yaffs_closedir(d); -	} -	printf("\n"); -	 -	printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname)); - -} - - -void dump_directory_tree_worker(const char *dname,int recursive) -{ -	yaffs_DIR *d; -	yaffs_dirent *de; -	struct yaffs_stat s; -	char str[1000]; -			 -	d = yaffs_opendir(dname); -	 -	if(!d) -	{ -		printf("opendir failed\n"); -	} -	else -	{ -		while((de = yaffs_readdir(d)) != NULL) -		{ -			sprintf(str,"%s/%s",dname,de->d_name); -			 -			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); -			switch(s.st_mode & S_IFMT) -			{ -				case S_IFREG: printf("data file"); break; -				case S_IFDIR: printf("directory"); break; -				case S_IFLNK: printf("symlink -->"); -							  if(yaffs_readlink(str,str,100) < 0) -								printf("no alias"); -							  else -								printf("\"%s\"",str);     -							  break; -				default: printf("unknown"); break; -			} -			 -			printf("\n"); - -			if((s.st_mode & S_IFMT) == S_IFDIR && recursive) -				dump_directory_tree_worker(str,1); -							 -		} -		 -		yaffs_closedir(d); -	} - -} - -static void dump_directory_tree(const char *dname) -{ -	dump_directory_tree_worker(dname,1); -	printf("\n"); -	printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname)); -} - -void dumpDir(const char *dname) -{	dump_directory_tree_worker(dname,0); -	printf("\n"); -	printf("Free space in %s is %d\n\n",dname,(int)yaffs_freespace(dname)); -} - - -static void PermissionsCheck(const char *path, mode_t tmode, int tflags,int expectedResult) -{ -	int fd; -	 -	if(yaffs_chmod(path,tmode)< 0) printf("chmod failed\n"); -	 -	fd = yaffs_open(path,tflags,0); -	 -	if((fd >= 0) != (expectedResult > 0)) -	{ -		printf("Permissions check %x %x %d failed\n",tmode,tflags,expectedResult); -	} -	else -	{ -		printf("Permissions check %x %x %d OK\n",tmode,tflags,expectedResult); -	} -	 -	 -	yaffs_close(fd); -	 -	 -} - -int long_test(int argc, char *argv[]) -{ - -	int f; -	int r; -	char buffer[20]; -	 -	char str[100]; -	 -	int h; -	mode_t temp_mode; -	struct yaffs_stat ystat; -	 -	yaffs_StartUp(); -	 -	yaffs_mount("/boot"); -	yaffs_mount("/data"); -	yaffs_mount("/flash"); -	yaffs_mount("/ram"); -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	printf("\nDirectory look-up of /data\n"); -	dumpDir("/data"); -	printf("\nDirectory look-up of /flash\n"); -	dumpDir("/flash"); - -	//leave_unlinked_file("/flash",20000,0); -	//leave_unlinked_file("/data",20000,0); -	 -	leave_unlinked_file("/ram",20,0); -	 - -	f = yaffs_open("/boot/b1", O_RDONLY,0); -	 -	printf("open /boot/b1 readonly, f=%d\n",f); -	 -	f = yaffs_open("/boot/b1", O_CREAT,S_IREAD | S_IWRITE); -	 -	printf("open /boot/b1 O_CREAT, f=%d\n",f); -	 -	 -	r = yaffs_write(f,"hello",1); -	printf("write %d attempted to write to a read-only file\n",r); -	 -	r = yaffs_close(f); -	 -	printf("close %d\n",r); - -	f = yaffs_open("/boot/b1", O_RDWR,0); -	 -	printf("open /boot/b1 O_RDWR,f=%d\n",f); -	 -	 -	r = yaffs_write(f,"hello",2); -	printf("write %d attempted to write to a writeable file\n",r); -	r = yaffs_write(f,"world",3); -	printf("write %d attempted to write to a writeable file\n",r); -	 -	r= yaffs_lseek(f,0,SEEK_END); -	printf("seek end %d\n",r); -	memset(buffer,0,20); -	r = yaffs_read(f,buffer,10); -	printf("read %d \"%s\"\n",r,buffer); -	r= yaffs_lseek(f,0,SEEK_SET); -	printf("seek set %d\n",r); -	memset(buffer,0,20); -	r = yaffs_read(f,buffer,10); -	printf("read %d \"%s\"\n",r,buffer); -	memset(buffer,0,20); -	r = yaffs_read(f,buffer,10); -	printf("read %d \"%s\"\n",r,buffer); - -	// Check values reading at end. -	// A read past end of file should return 0 for 0 bytes read. -		 -	r= yaffs_lseek(f,0,SEEK_END); -	r = yaffs_read(f,buffer,10); -	printf("read at end returned  %d\n",r);  -	r= yaffs_lseek(f,500,SEEK_END); -	r = yaffs_read(f,buffer,10); -	printf("read past end returned  %d\n",r);        -	 -	r = yaffs_close(f); -	 -	printf("close %d\n",r); -	 -	copy_in_a_file("/boot/yyfile","xxx"); -	 -	// Create a file with a long name -	 -	copy_in_a_file("/boot/file with a long name","xxx"); -	 -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); - -	// Check stat -	r = yaffs_stat("/boot/file with a long name",&ystat); -	 -	// Check rename -	 -	r = yaffs_rename("/boot/file with a long name","/boot/r1"); -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	 -	// Check unlink -	r = yaffs_unlink("/boot/r1"); -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); - -	// Check mkdir -	 -	r = yaffs_mkdir("/boot/directory1",0); -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	printf("\nDirectory look-up of /boot/directory1\n"); -	dumpDir("/boot/directory1"); - -	// add a file to the directory                   -	copy_in_a_file("/boot/directory1/file with a long name","xxx"); -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	printf("\nDirectory look-up of /boot/directory1\n"); -	dumpDir("/boot/directory1"); -	 -	//  Attempt to delete directory (should fail) -	 -	r = yaffs_rmdir("/boot/directory1"); -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	printf("\nDirectory look-up of /boot/directory1\n"); -	dumpDir("/boot/directory1"); -	 -	// Delete file first, then rmdir should work -	r = yaffs_unlink("/boot/directory1/file with a long name"); -	r = yaffs_rmdir("/boot/directory1"); -	 -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	printf("\nDirectory look-up of /boot/directory1\n"); -	dumpDir("/boot/directory1"); - -#if 0 -	fill_disk_and_delete("/boot",20,20); -			 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -#endif - -	yaffs_symlink("yyfile","/boot/slink"); -	 -	yaffs_readlink("/boot/slink",str,100); -	printf("symlink alias is %s\n",str); -	 -	 -	 -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	printf("\nDirectory look-up of /boot (using stat instead of lstat)\n"); -	dumpDirFollow("/boot"); -	printf("\nDirectory look-up of /boot/directory1\n"); -	dumpDir("/boot/directory1"); - -	h = yaffs_open("/boot/slink",O_RDWR,0); -	 -	printf("file length is %d\n",(int)yaffs_lseek(h,0,SEEK_END)); -	 -	yaffs_close(h); -	 -	yaffs_unlink("/boot/slink"); - -	 -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	 -	// Check chmod -	 -	yaffs_stat("/boot/yyfile",&ystat); -	temp_mode = ystat.st_mode; -	 -	yaffs_chmod("/boot/yyfile",0x55555); -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	 -	yaffs_chmod("/boot/yyfile",temp_mode); -	printf("\nDirectory look-up of /boot\n"); -	dumpDir("/boot"); -	 -	// Permission checks... -	PermissionsCheck("/boot/yyfile",0, O_WRONLY,0); -	PermissionsCheck("/boot/yyfile",0, O_RDONLY,0); -	PermissionsCheck("/boot/yyfile",0, O_RDWR,0); - -	PermissionsCheck("/boot/yyfile",S_IREAD, O_WRONLY,0); -	PermissionsCheck("/boot/yyfile",S_IREAD, O_RDONLY,1); -	PermissionsCheck("/boot/yyfile",S_IREAD, O_RDWR,0); - -	PermissionsCheck("/boot/yyfile",S_IWRITE, O_WRONLY,1); -	PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDONLY,0); -	PermissionsCheck("/boot/yyfile",S_IWRITE, O_RDWR,0); -	 -	PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_WRONLY,1); -	PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDONLY,1); -	PermissionsCheck("/boot/yyfile",S_IREAD | S_IWRITE, O_RDWR,1); - -	yaffs_chmod("/boot/yyfile",temp_mode); -	 -	//create a zero-length file and unlink it (test for scan bug) -	 -	h = yaffs_open("/boot/zlf",O_CREAT | O_TRUNC | O_RDWR,0); -	yaffs_close(h); -	 -	yaffs_unlink("/boot/zlf"); -	 -	 -	yaffs_DumpDevStruct("/boot"); -	 -	fill_disk_and_delete("/boot",20,20); -	 -	yaffs_DumpDevStruct("/boot"); -	 -	fill_files("/boot",1,10000,0); -	fill_files("/boot",1,10000,5000); -	fill_files("/boot",2,10000,0); -	fill_files("/boot",2,10000,5000); -	 -	leave_unlinked_file("/data",20000,0); -	leave_unlinked_file("/data",20000,5000); -	leave_unlinked_file("/data",20000,5000); -	leave_unlinked_file("/data",20000,5000); -	leave_unlinked_file("/data",20000,5000); -	leave_unlinked_file("/data",20000,5000); -	 -	yaffs_DumpDevStruct("/boot"); -	yaffs_DumpDevStruct("/data"); -	 -		 -		 -	return 0; - -} - -int huge_directory_test_on_path(char *path) -{ - -	yaffs_DIR *d; -	yaffs_dirent *de; -	struct yaffs_stat s; - -	int f; -	int i; -	int r; -	int total = 0; -	int lastTotal = 0; -	char buffer[20]; -	 -	char str[100]; -	char name[100]; -	char name2[100]; -	 -	int h; -	mode_t temp_mode; -	struct yaffs_stat ystat; -	 -	yaffs_StartUp(); -	 -	yaffs_mount(path); -	 -	// Create a large number of files -	 -	for(i = 0; i < 2000; i++) -	{ -	  sprintf(str,"%s/%d",path,i); -	   -	   f = yaffs_open(str,O_CREAT,S_IREAD | S_IWRITE); -	   yaffs_close(f); -	} -	 -	 -	 -	d = yaffs_opendir(path); -	i = 0; -	if (d) { -	while((de = yaffs_readdir(d)) != NULL) { -	if (total >lastTotal+100*9*1024||(i & 1023)==0){ -	printf("files = %d, total = %d\n",i, total); -	lastTotal = total; -	} -		i++; -		sprintf(str,"%s/%s",path,de->d_name); -		yaffs_lstat(str,&s); -		switch(s.st_mode & S_IFMT){ -		case S_IFREG: -	//printf("data file"); -	total += s.st_size; -	break; -	} -	} -	 -	yaffs_closedir(d); -	} -	 -	return 0; -} - -int yaffs_scan_test(const char *path) -{ -} - - -void rename_over_test(const char *mountpt) -{ -	int i; -	char a[100]; -	char b[100]; -	 -	sprintf(a,"%s/a",mountpt); -	sprintf(b,"%s/b",mountpt); -	 -	yaffs_StartUp(); -	 -	yaffs_mount(mountpt); -	i = yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, 0);  -	yaffs_close(i); -	i = yaffs_open(b,O_CREAT | O_TRUNC | O_RDWR, 0); -	yaffs_close(i); -	yaffs_rename(a,b); // rename over -	yaffs_rename(b,a); // rename back again (not renaimng over) -	yaffs_rename(a,b); // rename back again (not renaimng over) -	 -	 -	yaffs_unmount(mountpt); -	 -} - -int resize_stress_test(const char *path) -{ -   int a,b,i,j; -   int x; -   int r; -   char aname[100]; -   char bname[100]; -    -   char abuffer[1000]; -   char bbuffer[1000]; -    -   yaffs_StartUp(); -    -   yaffs_mount(path); -    -   sprintf(aname,"%s%s",path,"/a"); -   sprintf(bname,"%s%s",path,"/b"); -    -   memset(abuffer,'a',1000); -   memset(bbuffer,'b',1000); -    -   a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -   b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -    -   printf(" %s %d %s %d\n",aname,a,bname,b); -   -   x = 0; -    -   for(j = 0; j < 100; j++) -   { -		yaffs_lseek(a,0,SEEK_END); - -		 -		for(i = 0; i <20000; i++) -		{ -		   //r =        yaffs_lseek(b,i,SEEK_SET); -			//r = yaffs_write(b,bbuffer,1000); -			 -			if(x & 0x16) -			{ -				// shrink -				int syz = yaffs_lseek(a,0,SEEK_END); -				 -				syz -= 500; -				if(syz < 0) syz = 0; -				yaffs_truncate(a,syz); -				 -			} -			else -			{ -				//expand -				r = yaffs_lseek(a,i * 500,SEEK_SET); -				r = yaffs_write(a,abuffer,1000); -			} -			x++; -			 -		} -   } -    -   return 0; -    -} - - -int resize_stress_test_no_grow_complex(const char *path,int iters) -{ -   int a,b,i,j; -   int x; -   int r; -   char aname[100]; -   char bname[100]; -    -   char abuffer[1000]; -   char bbuffer[1000]; -    -   yaffs_StartUp(); -    -   yaffs_mount(path); -    -   sprintf(aname,"%s%s",path,"/a"); -   sprintf(bname,"%s%s",path,"/b"); -    -   memset(abuffer,'a',1000); -   memset(bbuffer,'b',1000); -    -   a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -   b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -    -   printf(" %s %d %s %d\n",aname,a,bname,b); -   -   x = 0; -    -   for(j = 0; j < iters; j++) -   { -		yaffs_lseek(a,0,SEEK_END); - -		 -		for(i = 0; i <20000; i++) -		{ -		   //r =        yaffs_lseek(b,i,SEEK_SET); -			//r = yaffs_write(b,bbuffer,1000); -			 -			if(!(x%20)) -			{ -				// shrink -				int syz = yaffs_lseek(a,0,SEEK_END); -				 -				while(syz > 4000) -				{ -				 -					syz -= 2050; -					if(syz < 0) syz = 0; -					yaffs_truncate(a,syz); -					syz = yaffs_lseek(a,0,SEEK_END); -					printf("shrink to %d\n",syz); -				} -				 -				 -			} -			else -			{ -				//expand -				r = yaffs_lseek(a,500,SEEK_END); -				r = yaffs_write(a,abuffer,1000); -			} -			x++; -			 -					 -		} -		printf("file size is %d\n",yaffs_lseek(a,0,SEEK_END)); - -   } -    -   return 0; -    -} - -int resize_stress_test_no_grow(const char *path,int iters) -{ -   int a,b,i,j; -   int x; -   int r; -   char aname[100]; -   char bname[100]; -    -   char abuffer[1000]; -   char bbuffer[1000]; -    -   yaffs_StartUp(); -    -   yaffs_mount(path); -    -   sprintf(aname,"%s%s",path,"/a"); -   sprintf(bname,"%s%s",path,"/b"); -    -   memset(abuffer,'a',1000); -   memset(bbuffer,'b',1000); -    -   a = yaffs_open(aname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -   b = yaffs_open(bname, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -    -   printf(" %s %d %s %d\n",aname,a,bname,b); -   -   x = 0; -    -   for(j = 0; j < iters; j++) -   { -		yaffs_lseek(a,0,SEEK_END); - -		 -		for(i = 0; i <20000; i++) -		{ -		   //r =        yaffs_lseek(b,i,SEEK_SET); -			//r = yaffs_write(b,bbuffer,1000); -			 -			if(!(x%20)) -			{ -				// shrink -				int syz = yaffs_lseek(a,0,SEEK_END); -				 -				while(syz > 4000) -				{ -				 -					syz -= 2050; -					if(syz < 0) syz = 0; -					yaffs_truncate(a,syz); -					syz = yaffs_lseek(a,0,SEEK_END); -					printf("shrink to %d\n",syz); -				} -				 -				 -			} -			else -			{ -				//expand -				r = yaffs_lseek(a,-500,SEEK_END); -				r = yaffs_write(a,abuffer,1000); -			} -			x++; -			 -					 -		} -		printf("file size is %d\n",yaffs_lseek(a,0,SEEK_END)); - -   } -    -   return 0; -    -} - -int directory_rename_test(void) -{ -	int r; -	yaffs_StartUp(); -	 -	yaffs_mount("/ram"); -	yaffs_mkdir("/ram/a",0); -	yaffs_mkdir("/ram/a/b",0); -	yaffs_mkdir("/ram/c",0); -	 -	printf("\nDirectory look-up of /ram\n"); -	dumpDir("/ram"); -	dumpDir("/ram/a"); -	dumpDir("/ram/a/b"); - -	printf("Do rename (should fail)\n"); -		 -	r = yaffs_rename("/ram/a","/ram/a/b/d"); -	printf("\nDirectory look-up of /ram\n"); -	dumpDir("/ram"); -	dumpDir("/ram/a"); -	dumpDir("/ram/a/b"); - -	printf("Do rename (should not fail)\n"); -		 -	r = yaffs_rename("/ram/c","/ram/a/b/d"); -	printf("\nDirectory look-up of /ram\n"); -	dumpDir("/ram"); -	dumpDir("/ram/a"); -	dumpDir("/ram/a/b"); -	 -	 -	return 1; -	 -} - -int cache_read_test(void) -{ -	int a,b,c; -	int i; -	int sizeOfFiles = 500000; -	char buffer[100]; -	 -	yaffs_StartUp(); -	 -	yaffs_mount("/boot"); -	 -	make_a_file("/boot/a",'a',sizeOfFiles); -	make_a_file("/boot/b",'b',sizeOfFiles); - -	a = yaffs_open("/boot/a",O_RDONLY,0); -	b = yaffs_open("/boot/b",O_RDONLY,0); -	c = yaffs_open("/boot/c", O_CREAT | O_RDWR | O_TRUNC, S_IREAD | S_IWRITE); - -	do{ -		i = sizeOfFiles; -		if (i > 100) i = 100; -		sizeOfFiles  -= i; -		yaffs_read(a,buffer,i); -		yaffs_read(b,buffer,i); -		yaffs_write(c,buffer,i); -	} while(sizeOfFiles > 0); -	 -	 -	 -	return 1; -	 -} - -int cache_bypass_bug_test(void) -{ -	// This test reporoduces a bug whereby YAFFS caching *was* buypassed -	// resulting in erroneous reads after writes. -	// This bug has been fixed. -	 -	int a; -	int i; -	char buffer1[1000]; -	char buffer2[1000]; -	 -	memset(buffer1,0,sizeof(buffer1)); -	memset(buffer2,0,sizeof(buffer2)); -		 -	yaffs_StartUp(); -	 -	yaffs_mount("/boot"); -	 -	// Create a file of 2000 bytes. -	make_a_file("/boot/a",'X',2000); - -	a = yaffs_open("/boot/a",O_RDWR, S_IREAD | S_IWRITE); -	 -	// Write a short sequence to the file. -	// This will go into the cache. -	yaffs_lseek(a,0,SEEK_SET); -	yaffs_write(a,"abcdefghijklmnopqrstuvwxyz",20);  - -	// Read a short sequence from the file. -	// This will come from the cache. -	yaffs_lseek(a,0,SEEK_SET); -	yaffs_read(a,buffer1,30);  - -	// Read a page size sequence from the file. -	yaffs_lseek(a,0,SEEK_SET); -	yaffs_read(a,buffer2,512);  -	 -	printf("buffer 1 %s\n",buffer1); -	printf("buffer 2 %s\n",buffer2); -	 -	if(strncmp(buffer1,buffer2,20)) -	{ -		printf("Cache bypass bug detected!!!!!\n"); -	} -	 -	 -	return 1; -} - - -int free_space_check(void) -{ -	int f; -	 -		yaffs_StartUp(); -		yaffs_mount("/boot"); -	    fill_disk("/boot/",2); -	    f = yaffs_freespace("/boot"); -	     -	    printf("%d free when disk full\n",f);            -	    return 1; -} - -int truncate_test(void) -{ -	int a; -	int r; -	int i; -	int l; - -	char y[10]; - -	yaffs_StartUp(); -	yaffs_mount("/boot"); - -	yaffs_unlink("/boot/trunctest"); -	 -	a = yaffs_open("/boot/trunctest", O_CREAT | O_TRUNC | O_RDWR,  S_IREAD | S_IWRITE); -	 -	yaffs_write(a,"abcdefghijklmnopqrstuvwzyz",26); -	 -	yaffs_truncate(a,3); -	l= yaffs_lseek(a,0,SEEK_END); -	 -	printf("truncated length is %d\n",l); - -	yaffs_lseek(a,5,SEEK_SET); -	yaffs_write(a,"1",1); - -	yaffs_lseek(a,0,SEEK_SET); -	 -	r = yaffs_read(a,y,10); - -	printf("read %d bytes:",r); - -	for(i = 0; i < r; i++) printf("[%02X]",y[i]); - -	printf("\n"); - -	return 0; - -} - - - - - -void fill_disk_test(const char *mountpt) -{ -	int i; -	yaffs_StartUp(); -	 -	for(i = 0; i < 5; i++) -	{ -		yaffs_mount(mountpt); -		fill_disk_and_delete(mountpt,100,i+1); -		yaffs_unmount(mountpt); -	} -	 -} - - - -void lookup_test(const char *mountpt) -{ -	int i; -	int h; -	char a[100]; -	char b[100]; -	 - -	yaffs_DIR *d; -	yaffs_dirent *de; -	struct yaffs_stat s; -	char str[100]; - -	yaffs_StartUp(); -	 -	yaffs_mount(mountpt); -				 -	d = yaffs_opendir(mountpt); -	 -	if(!d) -	{ -		printf("opendir failed\n"); -	} -	else -	{ -		 -		for(i = 0; (de = yaffs_readdir(d)) != NULL; i++) -		{ -			printf("unlinking %s\n",de->d_name); -			yaffs_unlink(de->d_name); -		} -		 -		printf("%d files deleted\n",i); -	} -	 -	 -	for(i = 0; i < 2000; i++){ -	sprintf(a,"%s/%d",mountpt,i); -		h =  yaffs_open(a,O_CREAT | O_TRUNC | O_RDWR, 0); -		yaffs_close(h); -	} - -	yaffs_rewinddir(d); -	for(i = 0; (de = yaffs_readdir(d)) != NULL; i++) -	{ -		printf("%d  %s\n",i,de->d_name); -	}	 -	 -	printf("%d files listed\n\n\n",i); -	 -	yaffs_rewinddir(d); -	yaffs_readdir(d); -	yaffs_readdir(d); -	yaffs_readdir(d); -	 -	for(i = 0; i < 2000; i++){ -		sprintf(a,"%s/%d",mountpt,i); -		yaffs_unlink(a); -	} -	 -		 -	yaffs_unmount(mountpt); -	 -} - -void link_test(const char *mountpt) -{ -	int i; -	int h; -	char a[100]; -	char b[100]; -	char c[100]; -	 -	int  f0; -	int f1; -	int f2; -	int f3; -	sprintf(a,"%s/aaa",mountpt); -	sprintf(b,"%s/bbb",mountpt); -	sprintf(c,"%s/ccc",mountpt); -	 -	yaffs_StartUp(); -	 -	yaffs_mount(mountpt); -	 -	 -	h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -	for(i = 0; i < 100; i++) -		yaffs_write(h,a,100); -	 -	yaffs_close(h); -	 -	yaffs_unlink(b); -	yaffs_unlink(c); -	yaffs_link(a,b); -	yaffs_link(a,c); -	yaffs_unlink(b); -	yaffs_unlink(c); -	yaffs_unlink(a); -	 -	 -	yaffs_unmount(mountpt); -	yaffs_mount(mountpt); -	 -	printf("link test done\n");	 -	 -} - -void freespace_test(const char *mountpt) -{ -	int i; -	int h; -	char a[100]; -	char b[100]; -	 -	int  f0; -	int f1; -	int f2; -	int f3; -	sprintf(a,"%s/aaa",mountpt); -	 -	yaffs_StartUp(); -	 -	yaffs_mount(mountpt); -	 -	f0 = yaffs_freespace(mountpt); -	 -	h = yaffs_open(a, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -	 -	for(i = 0; i < 100; i++) -		yaffs_write(h,a,100); -	 -	yaffs_close(h); -	 -	f1 = yaffs_freespace(mountpt); -	 -	yaffs_unlink(a); -	 -	f2 = yaffs_freespace(mountpt); -	 -		 -	yaffs_unmount(mountpt); -	yaffs_mount(mountpt); -	 -	f3 = yaffs_freespace(mountpt); -	 -	printf("%d\n%d\n%d\n%d\n",f0, f1,f2,f3); -	 -	 -} - -void simple_rw_test(const char *mountpt) -{ -	int i; -	int h; -	char a[100]; -	 -	int x; -	int result; - -	sprintf(a,"%s/aaa",mountpt); -	 -	yaffs_StartUp(); -	 -	yaffs_mount(mountpt); -	 -	yaffs_unlink(a); -	 -	h = yaffs_open(a,O_CREAT| O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -	 -	for(i = 100000;i < 200000; i++){ -		result = yaffs_write(h,&i,sizeof(i)); -		 -		if(result != 4) -		{ -			printf("write error\n"); -			exit(1); -		} -	} -	 -	//yaffs_close(h); -	 -	// h = yaffs_open(a,O_RDWR, S_IREAD | S_IWRITE); -	 -	 -	yaffs_lseek(h,0,SEEK_SET); -	 -	for(i = 100000; i < 200000; i++){ -		result = yaffs_read(h,&x,sizeof(x)); -		 -		if(result != 4 || x != i){ -			printf("read error %d %x %x\n",i,result,x); -		} -	} -	 -	printf("Simple rw test passed\n"); -	 -	 -	 -} - - -void scan_deleted_files_test(const char *mountpt) -{ -	char fn[100]; -	char sub[100]; -	 -	const char *p; -	 -	int i; -	int j; -	int k; -	int h; -	 -	sprintf(sub,"%s/sdir",mountpt); -	yaffs_StartUp(); -	 -	for(j = 0; j < 10; j++) -	{ -		printf("\n\n>>>>>>> Run %d <<<<<<<<<<<<<\n\n",j); -		yaffs_mount(mountpt); -		yaffs_mkdir(sub,0); -		 -		 -		p = (j & 0) ? mountpt: sub; -	 -		for(i = 0; i < 100; i++) -		{ -		  sprintf(fn,"%s/%d",p,i);   -		   -		  if(i & 1) -		  { -			  h = yaffs_open(fn,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -			  for(k = 0; k < 1000; k++) -				  yaffs_write(h,fn,100); -			  yaffs_close(h); -		  } -		  else -		    	yaffs_mkdir(fn,0); -		} -		 -		for(i = 0; i < 10; i++) -		{ -		  sprintf(fn,"%s/%d",p,i);   -		  if(i & 1)  -		  	yaffs_unlink(fn); -		  else -		  	yaffs_rmdir(fn); -		   -		} -				 -		yaffs_unmount(mountpt); -	} -	 -	 -	 - -} - - -void write_10k(int h) -{ -   int i; -   const char *s="0123456789"; -   for(i = 0; i < 1000; i++) -     yaffs_write(h,s,10); - -} -void write_200k_file(const char *fn, const char *fdel, const char *fdel1) -{ -   int h1; -   int i; -   int offs; -    -   h1 = yaffs_open(fn, O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -    -   for(i = 0; i < 100000; i+= 10000) -   { -   	write_10k(h1); -   } -    -   offs = yaffs_lseek(h1,0,SEEK_CUR); -   if( offs != 100000) -   { -   	printf("Could not write file\n"); -   } -    -   yaffs_unlink(fdel); -   for(i = 0; i < 100000; i+= 10000) -   { -   	write_10k(h1); -   } -    -   offs = yaffs_lseek(h1,0,SEEK_CUR); -   if( offs != 200000) -   { -   	printf("Could not write file\n"); -   } -    -   yaffs_close(h1); -   yaffs_unlink(fdel1); -    -} - - -void verify_200k_file(const char *fn) -{ -   int h1; -   int i; -   char x[11]; -   const char *s="0123456789"; -   int errCount = 0; -    -   h1 = yaffs_open(fn, O_RDONLY, 0); -    -   for(i = 0; i < 200000 && errCount < 10; i+= 10) -   { -   	yaffs_read(h1,x,10); -	if(strncmp(x,s,10) != 0) -	{ -		printf("File %s verification failed at %d\n",fn,i); -		errCount++; -	} -   } -   if(errCount >= 10) -   	printf("Too many errors... aborted\n"); -       -   yaffs_close(h1);	    -	 -} - - -void check_resize_gc_bug(const char *mountpt) -{ - -	char a[30]; -	char b[30]; -	char c[30]; -	 -	int i; -	 -	sprintf(a,"%s/a",mountpt); -	sprintf(b,"%s/b",mountpt); -	sprintf(c,"%s/c",mountpt); -	 - -	 -	 -	yaffs_StartUp(); -	yaffs_mount(mountpt); -	yaffs_unlink(a); -	yaffs_unlink(b); -	 -	for(i = 0; i < 50; i++) -	{   -	   printf("A\n");write_200k_file(a,"",c); -	   printf("B\n");verify_200k_file(a); -	   printf("C\n");write_200k_file(b,a,c); -	   printf("D\n");verify_200k_file(b); -	   yaffs_unmount(mountpt); -	   yaffs_mount(mountpt); -	   printf("E\n");verify_200k_file(a); -	   printf("F\n");verify_200k_file(b); -	} -		 -} - - -void multi_mount_test(const char *mountpt,int nmounts) -{ - -	char a[30]; -	char b[30]; -	char c[30]; -	 -	int i; -	int j; -	 -	sprintf(a,"%s/a",mountpt); - -	yaffs_StartUp(); -	 -	for(i = 0; i < nmounts; i++){ -		int h0; -		int h1; -		int len0; -		int len1; -		 -		static char xx[1000]; -		 -		printf("############### Iteration %d   Start\n",i); -		if(1 || i == 0 || i == 5)  -			yaffs_mount(mountpt); - -		dump_directory_tree(mountpt); -		 -		 -		yaffs_mkdir(a,0); -		 -		sprintf(xx,"%s/0",a); -		h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); -		 -		sprintf(xx,"%s/1",a); -		h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); -		 -		for(j = 0; j < 200; j++){ -		   yaffs_write(h0,xx,1000); -		   yaffs_write(h1,xx,1000); -		} -		 -		len0 = yaffs_lseek(h0,0,SEEK_END); -		len1 = yaffs_lseek(h1,0,SEEK_END); -		 -		yaffs_lseek(h0,0,SEEK_SET); -		yaffs_lseek(h1,0,SEEK_SET); - -		for(j = 0; j < 200; j++){ -		   yaffs_read(h0,xx,1000); -		   yaffs_read(h1,xx,1000); -		} -		 -		 -		yaffs_truncate(h0,0); -		yaffs_close(h0); -		yaffs_close(h1); -		 -		printf("########### %d\n",i); -		dump_directory_tree(mountpt); - -		if(1 || i == 4 || i == nmounts -1) -			yaffs_unmount(mountpt); -	} -} - - -void small_mount_test(const char *mountpt,int nmounts) -{ - -	char a[30]; -	char b[30]; -	char c[30]; -	 -	int i; -	int j; - -	int h0; -	int h1; -	int len0; -	int len1; -	int nread; -	 -	sprintf(a,"%s/a",mountpt); - -	yaffs_StartUp(); -	 -	 -	 -	for(i = 0; i < nmounts; i++){ -		 -		static char xx[1000]; -		 -		printf("############### Iteration %d   Start\n",i); -		if(1 || i == 0 || i == 5)  -			yaffs_mount(mountpt); - -		dump_directory_tree(mountpt); -		 -		yaffs_mkdir(a,0); -		 -		sprintf(xx,"%s/0",a); -		if(i ==0){ -		 -			h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); -			for(j = 0; j < 130; j++) -				yaffs_write(h0,xx,1000); -			yaffs_close(h0); -		} -		 -		h0 = yaffs_open(xx,O_RDONLY,0); -		 -		sprintf(xx,"%s/1",a); -		h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); -		 -		while((nread = yaffs_read(h0,xx,1000)) > 0) -			yaffs_write(h1,xx,nread); -		 -		 -		len0 = yaffs_lseek(h0,0,SEEK_END); -		len1 = yaffs_lseek(h1,0,SEEK_END); -		 -		yaffs_lseek(h0,0,SEEK_SET); -		yaffs_lseek(h1,0,SEEK_SET); - -		for(j = 0; j < 200; j++){ -		   yaffs_read(h0,xx,1000); -		   yaffs_read(h1,xx,1000); -		} -		 -		yaffs_close(h0); -		yaffs_close(h1); -		 -		printf("########### %d\n",i); -		dump_directory_tree(mountpt); - -		if(1 || i == 4 || i == nmounts -1) -			yaffs_unmount(mountpt); -	} -} - - -int early_exit; - -void small_overwrite_test(const char *mountpt,int nmounts) -{ - -	char a[30]; -	char b[30]; -	char c[30]; -	 -	int i; -	int j; - -	int h0; -	int h1; -	int len0; -	int len1; -	int nread; -	 -	sprintf(a,"%s/a",mountpt); - -	yaffs_StartUp(); -	 -	 -	 -	for(i = 0; i < nmounts; i++){ -		 -		static char xx[8000]; -		 -		printf("############### Iteration %d   Start\n",i); -		if(1) -			yaffs_mount(mountpt); - -		dump_directory_tree(mountpt); -		 -		yaffs_mkdir(a,0); -		 -		sprintf(xx,"%s/0",a); -		h0 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); -		sprintf(xx,"%s/1",a); -		h1 = yaffs_open(xx, O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); -		 -		for(j = 0; j < 1000000; j+=1000){ -			yaffs_truncate(h0,j); -			yaffs_lseek(h0,j,SEEK_SET); -			yaffs_write(h0,xx,7000); -			yaffs_write(h1,xx,7000); -			 -			if(early_exit) -				exit(0); -		} -		 -		yaffs_close(h0); -		 -		printf("########### %d\n",i); -		dump_directory_tree(mountpt); - -		if(1) -			yaffs_unmount(mountpt); -	} -} - - -void yaffs_touch(const char *fn) -{ -	yaffs_chmod(fn, S_IREAD | S_IWRITE); -} - -void checkpoint_fill_test(const char *mountpt,int nmounts) -{ - -	char a[50]; -	char b[50]; -	char c[50]; -	 -	int i; -	int j; -	int h; -	 -	sprintf(a,"%s/a",mountpt); -	 - -	 -	 -	yaffs_StartUp(); -	 -	for(i = 0; i < nmounts; i++){ -		printf("############### Iteration %d   Start\n",i); -		yaffs_mount(mountpt); -		dump_directory_tree(mountpt); -		yaffs_mkdir(a,0); -		 -		sprintf(b,"%s/zz",a); -		 -		h = yaffs_open(b,O_CREAT | O_RDWR,S_IREAD |S_IWRITE); -		 -		 -		while(yaffs_write(h,c,50) == 50){} -		 -		yaffs_close(h); -		 -		for(j = 0; j < 2; j++){ -			printf("touch %d\n",j); -			yaffs_touch(b); -			yaffs_unmount(mountpt); -			yaffs_mount(mountpt); -		} - -		dump_directory_tree(mountpt);		 -		yaffs_unmount(mountpt); -	} -} - - -int make_file2(const char *name1, const char *name2,int syz) -{ - -	char xx[2500]; -	int i; -	int h1=-1,h2=-1; -	int n = 1; - - -	if(name1) -		h1 = yaffs_open(name1,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -	if(name2) -		h2 = yaffs_open(name2,O_CREAT | O_TRUNC | O_RDWR, S_IREAD | S_IWRITE); -	 -	while(syz > 0 && n > 0){ -		i = (syz > 2500) ? 2500 : syz; -		n = yaffs_write(h1,xx,i); -		n = yaffs_write(h2,xx,i); -		syz -= 500; -	} -	yaffs_close(h1); -	yaffs_close(h2); -	 -} - - -extern void SetCheckpointReservedBlocks(int n); - -void checkpoint_upgrade_test(const char *mountpt,int nmounts) -{ - -	char a[50]; -	char b[50]; -	char c[50]; -	char d[50]; -	 -	int i; -	int j; -	int h; -	 -	sprintf(a,"%s/a",mountpt); -	 - -	 -	 -	printf("Create start condition\n"); -	yaffs_StartUp(); -	SetCheckpointReservedBlocks(0); -	yaffs_mount(mountpt); -	yaffs_mkdir(a,0); -	sprintf(b,"%s/zz",a); -	sprintf(c,"%s/xx",a); -	make_file2(b,c,2000000); -	sprintf(d,"%s/aa",a); -	make_file2(d,NULL,500000000); -	dump_directory_tree(mountpt); -	 -	printf("Umount/mount attempt full\n"); -	yaffs_unmount(mountpt); -	 -	SetCheckpointReservedBlocks(10); -	yaffs_mount(mountpt); -	 -	printf("unlink small file\n"); -	yaffs_unlink(c); -	dump_directory_tree(mountpt); -		 -	printf("Umount/mount attempt\n"); -	yaffs_unmount(mountpt); -	yaffs_mount(mountpt); -	 -	for(j = 0; j < 500; j++){ -		printf("***** touch %d\n",j); -		dump_directory_tree(mountpt); -		yaffs_touch(b); -		yaffs_unmount(mountpt); -		yaffs_mount(mountpt); -	} - -	for(j = 0; j < 500; j++){ -		printf("***** touch %d\n",j); -		dump_directory_tree(mountpt); -		yaffs_touch(b); -		yaffs_unmount(mountpt); -		yaffs_mount(mountpt); -	} -} -	 -void huge_array_test(const char *mountpt,int n) -{ - -	char a[50]; - -	 -	int i; -	int j; -	int h; -	 -	int fnum; -	 -	sprintf(a,"mount point %s",mountpt); -	 - -	 -	yaffs_StartUp(); - -	yaffs_mount(mountpt); -	 -	while(n>0){ -		n--; -		fnum = 0; -		printf("\n\n START run\n\n"); -		while(yaffs_freespace(mountpt) > 25000000){ -			sprintf(a,"%s/file%d",mountpt,fnum); -			fnum++; -			printf("create file %s\n",a); -			create_file_of_size(a,10000000); -			printf("verifying file %s\n",a); -			verify_file_of_size(a,10000000); -		} -		 -		printf("\n\n verification/deletion\n\n"); -		 -		for(i = 0; i < fnum; i++){ -			sprintf(a,"%s/file%d",mountpt,i); -			printf("verifying file %s\n",a); -			verify_file_of_size(a,10000000); -			printf("deleting file %s\n",a); -			yaffs_unlink(a); -		} -		printf("\n\n done \n\n"); -			 -		    -	} -} - - -void random_write(int h) -{ -	static char buffer[12000]; -	int n; -	 -	n = random() & 0x1FFF; -	yaffs_write(h,buffer,n); -} - -void random_seek(int h) -{ -	int n; -	n = random() & 0xFFFFF; -	yaffs_lseek(h,n,SEEK_SET); -} - -void random_truncate(int h, char * name) -{ -	int n; -	int flen; -	n = random() & 0xFFFFF; -	flen = yaffs_lseek(h,0,SEEK_END); -	if(n > flen) -		n = flen / 2; -	yaffs_truncate(name,n); -	yaffs_lseek(h,n,SEEK_SET); -} - - -#define NSMALLFILES 10	 -void random_small_file_test(const char *mountpt,int iterations) -{ - -	char a[NSMALLFILES][50]; - -	 -	int i; -	int n; -	int j; -	int h[NSMALLFILES]; -	int r; -	int fnum; -	 -	 -	yaffs_StartUp(); - -	yaffs_mount(mountpt); -	 -	for(i = 0; i < NSMALLFILES; i++){ -		h[i]=-1; -		strcpy(a[i],""); -	} -	 -	for(n = 0; n < iterations; n++){ -				 -		for(i = 0; i < NSMALLFILES; i++) { -			r = random(); -			 -			if(strlen(a[i]) == 0){ -				sprintf(a[i],"%s/%dx%d",mountpt,n,i); -				h[i] = yaffs_open(a,O_RDWR | O_CREAT | O_TRUNC, S_IREAD | S_IWRITE); -			} -			 -			if(h[i] < -1) -				printf("Could not open yaffs file %d %d error %d\n",n,i,h[i]); -			else { -				r = r & 7; -				switch(r){ -					case 0: -					case 1: -					case 2: -						random_write(h[i]); -						break; -					case 3: -						random_truncate(h[i],a[i]); -						break; -					case 4: -					case 5:	random_seek(h[i]); -						break; -					case 6: -						yaffs_close(h[i]); -						h[i] = -1; -						break; -					case 7: -						yaffs_close(h[i]); -						yaffs_unlink(a[i]); -						strcpy(a[i],""); -						h[i] = -1; -				} -			} -		} -		    -	} -	 -	for(i = 0; i < NSMALLFILES; i++) -		yaffs_close(h[i]); -		 -	yaffs_unmount(mountpt); -} -	 - - -int main(int argc, char *argv[]) -{ -	//return long_test(argc,argv); -	 -	//return cache_read_test(); -	 -	resize_stress_test_no_grow("/flash/flash",20); -	 -	//huge_directory_test_on_path("/ram2k"); -	 -	 //yaffs_backward_scan_test("/flash/flash"); -	// yaffs_device_flush_test("/flash/flash"); - -	  -	 //scan_pattern_test("/flash",10000,10); -	//short_scan_test("/flash/flash",40000,200); -	  //small_mount_test("/flash/flash",1000); -	  //small_overwrite_test("/flash/flash",1000); -	  //checkpoint_fill_test("/flash/flash",20); -	// random_small_file_test("/flash/flash",10000); -	 // huge_array_test("/flash/flash",10); - - - -	 -	//long_test_on_path("/ram2k"); -	// long_test_on_path("/flash"); -	//simple_rw_test("/flash/flash"); -	//fill_disk_test("/flash/flash"); -	// rename_over_test("/flash"); -	//lookup_test("/flash"); -	//freespace_test("/flash/flash"); -	 -	//link_test("/flash/flash"); -	 -	 -	 -	 -	// cache_bypass_bug_test(); -	 -	 //free_space_check(); -	  -	 //check_resize_gc_bug("/flash"); -	  -	 return 0; -	 -} diff --git a/fs/yaffs2/direct/fsx_test/Makefile b/fs/yaffs2/direct/fsx_test/Makefile deleted file mode 100644 index 192786542..000000000 --- a/fs/yaffs2/direct/fsx_test/Makefile +++ /dev/null @@ -1,75 +0,0 @@ -# Makefile for YAFFS direct test -# -# -# YAFFS: Yet another Flash File System. A NAND-flash specific file system. -# -# Copyright (C) 2003 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.1 2007/10/16 00:46:33 charles Exp $ - -#EXTRA_COMPILE_FLAGS = -DYAFFS_IGNORE_TAGS_ECC - -CFLAGS =    -Wall -DCONFIG_YAFFS_DIRECT -DCONFIG_YAFFS_SHORT_NAMES_IN_RAM -DCONFIG_YAFFS_YAFFS2 -g $(EXTRA_COMPILE_FLAGS) -DNO_Y_INLINE -CFLAGS+=    -fstack-check -O0 - -#CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations -#CFLAGS+=   -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline - - -FSXTESTOBJS = yaffs_fsx.o yaffscfg2k.o yaffs_ecc.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_tagsvalidity.o yaffs_nand.o \ -		 yaffs_checkptrw.o  yaffs_qsort.o \ -#		 yaffs_checkptrwtest.o\ -		  - -BOOTTESTOBJS = bootldtst.o yboot.o yaffs_fileem.o nand_ecc.o - -#ALLOBJS =  dtest.o nand_ecc.o yaffscfg.o yaffs_fileem.o yaffsfs.o yaffs_ramdisk.o bootldtst.o yboot.o yaffs_ramem2k.o - -ALLOBJS = $(FSXTESTOBJS) $(BOOTTESTOBJS) - -YAFFSSYMLINKS = devextras.h yaffs_ecc.c yaffs_ecc.h yaffs_guts.c yaffs_guts.h yaffsinterface.h yportenv.h yaffs_tagscompat.c yaffs_tagscompat.h \ -          yaffs_packedtags1.c yaffs_packedtags1.h yaffs_packedtags2.c yaffs_packedtags2.h  yaffs_nandemul2k.h \ -          yaffs_nand.c yaffs_nand.h \ -          yaffs_tagsvalidity.c yaffs_tagsvalidity.h yaffs_checkptrw.h yaffs_checkptrw.c \ -          yaffs_qsort.c yaffs_qsort.h - -YAFFSDIRECTSYMLINKS =  yaffscfg2k.c yaffs_fileem2k.c yaffsfs.c yaffs_flashif.h \ -		       yaffs_fileem2k.h yaffsfs.h yaffs_malloc.h yaffs_ramdisk.h ydirectenv.h \ -		       yaffscfg.h yaffs_fileem.c yaffs_flashif.c yaffs_ramdisk.c yaffs_ramem2k.c - - - -#all: fsxtest boottest - -all: fsxtest - -$(ALLOBJS): %.o: %.c -	gcc -c $(CFLAGS) $< -o $@ - -$(YAFFSSYMLINKS): -	ln -s ../../$@ $@ - -$(YAFFSDIRECTSYMLINKS): -	ln -s ../$@ $@ - -fsxtest: $(YAFFSSYMLINKS) $(YAFFSDIRECTSYMLINKS) $(FSXTESTOBJS) -	gcc -o $@ $(FSXTESTOBJS) - - -boottest: $(SYMLINKS) $(BOOTTESTOBJS) -	gcc -o $@ $(BOOTTESTOBJS) - - -clean: -	rm -f $(ALLOBJS) core diff --git a/fs/yaffs2/direct/fsx_test/README b/fs/yaffs2/direct/fsx_test/README deleted file mode 100644 index 725ab0755..000000000 --- a/fs/yaffs2/direct/fsx_test/README +++ /dev/null @@ -1,7 +0,0 @@ -NB THis directory uses a hacked version of fsx.c which is released under -Apple Public Source License. - -From what I have been able to determine, it is legally OK to release a hacked -version for the purposes of testing. - -If anyone knows otherwise, please contact me: manningc2@actrix.gen.nz diff --git a/fs/yaffs2/direct/fsx_test/yaffs_fsx.c b/fs/yaffs2/direct/fsx_test/yaffs_fsx.c deleted file mode 100644 index 1e110b9b7..000000000 --- a/fs/yaffs2/direct/fsx_test/yaffs_fsx.c +++ /dev/null @@ -1,1007 +0,0 @@ -/* - * Copyright (c) 1998-2001 Apple Computer, Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * The contents of this file constitute Original Code as defined in and - * are subject to the Apple Public Source License Version 1.2 (the - * "License").  You may not use this file except in compliance with the - * License.  Please obtain a copy of the License at - * http://www.apple.com/publicsource and read it before using this file. - * - * This Original Code and all software distributed under the License are - * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the - * License for the specific language governing rights and limitations - * under the License. - * - * @APPLE_LICENSE_HEADER_END@ - * - *	WARNING--WARNING--WARNING - *	This is not the original fsx.c. It has been modified to run with - *      yaffs direct. Seek out the original fsx.c if you want to do anything - *	else. - * - *	 - * - *	File:	fsx.c - *	Author:	Avadis Tevanian, Jr. - * - *	File system exerciser.  - * - *	Rewrite and enhancements 1998-2001 Conrad Minshall -- conrad@mac.com - * - *	Various features from Joe Sokol, Pat Dirks, and Clark Warner. - * - *	Small changes to work under Linux -- davej@suse.de - * - *	Sundry porting patches from Guy Harris 12/2001 - * - *	Checks for mmap last-page zero fill. - * - *	Modified heavily by Charles Manning to exercise via the - *	yaffs direct interface. - * - */ - -#include <sys/types.h> -#include <sys/stat.h> -#ifdef _UWIN -# include <sys/param.h> -# include <limits.h> -# include <time.h> -# include <strings.h> -#endif -#include <fcntl.h> -#include <sys/mman.h> -#ifndef MAP_FILE -# define MAP_FILE 0 -#endif -#include <limits.h> -#include <signal.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> -#include <stdarg.h> -#include <errno.h> - -#include "yaffsfs.h" - -#define NUMPRINTCOLUMNS 32	/* # columns of data to print on each line */ - -/* - *	A log entry is an operation and a bunch of arguments. - */ - -struct log_entry { -	int	operation; -	int	args[3]; -}; - -#define	LOGSIZE	1000 - -struct log_entry	oplog[LOGSIZE];	/* the log */ -int			logptr = 0;	/* current position in log */ -int			logcount = 0;	/* total ops */ - -/* - *	Define operations - */ - -#define	OP_READ		1 -#define OP_WRITE	2 -#define OP_TRUNCATE	3 -#define OP_CLOSEOPEN	4 -#define OP_MAPREAD	5 -#define OP_MAPWRITE	6 -#define OP_SKIPPED	7 - -int page_size; -int page_mask; - -char	*original_buf;			/* a pointer to the original data */ -char	*good_buf;			/* a pointer to the correct data */ -char	*temp_buf;			/* a pointer to the current data */ -char	*fname;				/* name of our test file */ -int	fd;				/* fd for our test file */ - -off_t		file_size = 0; -off_t		biggest = 0; -char		state[256]; -unsigned long	testcalls = 0;		/* calls to function "test" */ - -unsigned long	simulatedopcount = 0;	/* -b flag */ -int	closeprob = 0;			/* -c flag */ -int	debug = 0;			/* -d flag */ -unsigned long	debugstart = 0;		/* -D flag */ -unsigned long	maxfilelen = 256 * 1024;	/* -l flag */ -int	sizechecks = 1;			/* -n flag disables them */ -int	maxoplen = 64 * 1024;		/* -o flag */ -int	quiet = 0;			/* -q flag */ -unsigned long progressinterval = 0;	/* -p flag */ -int	readbdy = 1;			/* -r flag */ -int	style = 0;			/* -s flag */ -int	truncbdy = 1;			/* -t flag */ -int	writebdy = 1;			/* -w flag */ -long	monitorstart = -1;		/* -m flag */ -long	monitorend = -1;		/* -m flag */ -int	lite = 0;			/* -L flag */ -long	numops = -1;			/* -N flag */ -int	randomoplen = 1;		/* -O flag disables it */ -int	seed = 1;			/* -S flag */ - -int     mapped_writes = 0;	      /* yaffs direct does not support mmapped files */ -int 	mapped_reads = 0; - -int	fsxgoodfd = 0; -FILE *	fsxlogf = NULL; -int badoff = -1; -int closeopen = 0; - - -void -vwarnc(code, fmt, ap) -	int code; -	const char *fmt; -	va_list ap; -{ -	fprintf(stderr, "fsx: "); -	if (fmt != NULL) { -		vfprintf(stderr, fmt, ap); -		fprintf(stderr, ": "); -	} -	fprintf(stderr, "%s\n", strerror(code)); -} - - -void -warn(const char * fmt, ...) -{ -	va_list ap; -	va_start(ap, fmt); -	vwarnc(errno, fmt, ap); -	va_end(ap); -} - - -void -prt(char *fmt, ...) -{ -	va_list args; - -	va_start(args, fmt); -	vfprintf(stdout, fmt, args); -	if (fsxlogf) -		vfprintf(fsxlogf, fmt, args); -	va_end(args); -} - -void -prterr(char *prefix) -{ -	prt("%s%s%s\n", prefix, prefix ? ": " : "", strerror(errno)); -} - - -void -log4(int operation, int arg0, int arg1, int arg2) -{ -	struct log_entry *le; - -	le = &oplog[logptr]; -	le->operation = operation; -	if (closeopen) -		le->operation = ~ le->operation; -	le->args[0] = arg0; -	le->args[1] = arg1; -	le->args[2] = arg2; -	logptr++; -	logcount++; -	if (logptr >= LOGSIZE) -		logptr = 0; -} - - -void -logdump(void) -{ -	int	i, count, down; -	struct log_entry	*lp; - -	prt("LOG DUMP (%d total operations):\n", logcount); -	if (logcount < LOGSIZE) { -		i = 0; -		count = logcount; -	} else { -		i = logptr; -		count = LOGSIZE; -	} -	for ( ; count > 0; count--) { -		int opnum; - -		opnum = i+1 + (logcount/LOGSIZE)*LOGSIZE; -		prt("%d(%d mod 256): ", opnum, opnum%256); -		lp = &oplog[i]; -		if ((closeopen = lp->operation < 0)) -			lp->operation = ~ lp->operation; -			 -		switch (lp->operation) { -		case OP_MAPREAD: -			prt("MAPREAD\t0x%x thru 0x%x\t(0x%x bytes)", -			    lp->args[0], lp->args[0] + lp->args[1] - 1, -			    lp->args[1]); -			if (badoff >= lp->args[0] && badoff < -						     lp->args[0] + lp->args[1]) -				prt("\t***RRRR***"); -			break; -		case OP_MAPWRITE: -			prt("MAPWRITE 0x%x thru 0x%x\t(0x%x bytes)", -			    lp->args[0], lp->args[0] + lp->args[1] - 1, -			    lp->args[1]); -			if (badoff >= lp->args[0] && badoff < -						     lp->args[0] + lp->args[1]) -				prt("\t******WWWW"); -			break; -		case OP_READ: -			prt("READ\t0x%x thru 0x%x\t(0x%x bytes)", -			    lp->args[0], lp->args[0] + lp->args[1] - 1, -			    lp->args[1]); -			if (badoff >= lp->args[0] && -			    badoff < lp->args[0] + lp->args[1]) -				prt("\t***RRRR***"); -			break; -		case OP_WRITE: -			prt("WRITE\t0x%x thru 0x%x\t(0x%x bytes)", -			    lp->args[0], lp->args[0] + lp->args[1] - 1, -			    lp->args[1]); -			if (lp->args[0] > lp->args[2]) -				prt(" HOLE"); -			else if (lp->args[0] + lp->args[1] > lp->args[2]) -				prt(" EXTEND"); -			if ((badoff >= lp->args[0] || badoff >=lp->args[2]) && -			    badoff < lp->args[0] + lp->args[1]) -				prt("\t***WWWW"); -			break; -		case OP_TRUNCATE: -			down = lp->args[0] < lp->args[1]; -			prt("TRUNCATE %s\tfrom 0x%x to 0x%x", -			    down ? "DOWN" : "UP", lp->args[1], lp->args[0]); -			if (badoff >= lp->args[!down] && -			    badoff < lp->args[!!down]) -				prt("\t******WWWW"); -			break; -		case OP_SKIPPED: -			prt("SKIPPED (no operation)"); -			break; -		default: -			prt("BOGUS LOG ENTRY (operation code = %d)!", -			    lp->operation); -		} -		if (closeopen) -			prt("\n\t\tCLOSE/OPEN"); -		prt("\n"); -		i++; -		if (i == LOGSIZE) -			i = 0; -	} -} - - -void -save_buffer(char *buffer, off_t bufferlength, int fd) -{ -	off_t ret; -	ssize_t byteswritten; - -	if (fd <= 0 || bufferlength == 0) -		return; - -	if (bufferlength > SSIZE_MAX) { -		prt("fsx flaw: overflow in save_buffer\n"); -		exit(67); -	} -	if (lite) { -		off_t size_by_seek = yaffs_lseek(fd, (off_t)0, SEEK_END); -		if (size_by_seek == (off_t)-1) -			prterr("save_buffer: lseek eof"); -		else if (bufferlength > size_by_seek) { -			warn("save_buffer: .fsxgood file too short... will save 0x%llx bytes instead of 0x%llx\n", (unsigned long long)size_by_seek, -			     (unsigned long long)bufferlength); -			bufferlength = size_by_seek; -		} -	} - -	ret = yaffs_lseek(fd, (off_t)0, SEEK_SET); -	if (ret == (off_t)-1) -		prterr("save_buffer: lseek 0"); -	 -	byteswritten = yaffs_write(fd, buffer, (size_t)bufferlength); -	if (byteswritten != bufferlength) { -		if (byteswritten == -1) -			prterr("save_buffer write"); -		else -			warn("save_buffer: short write, 0x%x bytes instead of 0x%llx\n", -			     (unsigned)byteswritten, -			     (unsigned long long)bufferlength); -	} -} - - -void -report_failure(int status) -{ -	logdump(); -	 -	if (fsxgoodfd) { -		if (good_buf) { -			save_buffer(good_buf, file_size, fsxgoodfd); -			prt("Correct content saved for comparison\n"); -			prt("(maybe hexdump \"%s\" vs \"%s.fsxgood\")\n", -			    fname, fname); -		} -		close(fsxgoodfd); -	} -	prt("Exiting with %d\n",status); -	exit(status); -} - - -#define short_at(cp) ((unsigned short)((*((unsigned char *)(cp)) << 8) | \ -					*(((unsigned char *)(cp)) + 1))) - -void -check_buffers(unsigned offset, unsigned size) -{ -	unsigned char c, t; -	unsigned i = 0; -	unsigned n = 0; -	unsigned op = 0; -	unsigned bad = 0; - -	if (memcmp(good_buf + offset, temp_buf, size) != 0) { -		prt("READ BAD DATA: offset = 0x%x, size = 0x%x\n", -		    offset, size); -		prt("OFFSET\tGOOD\tBAD\tRANGE\n"); -		while (size > 0) { -			c = good_buf[offset]; -			t = temp_buf[i]; -			if (c != t) { -				if (n == 0) { -					bad = short_at(&temp_buf[i]); -					prt("0x%5x\t0x%04x\t0x%04x", offset, -					    short_at(&good_buf[offset]), bad); -					op = temp_buf[offset & 1 ? i+1 : i]; -				} -				n++; -				badoff = offset; -			} -			offset++; -			i++; -			size--; -		} -		if (n) { -			prt("\t0x%5x\n", n); -			if (bad) -				prt("operation# (mod 256) for the bad data may be %u\n", ((unsigned)op & 0xff)); -			else -				prt("operation# (mod 256) for the bad data unknown, check HOLE and EXTEND ops\n"); -		} else -			prt("????????????????\n"); -		report_failure(110); -	} -} - - -void -check_size(void) -{ -	struct yaffs_stat	statbuf; -	off_t	size_by_seek; - -	if (yaffs_fstat(fd, &statbuf)) { -		prterr("check_size: fstat"); -		statbuf.st_size = -1; -	} -	size_by_seek = yaffs_lseek(fd, (off_t)0, SEEK_END); -	if (file_size != statbuf.st_size || file_size != size_by_seek) { -		prt("Size error: expected 0x%llx stat 0x%llx seek 0x%llx\n", -		    (unsigned long long)file_size, -		    (unsigned long long)statbuf.st_size, -		    (unsigned long long)size_by_seek); -		report_failure(120); -	} -} - - -void -check_trunc_hack(void) -{ -	struct yaffs_stat statbuf; - -	yaffs_truncate(fd, (off_t)0); -	yaffs_truncate(fd, (off_t)100000); -	yaffs_fstat(fd, &statbuf); -	if (statbuf.st_size != (off_t)100000) { -		prt("no extend on truncate! not posix!\n"); -		exit(130); -	} -	yaffs_truncate(fd, (off_t)0); -} - - -void -doread(unsigned offset, unsigned size) -{ -	off_t ret; -	unsigned iret; - -	offset -= offset % readbdy; -	if (size == 0) { -		if (!quiet && testcalls > simulatedopcount) -			prt("skipping zero size read\n"); -		log4(OP_SKIPPED, OP_READ, offset, size); -		return; -	} -	if (size + offset > file_size) { -		if (!quiet && testcalls > simulatedopcount) -			prt("skipping seek/read past end of file\n"); -		log4(OP_SKIPPED, OP_READ, offset, size); -		return; -	} - -	log4(OP_READ, offset, size, 0); - -	if (testcalls <= simulatedopcount) -		return; - -	if (!quiet && ((progressinterval && -			testcalls % progressinterval == 0) || -		       (debug && -			(monitorstart == -1 || -			 (offset + size > monitorstart && -			  (monitorend == -1 || offset <= monitorend)))))) -		prt("%lu read\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls, -		    offset, offset + size - 1, size); -	ret = yaffs_lseek(fd, (off_t)offset, SEEK_SET); -	if (ret == (off_t)-1) { -		prterr("doread: lseek"); -		report_failure(140); -	} -	iret = yaffs_read(fd, temp_buf, size); -	if (iret != size) { -		if (iret == -1) -			prterr("doread: read"); -		else -			prt("short read: 0x%x bytes instead of 0x%x\n", -			    iret, size); -		report_failure(141); -	} -	check_buffers(offset, size); -} - - - - - -void -gendata(char *original_buf, char *good_buf, unsigned offset, unsigned size) -{ -	while (size--) { -		good_buf[offset] = testcalls % 256;  -		if (offset % 2) -			good_buf[offset] += original_buf[offset]; -		offset++; -	} -} - - -void -dowrite(unsigned offset, unsigned size) -{ -	off_t ret; -	unsigned iret; - -	offset -= offset % writebdy; -	if (size == 0) { -		if (!quiet && testcalls > simulatedopcount) -			prt("skipping zero size write\n"); -		log4(OP_SKIPPED, OP_WRITE, offset, size); -		return; -	} - -	log4(OP_WRITE, offset, size, file_size); - -	gendata(original_buf, good_buf, offset, size); -	if (file_size < offset + size) { -		if (file_size < offset) -			memset(good_buf + file_size, '\0', offset - file_size); -		file_size = offset + size; -		if (lite) { -			warn("Lite file size bug in fsx!"); -			report_failure(149); -		} -	} - -	if (testcalls <= simulatedopcount) -		return; - -	if (!quiet && ((progressinterval && -			testcalls % progressinterval == 0) || -		       (debug && -			(monitorstart == -1 || -			 (offset + size > monitorstart && -			  (monitorend == -1 || offset <= monitorend)))))) -		prt("%lu write\t0x%x thru\t0x%x\t(0x%x bytes)\n", testcalls, -		    offset, offset + size - 1, size); -	ret = yaffs_lseek(fd, (off_t)offset, SEEK_SET); -	if (ret == (off_t)-1) { -		prterr("dowrite: lseek"); -		report_failure(150); -	} -	iret = yaffs_write(fd, good_buf + offset, size); -	if (iret != size) { -		if (iret == -1) -			prterr("dowrite: write"); -		else -			prt("short write: 0x%x bytes instead of 0x%x\n", -			    iret, size); -		report_failure(151); -	} -} - - - -void -dotruncate(unsigned size) -{ -	int oldsize = file_size; - -	size -= size % truncbdy; -	if (size > biggest) { -		biggest = size; -		if (!quiet && testcalls > simulatedopcount) -			prt("truncating to largest ever: 0x%x\n", size); -	} - -	log4(OP_TRUNCATE, size, (unsigned)file_size, 0); - -	if (size > file_size) -		memset(good_buf + file_size, '\0', size - file_size); -	file_size = size; - -	if (testcalls <= simulatedopcount) -		return; -	 -	if ((progressinterval && testcalls % progressinterval == 0) || -	    (debug && (monitorstart == -1 || monitorend == -1 || -		       size <= monitorend))) -		prt("%lu trunc\tfrom 0x%x to 0x%x\n", testcalls, oldsize, size); -	if (yaffs_truncate(fd, (off_t)size) == -1) { -		prt("ftruncate1: %x\n", size); -		prterr("dotruncate: ftruncate"); -		report_failure(160); -	} -} - - -void -writefileimage() -{ -	ssize_t iret; - -	if (yaffs_lseek(fd, (off_t)0, SEEK_SET) == (off_t)-1) { -		prterr("writefileimage: lseek"); -		report_failure(171); -	} -	iret = yaffs_write(fd, good_buf, file_size); -	if ((off_t)iret != file_size) { -		if (iret == -1) -			prterr("writefileimage: write"); -		else -			prt("short write: 0x%x bytes instead of 0x%llx\n", -			    iret, (unsigned long long)file_size); -		report_failure(172); -	} -	if (lite ? 0 : yaffs_truncate(fd, file_size) == -1) { -		prt("ftruncate2: %llx\n", (unsigned long long)file_size); -		prterr("writefileimage: ftruncate"); -		report_failure(173); -	} -} - - -void -docloseopen(void) -{  -	if (testcalls <= simulatedopcount) -		return; - -	if (debug) -		prt("%lu close/open\n", testcalls); -	if (yaffs_close(fd)) { -		prterr("docloseopen: close"); -		report_failure(180); -	} -	fd = yaffs_open(fname, O_RDWR, 0); -	if (fd < 0) { -		prterr("docloseopen: open"); -		report_failure(181); -	} -} - - -void -test(void) -{ -	unsigned long	offset; -	unsigned long	size = maxoplen; -	unsigned long	rv = random(); -	unsigned long	op = rv % (3 + !lite + mapped_writes); - -	/* turn off the map read if necessary */ - -	if (op == 2 && !mapped_reads) -	    op = 0; - -	if (simulatedopcount > 0 && testcalls == simulatedopcount) -		writefileimage(); - -	testcalls++; - -	if (closeprob) -		closeopen = (rv >> 3) < (1 << 28) / closeprob; - -	if (debugstart > 0 && testcalls >= debugstart) -		debug = 1; - -	if (!quiet && testcalls < simulatedopcount && testcalls % 100000 == 0) -		prt("%lu...\n", testcalls); - -	/* -	 * READ:	op = 0 -	 * WRITE:	op = 1 -	 * MAPREAD:     op = 2 -	 * TRUNCATE:	op = 3 -	 * MAPWRITE:    op = 3 or 4 -	 */ -	if (lite ? 0 : op == 3 && (style & 1) == 0) /* vanilla truncate? */ -		dotruncate(random() % maxfilelen); -	else { -		if (randomoplen) -			size = random() % (maxoplen+1); -		if (lite ? 0 : op == 3) -			dotruncate(size); -		else { -			offset = random(); -			if (op == 1 || op == (lite ? 3 : 4)) { -				offset %= maxfilelen; -				if (offset + size > maxfilelen) -					size = maxfilelen - offset; -				dowrite(offset, size); -			} else { -				if (file_size) -					offset %= file_size; -				else -					offset = 0; -				if (offset + size > file_size) -					size = file_size - offset; -				doread(offset, size); -			} -		} -	} -	if (sizechecks && testcalls > simulatedopcount) -		check_size(); -	if (closeopen) -		docloseopen(); -} - - -void -cleanup(sig) -	int	sig; -{ -	if (sig) -		prt("signal %d\n", sig); -	prt("testcalls = %lu\n", testcalls); -	exit(sig); -} - - -void -usage(void) -{ -	fprintf(stdout, "usage: %s", -		"fsx [-dnqLOW] [-b opnum] [-c Prob] [-l flen] [-m start:end] [-o oplen] [-p progressinterval] [-r readbdy] [-s style] [-t truncbdy] [-w writebdy] [-D startingop] [-N numops] [-P dirpath] [-S seed] fname\n\ -	-b opnum: beginning operation number (default 1)\n\ -	-c P: 1 in P chance of file close+open at each op (default infinity)\n\ -	-d: debug output for all operations\n\ -	-l flen: the upper bound on file size (default 262144)\n\ -	-m startop:endop: monitor (print debug output) specified byte range (default 0:infinity)\n\ -	-n: no verifications of file size\n\ -	-o oplen: the upper bound on operation size (default 65536)\n\ -	-p progressinterval: debug output at specified operation interval\n\ -	-q: quieter operation\n\ -	-r readbdy: 4096 would make reads page aligned (default 1)\n\ -	-s style: 1 gives smaller truncates (default 0)\n\ -	-t truncbdy: 4096 would make truncates page aligned (default 1)\n\ -	-w writebdy: 4096 would make writes page aligned (default 1)\n\ -	-D startingop: debug output starting at specified operation\n\ -	-L: fsxLite - no file creations & no file size changes\n\ -	-N numops: total # operations to do (default infinity)\n\ -	-O: use oplen (see -o flag) for every op (default random)\n\ -	-P dirpath: save .fsxlog and .fsxgood files in dirpath (default ./)\n\ -	-S seed: for random # generator (default 1) 0 gets timestamp\n\ -	fname: this filename is REQUIRED (no default)\n"); -	exit(90); -} - - -int -getnum(char *s, char **e) -{ -	int ret = -1; - -	*e = (char *) 0; -	ret = strtol(s, e, 0); -	if (*e) -		switch (**e) { -		case 'b': -		case 'B': -			ret *= 512; -			*e = *e + 1; -			break; -		case 'k': -		case 'K': -			ret *= 1024; -			*e = *e + 1; -			break; -		case 'm': -		case 'M': -			ret *= 1024*1024; -			*e = *e + 1; -			break; -		case 'w': -		case 'W': -			ret *= 4; -			*e = *e + 1; -			break; -		} -	return (ret); -} - - -int -main(int argc, char **argv) -{ -	int	i, style, ch; -	char	*endp; -	char goodfile[1024]; -	char logfile[1024]; - -	goodfile[0] = 0; -	logfile[0] = 0; - -	page_size = getpagesize(); -	page_mask = page_size - 1; - -	setvbuf(stdout, (char *)0, _IOLBF, 0); /* line buffered stdout */ - -	while ((ch = getopt(argc, argv, "b:c:dl:m:no:p:qr:s:t:w:D:LN:OP:RS:W")) -	       != EOF) -		switch (ch) { -		case 'b': -			simulatedopcount = getnum(optarg, &endp); -			if (!quiet) -				fprintf(stdout, "Will begin at operation %ld\n", -					simulatedopcount); -			if (simulatedopcount == 0) -				usage(); -			simulatedopcount -= 1; -			break; -		case 'c': -			closeprob = getnum(optarg, &endp); -			if (!quiet) -				fprintf(stdout, -					"Chance of close/open is 1 in %d\n", -					closeprob); -			if (closeprob <= 0) -				usage(); -			break; -		case 'd': -			debug = 1; -			break; -		case 'l': -			maxfilelen = getnum(optarg, &endp); -			if (maxfilelen <= 0) -				usage(); -			break; -		case 'm': -			monitorstart = getnum(optarg, &endp); -			if (monitorstart < 0) -				usage(); -			if (!endp || *endp++ != ':') -				usage(); -			monitorend = getnum(endp, &endp); -			if (monitorend < 0) -				usage(); -			if (monitorend == 0) -				monitorend = -1; /* aka infinity */ -			debug = 1; -		case 'n': -			sizechecks = 0; -			break; -		case 'o': -			maxoplen = getnum(optarg, &endp); -			if (maxoplen <= 0) -				usage(); -			break; -		case 'p': -			progressinterval = getnum(optarg, &endp); -			if (progressinterval < 0) -				usage(); -			break; -		case 'q': -			quiet = 1; -			break; -		case 'r': -			readbdy = getnum(optarg, &endp); -			if (readbdy <= 0) -				usage(); -			break; -		case 's': -			style = getnum(optarg, &endp); -			if (style < 0 || style > 1) -				usage(); -			break; -		case 't': -			truncbdy = getnum(optarg, &endp); -			if (truncbdy <= 0) -				usage(); -			break; -		case 'w': -			writebdy = getnum(optarg, &endp); -			if (writebdy <= 0) -				usage(); -			break; -		case 'D': -			debugstart = getnum(optarg, &endp); -			if (debugstart < 1) -				usage(); -			break; -		case 'L': -			lite = 1; -			break; -		case 'N': -			numops = getnum(optarg, &endp); -			if (numops < 0) -				usage(); -			break; -		case 'O': -			randomoplen = 0; -			break; -		case 'P': -			strncpy(goodfile, optarg, sizeof(goodfile)); -			strcat(goodfile, "/"); -			strncpy(logfile, optarg, sizeof(logfile)); -			strcat(logfile, "/"); -			break; -		case 'R': -			mapped_reads = 0; -			break; -		case 'S': -			seed = getnum(optarg, &endp); -			if (seed == 0) -				seed = time(0) % 10000; -			if (!quiet) -				fprintf(stdout, "Seed set to %d\n", seed); -			if (seed < 0) -				usage(); -			break; -		case 'W': -			mapped_writes = 0; -			if (!quiet) -				fprintf(stdout, "mapped writes DISABLED\n"); -			break; - -		default: -			usage(); -			/* NOTREACHED */ -		} -	argc -= optind; -	argv += optind; - -	yaffs_StartUp(); -	yaffs_mount("/flash/flash"); -	 -	fname = "/flash/flash/fsxdata"; - -	signal(SIGHUP,	cleanup); -	signal(SIGINT,	cleanup); -	signal(SIGPIPE,	cleanup); -	signal(SIGALRM,	cleanup); -	signal(SIGTERM,	cleanup); -	signal(SIGXCPU,	cleanup); -	signal(SIGXFSZ,	cleanup); -	signal(SIGVTALRM,	cleanup); -	signal(SIGUSR1,	cleanup); -	signal(SIGUSR2,	cleanup); - -	initstate(seed, state, 256); -	setstate(state); -	fd = yaffs_open(fname, O_RDWR|(lite ? 0 : O_CREAT|O_TRUNC), 0666); -	if (fd < 0) { -		prterr(fname); -		exit(91); -	} -	strncat(goodfile, fname, 256); -	strcat (goodfile, ".fsxgood"); -	fsxgoodfd = yaffs_open(goodfile, O_RDWR|O_CREAT|O_TRUNC, 0666); -	if (fsxgoodfd < 0) { -		prterr(goodfile); -		exit(92); -	} -	strncat(logfile, "fsx", 256); -	strcat (logfile, ".fsxlog"); -	fsxlogf = fopen(logfile, "w"); -	if (fsxlogf == NULL) { -		prterr(logfile); -		exit(93); -	} -	if (lite) { -		off_t ret; -		file_size = maxfilelen = yaffs_lseek(fd, (off_t)0, SEEK_END); -		if (file_size == (off_t)-1) { -			prterr(fname); -			warn("main: lseek eof"); -			exit(94); -		} -		ret = yaffs_lseek(fd, (off_t)0, SEEK_SET); -		if (ret == (off_t)-1) { -			prterr(fname); -			warn("main: lseek 0"); -			exit(95); -		} -	} -	original_buf = (char *) malloc(maxfilelen); -	for (i = 0; i < maxfilelen; i++) -		original_buf[i] = random() % 256; -	good_buf = (char *) malloc(maxfilelen); -	memset(good_buf, '\0', maxfilelen); -	temp_buf = (char *) malloc(maxoplen); -	memset(temp_buf, '\0', maxoplen); -	if (lite) {	/* zero entire existing file */ -		ssize_t written; - -		written = yaffs_write(fd, good_buf, (size_t)maxfilelen); -		if (written != maxfilelen) { -			if (written == -1) { -				prterr(fname); -				warn("main: error on write"); -			} else -				warn("main: short write, 0x%x bytes instead of 0x%x\n", -				     (unsigned)written, maxfilelen); -			exit(98); -		} -	} else  -		check_trunc_hack(); - -	while (numops == -1 || numops--) -		test(); - -	if (yaffs_close(fd)) { -		prterr("close"); -		report_failure(99); -	} -	 -	yaffs_close(fsxgoodfd); -	 -	yaffs_unmount("flash/flash"); -	prt("All operations completed A-OK!\n"); - -	exit(0); -	return 0; -} - diff --git a/fs/yaffs2/direct/yaffs_fileem.c b/fs/yaffs2/direct/yaffs_fileem.c deleted file mode 100644 index 5779d7ebc..000000000 --- a/fs/yaffs2/direct/yaffs_fileem.c +++ /dev/null @@ -1,219 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* - * This provides a YAFFS nand emulation on a file. - * This is only intended as test code to test persistence etc. - */ - -/* XXX U-BOOT XXX */ -#include <common.h> - -const char *yaffs_flashif_c_version = "$Id: yaffs_fileem.c,v 1.3 2007/02/14 01:09:06 wookey Exp $"; - - -#include "yportenv.h" - -#include "yaffs_flashif.h" -#include "yaffs_guts.h" - -#include "devextras.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h>  - - - -#define SIZE_IN_MB 16 - -#define BLOCK_SIZE (32 * 528) -#define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) - - - -typedef struct  -{ -	__u8 data[528]; // Data + spare -} yflash_Page; - -typedef struct -{ -	yflash_Page page[32]; // The pages in the block -	 -} yflash_Block; - - - -typedef struct -{ -	int handle; -	int nBlocks; -} yflash_Device; - -static yflash_Device filedisk; - -static int  CheckInit(yaffs_Device *dev) -{ -	static int initialised = 0; -	 -	int i; - -	 -	int fSize; -	int written; -	 -	yflash_Page p; -	 -	if(initialised)  -	{ -		return YAFFS_OK; -	} - -	initialised = 1; -	 -	 -	filedisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024); -	 -	filedisk.handle = open("yaffsemfile", O_RDWR | O_CREAT, S_IREAD | S_IWRITE); -	 -	if(filedisk.handle < 0) -	{ -		perror("Failed to open yaffs emulation file"); -		return YAFFS_FAIL; -	} -	 -	 -	fSize = lseek(filedisk.handle,0,SEEK_END); -	 -	if(fSize < SIZE_IN_MB * 1024 * 1024) -	{ -		printf("Creating yaffs emulation file\n"); -		 -		lseek(filedisk.handle,0,SEEK_SET); -		 -		memset(&p,0xff,sizeof(yflash_Page)); -		 -		for(i = 0; i < SIZE_IN_MB * 1024 * 1024; i+= 512) -		{ -			written = write(filedisk.handle,&p,sizeof(yflash_Page)); -			 -			if(written != sizeof(yflash_Page)) -			{ -				printf("Write failed\n"); -				return YAFFS_FAIL; -			} -		}		 -	} -	 -	return 1; -} - -int yflash_WriteChunkToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, const yaffs_Spare *spare) -{ -	int written; - -	CheckInit(dev); -	 -	 -	 -	if(data) -	{ -		lseek(filedisk.handle,chunkInNAND * 528,SEEK_SET); -		written = write(filedisk.handle,data,512); -		 -		if(written != 512) return YAFFS_FAIL; -	} -	 -	if(spare) -	{ -		lseek(filedisk.handle,chunkInNAND * 528 + 512,SEEK_SET); -		written = write(filedisk.handle,spare,16); -		 -		if(written != 16) return YAFFS_FAIL; -	} -	 - -	return YAFFS_OK;	 - -} - - -int yflash_ReadChunkFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Spare *spare) -{ -	int nread; - -	CheckInit(dev); -	 -	 -	 -	if(data) -	{ -		lseek(filedisk.handle,chunkInNAND * 528,SEEK_SET); -		nread = read(filedisk.handle,data,512); -		 -		if(nread != 512) return YAFFS_FAIL; -	} -	 -	if(spare) -	{ -		lseek(filedisk.handle,chunkInNAND * 528 + 512,SEEK_SET); -		nread= read(filedisk.handle,spare,16); -		 -		if(nread != 16) return YAFFS_FAIL; -	} -	 - -	return YAFFS_OK;	 - -} - - -int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) -{ - -	int i; -		 -	CheckInit(dev); -	 -	if(blockNumber < 0 || blockNumber >= filedisk.nBlocks) -	{ -		T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber)); -		return YAFFS_FAIL; -	} -	else -	{ -	 -		yflash_Page pg; -		 -		memset(&pg,0xff,sizeof(yflash_Page)); -		 -		lseek(filedisk.handle, blockNumber * 32 * 528, SEEK_SET); -		 -		for(i = 0; i < 32; i++) -		{ -			write(filedisk.handle,&pg,528); -		} -		return YAFFS_OK; -	} -	 -} - -int yflash_InitialiseNAND(yaffs_Device *dev) -{ -	dev->useNANDECC = 1; // force on useNANDECC which gets faked.  -						 // This saves us doing ECC checks. -	 -	return YAFFS_OK; -} diff --git a/fs/yaffs2/direct/yaffs_fileem2k.c b/fs/yaffs2/direct/yaffs_fileem2k.c deleted file mode 100644 index 34a4e87b3..000000000 --- a/fs/yaffs2/direct/yaffs_fileem2k.c +++ /dev/null @@ -1,443 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* - * This provides a YAFFS nand emulation on a file for emulating 2kB pages. - * This is only intended as test code to test persistence etc. - */ - -/* XXX U-BOOT XXX */ -#include <common.h> - -const char *yaffs_flashif_c_version = "$Id: yaffs_fileem2k.c,v 1.12 2007/02/14 01:09:06 wookey Exp $"; - - -#include "yportenv.h" - -#include "yaffs_flashif.h" -#include "yaffs_guts.h" -#include "devextras.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h>  - -#include "yaffs_fileem2k.h" -#include "yaffs_packedtags2.h" - -//#define SIMULATE_FAILURES - -typedef struct  -{ -	__u8 data[PAGE_SIZE]; // Data + spare -} yflash_Page; - -typedef struct -{ -	yflash_Page page[PAGES_PER_BLOCK]; // The pages in the block -	 -} yflash_Block; - - - -#define MAX_HANDLES 20 -#define BLOCKS_PER_HANDLE 8000 - -typedef struct -{ -	int handle[MAX_HANDLES]; -	int nBlocks; -} yflash_Device; - -static yflash_Device filedisk; - -int yaffs_testPartialWrite = 0; - - - - -static __u8 localBuffer[PAGE_SIZE]; - -static char *NToName(char *buf,int n) -{ -	sprintf(buf,"emfile%d",n); -	return buf; -} - -static char dummyBuffer[BLOCK_SIZE]; - -static int GetBlockFileHandle(int n) -{ -	int h; -	int requiredSize; -	 -	char name[40]; -	NToName(name,n); -	int fSize; -	int i; -	 -	h =  open(name, O_RDWR | O_CREAT, S_IREAD | S_IWRITE); -	if(h >= 0){ -		fSize = lseek(h,0,SEEK_END); -		requiredSize = BLOCKS_PER_HANDLE * BLOCK_SIZE; -		if(fSize < requiredSize){ -		   for(i = 0; i < BLOCKS_PER_HANDLE; i++) -		   	if(write(h,dummyBuffer,BLOCK_SIZE) != BLOCK_SIZE) -				return -1; -			 -		} -	} -	 -	return h; - -} - -static int  CheckInit(void) -{ -	static int initialised = 0; -	int h; -	int i; - -	 -	off_t fSize; -	off_t requiredSize; -	int written; -	int blk; -	 -	yflash_Page p; -	 -	if(initialised)  -	{ -		return YAFFS_OK; -	} - -	initialised = 1; -	 -	memset(dummyBuffer,0xff,sizeof(dummyBuffer)); -	 -	 -	filedisk.nBlocks = SIZE_IN_MB * BLOCKS_PER_MB; - -	for(i = 0; i <  MAX_HANDLES; i++) -		filedisk.handle[i] = -1; -	 -	for(i = 0,blk = 0; blk < filedisk.nBlocks; blk+=BLOCKS_PER_HANDLE,i++) -		filedisk.handle[i] = GetBlockFileHandle(i); -	 -	 -	return 1; -} - - -int yflash_GetNumberOfBlocks(void) -{ -	CheckInit(); -	 -	return filedisk.nBlocks; -} - -int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags) -{ -	int written; -	int pos; -	int h; -	int i; -	int nRead; -	int error; -	 -	T(YAFFS_TRACE_MTD,(TSTR("write chunk %d data %x tags %x" TENDSTR),chunkInNAND,(unsigned)data, (unsigned)tags)); - -	CheckInit(); -	 -	 -	 -	if(data) -	{ -		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE; -		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))]; -		 -		lseek(h,pos,SEEK_SET); -		nRead =  read(h, localBuffer,dev->nDataBytesPerChunk); -		for(i = error = 0; i < dev->nDataBytesPerChunk && !error; i++){ -			if(localBuffer[i] != 0xFF){ -				printf("nand simulation: chunk %d data byte %d was %0x2\n", -					chunkInNAND,i,localBuffer[i]); -				error = 1; -			} -		} -		 -		for(i = 0; i < dev->nDataBytesPerChunk; i++) -		  localBuffer[i] &= data[i]; -		   -		if(memcmp(localBuffer,data,dev->nDataBytesPerChunk)) -			printf("nand simulator: data does not match\n"); -			 -		lseek(h,pos,SEEK_SET); -		written = write(h,localBuffer,dev->nDataBytesPerChunk); -		 -		if(yaffs_testPartialWrite){ -			close(h); -			exit(1); -		} -		 -#ifdef SIMULATE_FAILURES -			if((chunkInNAND >> 6) == 100)  -			  written = 0; - -			if((chunkInNAND >> 6) == 110)  -			  written = 0; -#endif - - -		if(written != dev->nDataBytesPerChunk) return YAFFS_FAIL; -	} -	 -	if(tags) -	{ -		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE ; -		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))]; -		 -		lseek(h,pos,SEEK_SET); - -		if( 0 && dev->isYaffs2) -		{ -			 -			written = write(h,tags,sizeof(yaffs_ExtendedTags)); -			if(written != sizeof(yaffs_ExtendedTags)) return YAFFS_FAIL; -		} -		else -		{ -			yaffs_PackedTags2 pt; -			yaffs_PackTags2(&pt,tags); -			__u8 * ptab = (__u8 *)&pt; - -			nRead = read(h,localBuffer,sizeof(pt)); -			for(i = error = 0; i < sizeof(pt) && !error; i++){ -				if(localBuffer[i] != 0xFF){ -					printf("nand simulation: chunk %d oob byte %d was %0x2\n", -						chunkInNAND,i,localBuffer[i]); -						error = 1; -				} -			} -		 -			for(i = 0; i < sizeof(pt); i++) -			  localBuffer[i] &= ptab[i]; -			  -			if(memcmp(localBuffer,&pt,sizeof(pt))) -				printf("nand sim: tags corruption\n"); -				 -			lseek(h,pos,SEEK_SET); -			 -			written = write(h,localBuffer,sizeof(pt)); -			if(written != sizeof(pt)) return YAFFS_FAIL; -		} -	} -	 - -	return YAFFS_OK;	 - -} - -int yaffs_CheckAllFF(const __u8 *ptr, int n) -{ -	while(n) -	{ -		n--; -		if(*ptr!=0xFF) return 0; -		ptr++; -	} -	return 1; -} - - -static int fail300 = 1; -static int fail320 = 1; - -static int failRead10 = 2; - -int yflash_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags) -{ -	int nread; -	int pos; -	int h; -	 -	T(YAFFS_TRACE_MTD,(TSTR("read chunk %d data %x tags %x" TENDSTR),chunkInNAND,(unsigned)data, (unsigned)tags)); -	 -	CheckInit(); -	 -	 -	 -	if(data) -	{ - -		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE; -		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];		 -		lseek(h,pos,SEEK_SET); -		nread = read(h,data,dev->nDataBytesPerChunk); -		 -		 -		if(nread != dev->nDataBytesPerChunk) return YAFFS_FAIL; -	} -	 -	if(tags) -	{ -		pos = (chunkInNAND % (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE)) * PAGE_SIZE + PAGE_DATA_SIZE; -		h = filedisk.handle[(chunkInNAND / (PAGES_PER_BLOCK * BLOCKS_PER_HANDLE))];		 -		lseek(h,pos,SEEK_SET); - -		if(0 && dev->isYaffs2) -		{ -			nread= read(h,tags,sizeof(yaffs_ExtendedTags)); -			if(nread != sizeof(yaffs_ExtendedTags)) return YAFFS_FAIL; -			if(yaffs_CheckAllFF((__u8 *)tags,sizeof(yaffs_ExtendedTags))) -			{ -				yaffs_InitialiseTags(tags); -			} -			else -			{ -				tags->chunkUsed = 1; -			} -		} -		else -		{ -			yaffs_PackedTags2 pt; -			nread= read(h,&pt,sizeof(pt)); -			yaffs_UnpackTags2(tags,&pt); -#ifdef SIMULATE_FAILURES -			if((chunkInNAND >> 6) == 100) { -			    if(fail300 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){ -			       tags->eccResult = YAFFS_ECC_RESULT_FIXED; -			       fail300 = 0; -			    } -			     -			} -			if((chunkInNAND >> 6) == 110) { -			    if(fail320 && tags->eccResult == YAFFS_ECC_RESULT_NO_ERROR){ -			       tags->eccResult = YAFFS_ECC_RESULT_FIXED; -			       fail320 = 0; -			    } -			} -#endif -			if(failRead10>0 && chunkInNAND == 10){ -				failRead10--; -				nread = 0; -			} -			 -			if(nread != sizeof(pt)) return YAFFS_FAIL; -		} -	} -	 - -	return YAFFS_OK;	 - -} - - -int yflash_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) -{ -	int written; -	int h; -	 -	yaffs_PackedTags2 pt; - -	CheckInit(); -	 -	memset(&pt,0,sizeof(pt)); -	h = filedisk.handle[(blockNo / ( BLOCKS_PER_HANDLE))]; -	lseek(h,((blockNo % BLOCKS_PER_HANDLE) * dev->nChunksPerBlock) * PAGE_SIZE + PAGE_DATA_SIZE,SEEK_SET); -	written = write(h,&pt,sizeof(pt)); -		 -	if(written != sizeof(pt)) return YAFFS_FAIL; -	 -	 -	return YAFFS_OK; -	 -} - -int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) -{ - -	int i; -	int h; -		 -	CheckInit(); -	 -	printf("erase block %d\n",blockNumber); -	 -	if(blockNumber == 320) -		fail320 = 1; -	 -	if(blockNumber < 0 || blockNumber >= filedisk.nBlocks) -	{ -		T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber)); -		return YAFFS_FAIL; -	} -	else -	{ -	 -		__u8 pg[PAGE_SIZE]; -		int syz = PAGE_SIZE; -		int pos; -		 -		memset(pg,0xff,syz); -		 - -		h = filedisk.handle[(blockNumber / ( BLOCKS_PER_HANDLE))]; -		lseek(h,((blockNumber % BLOCKS_PER_HANDLE) * dev->nChunksPerBlock) * PAGE_SIZE,SEEK_SET);		 -		for(i = 0; i < dev->nChunksPerBlock; i++) -		{ -			write(h,pg,PAGE_SIZE); -		} -		pos = lseek(h, 0,SEEK_CUR); -		 -		return YAFFS_OK; -	} -	 -} - -int yflash_InitialiseNAND(yaffs_Device *dev) -{ -	CheckInit(); -	 -	return YAFFS_OK; -} - - - - -int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber) -{ -	yaffs_ExtendedTags tags; -	int chunkNo; - -	*sequenceNumber = 0; -	 -	chunkNo = blockNo * dev->nChunksPerBlock; -	 -	yflash_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags); -	if(tags.blockBad) -	{ -		*state = YAFFS_BLOCK_STATE_DEAD; -	} -	else if(!tags.chunkUsed) -	{ -		*state = YAFFS_BLOCK_STATE_EMPTY; -	} -	else if(tags.chunkUsed) -	{ -		*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; -		*sequenceNumber = tags.sequenceNumber; -	} -	return YAFFS_OK; -} diff --git a/fs/yaffs2/direct/yaffs_fileem2k.h b/fs/yaffs2/direct/yaffs_fileem2k.h deleted file mode 100644 index e694c9258..000000000 --- a/fs/yaffs2/direct/yaffs_fileem2k.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * YAFFS: Yet another Flash File System . A NAND-flash specific file system.  - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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 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 __FILEEM2K_H__ -#define __FILEEM2K_H__ - -#if 1 - -#define SIZE_IN_MB 128 -//#define SIZE_IN_MB 8000 -#define PAGE_DATA_SIZE (2048) -#define PAGE_SPARE_SIZE  (64) -#define PAGE_SIZE  (PAGE_DATA_SIZE + PAGE_SPARE_SIZE) -#define PAGES_PER_BLOCK (64) -#define BLOCK_DATA_SIZE (PAGE_DATA_SIZE * PAGES_PER_BLOCK) -#define BLOCK_SIZE (PAGES_PER_BLOCK * (PAGE_SIZE)) -#define BLOCKS_PER_MB ((1024*1024)/BLOCK_DATA_SIZE) -#define SIZE_IN_BLOCKS (BLOCKS_PER_MB * SIZE_IN_MB) - -#else - -#define SIZE_IN_MB 128 -#define PAGE_DATA_SIZE (512) -#define SPARE_SIZE  (16) -#define PAGE_SIZE  (PAGE_DATA_SIZE + SPARE_SIZE) -#define PAGES_PER_BLOCK (32) -#define BLOCK_DATA_SIZE (PAGE_SIZE * PAGES_PER_BLOCK) -#define BLOCK_SIZE (PAGES_PER_BLOCK * (PAGE_SIZE)) -#define BLOCKS_PER_MB ((1024*1024)/BLOCK_DATA_SIZE) -#define SIZE_IN_BLOCKS (BLOCKS_PER_MB * SIZE_IN_MB) - -#endif - - -int yflash_GetNumberOfBlocks(void); - -#endif - diff --git a/fs/yaffs2/direct/yaffs_flashif.c b/fs/yaffs2/direct/yaffs_flashif.c deleted file mode 100644 index 8d51dc6af..000000000 --- a/fs/yaffs2/direct/yaffs_flashif.c +++ /dev/null @@ -1,230 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* XXX U-BOOT XXX */ -#include <common.h> - -const char *yaffs_flashif_c_version = "$Id: yaffs_flashif.c,v 1.3 2007/02/14 01:09:06 wookey Exp $"; - - -#include "yportenv.h" - -#include "yaffs_flashif.h" -#include "yaffs_guts.h" -#include "devextras.h" - - -#define SIZE_IN_MB 16 - -#define BLOCK_SIZE (32 * 528) -#define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) - - - -typedef struct  -{ -	__u8 data[528]; // Data + spare -} yflash_Page; - -typedef struct -{ -	yflash_Page page[32]; // The pages in the block -	 -} yflash_Block; - - - -typedef struct -{ -	yflash_Block **block; -	int nBlocks; -} yflash_Device; - -static yflash_Device ramdisk; - -static int  CheckInit(yaffs_Device *dev) -{ -	static int initialised = 0; -	 -	int i; -	int fail = 0; -	int nAllocated = 0; -	 -	if(initialised)  -	{ -		return YAFFS_OK; -	} - -	initialised = 1; -	 -	 -	ramdisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024); -	 -	ramdisk.block = YMALLOC(sizeof(yflash_Block *) * ramdisk.nBlocks); -	 -	if(!ramdisk.block) return 0; -	 -	for(i=0; i <ramdisk.nBlocks; i++) -	{ -		ramdisk.block[i] = NULL; -	} -	 -	for(i=0; i <ramdisk.nBlocks && !fail; i++) -	{ -		if((ramdisk.block[i] = YMALLOC(sizeof(yflash_Block))) == 0) -		{ -			fail = 1; -		} -		else -		{ -			yflash_EraseBlockInNAND(dev,i); -			nAllocated++; -		} -	} -	 -	if(fail) -	{ -		for(i = 0; i < nAllocated; i++) -		{ -			YFREE(ramdisk.block[i]); -		} -		YFREE(ramdisk.block); -		 -		T(YAFFS_TRACE_ALWAYS,("Allocation failed, could only allocate %dMB of %dMB requested.\n", -		   nAllocated/64,ramdisk.nBlocks * YAFFS_BYTES_PER_BLOCK)); -		return 0; -	} -	 -	 -	 -	return 1; -} - -int yflash_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags) -{ -	int blk; -	int pg; -	 - -	CheckInit(dev); -	 -	blk = chunkInNAND/32; -	pg = chunkInNAND%32; -	 -	 -	if(data) -	{ -		memcpy(ramdisk.block[blk]->page[pg].data,data,512); -	} -	 -	 -	if(tags) -	{ -		yaffs_PackedTags pt; -		yaffs_PackTags(&pt,tags); -		memcpy(&ramdisk.block[blk]->page[pg].data[512],&pt,sizeof(pt)); -	} - -	return YAFFS_OK;	 - -} - - -int yflash_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_Tags *tags) -{ -	int blk; -	int pg; - -	 -	CheckInit(dev); -	 -	blk = chunkInNAND/32; -	pg = chunkInNAND%32; -	 -	 -	if(data) -	{ -		memcpy(data,ramdisk.block[blk]->page[pg].data,512); -	} -	 -	 -	if(tags) -	{ -		yaffs_PackedTags pt; -		memcpy(&pt,&ramdisk.block[blk]->page[pg].data[512],sizeof(yaffs_PackedTags)); -		yaffs_UnpackTags(tags,&pt); -	} - -	return YAFFS_OK; -} - - -int yflash_CheckChunkErased(yaffs_Device *dev,int chunkInNAND) -{ -	int blk; -	int pg; -	int i; - -	 -	CheckInit(dev); -	 -	blk = chunkInNAND/32; -	pg = chunkInNAND%32; -	 -	 -	for(i = 0; i < 528; i++) -	{ -		if(ramdisk.block[blk]->page[pg].data[i] != 0xFF) -		{ -			return YAFFS_FAIL; -		} -	} - -	return YAFFS_OK; - -} - -int yflash_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) -{ -	 -	CheckInit(dev); -	 -	if(blockNumber < 0 || blockNumber >= ramdisk.nBlocks) -	{ -		T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber)); -		return YAFFS_FAIL; -	} -	else -	{ -		memset(ramdisk.block[blockNumber],0xFF,sizeof(yflash_Block)); -		return YAFFS_OK; -	} -	 -} - -int yflash_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) -{ -	return YAFFS_OK; -	 -} -int yflash_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber) -{ -	*state = YAFFS_BLOCK_STATE_EMPTY; -	*sequenceNumber = 0; -} - - -int yflash_InitialiseNAND(yaffs_Device *dev) -{ -	return YAFFS_OK; -} diff --git a/fs/yaffs2/direct/yaffs_ramdisk.c b/fs/yaffs2/direct/yaffs_ramdisk.c deleted file mode 100644 index 57f27ce07..000000000 --- a/fs/yaffs2/direct/yaffs_ramdisk.c +++ /dev/null @@ -1,235 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* - * yaffs_ramdisk.c: yaffs ram disk component - * This provides a ram disk under yaffs. - * NB this is not intended for NAND emulation. - * Use this with dev->useNANDECC enabled, then ECC overheads are not required. - */ - -/* XXX U-BOOT XXX */ -#include <common.h> - -const char *yaffs_ramdisk_c_version = "$Id: yaffs_ramdisk.c,v 1.4 2007/02/14 01:09:06 wookey Exp $"; - - -#include "yportenv.h" - -#include "yaffs_ramdisk.h" -#include "yaffs_guts.h" -#include "devextras.h" -#include "yaffs_packedtags1.h" - - - -#define SIZE_IN_MB 2 - -#define BLOCK_SIZE (32 * 528) -#define BLOCKS_PER_MEG ((1024*1024)/(32 * 512)) - - - - - -typedef struct  -{ -	__u8 data[528]; // Data + spare -} yramdisk_Page; - -typedef struct -{ -	yramdisk_Page page[32]; // The pages in the block -	 -} yramdisk_Block; - - - -typedef struct -{ -	yramdisk_Block **block; -	int nBlocks; -} yramdisk_Device; - -static yramdisk_Device ramdisk; - -static int  CheckInit(yaffs_Device *dev) -{ -	static int initialised = 0; -	 -	int i; -	int fail = 0; -	//int nBlocks;  -	int nAllocated = 0; -	 -	if(initialised)  -	{ -		return YAFFS_OK; -	} - -	initialised = 1; -	 -	 -	ramdisk.nBlocks = (SIZE_IN_MB * 1024 * 1024)/(16 * 1024); -	 -	ramdisk.block = YMALLOC(sizeof(yramdisk_Block *) * ramdisk.nBlocks); -	 -	if(!ramdisk.block) return 0; -	 -	for(i=0; i <ramdisk.nBlocks; i++) -	{ -		ramdisk.block[i] = NULL; -	} -	 -	for(i=0; i <ramdisk.nBlocks && !fail; i++) -	{ -		if((ramdisk.block[i] = YMALLOC(sizeof(yramdisk_Block))) == 0) -		{ -			fail = 1; -		} -		else -		{ -			yramdisk_EraseBlockInNAND(dev,i); -			nAllocated++; -		} -	} -	 -	if(fail) -	{ -		for(i = 0; i < nAllocated; i++) -		{ -			YFREE(ramdisk.block[i]); -		} -		YFREE(ramdisk.block); -		 -		T(YAFFS_TRACE_ALWAYS,("Allocation failed, could only allocate %dMB of %dMB requested.\n", -		   nAllocated/64,ramdisk.nBlocks * 528)); -		return 0; -	} -	 -	 -	return 1; -} - -int yramdisk_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags) -{ -	int blk; -	int pg; -	 - -	CheckInit(dev); -	 -	blk = chunkInNAND/32; -	pg = chunkInNAND%32; -	 -	 -	if(data) -	{ -		memcpy(ramdisk.block[blk]->page[pg].data,data,512); -	} -	 -	 -	if(tags) -	{ -		yaffs_PackedTags1 pt; -		 -		yaffs_PackTags1(&pt,tags); -		memcpy(&ramdisk.block[blk]->page[pg].data[512],&pt,sizeof(pt)); -	} - -	return YAFFS_OK;	 - -} - - -int yramdisk_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags) -{ -	int blk; -	int pg; - -	 -	CheckInit(dev); -	 -	blk = chunkInNAND/32; -	pg = chunkInNAND%32; -	 -	 -	if(data) -	{ -		memcpy(data,ramdisk.block[blk]->page[pg].data,512); -	} -	 -	 -	if(tags) -	{ -		yaffs_PackedTags1 pt; -		 -		memcpy(&pt,&ramdisk.block[blk]->page[pg].data[512],sizeof(pt)); -		yaffs_UnpackTags1(tags,&pt); -		 -	} - -	return YAFFS_OK; -} - - -int yramdisk_CheckChunkErased(yaffs_Device *dev,int chunkInNAND) -{ -	int blk; -	int pg; -	int i; - -	 -	CheckInit(dev); -	 -	blk = chunkInNAND/32; -	pg = chunkInNAND%32; -	 -	 -	for(i = 0; i < 528; i++) -	{ -		if(ramdisk.block[blk]->page[pg].data[i] != 0xFF) -		{ -			return YAFFS_FAIL; -		} -	} - -	return YAFFS_OK; - -} - -int yramdisk_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) -{ -	 -	CheckInit(dev); -	 -	if(blockNumber < 0 || blockNumber >= ramdisk.nBlocks) -	{ -		T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber)); -		return YAFFS_FAIL; -	} -	else -	{ -		memset(ramdisk.block[blockNumber],0xFF,sizeof(yramdisk_Block)); -		return YAFFS_OK; -	} -	 -} - -int yramdisk_InitialiseNAND(yaffs_Device *dev) -{ -	//dev->useNANDECC = 1; // force on useNANDECC which gets faked.  -						 // This saves us doing ECC checks. -	 -	return YAFFS_OK; -} diff --git a/fs/yaffs2/direct/yaffs_ramem2k.c b/fs/yaffs2/direct/yaffs_ramem2k.c deleted file mode 100644 index 816178928..000000000 --- a/fs/yaffs2/direct/yaffs_ramem2k.c +++ /dev/null @@ -1,364 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* - * yaffs_ramem2k.c: RAM emulation in-kernel for 2K pages (YAFFS2) - */ - -/* XXX U-BOOT XXX */ -#include <common.h> - -const char *yaffs_ramem2k_c_version = "$Id: yaffs_ramem2k.c,v 1.3 2007/02/14 01:09:06 wookey Exp $"; - -#ifndef __KERNEL__ -#define CONFIG_YAFFS_RAM_ENABLED -#else -#include <linux/config.h> -#endif - -#ifdef CONFIG_YAFFS_RAM_ENABLED - -#include "yportenv.h" - -#include "yaffs_nandemul2k.h" -#include "yaffs_guts.h" -#include "yaffsinterface.h" -#include "devextras.h" -#include "yaffs_packedtags2.h" - - - -#define EM_SIZE_IN_MEG (32) -#define PAGE_DATA_SIZE  (2048) -#define PAGE_SPARE_SIZE (64) -#define PAGES_PER_BLOCK (64) - - - -#define EM_SIZE_IN_BYTES (EM_SIZE_IN_MEG * (1<<20)) - -#define PAGE_TOTAL_SIZE (PAGE_DATA_SIZE+PAGE_SPARE_SIZE) - -#define BLOCK_TOTAL_SIZE (PAGES_PER_BLOCK * PAGE_TOTAL_SIZE) - -#define BLOCKS_PER_MEG ((1<<20)/(PAGES_PER_BLOCK * PAGE_DATA_SIZE)) - - -typedef struct  -{ -	__u8 data[PAGE_TOTAL_SIZE]; // Data + spare -	int empty;      // is this empty? -} nandemul_Page; - - -typedef struct -{ -	nandemul_Page *page[PAGES_PER_BLOCK]; -	int damaged;	 -} nandemul_Block; - - - -typedef struct -{ -	nandemul_Block**block; -	int nBlocks; -} nandemul_Device; - -static nandemul_Device ned; - -static int sizeInMB = EM_SIZE_IN_MEG; - - -static void nandemul_yield(int n) -{ -#ifdef __KERNEL__ -	if(n > 0) schedule_timeout(n); -#endif - -} - - -static void nandemul_ReallyEraseBlock(int blockNumber) -{ -	int i; -	 -	nandemul_Block *blk; -	 -	if(blockNumber < 0 || blockNumber >= ned.nBlocks) -	{ -		return; -	} -	 -	blk = ned.block[blockNumber]; -	 -	for(i = 0; i < PAGES_PER_BLOCK; i++) -	{ -		memset(blk->page[i],0xff,sizeof(nandemul_Page)); -		blk->page[i]->empty = 1; -	} -	nandemul_yield(2); -} - - -static int nandemul2k_CalcNBlocks(void) -{ -	return EM_SIZE_IN_MEG * BLOCKS_PER_MEG; -} - - - -static int  CheckInit(void) -{ -	static int initialised = 0; -	 -	int i,j; -	 -	int fail = 0; -	int nBlocks;  - -	int nAllocated = 0; -	 -	if(initialised)  -	{ -		return YAFFS_OK; -	} -	 -	 -	ned.nBlocks = nBlocks = nandemul2k_CalcNBlocks(); - -	 -	ned.block = YMALLOC(sizeof(nandemul_Block*) * nBlocks ); -	 -	if(!ned.block) return YAFFS_FAIL; -	 -	 -	 - -		 -	for(i=fail=0; i <nBlocks; i++) -	{ -		 -		nandemul_Block *blk; -		 -		if(!(blk = ned.block[i] = YMALLOC(sizeof(nandemul_Block)))) -		{ -		 fail = 1; -		}   -		else -		{ -			for(j = 0; j < PAGES_PER_BLOCK; j++) -			{ -				if((blk->page[j] = YMALLOC(sizeof(nandemul_Page))) == 0) -				{ -					fail = 1; -				} -			} -			nandemul_ReallyEraseBlock(i); -			ned.block[i]->damaged = 0; -			nAllocated++; -		} -	} -	 -	if(fail) -	{ -		//Todo thump pages -		 -		for(i = 0; i < nAllocated; i++) -		{ -			YFREE(ned.block[i]); -		} -		YFREE(ned.block); -		 -		T(YAFFS_TRACE_ALWAYS,("Allocation failed, could only allocate %dMB of %dMB requested.\n", -		   nAllocated/64,sizeInMB)); -		return 0; -	} -	 -	ned.nBlocks = nBlocks; -	 -	initialised = 1; -	 -	return 1; -} - -int nandemul2k_WriteChunkWithTagsToNAND(yaffs_Device *dev,int chunkInNAND,const __u8 *data, yaffs_ExtendedTags *tags) -{ -	int blk; -	int pg; -	int i; -	 -	__u8 *x; - -	 -	blk = chunkInNAND/PAGES_PER_BLOCK; -	pg = chunkInNAND%PAGES_PER_BLOCK; -	 -	 -	if(data) -	{ -		x = ned.block[blk]->page[pg]->data; -		 -		for(i = 0; i < PAGE_DATA_SIZE; i++) -		{ -			x[i] &=data[i]; -		} - -		ned.block[blk]->page[pg]->empty = 0; -	} -	 -	 -	if(tags) -	{ -		x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE]; -		 -		yaffs_PackTags2((yaffs_PackedTags2 *)x,tags); -			 -	} -	 -	if(tags || data) -	{ -		nandemul_yield(1); -	} - -	return YAFFS_OK; -} - - -int nandemul2k_ReadChunkWithTagsFromNAND(yaffs_Device *dev,int chunkInNAND, __u8 *data, yaffs_ExtendedTags *tags) -{ -	int blk; -	int pg; -	 -	__u8 *x; - -	 -	 -	blk = chunkInNAND/PAGES_PER_BLOCK; -	pg = chunkInNAND%PAGES_PER_BLOCK; -	 -	 -	if(data) -	{ -		memcpy(data,ned.block[blk]->page[pg]->data,PAGE_DATA_SIZE); -	} -	 -	 -	if(tags) -	{ -		x = &ned.block[blk]->page[pg]->data[PAGE_DATA_SIZE]; -		 -		yaffs_UnpackTags2(tags,(yaffs_PackedTags2 *)x); -	} - -	return YAFFS_OK; -} - - -static int nandemul2k_CheckChunkErased(yaffs_Device *dev,int chunkInNAND) -{ -	int blk; -	int pg; -	int i; - -	 -	 -	blk = chunkInNAND/PAGES_PER_BLOCK; -	pg = chunkInNAND%PAGES_PER_BLOCK; -	 -	 -	for(i = 0; i < PAGE_TOTAL_SIZE; i++) -	{ -		if(ned.block[blk]->page[pg]->data[i] != 0xFF) -		{ -			return YAFFS_FAIL; -		} -	} - -	return YAFFS_OK; - -} - -int nandemul2k_EraseBlockInNAND(yaffs_Device *dev, int blockNumber) -{ -	 -	 -	if(blockNumber < 0 || blockNumber >= ned.nBlocks) -	{ -		T(YAFFS_TRACE_ALWAYS,("Attempt to erase non-existant block %d\n",blockNumber)); -	} -	else if(ned.block[blockNumber]->damaged) -	{ -		T(YAFFS_TRACE_ALWAYS,("Attempt to erase damaged block %d\n",blockNumber)); -	} -	else -	{ -		nandemul_ReallyEraseBlock(blockNumber); -	} -	 -	return YAFFS_OK; -} - -int nandemul2k_InitialiseNAND(yaffs_Device *dev) -{ -	CheckInit(); -	return YAFFS_OK; -} -  -int nandemul2k_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) -{ -	 -	__u8 *x; -	 -	x = &ned.block[blockNo]->page[0]->data[PAGE_DATA_SIZE]; -	 -	memset(x,0,sizeof(yaffs_PackedTags2)); -	 -	 -	return YAFFS_OK; -	 -} - -int nandemul2k_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, yaffs_BlockState *state, int *sequenceNumber) -{ -	yaffs_ExtendedTags tags; -	int chunkNo; - -	*sequenceNumber = 0; -	 -	chunkNo = blockNo * dev->nChunksPerBlock; -	 -	nandemul2k_ReadChunkWithTagsFromNAND(dev,chunkNo,NULL,&tags); -	if(tags.blockBad) -	{ -		*state = YAFFS_BLOCK_STATE_DEAD; -	} -	else if(!tags.chunkUsed) -	{ -		*state = YAFFS_BLOCK_STATE_EMPTY; -	} -	else if(tags.chunkUsed) -	{ -		*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; -		*sequenceNumber = tags.sequenceNumber; -	} -	return YAFFS_OK; -} - -int nandemul2k_GetBytesPerChunk(void) { return PAGE_DATA_SIZE;} - -int nandemul2k_GetChunksPerBlock(void) { return PAGES_PER_BLOCK; } -int nandemul2k_GetNumberOfBlocks(void) {return nandemul2k_CalcNBlocks();} - - -#endif //YAFFS_RAM_ENABLED diff --git a/fs/yaffs2/direct/yaffscfg2k.c b/fs/yaffs2/direct/yaffscfg2k.c deleted file mode 100644 index 1daede181..000000000 --- a/fs/yaffs2/direct/yaffscfg2k.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* - * yaffscfg2k.c  The configuration for the "direct" use of yaffs. - * - * This file is intended to be modified to your requirements. - * There is no need to redistribute this file. - */ - -/* XXX U-BOOT XXX */ -#include <common.h> - -#include "yaffscfg.h" -#include "yaffsfs.h" -#include "yaffs_fileem2k.h" -#include "yaffs_nandemul2k.h" - -#include <errno.h> - -unsigned yaffs_traceMask =  - -	YAFFS_TRACE_SCAN |   -	YAFFS_TRACE_GC | YAFFS_TRACE_GC_DETAIL |  -	YAFFS_TRACE_ERASE |  -	YAFFS_TRACE_TRACING |  -	YAFFS_TRACE_ALLOCATE |  -	YAFFS_TRACE_CHECKPOINT | -	YAFFS_TRACE_BAD_BLOCKS | -	YAFFS_TRACE_VERIFY | -	YAFFS_TRACE_VERIFY_NAND | -	YAFFS_TRACE_VERIFY_FULL | -//	(~0) | -	 -	0; -         - - -void yaffsfs_SetError(int err) -{ -	//Do whatever to set error -	errno = err; -} - -void yaffsfs_Lock(void) -{ -} - -void yaffsfs_Unlock(void) -{ -} - -__u32 yaffsfs_CurrentTime(void) -{ -	return 0; -} - - -static int yaffs_kill_alloc = 0; -static size_t total_malloced = 0; -static size_t malloc_limit = 0 & 6000000; - -void *yaffs_malloc(size_t size) -{ -	size_t this; -	if(yaffs_kill_alloc) -		return NULL; -	if(malloc_limit && malloc_limit <(total_malloced + size) ) -		return NULL; - -	this = malloc(size); -	if(this) -		total_malloced += size; -	return this; -} - -void yaffs_free(void *ptr) -{ -	free(ptr); -} - -void yaffsfs_LocalInitialisation(void) -{ -	// Define locking semaphore. -} - -// Configuration for: -// /ram  2MB ramdisk -// /boot 2MB boot disk (flash) -// /flash 14MB flash disk (flash) -// NB Though /boot and /flash occupy the same physical device they -// are still disticnt "yaffs_Devices. You may think of these as "partitions" -// using non-overlapping areas in the same device. -//  - -#include "yaffs_ramdisk.h" -#include "yaffs_flashif.h" -#include "yaffs_nandemul2k.h" - -static yaffs_Device ramDev; -static yaffs_Device bootDev; -static yaffs_Device flashDev; -static yaffs_Device ram2kDev; - -static yaffsfs_DeviceConfiguration yaffsfs_config[] = { -#if 0 -	{ "/ram", &ramDev}, -	{ "/boot", &bootDev}, -	{ "/flash/", &flashDev}, -	{ "/ram2k", &ram2kDev}, -	{(void *)0,(void *)0} -#else -	{ "/", &ramDev}, -	{ "/flash/boot", &bootDev}, -	{ "/flash/flash", &flashDev}, -	{ "/ram2k", &ram2kDev}, -	{(void *)0,(void *)0} /* Null entry to terminate list */ -#endif -}; - - -int yaffs_StartUp(void) -{ -	// Stuff to configure YAFFS -	// Stuff to initialise anything special (eg lock semaphore). -	yaffsfs_LocalInitialisation(); -	 -	// Set up devices -	// /ram -	memset(&ramDev,0,sizeof(ramDev)); -	ramDev.nDataBytesPerChunk = 512; -	ramDev.nChunksPerBlock = 32; -	ramDev.nReservedBlocks = 2; // Set this smaller for RAM -	ramDev.startBlock = 0; // Can use block 0 -	ramDev.endBlock = 127; // Last block in 2MB.	 -	//ramDev.useNANDECC = 1; -	ramDev.nShortOpCaches = 0;	// Disable caching on this device. -	ramDev.genericDevice = (void *) 0;	// Used to identify the device in fstat. -	ramDev.writeChunkWithTagsToNAND = yramdisk_WriteChunkWithTagsToNAND; -	ramDev.readChunkWithTagsFromNAND = yramdisk_ReadChunkWithTagsFromNAND; -	ramDev.eraseBlockInNAND = yramdisk_EraseBlockInNAND; -	ramDev.initialiseNAND = yramdisk_InitialiseNAND; - -	// /boot -	memset(&bootDev,0,sizeof(bootDev)); -	bootDev.nDataBytesPerChunk = 512; -	bootDev.nChunksPerBlock = 32; -	bootDev.nReservedBlocks = 5; -	bootDev.startBlock = 0; // Can use block 0 -	bootDev.endBlock = 63; // Last block -	//bootDev.useNANDECC = 0; // use YAFFS's ECC -	bootDev.nShortOpCaches = 10; // Use caches -	bootDev.genericDevice = (void *) 1;	// Used to identify the device in fstat. -	bootDev.writeChunkWithTagsToNAND = yflash_WriteChunkWithTagsToNAND; -	bootDev.readChunkWithTagsFromNAND = yflash_ReadChunkWithTagsFromNAND; -	bootDev.eraseBlockInNAND = yflash_EraseBlockInNAND; -	bootDev.initialiseNAND = yflash_InitialiseNAND; -	bootDev.markNANDBlockBad = yflash_MarkNANDBlockBad; -	bootDev.queryNANDBlock = yflash_QueryNANDBlock; - - - -	// /flash -	// Set this puppy up to use -	// the file emulation space as -	// 2kpage/64chunk per block/128MB device -	memset(&flashDev,0,sizeof(flashDev)); - -	flashDev.nDataBytesPerChunk = 2048; -	flashDev.nChunksPerBlock = 64; -	flashDev.nReservedBlocks = 5; -	flashDev.nCheckpointReservedBlocks = 5; -	//flashDev.checkpointStartBlock = 1; -	//flashDev.checkpointEndBlock = 20; -	flashDev.startBlock = 0; -	flashDev.endBlock = 200; // Make it smaller -	//flashDev.endBlock = yflash_GetNumberOfBlocks()-1; -	flashDev.isYaffs2 = 1; -	flashDev.wideTnodesDisabled=0; -	flashDev.nShortOpCaches = 10; // Use caches -	flashDev.genericDevice = (void *) 2;	// Used to identify the device in fstat. -	flashDev.writeChunkWithTagsToNAND = yflash_WriteChunkWithTagsToNAND; -	flashDev.readChunkWithTagsFromNAND = yflash_ReadChunkWithTagsFromNAND; -	flashDev.eraseBlockInNAND = yflash_EraseBlockInNAND; -	flashDev.initialiseNAND = yflash_InitialiseNAND; -	flashDev.markNANDBlockBad = yflash_MarkNANDBlockBad; -	flashDev.queryNANDBlock = yflash_QueryNANDBlock; - -	// /ram2k -	// Set this puppy up to use -	// the file emulation space as -	// 2kpage/64chunk per block/128MB device -	memset(&ram2kDev,0,sizeof(ram2kDev)); - -	ram2kDev.nDataBytesPerChunk = nandemul2k_GetBytesPerChunk(); -	ram2kDev.nChunksPerBlock = nandemul2k_GetChunksPerBlock(); -	ram2kDev.nReservedBlocks = 5; -	ram2kDev.startBlock = 0; // First block after /boot -	//ram2kDev.endBlock = 127; // Last block in 16MB -	ram2kDev.endBlock = nandemul2k_GetNumberOfBlocks() - 1; // Last block in 512MB -	ram2kDev.isYaffs2 = 1; -	ram2kDev.nShortOpCaches = 10; // Use caches -	ram2kDev.genericDevice = (void *) 3;	// Used to identify the device in fstat. -	ram2kDev.writeChunkWithTagsToNAND = nandemul2k_WriteChunkWithTagsToNAND; -	ram2kDev.readChunkWithTagsFromNAND = nandemul2k_ReadChunkWithTagsFromNAND; -	ram2kDev.eraseBlockInNAND = nandemul2k_EraseBlockInNAND; -	ram2kDev.initialiseNAND = nandemul2k_InitialiseNAND; -	ram2kDev.markNANDBlockBad = nandemul2k_MarkNANDBlockBad; -	ram2kDev.queryNANDBlock = nandemul2k_QueryNANDBlock; - -	yaffs_initialise(yaffsfs_config); -	 -	return 0; -} - - - -void SetCheckpointReservedBlocks(int n) -{ -	flashDev.nCheckpointReservedBlocks = n; -} diff --git a/fs/yaffs2/moduleconfig.h b/fs/yaffs2/moduleconfig.h deleted file mode 100644 index faf135d02..000000000 --- a/fs/yaffs2/moduleconfig.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * YAFFS: Yet another Flash File System . A NAND-flash specific file system.  - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Martin Fouts <Martin.Fouts@palmsource.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. - */ - -#ifndef __YAFFS_CONFIG_H__ -#define __YAFFS_CONFIG_H__ - -#ifdef YAFFS_OUT_OF_TREE - -/* DO NOT UNSET THESE THREE. YAFFS2 will not compile if you do. */ -#define CONFIG_YAFFS_FS -#define CONFIG_YAFFS_YAFFS1 -#define CONFIG_YAFFS_YAFFS2 - -/* These options are independent of each other.  Select those that matter. */ - -/* Default: Not selected */ -/* Meaning: Yaffs does its own ECC, rather than using MTD ECC */ -//#define CONFIG_YAFFS_DOES_ECC - -/* Default: Not selected */ -/* Meaning: ECC byte order is 'wrong'.  Only meaningful if */ -/*          CONFIG_YAFFS_DOES_ECC is set */ -//#define CONFIG_YAFFS_ECC_WRONG_ORDER - -/* Default: Selected */ -/* Meaning: Disables testing whether chunks are erased before writing to them*/ -#define CONFIG_YAFFS_DISABLE_CHUNK_ERASED_CHECK - -/* Default: Selected */ -/* Meaning: Cache short names, taking more RAM, but faster look-ups */ -#define CONFIG_YAFFS_SHORT_NAMES_IN_RAM - -/* Default: 10 */ -/* Meaning: set the count of blocks to reserve for checkpointing */ -#define CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS 10 - -/* -Older-style on-NAND data format has a "pageStatus" byte to record -chunk/page state.  This byte is zeroed when the page is discarded. -Choose this option if you have existing on-NAND data in this format -that you need to continue to support.  New data written also uses the -older-style format. -Note: Use of this option generally requires that MTD's oob layout be -adjusted to use the older-style format.  See notes on tags formats and -MTD versions in yaffs_mtdif1.c. -*/ -/* Default: Not selected */ -/* Meaning: Use older-style on-NAND data format with pageStatus byte */ -//#define CONFIG_YAFFS_9BYTE_TAGS - -#endif /* YAFFS_OUT_OF_TREE */ - -#endif /* __YAFFS_CONFIG_H__ */ diff --git a/fs/yaffs2/mtdemul/Makefile b/fs/yaffs2/mtdemul/Makefile deleted file mode 100644 index fe03b478d..000000000 --- a/fs/yaffs2/mtdemul/Makefile +++ /dev/null @@ -1,33 +0,0 @@ -#Makefile for NANDemul MTD -# -# NB this is not yet suitable for putting into the kernel tree. -# YAFFS: Yet another Flash File System. A NAND-flash specific file system.  -# -# Copyright (C) 2002 Aleph One Ltd. -#   for Toby Churchill Ltd and Brightstar Engineering -# -# 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. - -## Change or override  KERNELDIR to your kernel -## comment out USE_xxxx if you don't want these features. - -KERNELDIR = /usr/src/kernel-headers-2.4.27 - -CFLAGS = -D__KERNEL__ -DMODULE   -I$(KERNELDIR)/include -O2 -Wall -g - - - -TARGET = nandemul2k.o - -default: $(TARGET) - -clean: -	rm -f $(TARGET) - -$(TARGET): %.o: %.c -	gcc -c $(CFLAGS) $< -o $@ - diff --git a/fs/yaffs2/mtdemul/nandemul2k.c b/fs/yaffs2/mtdemul/nandemul2k.c deleted file mode 100644 index bcbf16ad1..000000000 --- a/fs/yaffs2/mtdemul/nandemul2k.c +++ /dev/null @@ -1,714 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* - *  This version hacked for emulating 2kpage NAND for YAFFS2 testing. - */ - -#include <linux/config.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/version.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/list.h> -#include <linux/fs.h> -#include <linux/proc_fs.h> -#include <linux/pagemap.h> -#include <linux/mtd/mtd.h> -#include <linux/interrupt.h> -#include <linux/string.h> -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -#include <linux/locks.h> -#endif - -#include <asm/uaccess.h> -#include <linux/mtd/mtd.h> -#include <linux/mtd/partitions.h> -#include <linux/mtd/nand.h> -#include "../yaffs_nandemul2k.h" - -#define ALLOCATE(x) kmalloc(x,GFP_KERNEL) -#define FREE(x)     kfree(x) - - - - - -#define NAND_SHIFT      (11)   // Shifter for 2k -#define PAGE_DATA_SIZE  (1 << NAND_SHIFT) -#define PAGE_SPARE_SIZE (64) -#define BLK_SHIFT	6 -#define PAGES_PER_BLOCK (1 << BLK_SHIFT)	// = 64 - - -#define EM_SIZE_IN_MEG 4 -#define EM_SIZE_IN_BYTES (EM_SIZE_IN_MEG * (1<<20)) - -#define PAGE_TOTAL_SIZE (PAGE_DATA_SIZE+PAGE_SPARE_SIZE) - -#define BLOCK_TOTAL_SIZE (PAGES_PER_BLOCK * PAGE_TOTAL_SIZE) - -#define BLOCKS_PER_MEG ((1<<20)/(PAGES_PER_BLOCK * PAGE_DATA_SIZE)) - - -static struct mtd_info nandemul2k_mtd; - -typedef struct  -{ -	__u8 data[PAGE_TOTAL_SIZE]; // Data + spare -	int empty;      // is this empty? -} nandemul_Page; - - -typedef struct -{ -	nandemul_Page *page[PAGES_PER_BLOCK]; -	int damaged;	 -} nandemul_Block; - - - -typedef struct -{ -	nandemul_Block**block; -	int nBlocks; -} nandemul_Device; - -static nandemul_Device ned; - -static int sizeInMB = EM_SIZE_IN_MEG; - - -static void nandemul_yield(int n) -{ -#ifdef __KERNEL__ -	if(n > 0) schedule_timeout(n); -#endif - -} - - -static void nandemul2k_Read(void *buffer, int page, int start, int nBytes) -{ -	int pg = page%PAGES_PER_BLOCK; -	int blk = page/PAGES_PER_BLOCK; -	if(buffer && nBytes > 0) -	{ -		memcpy(buffer,&ned.block[blk]->page[pg]->data[start],nBytes); -	} -	 -} - -static void nandemul2k_Program(const void *buffer, int page, int start, int nBytes) -{ -	int pg = page%PAGES_PER_BLOCK; -	int blk = page/PAGES_PER_BLOCK; -	__u8 *p; -	__u8 *b = (__u8 *)buffer; - -	p = &ned.block[blk]->page[pg]->data[start]; -	 -	while(buffer && nBytes>0) -	{ -		*p = *p & *b; -		p++; -		b++; -		nBytes--; -	} -} - -static void nandemul2k_DoErase(int blockNumber) -{ -	int i; -	 -	nandemul_Block *blk; -	 -	if(blockNumber < 0 || blockNumber >= ned.nBlocks) -	{ -		return; -	} -	 -	blk = ned.block[blockNumber]; -	 -	for(i = 0; i < PAGES_PER_BLOCK; i++) -	{ -		memset(blk->page[i],0xff,sizeof(nandemul_Page)); -		blk->page[i]->empty = 1; -	} -	nandemul_yield(2); -} - - -static int nandemul2k_CalcNBlocks(void) -{ -	return EM_SIZE_IN_MEG * BLOCKS_PER_MEG; -} - - - -static int  CheckInit(void) -{ -	static int initialised = 0; -	 -	int i,j; -	 -	int fail = 0; -	int nBlocks;  - -	int nAllocated = 0; -	 -	if(initialised)  -	{ -		return 0; -	} -	 -	 -	ned.nBlocks = nBlocks = nandemul2k_CalcNBlocks(); - -	 -	ned.block = ALLOCATE(sizeof(nandemul_Block*) * nBlocks ); -	 -	if(!ned.block) return ENOMEM; -	 -	 -	 - -		 -	for(i=fail=0; i <nBlocks; i++) -	{ -		 -		nandemul_Block *blk; -		 -		if(!(blk = ned.block[i] = ALLOCATE(sizeof(nandemul_Block)))) -		{ -		 fail = 1; -		}   -		else -		{ -			for(j = 0; j < PAGES_PER_BLOCK; j++) -			{ -				if((blk->page[j] = ALLOCATE(sizeof(nandemul_Page))) == 0) -				{ -					fail = 1; -				} -			} -			nandemul2k_DoErase(i); -			ned.block[i]->damaged = 0; -			nAllocated++; -		} -	} -	 -	if(fail) -	{ -		//Todo thump pages -		 -		for(i = 0; i < nAllocated; i++) -		{ -			FREE(ned.block[i]); -		} -		FREE(ned.block); -		 -		return ENOMEM; -	} -	 -	ned.nBlocks = nBlocks; -	 -	initialised = 1; -	 -	return 1; -} - - - -static void nandemul2k_CleanUp(void) -{ -	int i,j; -	 -	for(i = 0; i < ned.nBlocks; i++) -	{ -		for(j = 0; j < PAGES_PER_BLOCK; j++) -		{ -		   FREE(ned.block[i]->page[j]); -		} -		FREE(ned.block[i]); -		 -	} -	FREE(ned.block); -	ned.block = 0; -} - -int nandemul2k_GetBytesPerChunk(void) { return PAGE_DATA_SIZE;} - -int nandemul2k_GetChunksPerBlock(void) { return PAGES_PER_BLOCK; } -int nandemul2k_GetNumberOfBlocks(void) {return nandemul2k_CalcNBlocks();} - - - -static int nandemul2k_ReadId(__u8 *vendorId, __u8 *deviceId) -{ -	*vendorId = 'Y';  -	*deviceId = '2'; -	 -	return 1; -} - - -static int nandemul2k_ReadStatus(__u8 *status) -{ -		*status = 0; -		return 1; -} - - -#ifdef CONFIG_MTD_NAND_ECC -#include <linux/mtd/nand_ecc.h> -#endif - -/* - * NAND low-level MTD interface functions - */ -static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, -			size_t *retlen, u_char *buf); -static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, -				size_t *retlen, u_char *buf, u_char *oob_buf, struct nand_oobinfo *dummy); -static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, -				size_t *retlen, u_char *buf); -static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, -			size_t *retlen, const u_char *buf); -static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, -				size_t *retlen, const u_char *buf, -				u_char *oob_buf, struct nand_oobinfo *dummy); -static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, -				size_t *retlen, const u_char *buf); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) -static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, -				unsigned long count, loff_t to, size_t *retlen); -#else -static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs, -				unsigned long count, loff_t to, size_t *retlen); -#endif -static int nand_erase (struct mtd_info *mtd, struct erase_info *instr); -static void nand_sync (struct mtd_info *mtd); - - - -/* - * NAND read - */ -static int nand_read (struct mtd_info *mtd, loff_t from, size_t len, -			size_t *retlen, u_char *buf) -{ -	return nand_read_ecc (mtd, from, len, retlen, buf, NULL,NULL); -} - - -/* - * NAND read with ECC - */ -static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len, -				size_t *retlen, u_char *buf, u_char *oob_buf,struct nand_oobinfo *oobsel) -{ -	int 	start, page; -	int n = len; -	int nToCopy; - - - -	/* Do not allow reads past end of device */ -	if ((from + len) > mtd->size) { -		*retlen = 0; -		return -EINVAL; -	} - - -	/* Initialize return value */ -	*retlen = 0; - -	while(n > 0) -	{ - -		/* First we calculate the starting page */ -		page = from >> NAND_SHIFT; - -		/* Get raw starting column */ - -		start = from & (mtd->oobblock-1); - -		// OK now check for the curveball where the start and end are in -		// the same page -		if((start + n) < mtd->oobblock) -		{ -			nToCopy = n; -		} -		else -		{ -			nToCopy =  mtd->oobblock - start; -		} - -		nandemul2k_Read(buf, page, start, nToCopy); -		nandemul2k_Read(oob_buf,page,PAGE_DATA_SIZE,PAGE_SPARE_SIZE); - -		n -= nToCopy; -		from += nToCopy; -		buf += nToCopy; -		if(oob_buf) oob_buf += PAGE_SPARE_SIZE; -		*retlen += nToCopy; - -	} - - -	return 0; -} - -/* - * NAND read out-of-band - */ -static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, -				size_t *retlen, u_char *buf) -{ -	int col, page; - -	T(0,("nand_read_oob: from = 0x%08x, buf = 0x%08x, len = %i\n", (unsigned int) from, (unsigned int) buf, -		(int) len)); - -	/* Shift to get page */ -	page = ((int) from) >> NAND_SHIFT; - -	/* Mask to get column */ -	col = from & 0x0f; - -	/* Initialize return length value */ -	*retlen = 0; - -	/* Do not allow reads past end of device */ -	if ((from + len) > mtd->size) { -		T(0, -			("nand_read_oob: Attempt read beyond end of device\n")); -		*retlen = 0; -		return -EINVAL; -	} - -	nandemul2k_Read(buf,page,PAGE_DATA_SIZE + col,len); - -	/* Return happy */ -	*retlen = len; -	return 0; -} - -/* - * NAND write - */ -static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, -			size_t *retlen, const u_char *buf) -{ -	return nand_write_ecc (mtd, to, len, retlen, buf, NULL,NULL); -} - -/* - * NAND write with ECC - */ -static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len, -				size_t *retlen, const u_char *buf, -				u_char *oob_buf, struct nand_oobinfo *dummy) -{ - -	int 	start, page; -	int n = len; -	int nToCopy; - - - -	/* Do not allow reads past end of device */ -	if ((to + len) > mtd->size) { -		*retlen = 0; -		return -EINVAL; -	} - - -	/* Initialize return value */ -	*retlen = 0; - -	while(n > 0) -	{ - -		/* First we calculate the starting page */ -		page = to >> NAND_SHIFT; - -		/* Get raw starting column */ - -		start = to & (mtd->oobblock - 1); - -		// OK now check for the curveball where the start and end are in -		// the same page -		if((start + n) < mtd->oobblock) -		{ -			nToCopy = n; -		} -		else -		{ -			nToCopy =  mtd->oobblock - start; -		} - -		nandemul2k_Program(buf, page, start, nToCopy); -		nandemul2k_Program(oob_buf, page, PAGE_DATA_SIZE, PAGE_SPARE_SIZE); - -		n -= nToCopy; -		to += nToCopy; -		buf += nToCopy; -		if(oob_buf) oob_buf += PAGE_SPARE_SIZE; -		*retlen += nToCopy; - -	} - - -	return 0; -} - -/* - * NAND write out-of-band - */ -static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, -				size_t *retlen, const u_char *buf) -{ -	int col, page; - - -	T(0,( -		"nand_read_oob: to = 0x%08x, len = %i\n", (unsigned int) to, -		(int) len)); - -	/* Shift to get page */ -	page = ((int) to) >> NAND_SHIFT; - -	/* Mask to get column */ -	col = to & 0x0f; - -	/* Initialize return length value */ -	*retlen = 0; - -	/* Do not allow reads past end of device */ -	if ((to + len) > mtd->size) { -		T(0,( -		   "nand_read_oob: Attempt read beyond end of device\n")); -		*retlen = 0; -		return -EINVAL; -	} - -	nandemul2k_Program(buf,page,512 + col,len); - -	/* Return happy */ -	*retlen = len; -	return 0; - -} - -/* - * NAND write with iovec - */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,7)) -static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, -				unsigned long count, loff_t to, size_t *retlen) -#else -static int nand_writev (struct mtd_info *mtd, const struct iovec *vecs, -				unsigned long count, loff_t to, size_t *retlen) -#endif -{ -	return -EINVAL; -} - -/* - * NAND erase a block - */ -static int nand_erase (struct mtd_info *mtd, struct erase_info *instr) -{ -	int i, nBlocks,block; - -	T(0,( -		"nand_erase: start = 0x%08x, len = %i\n", -		(unsigned int) instr->addr, (unsigned int) instr->len)); - -	/* Start address must align on block boundary */ -	if (instr->addr & (mtd->erasesize - 1)) { -		T(0,( -			"nand_erase: Unaligned address\n")); -		return -EINVAL; -	} - -	/* Length must align on block boundary */ -	if (instr->len & (mtd->erasesize - 1)) { -		T(0,( -			"nand_erase: Length not block aligned\n")); -		return -EINVAL; -	} - -	/* Do not allow erase past end of device */ -	if ((instr->len + instr->addr) > mtd->size) { -		T(0,( -			"nand_erase: Erase past end of device\n")); -		return -EINVAL; -	} - -	nBlocks = instr->len >> (NAND_SHIFT + BLK_SHIFT); -	block = instr->addr >> (NAND_SHIFT + BLK_SHIFT); - -	for(i = 0; i < nBlocks; i++) -	{ -		nandemul2k_DoErase(block); -		block++; -	} - -	instr->state = MTD_ERASE_DONE;  * change state to ERASE_DONE */ - -	instr->callback(instr);  * wake up */ - -	return 0; - - -} - - -static int nand_block_isbad(struct mtd_info *mtd, loff_t ofs) -{ -	return 0; -} - -static int nand_block_markbad(struct mtd_info *mtd, loff_t ofs) -{ -	return 0; -} - - -/* - * NAND sync - */ -static void nand_sync (struct mtd_info *mtd) -{ -	T(0,("nand_sync: called\n")); - -} - -/* - * Scan for the NAND device - */ -static int nandemul2k_scan (struct mtd_info *mtd,int nchips) -{ -	mtd->oobblock = PAGE_DATA_SIZE; -	mtd->oobsize =  PAGE_SPARE_SIZE; -	mtd->erasesize = PAGE_DATA_SIZE * PAGES_PER_BLOCK; -	mtd->size = sizeInMB * 1024*1024; - - - -	/* Fill in remaining MTD driver data */ -	mtd->type = MTD_NANDFLASH; -	mtd->flags = MTD_CAP_NANDFLASH; -	mtd->owner = THIS_MODULE; -	mtd->ecctype = MTD_ECC_NONE; -	mtd->erase = nand_erase; -	mtd->point = NULL; -	mtd->unpoint = NULL; -	mtd->read = nand_read; -	mtd->write = nand_write; -	mtd->read_ecc = nand_read_ecc; -	mtd->write_ecc = nand_write_ecc; -	mtd->read_oob = nand_read_oob; -	mtd->write_oob = nand_write_oob; -	mtd->block_isbad = nand_block_isbad; -	mtd->block_markbad = nand_block_markbad; -	mtd->readv = NULL; -	mtd->writev = nand_writev; -	mtd->sync = nand_sync; -	mtd->lock = NULL; -	mtd->unlock = NULL; -	mtd->suspend = NULL; -	mtd->resume = NULL; - -	mtd->name = "NANDemul2k"; - -	/* Return happy */ -	return 0; -} - -#if 0 -#ifdef MODULE -MODULE_PARM(sizeInMB, "i"); - -__setup("sizeInMB=",sizeInMB); -#endif -#endif - -/* - * Define partitions for flash devices - */ - -static struct mtd_partition nandemul2k_partition[] = -{ -	{ .name		= "NANDemul partition 1", -	  .offset	= 0, -	  .size		= 0 }, -}; - -static int nPartitions = sizeof(nandemul2k_partition)/sizeof(nandemul2k_partition[0]); - -/* - * Main initialization routine - */ -int __init nandemul2k_init (void) -{ - -	// Do the nand init -	 -	CheckInit(); - -	nandemul2k_scan(&nandemul2k_mtd,1); - -	// Build the partition table - -	nandemul2k_partition[0].size = sizeInMB * 1024 * 1024; - -	// Register the partition -	add_mtd_partitions(&nandemul2k_mtd,nandemul2k_partition,nPartitions); - -	return 0; - -} - -module_init(nandemul2k_init); - -/* - * Clean up routine - */ -#ifdef MODULE -static void __exit nandemul2k_cleanup (void) -{ - -	nandemul2k_CleanUp(); - -	/* Unregister partitions */ -	del_mtd_partitions(&nandemul2k_mtd); - -	/* Unregister the device */ -	del_mtd_device (&nandemul2k_mtd); - -} -module_exit(nandemul2k_cleanup); -#endif - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Charles Manning <manningc@aleph1.co.uk>"); -MODULE_DESCRIPTION("2k Page/128k Block NAND emulated in RAM"); - - - - diff --git a/fs/yaffs2/patch-ker.sh b/fs/yaffs2/patch-ker.sh deleted file mode 100755 index 173d1ce8b..000000000 --- a/fs/yaffs2/patch-ker.sh +++ /dev/null @@ -1,121 +0,0 @@ -#!/bin/sh -# -# YAFFS: Yet another FFS. A NAND-flash specific file system. -# -# Copyright (C) 2002-2006 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. -# -# Patch YAFFS into the kernel -# -#  args:  kpath  : Full path to kernel sources to be patched -# -#  Somewhat "inspired by" the mtd patchin script -# -#  $Id: patch-ker.sh,v 1.3 2007/07/25 01:04:38 charles Exp $ - -VERSION=0 -PATCHLEVEL=0 -SUBLEVEL=0 -COPYORLINK=$1 -LINUXDIR=$2 - -# To be a Linux directory, it must have a Makefile - - -# Display usage of this script -usage () { -	echo "usage:  $0  c/l kernelpath" -	echo " if c/l is c, then copy. If l then link" -	exit 1 -} - - - -if [ -z $LINUXDIR ] -then -    usage; -fi - -if [ $COPYORLINK = l ]; then -   CPY="ln -s" -elif [ $COPYORLINK = c ]; then -   CPY="cp" -else -   echo "unknown copy or link type" -   usage; -fi - - -# Check if kerneldir contains a Makefile -if [ ! -f $LINUXDIR/Makefile ]  -then  -	echo "Directory $LINUXDIR does not exist or is not a kernel source directory"; -	exit 1; -fi - -# Get kernel version -VERSION=`grep -s VERSION <$LINUXDIR/Makefile | head -n 1 | sed s/'VERSION = '//` -PATCHLEVEL=`grep -s PATCHLEVEL <$LINUXDIR/Makefile | head -n 1 | sed s/'PATCHLEVEL = '//` -SUBLEVEL=`grep -s SUBLEVEL <$LINUXDIR/Makefile | head -n 1 | sed s/'SUBLEVEL = '//` - -# Can we handle this version? -if [ $VERSION -ne 2  -o $PATCHLEVEL -lt 6  ] -then  -	echo "Cannot patch kernel version $VERSION.$PATCHLEVEL.$SUBLEVEL, must be 2.6.x or higher" -	exit 1; -fi - - -KCONFIG=$LINUXDIR/fs/Kconfig -KCONFIGOLD=$LINUXDIR/fs/Kconfig.pre.yaffs -YAFFS_PATCHED_STRING=`grep -s yaffs <$KCONFIG | head -n 1` - -MAKEFILE=$LINUXDIR/fs/Makefile -MAKEFILEOLD=$LINUXDIR/fs/Makefile.pre.yaffs - -if [ ! -z "$YAFFS_PATCHED_STRING" ] -then -    YAFFS_PATCHED=0 -    echo "$KCONFIG already mentions YAFFS, so we will not change it" -else -   # Change the fs/Kconfig file -   # Save the old Kconfig -   # Copy all stuff up to JFFS -   # Insert some YAFFS stuff -   # Copy all the rest of the stuff - -    YAFFS_PATCHED=1 -    echo "Updating $KCONFIG" -    mv -f $KCONFIG  $KCONFIGOLD -    sed -n -e "/JFFS/,99999 ! p" $KCONFIGOLD >$KCONFIG -    echo "">>$KCONFIG -    echo "# Patched by YAFFS" >>$KCONFIG -    echo "source \"fs/yaffs2/Kconfig\"">>$KCONFIG -    echo "">>$KCONFIG -    sed -n -e "/JFFS/,99999 p" $KCONFIGOLD >>$KCONFIG - -   # now do fs/Makefile -- simply add the target at the end -    echo "Updating $MAKEFILE" -    cp -f $MAKEFILE $MAKEFILEOLD -    echo "">>$MAKEFILE -    echo "# Patched by YAFFS" >>$MAKEFILE -    echo "obj-\$(CONFIG_YAFFS_FS)		+= yaffs2/" >>$MAKEFILE - -fi - -YAFFSDIR=$LINUXDIR/fs/yaffs2 - -if [ -e $YAFFSDIR ] -then -   echo "$YAFFSDIR exists, not patching" -else -   mkdir $LINUXDIR/fs/yaffs2 -   $CPY  $PWD/Makefile.kernel $LINUXDIR/fs/yaffs2/Makefile -   $CPY $PWD/Kconfig $LINUXDIR/fs/yaffs2 -   $CPY $PWD/*.c $PWD/*.h  $LINUXDIR/fs/yaffs2 -fi diff --git a/fs/yaffs2/patches/README.txt b/fs/yaffs2/patches/README.txt deleted file mode 100644 index e3666d9ec..000000000 --- a/fs/yaffs2/patches/README.txt +++ /dev/null @@ -1,6 +0,0 @@ -This directory holds patches that are useful for Linux integration. - -Right now there is only one patched file, yaffs_mtdif2.c. This has been -patched with a tweaked version of "Sergey's patch" and typically makes a -stock mtd work properly. - diff --git a/fs/yaffs2/patches/yaffs_mtdif2.c b/fs/yaffs2/patches/yaffs_mtdif2.c deleted file mode 100644 index df5753b50..000000000 --- a/fs/yaffs2/patches/yaffs_mtdif2.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - * YAFFS: Yet another FFS. A NAND-flash specific file system.  - * - * Copyright (C) 2002 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* mtd interface for YAFFS2 */ - -const char *yaffs_mtdif2_c_version = -    "$Id: yaffs_mtdif2.c,v 1.2 2007/03/07 08:05:58 colin Exp $"; - -#include "yportenv.h" - - -#include "yaffs_mtdif2.h" - -#include "linux/mtd/mtd.h" -#include "linux/types.h" -#include "linux/time.h" - -#include "yaffs_packedtags2.h" - - -void nandmtd2_pt2buf(yaffs_Device *dev, yaffs_PackedTags2 *pt, int is_raw) -{ -	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); -	__u8 *ptab = (__u8 *)pt; /* packed tags as bytes */ -	 -	int	i, j = 0, k, n; - -	/* Pack buffer with 0xff */ -	for (i = 0; i < mtd->oobsize; i++) -		dev->spareBuffer[i] = 0xff; -		 -	if(!is_raw){ -		memcpy(dev->spareBuffer,pt,sizeof(yaffs_PackedTags2)); -	} else { -		j = 0; -		k = mtd->oobinfo.oobfree[j][0]; -		n = mtd->oobinfo.oobfree[j][1]; - -		if (n == 0) { -			T(YAFFS_TRACE_ERROR, (TSTR("No OOB space for tags" TENDSTR))); -			YBUG(); -		} - -		for (i = 0; i < sizeof(yaffs_PackedTags2); i++) { -			if (n == 0) { -				j++; -				k = mtd->oobinfo.oobfree[j][0]; -				n = mtd->oobinfo.oobfree[j][1]; -				if (n == 0) { -					T(YAFFS_TRACE_ERROR, (TSTR("No OOB space for tags" TENDSTR))); -					YBUG(); -				} -			} -			dev->spareBuffer[k] = ptab[i]; -			k++; -			n--; -		} -	} - -} - -void nandmtd2_buf2pt(yaffs_Device *dev, yaffs_PackedTags2 *pt, int is_raw) -{ -	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); -	int	i, j = 0, k, n; -	__u8 *ptab = (__u8 *)pt; /* packed tags as bytes */ - - -	if (!is_raw) { -	 -		memcpy(pt,dev->spareBuffer,sizeof(yaffs_PackedTags2)); -	} else { -		j = 0; -		k = mtd->oobinfo.oobfree[j][0]; -		n = mtd->oobinfo.oobfree[j][1]; - -		if (n == 0) { -			T(YAFFS_TRACE_ERROR, (TSTR("No space in OOB for tags" TENDSTR))); -			YBUG(); -		} - -		for (i = 0; i < sizeof(yaffs_PackedTags2); i++) { -			if (n == 0) { -				j++; -				k = mtd->oobinfo.oobfree[j][0]; -				n = mtd->oobinfo.oobfree[j][1]; -				if (n == 0) { -					T(YAFFS_TRACE_ERROR, (TSTR("No space in OOB for tags" TENDSTR))); -					YBUG(); -				} -			} -			ptab[i] = dev->spareBuffer[k]; -			k++; -			n--; -		} -	} -		 -} - -int nandmtd2_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, -				      const __u8 * data, -				      const yaffs_ExtendedTags * tags) -{ -	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); -	size_t dummy; -	int retval = 0; - -	loff_t addr = ((loff_t) chunkInNAND) * dev->nBytesPerChunk; - -	yaffs_PackedTags2 pt; - -	T(YAFFS_TRACE_MTD, -	  (TSTR -	   ("nandmtd2_WriteChunkWithTagsToNAND chunk %d data %p tags %p" -	    TENDSTR), chunkInNAND, data, tags)); - -	if (tags) { -		yaffs_PackTags2(&pt, tags); -	} - -	if (data && tags) { -	                nandmtd2_pt2buf(dev, &pt, 0); -			retval = -			    mtd->write_ecc(mtd, addr, dev->nBytesPerChunk, -					   &dummy, data, dev->spareBuffer, -					   NULL); - -	} else { -	 -		T(YAFFS_TRACE_ALWAYS, -		  (TSTR -		  ("Write chunk with null tags or data!" TENDSTR))); -		YBUG(); - 	} - -	if (retval == 0) -		return YAFFS_OK; -	else -		return YAFFS_FAIL; -} - -int nandmtd2_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, -				       __u8 * data, yaffs_ExtendedTags * tags) -{ -	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); -	size_t dummy; -	int retval = 0; - -	loff_t addr = ((loff_t) chunkInNAND) * dev->nBytesPerChunk; - -	yaffs_PackedTags2 pt; - -	T(YAFFS_TRACE_MTD, -	  (TSTR -	   ("nandmtd2_ReadChunkWithTagsToNAND chunk %d data %p tags %p" -	    TENDSTR), chunkInNAND, data, tags)); - -	if (0 && data && tags) { -			retval = -			    mtd->read_ecc(mtd, addr, dev->nBytesPerChunk, -					  &dummy, data, dev->spareBuffer, -					  NULL); -			nandmtd2_buf2pt(dev, &pt, 0); -	} else { -		if (data) -			retval = -			    mtd->read(mtd, addr, dev->nBytesPerChunk, &dummy, -				      data); -		if (tags) { -			retval = -			    mtd->read_oob(mtd, addr, mtd->oobsize, &dummy, -					  dev->spareBuffer); -			nandmtd2_buf2pt(dev, &pt, 1); -		} -	} - -	if (tags) -		yaffs_UnpackTags2(tags, &pt); - -	if (retval == 0) -		return YAFFS_OK; -	else -		return YAFFS_FAIL; -} - -int nandmtd2_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) -{ -	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); -	int retval; -	T(YAFFS_TRACE_MTD, -	  (TSTR("nandmtd2_MarkNANDBlockBad %d" TENDSTR), blockNo)); - -	retval = -	    mtd->block_markbad(mtd, -			       blockNo * dev->nChunksPerBlock * -			       dev->nBytesPerChunk); - -	if (retval == 0) -		return YAFFS_OK; -	else -		return YAFFS_FAIL; - -} - -int nandmtd2_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, -			    yaffs_BlockState * state, int *sequenceNumber) -{ -	struct mtd_info *mtd = (struct mtd_info *)(dev->genericDevice); -	int retval; - -	T(YAFFS_TRACE_MTD, -	  (TSTR("nandmtd2_QueryNANDBlock %d" TENDSTR), blockNo)); -	retval = -	    mtd->block_isbad(mtd, -			     blockNo * dev->nChunksPerBlock * -			     dev->nBytesPerChunk); - -	if (retval) { -		T(YAFFS_TRACE_MTD, (TSTR("block is bad" TENDSTR))); - -		*state = YAFFS_BLOCK_STATE_DEAD; -		*sequenceNumber = 0; -	} else { -		yaffs_ExtendedTags t; -		nandmtd2_ReadChunkWithTagsFromNAND(dev, -						   blockNo * -						   dev->nChunksPerBlock, NULL, -						   &t); - -		if (t.chunkUsed) { -			*sequenceNumber = t.sequenceNumber; -			*state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; -		} else { -			*sequenceNumber = 0; -			*state = YAFFS_BLOCK_STATE_EMPTY; -		} - -		T(YAFFS_TRACE_MTD, -		  (TSTR("block is OK seq %d state %d" TENDSTR), *sequenceNumber, -		   *state)); -	} - -	if (retval == 0) -		return YAFFS_OK; -	else -		return YAFFS_FAIL; -} - diff --git a/fs/yaffs2/utils/Makefile b/fs/yaffs2/utils/Makefile deleted file mode 100644 index 49bf03b1b..000000000 --- a/fs/yaffs2/utils/Makefile +++ /dev/null @@ -1,54 +0,0 @@ -#Makefile for mkyaffs -# -# NB this is not yet suitable for putting into the kernel tree. -# YAFFS: Yet another Flash File System. A NAND-flash specific file system.  -# -# Copyright (C) 2002 Aleph One Ltd. -#   for Toby Churchill Ltd and Brightstar Engineering -# -# 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. - -## Change or override  KERNELDIR to your kernel - -#KERNELDIR = /usr/src/kernel-headers-2.4.18 - -CFLAGS =   -I/usr/include -I.. -O2 -Wall -DCONFIG_YAFFS_UTIL -CFLAGS+=   -Wshadow -Wpointer-arith -Wwrite-strings -Wstrict-prototypes -Wmissing-declarations -CFLAGS+=   -Wmissing-prototypes -Wredundant-decls -Wnested-externs -Winline - -## Change if you are using a cross-compiler -MAKETOOLS =  - -CC=$(MAKETOOLS)gcc - -COMMONLINKS = yaffs_ecc.c -COMMONOBJS = $(COMMONLINKS:.c=.o) - -MKYAFFSSOURCES = mkyaffsimage.c -MKYAFFSIMAGEOBJS = $(MKYAFFSSOURCES:.c=.o) - -MKYAFFS2SOURCES = mkyaffs2image.c -MKYAFFS2LINKS = yaffs_packedtags2.c yaffs_tagsvalidity.c -MKYAFFS2IMAGEOBJS = $(MKYAFFS2SOURCES:.c=.o) $(MKYAFFS2LINKS:.c=.o) - -all: mkyaffsimage mkyaffs2image - -$(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS2LINKS): -	ln -s ../$@ $@ - -$(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) : %.o: %.c -	$(CC) -c $(CFLAGS) $< -o $@ - -mkyaffsimage: $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) -	$(CC) -o $@ $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) - -mkyaffs2image: $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS) -	$(CC) -o $@ $(COMMONOBJS) $(MKYAFFS2IMAGEOBJS) - - -clean: -	rm -f $(COMMONOBJS) $(MKYAFFSIMAGEOBJS) $(MKYAFFS2IMAGEOBJS) $(COMMONLINKS) $(MKYAFFSLINKS) $(MKYAFFS2LINKS) mkyaffsimage mkyaffs2image core diff --git a/fs/yaffs2/utils/mkyaffs2image.c b/fs/yaffs2/utils/mkyaffs2image.c deleted file mode 100644 index 051666bcd..000000000 --- a/fs/yaffs2/utils/mkyaffs2image.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning <charles@aleph1.co.uk> - * Nick Bane modifications flagged NCB - * Endian handling patches by James Ng. - * mkyaffs2image hacks by NCB - * - * 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. - */ - -/* - * makeyaffs2image.c  - * - * Makes a YAFFS2 file system image that can be used to load up a file system. - * Uses default Linux MTD layout - change if you need something different. - */ -  -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <string.h> -#include <unistd.h> -#include "yaffs_ecc.h" -#include "yaffs_guts.h" - -#include "yaffs_tagsvalidity.h" -#include "yaffs_packedtags2.h" - -unsigned yaffs_traceMask=0; - -#define MAX_OBJECTS 10000 - -#define chunkSize 2048 -#define spareSize 64 - -const char * mkyaffsimage_c_version = "$Id: mkyaffs2image.c,v 1.4 2007/02/14 01:09:06 wookey Exp $"; - - -typedef struct -{ -	dev_t dev; -	ino_t ino; -	int   obj; -} objItem; - - -static objItem obj_list[MAX_OBJECTS]; -static int n_obj = 0; -static int obj_id = YAFFS_NOBJECT_BUCKETS + 1; - -static int nObjects, nDirectories, nPages; - -static int outFile; - -static int error; - -static int convert_endian = 0; - -static int obj_compare(const void *a, const void * b) -{ -  objItem *oa, *ob; -   -  oa = (objItem *)a; -  ob = (objItem *)b; -   -  if(oa->dev < ob->dev) return -1; -  if(oa->dev > ob->dev) return 1; -  if(oa->ino < ob->ino) return -1; -  if(oa->ino > ob->ino) return 1; -   -  return 0; -} - - -static void add_obj_to_list(dev_t dev, ino_t ino, int obj) -{ -	if(n_obj < MAX_OBJECTS) -	{ -		obj_list[n_obj].dev = dev; -		obj_list[n_obj].ino = ino; -		obj_list[n_obj].obj = obj; -		n_obj++; -		qsort(obj_list,n_obj,sizeof(objItem),obj_compare); -		 -	} -	else -	{ -		// oops! not enough space in the object array -		fprintf(stderr,"Not enough space in object array\n"); -		exit(2); -	} -} - - -static int find_obj_in_list(dev_t dev, ino_t ino) -{ -	objItem *i = NULL; -	objItem test; - -	test.dev = dev; -	test.ino = ino; -	 -	if(n_obj > 0) -	{ -		i = bsearch(&test,obj_list,n_obj,sizeof(objItem),obj_compare); -	} - -	if(i) -	{ -		return i->obj; -	} -	return -1; -} - -/* This little function converts a little endian tag to a big endian tag. - * NOTE: The tag is not usable after this other than calculating the CRC - * with. - */ -static void little_to_big_endian(yaffs_Tags *tagsPtr) -{ -#if 0 // FIXME NCB -    yaffs_TagsUnion * tags = (yaffs_TagsUnion* )tagsPtr; // Work in bytes. -    yaffs_TagsUnion   temp; - -    memset(&temp, 0, sizeof(temp)); -    // Ick, I hate magic numbers. -    temp.asBytes[0] = ((tags->asBytes[2] & 0x0F) << 4) | ((tags->asBytes[1] & 0xF0) >> 4); -    temp.asBytes[1] = ((tags->asBytes[1] & 0x0F) << 4) | ((tags->asBytes[0] & 0xF0) >> 4); -    temp.asBytes[2] = ((tags->asBytes[0] & 0x0F) << 4) | ((tags->asBytes[2] & 0x30) >> 2) | ((tags->asBytes[3] & 0xC0) >> 6); -    temp.asBytes[3] = ((tags->asBytes[3] & 0x3F) << 2) | ((tags->asBytes[2] & 0xC0) >> 6); -    temp.asBytes[4] = ((tags->asBytes[6] & 0x03) << 6) | ((tags->asBytes[5] & 0xFC) >> 2); -    temp.asBytes[5] = ((tags->asBytes[5] & 0x03) << 6) | ((tags->asBytes[4] & 0xFC) >> 2); -    temp.asBytes[6] = ((tags->asBytes[4] & 0x03) << 6) | (tags->asBytes[7] & 0x3F); -    temp.asBytes[7] = (tags->asBytes[6] & 0xFC) | ((tags->asBytes[7] & 0xC0) >> 6); - -    // Now copy it back. -    tags->asBytes[0] = temp.asBytes[0]; -    tags->asBytes[1] = temp.asBytes[1]; -    tags->asBytes[2] = temp.asBytes[2]; -    tags->asBytes[3] = temp.asBytes[3]; -    tags->asBytes[4] = temp.asBytes[4]; -    tags->asBytes[5] = temp.asBytes[5]; -    tags->asBytes[6] = temp.asBytes[6]; -    tags->asBytes[7] = temp.asBytes[7]; -#endif -} - -static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes) -{ -	yaffs_ExtendedTags t; -	yaffs_PackedTags2 pt; - -	error = write(outFile,data,chunkSize); -	if(error < 0) return error; - -	yaffs_InitialiseTags(&t); -	 -	t.chunkId = chunkId; -//	t.serialNumber = 0; -	t.serialNumber = 1;	// **CHECK** -	t.byteCount = nBytes; -	t.objectId = objId; -	 -	t.sequenceNumber = YAFFS_LOWEST_SEQUENCE_NUMBER; - -// added NCB **CHECK** -	t.chunkUsed = 1; - -	if (convert_endian) -	{ -    	    little_to_big_endian(&t); -	} - -	nPages++; - -	yaffs_PackTags2(&pt,&t); -	 -//	return write(outFile,&pt,sizeof(yaffs_PackedTags2)); -	return write(outFile,&pt,spareSize); -	 -} - -#define SWAP32(x)   ((((x) & 0x000000FF) << 24) | \ -                     (((x) & 0x0000FF00) << 8 ) | \ -                     (((x) & 0x00FF0000) >> 8 ) | \ -                     (((x) & 0xFF000000) >> 24)) - -#define SWAP16(x)   ((((x) & 0x00FF) << 8) | \ -                     (((x) & 0xFF00) >> 8)) -         -// This one is easier, since the types are more standard. No funky shifts here. -static void object_header_little_to_big_endian(yaffs_ObjectHeader* oh) -{ -    oh->type = SWAP32(oh->type); // GCC makes enums 32 bits. -    oh->parentObjectId = SWAP32(oh->parentObjectId); // int -    oh->sum__NoLongerUsed = SWAP16(oh->sum__NoLongerUsed); // __u16 - Not used, but done for completeness. -    // name = skip. Char array. Not swapped. -    oh->yst_mode = SWAP32(oh->yst_mode); -#ifdef CONFIG_YAFFS_WINCE // WinCE doesn't implement this, but we need to just in case.  -    // In fact, WinCE would be *THE* place where this would be an issue! -    oh->notForWinCE[0] = SWAP32(oh->notForWinCE[0]); -    oh->notForWinCE[1] = SWAP32(oh->notForWinCE[1]); -    oh->notForWinCE[2] = SWAP32(oh->notForWinCE[2]); -    oh->notForWinCE[3] = SWAP32(oh->notForWinCE[3]); -    oh->notForWinCE[4] = SWAP32(oh->notForWinCE[4]); -#else -    // Regular POSIX. -    oh->yst_uid = SWAP32(oh->yst_uid); -    oh->yst_gid = SWAP32(oh->yst_gid); -    oh->yst_atime = SWAP32(oh->yst_atime); -    oh->yst_mtime = SWAP32(oh->yst_mtime); -    oh->yst_ctime = SWAP32(oh->yst_ctime); -#endif - -    oh->fileSize = SWAP32(oh->fileSize); // Aiee. An int... signed, at that! -    oh->equivalentObjectId = SWAP32(oh->equivalentObjectId); -    // alias  - char array. -    oh->yst_rdev = SWAP32(oh->yst_rdev); - -#ifdef CONFIG_YAFFS_WINCE -    oh->win_ctime[0] = SWAP32(oh->win_ctime[0]); -    oh->win_ctime[1] = SWAP32(oh->win_ctime[1]); -    oh->win_atime[0] = SWAP32(oh->win_atime[0]); -    oh->win_atime[1] = SWAP32(oh->win_atime[1]); -    oh->win_mtime[0] = SWAP32(oh->win_mtime[0]); -    oh->win_mtime[1] = SWAP32(oh->win_mtime[1]); -    oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]); -    oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]); -    oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]); -    oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]); -    oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]); -    oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]); -#else -    oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]); -    oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]); -    oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]); -    oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]); -    oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]); -    oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]); -    oh->roomToGrow[6] = SWAP32(oh->roomToGrow[6]); -    oh->roomToGrow[7] = SWAP32(oh->roomToGrow[7]); -    oh->roomToGrow[8] = SWAP32(oh->roomToGrow[8]); -    oh->roomToGrow[9] = SWAP32(oh->roomToGrow[9]); -    oh->roomToGrow[10] = SWAP32(oh->roomToGrow[10]); -    oh->roomToGrow[11] = SWAP32(oh->roomToGrow[11]); -#endif -} - -static int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias) -{ -	__u8 bytes[chunkSize]; -	 -	 -	yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bytes; -	 -	memset(bytes,0xff,sizeof(bytes)); -	 -	oh->type = t; - -	oh->parentObjectId = parent; -	 -	strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH); -	 -	 -	if(t != YAFFS_OBJECT_TYPE_HARDLINK) -	{ -		oh->yst_mode = s->st_mode; -		oh->yst_uid = s->st_uid; -// NCB 12/9/02		oh->yst_gid = s->yst_uid; -		oh->yst_gid = s->st_gid; -		oh->yst_atime = s->st_atime; -		oh->yst_mtime = s->st_mtime; -		oh->yst_ctime = s->st_ctime; -		oh->yst_rdev  = s->st_rdev; -	} -	 -	if(t == YAFFS_OBJECT_TYPE_FILE) -	{ -		oh->fileSize = s->st_size; -	} -	 -	if(t == YAFFS_OBJECT_TYPE_HARDLINK) -	{ -		oh->equivalentObjectId = equivalentObj; -	} -	 -	if(t == YAFFS_OBJECT_TYPE_SYMLINK) -	{ -		strncpy(oh->alias,alias,YAFFS_MAX_ALIAS_LENGTH); -	} - -	if (convert_endian) -	{ -    		object_header_little_to_big_endian(oh); -	} -	 -	return write_chunk(bytes,objId,0,0xffff); -	 -} - - -static int process_directory(int parent, const char *path) -{ - -	DIR *dir; -	struct dirent *entry; - -	nDirectories++; -	 -	dir = opendir(path); -	 -	if(dir) -	{ -		while((entry = readdir(dir)) != NULL) -		{ -		 -			/* Ignore . and .. */ -			if(strcmp(entry->d_name,".") && -			   strcmp(entry->d_name,"..")) - 			{ - 				char full_name[500]; -				struct stat stats; -				int equivalentObj; -				int newObj; -				 -				sprintf(full_name,"%s/%s",path,entry->d_name); -				 -				lstat(full_name,&stats); -				 -				if(S_ISLNK(stats.st_mode) || -				    S_ISREG(stats.st_mode) || -				    S_ISDIR(stats.st_mode) || -				    S_ISFIFO(stats.st_mode) || -				    S_ISBLK(stats.st_mode) || -				    S_ISCHR(stats.st_mode) || -				    S_ISSOCK(stats.st_mode)) -				{ -				 -					newObj = obj_id++; -					nObjects++; -					 -					printf("Object %d, %s is a ",newObj,full_name); -					 -					/* We're going to create an object for it */ -					if((equivalentObj = find_obj_in_list(stats.st_dev, stats.st_ino)) > 0) -					{ -					 	/* we need to make a hard link */ -					 	printf("hard link to object %d\n",equivalentObj); -						error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL); -					} -					else  -					{ -						 -						add_obj_to_list(stats.st_dev,stats.st_ino,newObj); -						 -						if(S_ISLNK(stats.st_mode)) -						{ -					 -							char symname[500]; -						 -							memset(symname,0, sizeof(symname)); -					 -							readlink(full_name,symname,sizeof(symname) -1); -						 -							printf("symlink to \"%s\"\n",symname); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname); - -						} -						else if(S_ISREG(stats.st_mode)) -						{ -							printf("file, "); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL); - -							if(error >= 0) -							{ -								int h; -								__u8 bytes[chunkSize]; -								int nBytes; -								int chunk = 0; -								 -								h = open(full_name,O_RDONLY); -								if(h >= 0) -								{ -									memset(bytes,0xff,sizeof(bytes)); -									while((nBytes = read(h,bytes,sizeof(bytes))) > 0) -									{ -										chunk++; -										write_chunk(bytes,newObj,chunk,nBytes); -										memset(bytes,0xff,sizeof(bytes)); -									} -									if(nBytes < 0)  -									   error = nBytes; -									    -									printf("%d data chunks written\n",chunk); -								} -								else -								{ -									perror("Error opening file"); -								} -								close(h); -								 -							}							 -														 -						} -						else if(S_ISSOCK(stats.st_mode)) -						{ -							printf("socket\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL); -						} -						else if(S_ISFIFO(stats.st_mode)) -						{ -							printf("fifo\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL); -						} -						else if(S_ISCHR(stats.st_mode)) -						{ -							printf("character device\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL); -						} -						else if(S_ISBLK(stats.st_mode)) -						{ -							printf("block device\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL); -						} -						else if(S_ISDIR(stats.st_mode)) -						{ -							printf("directory\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL); -// NCB modified 10/9/2001				process_directory(1,full_name); -							process_directory(newObj,full_name); -						} -					} -				} -				else -				{ -					printf(" we don't handle this type\n"); -				} -			} -		} -	} -	 -	return 0; - -} - - -int main(int argc, char *argv[]) -{ -	struct stat stats; -	 -	printf("mkyaffs2image: image building tool for YAFFS2 built "__DATE__"\n"); -	 -	if(argc < 3) -	{ -		printf("usage: mkyaffs2image dir image_file [convert]\n"); -		printf("           dir        the directory tree to be converted\n"); -		printf("           image_file the output file to hold the image\n"); -        printf("           'convert'  produce a big-endian image from a little-endian machine\n"); -		exit(1); -	} - -    if ((argc == 4) && (!strncmp(argv[3], "convert", strlen("convert")))) -    { -        convert_endian = 1; -    } -     -	if(stat(argv[1],&stats) < 0) -	{ -		printf("Could not stat %s\n",argv[1]); -		exit(1); -	} -	 -	if(!S_ISDIR(stats.st_mode)) -	{ -		printf(" %s is not a directory\n",argv[1]); -		exit(1); -	} -	 -	outFile = open(argv[2],O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE); -	 -	 -	if(outFile < 0) -	{ -		printf("Could not open output file %s\n",argv[2]); -		exit(1); -	} -	 -	printf("Processing directory %s into image file %s\n",argv[1],argv[2]); -	error =  write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL); -	if(error) -	error = process_directory(YAFFS_OBJECTID_ROOT,argv[1]); -	 -	close(outFile); -	 -	if(error < 0) -	{ -		perror("operation incomplete"); -		exit(1); -	} -	else -	{ -		printf("Operation complete.\n" -		       "%d objects in %d directories\n" -		       "%d NAND pages\n",nObjects, nDirectories, nPages); -	} -	 -	close(outFile); -	 -	exit(0); -}	 - diff --git a/fs/yaffs2/utils/mkyaffsimage.c b/fs/yaffs2/utils/mkyaffsimage.c deleted file mode 100644 index 2b8dc1e91..000000000 --- a/fs/yaffs2/utils/mkyaffsimage.c +++ /dev/null @@ -1,590 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning <charles@aleph1.co.uk> - * Nick Bane modifications flagged NCB - * Endian handling patches by James Ng - * - * 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. - */ - -/* - * makeyaffsimage.c  - * - * Makes a YAFFS file system image that can be used to load up a file system. - */ -  -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <dirent.h> -#include <string.h> -#include <unistd.h> -#include "yaffs_ecc.h" -#include "yaffs_guts.h" - - -#define MAX_OBJECTS 10000 - -const char * mkyaffsimage_c_version = "$Id: mkyaffsimage.c,v 1.7 2003/07/16 03:00:48 charles Exp $"; - - -typedef struct -{ -	dev_t dev; -	ino_t ino; -	int   obj; -} objItem; - - -static objItem obj_list[MAX_OBJECTS]; -static int n_obj = 0; -static int obj_id = YAFFS_NOBJECT_BUCKETS + 1; - -static int nObjects, nDirectories, nPages; - -static int outFile; - -static int error; - -static int convert_endian = 0; - -static int obj_compare(const void *a, const void * b) -{ -  objItem *oa, *ob; -   -  oa = (objItem *)a; -  ob = (objItem *)b; -   -  if(oa->dev < ob->dev) return -1; -  if(oa->dev > ob->dev) return 1; -  if(oa->ino < ob->ino) return -1; -  if(oa->ino > ob->ino) return 1; -   -  return 0; -} - - -static void add_obj_to_list(dev_t dev, ino_t ino, int obj) -{ -	if(n_obj < MAX_OBJECTS) -	{ -		obj_list[n_obj].dev = dev; -		obj_list[n_obj].ino = ino; -		obj_list[n_obj].obj = obj; -		n_obj++; -		qsort(obj_list,n_obj,sizeof(objItem),obj_compare); -		 -	} -	else -	{ -		// oops! not enough space in the object array -		fprintf(stderr,"Not enough space in object array\n"); -		exit(2); -	} -} - - -static int find_obj_in_list(dev_t dev, ino_t ino) -{ -	objItem *i = NULL; -	objItem test; - -	test.dev = dev; -	test.ino = ino; -	 -	if(n_obj > 0) -	{ -		i = bsearch(&test,obj_list,n_obj,sizeof(objItem),obj_compare); -	} - -	if(i) -	{ -		return i->obj; -	} -	return -1; -} - -// NCB added 10/9/2002 -static __u16 yaffs_CalcNameSum(const char *name) -{ -	__u16 sum = 0; -	__u16 i = 1; -	 -	__u8 *bname = (__u8 *)name; -	 -	while (*bname) -	{ -		sum += (*bname) * i; -		i++; -		bname++; -	} -	return sum; -} - - -static void yaffs_CalcECC(const __u8 *data, yaffs_Spare *spare) -{ -	yaffs_ECCCalculate(data , spare->ecc1); -	yaffs_ECCCalculate(&data[256] , spare->ecc2); -} - -static void yaffs_CalcTagsECC(yaffs_Tags *tags) -{ -	// Todo don't do anything yet. Need to calculate ecc -	unsigned char *b = ((yaffs_TagsUnion *)tags)->asBytes; -	unsigned  i,j; -	unsigned  ecc = 0; -	unsigned bit = 0; - -    // Clear ECC fields -    if (!convert_endian) -    { -	    tags->ecc = 0; -    } -    else -    { -        // Because we're in "munged tag" mode, we have to clear it manually -        b[6] &= 0xC0; -        b[7] &= 0x03; -    } -	 -	for(i = 0; i < 8; i++) -	{ -// NCB modified 20-9-02		for(j = 1; j &0x7f; j<<=1) -		for(j = 1; j &0xff; j<<=1) -		{ -			bit++; -			if(b[i] & j) -			{ -				ecc ^= bit; -			} -		} -	} -	 -	// Write out ECC -    if (!convert_endian) -    { -        tags->ecc = ecc; -    } -    else -    { -	    // We have to munge the ECC again. -	    b[6] |= ((ecc >> 6) & 0x3F); -        b[7] |= ((ecc & 0x3F) << 2); -    } -} -static void yaffs_LoadTagsIntoSpare(yaffs_Spare *sparePtr, yaffs_Tags *tagsPtr) -{ -	yaffs_TagsUnion *tu = (yaffs_TagsUnion *)tagsPtr; -	 -	//yaffs_CalcTagsECC(tagsPtr); -	 -	sparePtr->tagByte0 = tu->asBytes[0]; -	sparePtr->tagByte1 = tu->asBytes[1]; -	sparePtr->tagByte2 = tu->asBytes[2]; -	sparePtr->tagByte3 = tu->asBytes[3]; -	sparePtr->tagByte4 = tu->asBytes[4]; -	sparePtr->tagByte5 = tu->asBytes[5]; -	sparePtr->tagByte6 = tu->asBytes[6]; -	sparePtr->tagByte7 = tu->asBytes[7]; -} - -/* This little function converts a little endian tag to a big endian tag. - * NOTE: The tag is not usable after this other than calculating the CRC - * with. - */ -static void little_to_big_endian(yaffs_Tags *tagsPtr) -{ -    yaffs_TagsUnion * tags = (yaffs_TagsUnion* )tagsPtr; // Work in bytes. -    yaffs_TagsUnion   temp; - -    memset(&temp, 0, sizeof(temp)); -    // Ick, I hate magic numbers. -    temp.asBytes[0] = ((tags->asBytes[2] & 0x0F) << 4) | ((tags->asBytes[1] & 0xF0) >> 4); -    temp.asBytes[1] = ((tags->asBytes[1] & 0x0F) << 4) | ((tags->asBytes[0] & 0xF0) >> 4); -    temp.asBytes[2] = ((tags->asBytes[0] & 0x0F) << 4) | ((tags->asBytes[2] & 0x30) >> 2) | ((tags->asBytes[3] & 0xC0) >> 6); -    temp.asBytes[3] = ((tags->asBytes[3] & 0x3F) << 2) | ((tags->asBytes[2] & 0xC0) >> 6); -    temp.asBytes[4] = ((tags->asBytes[6] & 0x03) << 6) | ((tags->asBytes[5] & 0xFC) >> 2); -    temp.asBytes[5] = ((tags->asBytes[5] & 0x03) << 6) | ((tags->asBytes[4] & 0xFC) >> 2); -    temp.asBytes[6] = ((tags->asBytes[4] & 0x03) << 6) | (tags->asBytes[7] & 0x3F); -    temp.asBytes[7] = (tags->asBytes[6] & 0xFC) | ((tags->asBytes[7] & 0xC0) >> 6); - -    // Now copy it back. -    tags->asBytes[0] = temp.asBytes[0]; -    tags->asBytes[1] = temp.asBytes[1]; -    tags->asBytes[2] = temp.asBytes[2]; -    tags->asBytes[3] = temp.asBytes[3]; -    tags->asBytes[4] = temp.asBytes[4]; -    tags->asBytes[5] = temp.asBytes[5]; -    tags->asBytes[6] = temp.asBytes[6]; -    tags->asBytes[7] = temp.asBytes[7]; -} - -static int write_chunk(__u8 *data, __u32 objId, __u32 chunkId, __u32 nBytes) -{ -	yaffs_Tags t; -	yaffs_Spare s; - -	error = write(outFile,data,512); -	if(error < 0) return error; - -	memset(&t,0xff,sizeof (yaffs_Tags)); -	memset(&s,0xff,sizeof (yaffs_Spare)); -	 -	t.chunkId = chunkId; -	t.serialNumber = 0; -	t.byteCount = nBytes; -	t.objectId = objId; - -    if (convert_endian) -    { -        little_to_big_endian(&t); -    } -	 -	yaffs_CalcTagsECC(&t); -	yaffs_LoadTagsIntoSpare(&s,&t); -	yaffs_CalcECC(data,&s); -	 -	nPages++; -	 -	return write(outFile,&s,sizeof(yaffs_Spare)); -	 -} - -#define SWAP32(x)   ((((x) & 0x000000FF) << 24) | \ -                     (((x) & 0x0000FF00) << 8 ) | \ -                     (((x) & 0x00FF0000) >> 8 ) | \ -                     (((x) & 0xFF000000) >> 24)) - -#define SWAP16(x)   ((((x) & 0x00FF) << 8) | \ -                     (((x) & 0xFF00) >> 8)) -         -// This one is easier, since the types are more standard. No funky shifts here. -static void object_header_little_to_big_endian(yaffs_ObjectHeader* oh) -{ -    oh->type = SWAP32(oh->type); // GCC makes enums 32 bits. -    oh->parentObjectId = SWAP32(oh->parentObjectId); // int -    oh->sum__NoLongerUsed = SWAP16(oh->sum__NoLongerUsed); // __u16 - Not used, but done for completeness. -    // name = skip. Char array. Not swapped. -    oh->yst_mode = SWAP32(oh->yst_mode); -#ifdef CONFIG_YAFFS_WINCE // WinCE doesn't implement this, but we need to just in case.  -    // In fact, WinCE would be *THE* place where this would be an issue! -    oh->notForWinCE[0] = SWAP32(oh->notForWinCE[0]); -    oh->notForWinCE[1] = SWAP32(oh->notForWinCE[1]); -    oh->notForWinCE[2] = SWAP32(oh->notForWinCE[2]); -    oh->notForWinCE[3] = SWAP32(oh->notForWinCE[3]); -    oh->notForWinCE[4] = SWAP32(oh->notForWinCE[4]); -#else -    // Regular POSIX. -    oh->yst_uid = SWAP32(oh->yst_uid); -    oh->yst_gid = SWAP32(oh->yst_gid); -    oh->yst_atime = SWAP32(oh->yst_atime); -    oh->yst_mtime = SWAP32(oh->yst_mtime); -    oh->yst_ctime = SWAP32(oh->yst_ctime); -#endif - -    oh->fileSize = SWAP32(oh->fileSize); // Aiee. An int... signed, at that! -    oh->equivalentObjectId = SWAP32(oh->equivalentObjectId); -    // alias  - char array. -    oh->yst_rdev = SWAP32(oh->yst_rdev); - -#ifdef CONFIG_YAFFS_WINCE -    oh->win_ctime[0] = SWAP32(oh->win_ctime[0]); -    oh->win_ctime[1] = SWAP32(oh->win_ctime[1]); -    oh->win_atime[0] = SWAP32(oh->win_atime[0]); -    oh->win_atime[1] = SWAP32(oh->win_atime[1]); -    oh->win_mtime[0] = SWAP32(oh->win_mtime[0]); -    oh->win_mtime[1] = SWAP32(oh->win_mtime[1]); -    oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]); -    oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]); -    oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]); -    oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]); -    oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]); -    oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]); -#else -    oh->roomToGrow[0] = SWAP32(oh->roomToGrow[0]); -    oh->roomToGrow[1] = SWAP32(oh->roomToGrow[1]); -    oh->roomToGrow[2] = SWAP32(oh->roomToGrow[2]); -    oh->roomToGrow[3] = SWAP32(oh->roomToGrow[3]); -    oh->roomToGrow[4] = SWAP32(oh->roomToGrow[4]); -    oh->roomToGrow[5] = SWAP32(oh->roomToGrow[5]); -    oh->roomToGrow[6] = SWAP32(oh->roomToGrow[6]); -    oh->roomToGrow[7] = SWAP32(oh->roomToGrow[7]); -    oh->roomToGrow[8] = SWAP32(oh->roomToGrow[8]); -    oh->roomToGrow[9] = SWAP32(oh->roomToGrow[9]); -    oh->roomToGrow[10] = SWAP32(oh->roomToGrow[10]); -    oh->roomToGrow[11] = SWAP32(oh->roomToGrow[11]); -#endif -} - -static int write_object_header(int objId, yaffs_ObjectType t, struct stat *s, int parent, const char *name, int equivalentObj, const char * alias) -{ -	__u8 bytes[512]; -	 -	 -	yaffs_ObjectHeader *oh = (yaffs_ObjectHeader *)bytes; -	 -	memset(bytes,0xff,512); -	 -	oh->type = t; - -	oh->parentObjectId = parent; -	 -	strncpy(oh->name,name,YAFFS_MAX_NAME_LENGTH); -	 -	 -	if(t != YAFFS_OBJECT_TYPE_HARDLINK) -	{ -		oh->yst_mode = s->st_mode; -		oh->yst_uid = s->st_uid; -// NCB 12/9/02		oh->yst_gid = s->yst_uid; -		oh->yst_gid = s->st_gid; -		oh->yst_atime = s->st_atime; -		oh->yst_mtime = s->st_mtime; -		oh->yst_ctime = s->st_ctime; -		oh->yst_rdev  = s->st_rdev; -	} -	 -	if(t == YAFFS_OBJECT_TYPE_FILE) -	{ -		oh->fileSize = s->st_size; -	} -	 -	if(t == YAFFS_OBJECT_TYPE_HARDLINK) -	{ -		oh->equivalentObjectId = equivalentObj; -	} -	 -	if(t == YAFFS_OBJECT_TYPE_SYMLINK) -	{ -		strncpy(oh->alias,alias,YAFFS_MAX_ALIAS_LENGTH); -	} - -    if (convert_endian) -    { -        object_header_little_to_big_endian(oh); -    } -	 -	return write_chunk(bytes,objId,0,0xffff); -	 -} - - -static int process_directory(int parent, const char *path) -{ - -	DIR *dir; -	struct dirent *entry; - -	nDirectories++; -	 -	dir = opendir(path); -	 -	if(dir) -	{ -		while((entry = readdir(dir)) != NULL) -		{ -		 -			/* Ignore . and .. */ -			if(strcmp(entry->d_name,".") && -			   strcmp(entry->d_name,"..")) - 			{ - 				char full_name[500]; -				struct stat stats; -				int equivalentObj; -				int newObj; -				 -				sprintf(full_name,"%s/%s",path,entry->d_name); -				 -				lstat(full_name,&stats); -				 -				if(S_ISLNK(stats.st_mode) || -				    S_ISREG(stats.st_mode) || -				    S_ISDIR(stats.st_mode) || -				    S_ISFIFO(stats.st_mode) || -				    S_ISBLK(stats.st_mode) || -				    S_ISCHR(stats.st_mode) || -				    S_ISSOCK(stats.st_mode)) -				{ -				 -					newObj = obj_id++; -					nObjects++; -					 -					printf("Object %d, %s is a ",newObj,full_name); -					 -					/* We're going to create an object for it */ -					if((equivalentObj = find_obj_in_list(stats.st_dev, stats.st_ino)) > 0) -					{ -					 	/* we need to make a hard link */ -					 	printf("hard link to object %d\n",equivalentObj); -						error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_HARDLINK, &stats, parent, entry->d_name, equivalentObj, NULL); -					} -					else  -					{ -						 -						add_obj_to_list(stats.st_dev,stats.st_ino,newObj); -						 -						if(S_ISLNK(stats.st_mode)) -						{ -					 -							char symname[500]; -						 -							memset(symname,0, sizeof(symname)); -					 -							readlink(full_name,symname,sizeof(symname) -1); -						 -							printf("symlink to \"%s\"\n",symname); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SYMLINK, &stats, parent, entry->d_name, -1, symname); - -						} -						else if(S_ISREG(stats.st_mode)) -						{ -							printf("file, "); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_FILE, &stats, parent, entry->d_name, -1, NULL); - -							if(error >= 0) -							{ -								int h; -								__u8 bytes[512]; -								int nBytes; -								int chunk = 0; -								 -								h = open(full_name,O_RDONLY); -								if(h >= 0) -								{ -									memset(bytes,0xff,512); -									while((nBytes = read(h,bytes,512)) > 0) -									{ -										chunk++; -										write_chunk(bytes,newObj,chunk,nBytes); -										memset(bytes,0xff,512); -									} -									if(nBytes < 0)  -									   error = nBytes; -									    -									printf("%d data chunks written\n",chunk); -								} -								else -								{ -									perror("Error opening file"); -								} -								close(h); -								 -							}							 -														 -						} -						else if(S_ISSOCK(stats.st_mode)) -						{ -							printf("socket\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL); -						} -						else if(S_ISFIFO(stats.st_mode)) -						{ -							printf("fifo\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL); -						} -						else if(S_ISCHR(stats.st_mode)) -						{ -							printf("character device\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL); -						} -						else if(S_ISBLK(stats.st_mode)) -						{ -							printf("block device\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_SPECIAL, &stats, parent, entry->d_name, -1, NULL); -						} -						else if(S_ISDIR(stats.st_mode)) -						{ -							printf("directory\n"); -							error =  write_object_header(newObj, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, parent, entry->d_name, -1, NULL); -// NCB modified 10/9/2001				process_directory(1,full_name); -							process_directory(newObj,full_name); -						} -					} -				} -				else -				{ -					printf(" we don't handle this type\n"); -				} -			} -		} -	} -	 -	return 0; - -} - - -int main(int argc, char *argv[]) -{ -	struct stat stats; -	 -	printf("mkyaffsimage: image building tool for YAFFS built "__DATE__"\n"); -	 -	if(argc < 3) -	{ -		printf("usage: mkyaffsimage dir image_file [convert]\n"); -		printf("           dir        the directory tree to be converted\n"); -		printf("           image_file the output file to hold the image\n"); -        printf("           'convert'  produce a big-endian image from a little-endian machine\n"); -		exit(1); -	} - -    if ((argc == 4) && (!strncmp(argv[3], "convert", strlen("convert")))) -    { -        convert_endian = 1; -    } -     -	if(stat(argv[1],&stats) < 0) -	{ -		printf("Could not stat %s\n",argv[1]); -		exit(1); -	} -	 -	if(!S_ISDIR(stats.st_mode)) -	{ -		printf(" %s is not a directory\n",argv[1]); -		exit(1); -	} -	 -	outFile = open(argv[2],O_CREAT | O_TRUNC | O_WRONLY, S_IREAD | S_IWRITE); -	 -	 -	if(outFile < 0) -	{ -		printf("Could not open output file %s\n",argv[2]); -		exit(1); -	} -	 -	printf("Processing directory %s into image file %s\n",argv[1],argv[2]); -	error =  write_object_header(1, YAFFS_OBJECT_TYPE_DIRECTORY, &stats, 1,"", -1, NULL); -	if(error) -	error = process_directory(YAFFS_OBJECTID_ROOT,argv[1]); -	 -	close(outFile); -	 -	if(error < 0) -	{ -		perror("operation incomplete"); -		exit(1); -	} -	else -	{ -		printf("Operation complete.\n" -		       "%d objects in %d directories\n" -		       "%d NAND pages\n",nObjects, nDirectories, nPages); -	} -	 -	close(outFile); -	 -	exit(0); -}	 - diff --git a/fs/yaffs2/yaffs_fs.c b/fs/yaffs2/yaffs_fs.c deleted file mode 100644 index f7a8ebd44..000000000 --- a/fs/yaffs2/yaffs_fs.c +++ /dev/null @@ -1,2299 +0,0 @@ -/* - * YAFFS: Yet Another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * Created by Charles Manning <charles@aleph1.co.uk> - * Acknowledgements: - * Luc van OostenRyck for numerous patches. - * Nick Bane for numerous patches. - * Nick Bane for 2.5/2.6 integration. - * Andras Toth for mknod rdev issue. - * Michael Fischer for finding the problem with inode inconsistency. - * Some code bodily lifted from JFFS - * - * 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. - */ - -/* - * - * This is the file system front-end to YAFFS that hooks it up to - * the VFS. - * - * Special notes:  - * >> 2.4: sb->u.generic_sbp points to the yaffs_Device associated with - *         this superblock - * >> 2.6: sb->s_fs_info  points to the yaffs_Device associated with this - *         superblock - * >> inode->u.generic_ip points to the associated yaffs_Object. - */ - -const char *yaffs_fs_c_version = -    "$Id: yaffs_fs.c,v 1.63 2007/09/19 20:35:40 imcd Exp $"; -extern const char *yaffs_guts_c_version; - -#include <linux/version.h> -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) -#include <linux/config.h> -#endif -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/init.h> -#include <linux/list.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> -#include <linux/string.h> -#include <linux/ctype.h> - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - -#include <linux/statfs.h>	/* Added NCB 15-8-2003 */ -#include <asm/statfs.h> -#define UnlockPage(p) unlock_page(p) -#define Page_Uptodate(page)	test_bit(PG_uptodate, &(page)->flags) - -/* FIXME: use sb->s_id instead ? */ -#define yaffs_devname(sb, buf)	bdevname(sb->s_bdev, buf) - -#else - -#include <linux/locks.h> -#define	BDEVNAME_SIZE		0 -#define	yaffs_devname(sb, buf)	kdevname(sb->s_dev) - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) -/* added NCB 26/5/2006 for 2.4.25-vrs2-tcl1 kernel */ -#define __user -#endif - -#endif - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -#define WRITE_SIZE_STR "writesize" -#define WRITE_SIZE(mtd) (mtd)->writesize -#else -#define WRITE_SIZE_STR "oobblock" -#define WRITE_SIZE(mtd) (mtd)->oobblock -#endif - -#include <asm/uaccess.h> - -#include "yportenv.h" -#include "yaffs_guts.h" - -#include <linux/mtd/mtd.h> -#include "yaffs_mtdif.h" -#include "yaffs_mtdif1.h" -#include "yaffs_mtdif2.h" - -unsigned int yaffs_traceMask = YAFFS_TRACE_BAD_BLOCKS; -unsigned int yaffs_wr_attempts = YAFFS_WR_ATTEMPTS; - -/* Module Parameters */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -module_param(yaffs_traceMask,uint,0644); -module_param(yaffs_wr_attempts,uint,0644); -#else -MODULE_PARM(yaffs_traceMask,"i"); -MODULE_PARM(yaffs_wr_attempts,"i"); -#endif - -/*#define T(x) printk x */ - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) -#define yaffs_InodeToObjectLV(iptr) (iptr)->i_private -#else -#define yaffs_InodeToObjectLV(iptr) (iptr)->u.generic_ip -#endif - -#define yaffs_InodeToObject(iptr) ((yaffs_Object *)(yaffs_InodeToObjectLV(iptr))) -#define yaffs_DentryToObject(dptr) yaffs_InodeToObject((dptr)->d_inode) - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -#define yaffs_SuperToDevice(sb)	((yaffs_Device *)sb->s_fs_info) -#else -#define yaffs_SuperToDevice(sb)	((yaffs_Device *)sb->u.generic_sbp) -#endif - -static void yaffs_put_super(struct super_block *sb); - -static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, -				loff_t * pos); - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static int yaffs_file_flush(struct file *file, fl_owner_t id); -#else -static int yaffs_file_flush(struct file *file); -#endif - -static int yaffs_sync_object(struct file *file, struct dentry *dentry, -			     int datasync); - -static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir); - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, -			struct nameidata *n); -static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, -				   struct nameidata *n); -#else -static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode); -static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry); -#endif -static int yaffs_link(struct dentry *old_dentry, struct inode *dir, -		      struct dentry *dentry); -static int yaffs_unlink(struct inode *dir, struct dentry *dentry); -static int yaffs_symlink(struct inode *dir, struct dentry *dentry, -			 const char *symname); -static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode); - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, -		       dev_t dev); -#else -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, -		       int dev); -#endif -static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, -			struct inode *new_dir, struct dentry *new_dentry); -static int yaffs_setattr(struct dentry *dentry, struct iattr *attr); - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static int yaffs_sync_fs(struct super_block *sb, int wait); -static void yaffs_write_super(struct super_block *sb); -#else -static int yaffs_sync_fs(struct super_block *sb); -static int yaffs_write_super(struct super_block *sb); -#endif - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf); -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf); -#else -static int yaffs_statfs(struct super_block *sb, struct statfs *buf); -#endif -static void yaffs_read_inode(struct inode *inode); - -static void yaffs_put_inode(struct inode *inode); -static void yaffs_delete_inode(struct inode *); -static void yaffs_clear_inode(struct inode *); - -static int yaffs_readpage(struct file *file, struct page *page); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_writepage(struct page *page, struct writeback_control *wbc); -#else -static int yaffs_writepage(struct page *page); -#endif -static int yaffs_prepare_write(struct file *f, struct page *pg, -			       unsigned offset, unsigned to); -static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, -			      unsigned to); - -static int yaffs_readlink(struct dentry *dentry, char __user * buffer, -			  int buflen); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) -static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); -#else -static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); -#endif - -static struct address_space_operations yaffs_file_address_operations = { -	.readpage = yaffs_readpage, -	.writepage = yaffs_writepage, -	.prepare_write = yaffs_prepare_write, -	.commit_write = yaffs_commit_write, -}; - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,22)) -static struct file_operations yaffs_file_operations = { -	.read = do_sync_read, -	.write = do_sync_write, -	.aio_read = generic_file_aio_read, -	.aio_write = generic_file_aio_write, -	.mmap = generic_file_mmap, -	.flush = yaffs_file_flush, -	.fsync = yaffs_sync_object, -	.splice_read = generic_file_splice_read, -	.splice_write = generic_file_splice_write, -}; - -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,18)) - -static struct file_operations yaffs_file_operations = { -	.read = do_sync_read, -	.write = do_sync_write, -	.aio_read = generic_file_aio_read, -	.aio_write = generic_file_aio_write, -	.mmap = generic_file_mmap, -	.flush = yaffs_file_flush, -	.fsync = yaffs_sync_object, -	.sendfile = generic_file_sendfile, -}; - -#else - -static struct file_operations yaffs_file_operations = { -	.read = generic_file_read, -	.write = generic_file_write, -	.mmap = generic_file_mmap, -	.flush = yaffs_file_flush, -	.fsync = yaffs_sync_object, -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -	.sendfile = generic_file_sendfile, -#endif -}; -#endif - -static struct inode_operations yaffs_file_inode_operations = { -	.setattr = yaffs_setattr, -}; - -static struct inode_operations yaffs_symlink_inode_operations = { -	.readlink = yaffs_readlink, -	.follow_link = yaffs_follow_link, -	.setattr = yaffs_setattr, -}; - -static struct inode_operations yaffs_dir_inode_operations = { -	.create = yaffs_create, -	.lookup = yaffs_lookup, -	.link = yaffs_link, -	.unlink = yaffs_unlink, -	.symlink = yaffs_symlink, -	.mkdir = yaffs_mkdir, -	.rmdir = yaffs_unlink, -	.mknod = yaffs_mknod, -	.rename = yaffs_rename, -	.setattr = yaffs_setattr, -}; - -static struct file_operations yaffs_dir_operations = { -	.read = generic_read_dir, -	.readdir = yaffs_readdir, -	.fsync = yaffs_sync_object, -}; - -static struct super_operations yaffs_super_ops = { -	.statfs = yaffs_statfs, -	.read_inode = yaffs_read_inode, -	.put_inode = yaffs_put_inode, -	.put_super = yaffs_put_super, -	.delete_inode = yaffs_delete_inode, -	.clear_inode = yaffs_clear_inode, -	.sync_fs = yaffs_sync_fs, -	.write_super = yaffs_write_super, -}; - -static void yaffs_GrossLock(yaffs_Device * dev) -{ -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs locking\n")); - -	down(&dev->grossLock); -} - -static void yaffs_GrossUnlock(yaffs_Device * dev) -{ -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs unlocking\n")); -	up(&dev->grossLock); - -} - -static int yaffs_readlink(struct dentry *dentry, char __user * buffer, -			  int buflen) -{ -	unsigned char *alias; -	int ret; - -	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; - -	yaffs_GrossLock(dev); - -	alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); - -	yaffs_GrossUnlock(dev); - -	if (!alias) -		return -ENOMEM; - -	ret = vfs_readlink(dentry, buffer, buflen, alias); -	kfree(alias); -	return ret; -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) -static void *yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) -#else -static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd) -#endif -{ -	unsigned char *alias; -	int ret; -	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; - -	yaffs_GrossLock(dev); - -	alias = yaffs_GetSymlinkAlias(yaffs_DentryToObject(dentry)); - -	yaffs_GrossUnlock(dev); - -	if (!alias) -        { -		ret = -ENOMEM; -		goto out; -        } - -	ret = vfs_follow_link(nd, alias); -	kfree(alias); -out: -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) -	return ERR_PTR (ret); -#else -	return ret; -#endif -} - -struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, -			      yaffs_Object * obj); - -/* - * Lookup is used to find objects in the fs - */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - -static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry, -				   struct nameidata *n) -#else -static struct dentry *yaffs_lookup(struct inode *dir, struct dentry *dentry) -#endif -{ -	yaffs_Object *obj; -	struct inode *inode = NULL;	/* NCB 2.5/2.6 needs NULL here */ - -	yaffs_Device *dev = yaffs_InodeToObject(dir)->myDev; - -	yaffs_GrossLock(dev); - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_lookup for %d:%s\n", -	   yaffs_InodeToObject(dir)->objectId, dentry->d_name.name)); - -	obj = -	    yaffs_FindObjectByName(yaffs_InodeToObject(dir), -				   dentry->d_name.name); - -	obj = yaffs_GetEquivalentObject(obj);	/* in case it was a hardlink */ -	 -	/* Can't hold gross lock when calling yaffs_get_inode() */ -	yaffs_GrossUnlock(dev); - -	if (obj) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_lookup found %d\n", obj->objectId)); - -		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); - -		if (inode) { -			T(YAFFS_TRACE_OS, -			  (KERN_DEBUG "yaffs_loookup dentry \n")); -/* #if 0 asserted by NCB for 2.5/6 compatability - falls through to - * d_add even if NULL inode */ -#if 0 -			/*dget(dentry); // try to solve directory bug */ -			d_add(dentry, inode); - -			/* return dentry; */ -			return NULL; -#endif -		} - -	} else { -		T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_lookup not found\n")); - -	} - -/* added NCB for 2.5/6 compatability - forces add even if inode is - * NULL which creates dentry hash */ -	d_add(dentry, inode); - -	return NULL; -	/*      return (ERR_PTR(-EIO)); */ - -} - -/* For now put inode is just for debugging - * Put inode is called when the inode **structure** is put. - */ -static void yaffs_put_inode(struct inode *inode) -{ -	T(YAFFS_TRACE_OS, -	  ("yaffs_put_inode: ino %d, count %d\n", (int)inode->i_ino, -	   atomic_read(&inode->i_count))); - -} - -/* clear is called to tell the fs to release any per-inode data it holds */ -static void yaffs_clear_inode(struct inode *inode) -{ -	yaffs_Object *obj; -	yaffs_Device *dev; - -	obj = yaffs_InodeToObject(inode); - -	T(YAFFS_TRACE_OS, -	  ("yaffs_clear_inode: ino %d, count %d %s\n", (int)inode->i_ino, -	   atomic_read(&inode->i_count), -	   obj ? "object exists" : "null object")); - -	if (obj) { -		dev = obj->myDev; -		yaffs_GrossLock(dev); - -		/* Clear the association between the inode and -		 * the yaffs_Object. -		 */ -		obj->myInode = NULL; -		yaffs_InodeToObjectLV(inode) = NULL; - -		/* If the object freeing was deferred, then the real -		 * free happens now. -		 * This should fix the inode inconsistency problem. -		 */ - -		yaffs_HandleDeferedFree(obj); - -		yaffs_GrossUnlock(dev); -	} - -} - -/* delete is called when the link count is zero and the inode - * is put (ie. nobody wants to know about it anymore, time to - * delete the file). - * NB Must call clear_inode() - */ -static void yaffs_delete_inode(struct inode *inode) -{ -	yaffs_Object *obj = yaffs_InodeToObject(inode); -	yaffs_Device *dev; - -	T(YAFFS_TRACE_OS, -	  ("yaffs_delete_inode: ino %d, count %d %s\n", (int)inode->i_ino, -	   atomic_read(&inode->i_count), -	   obj ? "object exists" : "null object")); - -	if (obj) { -		dev = obj->myDev; -		yaffs_GrossLock(dev); -		yaffs_DeleteFile(obj); -		yaffs_GrossUnlock(dev); -	} -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,13)) -        truncate_inode_pages (&inode->i_data, 0); -#endif -	clear_inode(inode); -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static int yaffs_file_flush(struct file *file, fl_owner_t id) -#else -static int yaffs_file_flush(struct file *file) -#endif -{ -	yaffs_Object *obj = yaffs_DentryToObject(file->f_dentry); - -	yaffs_Device *dev = obj->myDev; - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_file_flush object %d (%s)\n", obj->objectId, -	   obj->dirty ? "dirty" : "clean")); - -	yaffs_GrossLock(dev); - -	yaffs_FlushFile(obj, 1); - -	yaffs_GrossUnlock(dev); - -	return 0; -} - -static int yaffs_readpage_nolock(struct file *f, struct page *pg) -{ -	/* Lifted from jffs2 */ - -	yaffs_Object *obj; -	unsigned char *pg_buf; -	int ret; - -	yaffs_Device *dev; - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage at %08x, size %08x\n", -			   (unsigned)(pg->index << PAGE_CACHE_SHIFT), -			   (unsigned)PAGE_CACHE_SIZE)); - -	obj = yaffs_DentryToObject(f->f_dentry); - -	dev = obj->myDev; - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -	BUG_ON(!PageLocked(pg)); -#else -	if (!PageLocked(pg)) -		PAGE_BUG(pg); -#endif - -	pg_buf = kmap(pg); -	/* FIXME: Can kmap fail? */ - -	yaffs_GrossLock(dev); - -	ret = -	    yaffs_ReadDataFromFile(obj, pg_buf, pg->index << PAGE_CACHE_SHIFT, -				   PAGE_CACHE_SIZE); - -	yaffs_GrossUnlock(dev); - -	if (ret >= 0) -		ret = 0; - -	if (ret) { -		ClearPageUptodate(pg); -		SetPageError(pg); -	} else { -		SetPageUptodate(pg); -		ClearPageError(pg); -	} - -	flush_dcache_page(pg); -	kunmap(pg); - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_readpage done\n")); -	return ret; -} - -static int yaffs_readpage_unlock(struct file *f, struct page *pg) -{ -	int ret = yaffs_readpage_nolock(f, pg); -	UnlockPage(pg); -	return ret; -} - -static int yaffs_readpage(struct file *f, struct page *pg) -{ -	return yaffs_readpage_unlock(f, pg); -} - -/* writepage inspired by/stolen from smbfs */ - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_writepage(struct page *page, struct writeback_control *wbc) -#else -static int yaffs_writepage(struct page *page) -#endif -{ -	struct address_space *mapping = page->mapping; -	loff_t offset = (loff_t) page->index << PAGE_CACHE_SHIFT; -	struct inode *inode; -	unsigned long end_index; -	char *buffer; -	yaffs_Object *obj; -	int nWritten = 0; -	unsigned nBytes; - -	if (!mapping) -		BUG(); -	inode = mapping->host; -	if (!inode) -		BUG(); - -	if (offset > inode->i_size) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG -		   "yaffs_writepage at %08x, inode size = %08x!!!\n", -		   (unsigned)(page->index << PAGE_CACHE_SHIFT), -		   (unsigned)inode->i_size)); -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "                -> don't care!!\n")); -		unlock_page(page); -		return 0; -	} - -	end_index = inode->i_size >> PAGE_CACHE_SHIFT; - -	/* easy case */ -	if (page->index < end_index) { -		nBytes = PAGE_CACHE_SIZE; -	} else { -		nBytes = inode->i_size & (PAGE_CACHE_SIZE - 1); -	} - -	get_page(page); - -	buffer = kmap(page); - -	obj = yaffs_InodeToObject(inode); -	yaffs_GrossLock(obj->myDev); - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_writepage at %08x, size %08x\n", -	   (unsigned)(page->index << PAGE_CACHE_SHIFT), nBytes)); -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "writepag0: obj = %05x, ino = %05x\n", -	   (int)obj->variant.fileVariant.fileSize, (int)inode->i_size)); - -	nWritten = -	    yaffs_WriteDataToFile(obj, buffer, page->index << PAGE_CACHE_SHIFT, -				  nBytes, 0); - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "writepag1: obj = %05x, ino = %05x\n", -	   (int)obj->variant.fileVariant.fileSize, (int)inode->i_size)); - -	yaffs_GrossUnlock(obj->myDev); - -	kunmap(page); -	SetPageUptodate(page); -	UnlockPage(page); -	put_page(page); - -	return (nWritten == nBytes) ? 0 : -ENOSPC; -} - -static int yaffs_prepare_write(struct file *f, struct page *pg, -			       unsigned offset, unsigned to) -{ - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_prepair_write\n")); -	if (!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE)) -		return yaffs_readpage_nolock(f, pg); - -	return 0; - -} - -static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, -			      unsigned to) -{ - -	void *addr = page_address(pg) + offset; -	loff_t pos = (((loff_t) pg->index) << PAGE_CACHE_SHIFT) + offset; -	int nBytes = to - offset; -	int nWritten; - -	unsigned spos = pos; -	unsigned saddr = (unsigned)addr; - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_commit_write addr %x pos %x nBytes %d\n", saddr, -	   spos, nBytes)); - -	nWritten = yaffs_file_write(f, addr, nBytes, &pos); - -	if (nWritten != nBytes) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG -		   "yaffs_commit_write not same size nWritten %d  nBytes %d\n", -		   nWritten, nBytes)); -		SetPageError(pg); -		ClearPageUptodate(pg); -	} else { -		SetPageUptodate(pg); -	} - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_commit_write returning %d\n", -	   nWritten == nBytes ? 0 : nWritten)); - -	return nWritten == nBytes ? 0 : nWritten; - -} - -static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object * obj) -{ -	if (inode && obj) { - - -		/* Check mode against the variant type and attempt to repair if broken. */ - 		__u32 mode = obj->yst_mode; - 		switch( obj->variantType ){ - 		case YAFFS_OBJECT_TYPE_FILE : - 		        if( ! S_ISREG(mode) ){ - 			        obj->yst_mode &= ~S_IFMT; - 			        obj->yst_mode |= S_IFREG; - 			} -  - 			break; - 		case YAFFS_OBJECT_TYPE_SYMLINK : - 		        if( ! S_ISLNK(mode) ){ - 			        obj->yst_mode &= ~S_IFMT; - 				obj->yst_mode |= S_IFLNK; - 			} -  - 			break; - 		case YAFFS_OBJECT_TYPE_DIRECTORY : - 		        if( ! S_ISDIR(mode) ){ - 			        obj->yst_mode &= ~S_IFMT; - 			        obj->yst_mode |= S_IFDIR; - 			} -  - 			break; - 		case YAFFS_OBJECT_TYPE_UNKNOWN : - 		case YAFFS_OBJECT_TYPE_HARDLINK : - 		case YAFFS_OBJECT_TYPE_SPECIAL : - 		default: - 		        /* TODO? */ - 		        break; - 		} - -		inode->i_ino = obj->objectId; -		inode->i_mode = obj->yst_mode; -		inode->i_uid = obj->yst_uid; -		inode->i_gid = obj->yst_gid; -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19)) -		inode->i_blksize = inode->i_sb->s_blocksize; -#endif -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) - -		inode->i_rdev = old_decode_dev(obj->yst_rdev); -		inode->i_atime.tv_sec = (time_t) (obj->yst_atime); -		inode->i_atime.tv_nsec = 0; -		inode->i_mtime.tv_sec = (time_t) obj->yst_mtime; -		inode->i_mtime.tv_nsec = 0; -		inode->i_ctime.tv_sec = (time_t) obj->yst_ctime; -		inode->i_ctime.tv_nsec = 0; -#else -		inode->i_rdev = obj->yst_rdev; -		inode->i_atime = obj->yst_atime; -		inode->i_mtime = obj->yst_mtime; -		inode->i_ctime = obj->yst_ctime; -#endif -		inode->i_size = yaffs_GetObjectFileLength(obj); -		inode->i_blocks = (inode->i_size + 511) >> 9; - -		inode->i_nlink = yaffs_GetObjectLinkCount(obj); - -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG -		   "yaffs_FillInode mode %x uid %d gid %d size %d count %d\n", -		   inode->i_mode, inode->i_uid, inode->i_gid, -		   (int)inode->i_size, atomic_read(&inode->i_count))); - -		switch (obj->yst_mode & S_IFMT) { -		default:	/* fifo, device or socket */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -			init_special_inode(inode, obj->yst_mode, -					   old_decode_dev(obj->yst_rdev)); -#else -			init_special_inode(inode, obj->yst_mode, -					   (dev_t) (obj->yst_rdev)); -#endif -			break; -		case S_IFREG:	/* file */ -			inode->i_op = &yaffs_file_inode_operations; -			inode->i_fop = &yaffs_file_operations; -			inode->i_mapping->a_ops = -			    &yaffs_file_address_operations; -			break; -		case S_IFDIR:	/* directory */ -			inode->i_op = &yaffs_dir_inode_operations; -			inode->i_fop = &yaffs_dir_operations; -			break; -		case S_IFLNK:	/* symlink */ -			inode->i_op = &yaffs_symlink_inode_operations; -			break; -		} - -		yaffs_InodeToObjectLV(inode) = obj; - -		obj->myInode = inode; - -	} else { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_FileInode invalid parameters\n")); -	} - -} - -struct inode *yaffs_get_inode(struct super_block *sb, int mode, int dev, -			      yaffs_Object * obj) -{ -	struct inode *inode; - -	if (!sb) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_get_inode for NULL super_block!!\n")); -		return NULL; - -	} - -	if (!obj) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_get_inode for NULL object!!\n")); -		return NULL; - -	} - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_get_inode for object %d\n", obj->objectId)); - -	inode = iget(sb, obj->objectId); - -	/* NB Side effect: iget calls back to yaffs_read_inode(). */ -	/* iget also increments the inode's i_count */ -	/* NB You can't be holding grossLock or deadlock will happen! */ - -	return inode; -} - -static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, -				loff_t * pos) -{ -	yaffs_Object *obj; -	int nWritten, ipos; -	struct inode *inode; -	yaffs_Device *dev; - -	obj = yaffs_DentryToObject(f->f_dentry); - -	dev = obj->myDev; - -	yaffs_GrossLock(dev); - -	inode = f->f_dentry->d_inode; - -	if (!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) { -		ipos = inode->i_size; -	} else { -		ipos = *pos; -	} - -	if (!obj) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_file_write: hey obj is null!\n")); -	} else { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG -		   "yaffs_file_write about to write writing %d bytes" -		   "to object %d at %d\n", -		   n, obj->objectId, ipos)); -	} - -	nWritten = yaffs_WriteDataToFile(obj, buf, ipos, n, 0); - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_file_write writing %d bytes, %d written at %d\n", -	   n, nWritten, ipos)); -	if (nWritten > 0) { -		ipos += nWritten; -		*pos = ipos; -		if (ipos > inode->i_size) { -			inode->i_size = ipos; -			inode->i_blocks = (ipos + 511) >> 9; - -			T(YAFFS_TRACE_OS, -			  (KERN_DEBUG -			   "yaffs_file_write size updated to %d bytes, " -			   "%d blocks\n", -			   ipos, (int)(inode->i_blocks))); -		} - -	} -	yaffs_GrossUnlock(dev); -	return nWritten == 0 ? -ENOSPC : nWritten; -} - -static int yaffs_readdir(struct file *f, void *dirent, filldir_t filldir) -{ -	yaffs_Object *obj; -	yaffs_Device *dev; -	struct inode *inode = f->f_dentry->d_inode; -	unsigned long offset, curoffs; -	struct list_head *i; -	yaffs_Object *l; - -	char name[YAFFS_MAX_NAME_LENGTH + 1]; - -	obj = yaffs_DentryToObject(f->f_dentry); -	dev = obj->myDev; - -	yaffs_GrossLock(dev); - -	offset = f->f_pos; - -	T(YAFFS_TRACE_OS, ("yaffs_readdir: starting at %d\n", (int)offset)); - -	if (offset == 0) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_readdir: entry . ino %d \n", -		   (int)inode->i_ino)); -		if (filldir(dirent, ".", 1, offset, inode->i_ino, DT_DIR) -		    < 0) { -			goto out; -		} -		offset++; -		f->f_pos++; -	} -	if (offset == 1) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_readdir: entry .. ino %d \n", -		   (int)f->f_dentry->d_parent->d_inode->i_ino)); -		if (filldir -		    (dirent, "..", 2, offset, -		     f->f_dentry->d_parent->d_inode->i_ino, DT_DIR) < 0) { -			goto out; -		} -		offset++; -		f->f_pos++; -	} - -	curoffs = 1; - -	/* If the directory has changed since the open or last call to -	   readdir, rewind to after the 2 canned entries. */ - -	if (f->f_version != inode->i_version) { -		offset = 2; -		f->f_pos = offset; -		f->f_version = inode->i_version; -	} - -	list_for_each(i, &obj->variant.directoryVariant.children) { -		curoffs++; -		if (curoffs >= offset) { -			l = list_entry(i, yaffs_Object, siblings); - -			yaffs_GetObjectName(l, name, -					    YAFFS_MAX_NAME_LENGTH + 1); -			T(YAFFS_TRACE_OS, -			  (KERN_DEBUG "yaffs_readdir: %s inode %d\n", name, -			   yaffs_GetObjectInode(l))); - -			if (filldir(dirent, -				    name, -				    strlen(name), -				    offset, -				    yaffs_GetObjectInode(l), -				    yaffs_GetObjectType(l)) -			    < 0) { -				goto up_and_out; -			} - -			offset++; -			f->f_pos++; -		} -	} - -      up_and_out: -      out: - -	yaffs_GrossUnlock(dev); - -	return 0; -} - -/* - * File creation. Allocate an inode, and we're done.. - */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, -		       dev_t rdev) -#else -static int yaffs_mknod(struct inode *dir, struct dentry *dentry, int mode, -		       int rdev) -#endif -{ -	struct inode *inode; - -	yaffs_Object *obj = NULL; -	yaffs_Device *dev; - -	yaffs_Object *parent = yaffs_InodeToObject(dir); - -	int error = -ENOSPC; -	uid_t uid = current->fsuid; -	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; -	 -	if((dir->i_mode & S_ISGID) && S_ISDIR(mode)) -		mode |= S_ISGID; - -	if (parent) { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_mknod: parent object %d type %d\n", -		   parent->objectId, parent->variantType)); -	} else { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_mknod: could not get parent object\n")); -		return -EPERM; -	} - -	T(YAFFS_TRACE_OS, ("yaffs_mknod: making oject for %s, " -			   "mode %x dev %x\n", -			   dentry->d_name.name, mode, rdev)); - -	dev = parent->myDev; - -	yaffs_GrossLock(dev); - -	switch (mode & S_IFMT) { -	default: -		/* Special (socket, fifo, device...) */ -		T(YAFFS_TRACE_OS, (KERN_DEBUG -				   "yaffs_mknod: making special\n")); -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -		obj = -		    yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid, -				       gid, old_encode_dev(rdev)); -#else -		obj = -		    yaffs_MknodSpecial(parent, dentry->d_name.name, mode, uid, -				       gid, rdev); -#endif -		break; -	case S_IFREG:		/* file          */ -		T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n")); -		obj = -		    yaffs_MknodFile(parent, dentry->d_name.name, mode, uid, -				    gid); -		break; -	case S_IFDIR:		/* directory */ -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_mknod: making directory\n")); -		obj = -		    yaffs_MknodDirectory(parent, dentry->d_name.name, mode, -					 uid, gid); -		break; -	case S_IFLNK:		/* symlink */ -		T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mknod: making file\n")); -		obj = NULL;	/* Do we ever get here? */ -		break; -	} -	 -	/* Can not call yaffs_get_inode() with gross lock held */ -	yaffs_GrossUnlock(dev); - -	if (obj) { -		inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj); -		d_instantiate(dentry, inode); -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_mknod created object %d count = %d\n", -		   obj->objectId, atomic_read(&inode->i_count))); -		error = 0; -	} else { -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_mknod failed making object\n")); -		error = -ENOMEM; -	} - -	return error; -} - -static int yaffs_mkdir(struct inode *dir, struct dentry *dentry, int mode) -{ -	int retVal; -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_mkdir\n")); -	retVal = yaffs_mknod(dir, dentry, mode | S_IFDIR, 0); -#if 0 -	/* attempt to fix dir bug - didn't work */ -	if (!retVal) { -		dget(dentry); -	} -#endif -	return retVal; -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode, -			struct nameidata *n) -#else -static int yaffs_create(struct inode *dir, struct dentry *dentry, int mode) -#endif -{ -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_create\n")); -	return yaffs_mknod(dir, dentry, mode | S_IFREG, 0); -} - -static int yaffs_unlink(struct inode *dir, struct dentry *dentry) -{ -	int retVal; - -	yaffs_Device *dev; - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_unlink %d:%s\n", (int)(dir->i_ino), -	   dentry->d_name.name)); - -	dev = yaffs_InodeToObject(dir)->myDev; - -	yaffs_GrossLock(dev); - -	retVal = yaffs_Unlink(yaffs_InodeToObject(dir), dentry->d_name.name); - -	if (retVal == YAFFS_OK) { -		dentry->d_inode->i_nlink--; -		dir->i_version++; -		yaffs_GrossUnlock(dev); -		mark_inode_dirty(dentry->d_inode); -		return 0; -	} -	yaffs_GrossUnlock(dev); -	return -ENOTEMPTY; -} - -/* - * Create a link... - */ -static int yaffs_link(struct dentry *old_dentry, struct inode *dir, -		      struct dentry *dentry) -{ -	struct inode *inode = old_dentry->d_inode; -	yaffs_Object *obj = NULL; -	yaffs_Object *link = NULL; -	yaffs_Device *dev; - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_link\n")); - -	obj = yaffs_InodeToObject(inode); -	dev = obj->myDev; - -	yaffs_GrossLock(dev); - -	if (!S_ISDIR(inode->i_mode))	/* Don't link directories */ -	{ -		link = -		    yaffs_Link(yaffs_InodeToObject(dir), dentry->d_name.name, -			       obj); -	} - -	if (link) { -		old_dentry->d_inode->i_nlink = yaffs_GetObjectLinkCount(obj); -		d_instantiate(dentry, old_dentry->d_inode); -		atomic_inc(&old_dentry->d_inode->i_count); -		T(YAFFS_TRACE_OS, -		  (KERN_DEBUG "yaffs_link link count %d i_count %d\n", -		   old_dentry->d_inode->i_nlink, -		   atomic_read(&old_dentry->d_inode->i_count))); - -	} - -	yaffs_GrossUnlock(dev); - -	if (link) { - -		return 0; -	} - -	return -EPERM; -} - -static int yaffs_symlink(struct inode *dir, struct dentry *dentry, -			 const char *symname) -{ -	yaffs_Object *obj; -	yaffs_Device *dev; -	uid_t uid = current->fsuid; -	gid_t gid = (dir->i_mode & S_ISGID) ? dir->i_gid : current->fsgid; - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_symlink\n")); - -	dev = yaffs_InodeToObject(dir)->myDev; -	yaffs_GrossLock(dev); -	obj = yaffs_MknodSymLink(yaffs_InodeToObject(dir), dentry->d_name.name, -				 S_IFLNK | S_IRWXUGO, uid, gid, symname); -	yaffs_GrossUnlock(dev); - -	if (obj) { - -		struct inode *inode; - -		inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj); -		d_instantiate(dentry, inode); -		T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink created OK\n")); -		return 0; -	} else { -		T(YAFFS_TRACE_OS, (KERN_DEBUG "symlink not created\n")); - -	} - -	return -ENOMEM; -} - -static int yaffs_sync_object(struct file *file, struct dentry *dentry, -			     int datasync) -{ - -	yaffs_Object *obj; -	yaffs_Device *dev; - -	obj = yaffs_DentryToObject(dentry); - -	dev = obj->myDev; - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_object\n")); -	yaffs_GrossLock(dev); -	yaffs_FlushFile(obj, 1); -	yaffs_GrossUnlock(dev); -	return 0; -} - -/* - * The VFS layer already does all the dentry stuff for rename. - * - * NB: POSIX says you can rename an object over an old object of the same name - */ -static int yaffs_rename(struct inode *old_dir, struct dentry *old_dentry, -			struct inode *new_dir, struct dentry *new_dentry) -{ -	yaffs_Device *dev; -	int retVal = YAFFS_FAIL; -	yaffs_Object *target; - -        T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_rename\n")); -	dev = yaffs_InodeToObject(old_dir)->myDev; - -	yaffs_GrossLock(dev); - -	/* Check if the target is an existing directory that is not empty. */ -	target = -	    yaffs_FindObjectByName(yaffs_InodeToObject(new_dir), -				   new_dentry->d_name.name); -	 -	 - -	if (target && -	    target->variantType == YAFFS_OBJECT_TYPE_DIRECTORY && -	    !list_empty(&target->variant.directoryVariant.children)) { -	     -	        T(YAFFS_TRACE_OS, (KERN_DEBUG "target is non-empty dir\n")); - -		retVal = YAFFS_FAIL; -	} else { - -		/* Now does unlinking internally using shadowing mechanism */ -	        T(YAFFS_TRACE_OS, (KERN_DEBUG "calling yaffs_RenameObject\n")); -		 -		retVal = -		    yaffs_RenameObject(yaffs_InodeToObject(old_dir), -				       old_dentry->d_name.name, -				       yaffs_InodeToObject(new_dir), -				       new_dentry->d_name.name); - -	} -	yaffs_GrossUnlock(dev); - -	if (retVal == YAFFS_OK) { -		if(target) { -			new_dentry->d_inode->i_nlink--; -			mark_inode_dirty(new_dentry->d_inode); -		} - -		return 0; -	} else { -		return -ENOTEMPTY; -	} - -} - -static int yaffs_setattr(struct dentry *dentry, struct iattr *attr) -{ -	struct inode *inode = dentry->d_inode; -	int error; -	yaffs_Device *dev; - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_setattr of object %d\n", -	   yaffs_InodeToObject(inode)->objectId)); - -	if ((error = inode_change_ok(inode, attr)) == 0) { - -		dev = yaffs_InodeToObject(inode)->myDev; -		yaffs_GrossLock(dev); -		if (yaffs_SetAttributes(yaffs_InodeToObject(inode), attr) == -		    YAFFS_OK) { -			error = 0; -		} else { -			error = -EPERM; -		} -		yaffs_GrossUnlock(dev); -		if (!error) -			error = inode_setattr(inode, attr); -	} -	return error; -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static int yaffs_statfs(struct dentry *dentry, struct kstatfs *buf) -{ -	yaffs_Device *dev = yaffs_DentryToObject(dentry)->myDev; -	struct super_block *sb = dentry->d_sb; -#elif (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf) -{ -	yaffs_Device *dev = yaffs_SuperToDevice(sb); -#else -static int yaffs_statfs(struct super_block *sb, struct statfs *buf) -{ -	yaffs_Device *dev = yaffs_SuperToDevice(sb); -#endif - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_statfs\n")); - -	yaffs_GrossLock(dev); - -	buf->f_type = YAFFS_MAGIC; -	buf->f_bsize = sb->s_blocksize; -	buf->f_namelen = 255; -	if (sb->s_blocksize > dev->nDataBytesPerChunk) { - -		buf->f_blocks = -		    (dev->endBlock - dev->startBlock + -		     1) * dev->nChunksPerBlock / (sb->s_blocksize / -						  dev->nDataBytesPerChunk); -		buf->f_bfree = -		    yaffs_GetNumberOfFreeChunks(dev) / (sb->s_blocksize / -							dev->nDataBytesPerChunk); -	} else { - -		buf->f_blocks = -		    (dev->endBlock - dev->startBlock + -		     1) * dev->nChunksPerBlock * (dev->nDataBytesPerChunk / -						  sb->s_blocksize); -		buf->f_bfree = -		    yaffs_GetNumberOfFreeChunks(dev) * (dev->nDataBytesPerChunk / -							sb->s_blocksize); -	} -	buf->f_files = 0; -	buf->f_ffree = 0; -	buf->f_bavail = buf->f_bfree; - -	yaffs_GrossUnlock(dev); -	return 0; -} - - -/** -static int yaffs_do_sync_fs(struct super_block *sb) -{ - -	yaffs_Device *dev = yaffs_SuperToDevice(sb); -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_do_sync_fs\n")); - -	if(sb->s_dirt) { -		yaffs_GrossLock(dev); - -		if(dev) -			yaffs_CheckpointSave(dev); -		 -		yaffs_GrossUnlock(dev); - -		sb->s_dirt = 0; -	} -	return 0; -} -**/ - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static void yaffs_write_super(struct super_block *sb) -#else -static int yaffs_write_super(struct super_block *sb) -#endif -{ - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n")); -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) -	return 0; /* yaffs_do_sync_fs(sb);*/ -#endif -} - - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static int yaffs_sync_fs(struct super_block *sb, int wait) -#else -static int yaffs_sync_fs(struct super_block *sb) -#endif -{ - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_sync_fs\n")); -	 -	return 0; /* yaffs_do_sync_fs(sb);*/ -	 -} - - -static void yaffs_read_inode(struct inode *inode) -{ -	/* NB This is called as a side effect of other functions, but -	 * we had to release the lock to prevent deadlocks, so  -	 * need to lock again. -	 */ - -	yaffs_Object *obj; -	yaffs_Device *dev = yaffs_SuperToDevice(inode->i_sb); - -	T(YAFFS_TRACE_OS, -	  (KERN_DEBUG "yaffs_read_inode for %d\n", (int)inode->i_ino)); - -	yaffs_GrossLock(dev); -	 -	obj = yaffs_FindObjectByNumber(dev, inode->i_ino); - -	yaffs_FillInodeFromObject(inode, obj); - -	yaffs_GrossUnlock(dev); -} - -static LIST_HEAD(yaffs_dev_list); - -#if 0 // not used -static int yaffs_remount_fs(struct super_block *sb, int *flags, char *data) -{ -	yaffs_Device    *dev = yaffs_SuperToDevice(sb); - -	if( *flags & MS_RDONLY ) { -		struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; -	     -		T(YAFFS_TRACE_OS, -			(KERN_DEBUG "yaffs_remount_fs: %s: RO\n", dev->name )); - -		yaffs_GrossLock(dev); -     	  -		yaffs_FlushEntireDeviceCache(dev); -    	 -		yaffs_CheckpointSave(dev); -  -		if (mtd->sync) -			mtd->sync(mtd); - -		yaffs_GrossUnlock(dev); -	} -	else { -		T(YAFFS_TRACE_OS,  -			(KERN_DEBUG "yaffs_remount_fs: %s: RW\n", dev->name )); -	} -  -	return 0; -} -#endif - -static void yaffs_put_super(struct super_block *sb) -{ -	yaffs_Device *dev = yaffs_SuperToDevice(sb); - -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n")); - -	yaffs_GrossLock(dev); -	 -	yaffs_FlushEntireDeviceCache(dev); - -	yaffs_CheckpointSave(dev); - -	if (dev->putSuperFunc) { -		dev->putSuperFunc(sb); -	} - -	yaffs_Deinitialise(dev); -	 -	yaffs_GrossUnlock(dev); - -	/* we assume this is protected by lock_kernel() in mount/umount */ -	list_del(&dev->devList); -	 -	if(dev->spareBuffer){ -		YFREE(dev->spareBuffer); -		dev->spareBuffer = NULL; -	} - -	kfree(dev); -} - - -static void yaffs_MTDPutSuper(struct super_block *sb) -{ - -	struct mtd_info *mtd = yaffs_SuperToDevice(sb)->genericDevice; - -	if (mtd->sync) { -		mtd->sync(mtd); -	} - -	put_mtd_device(mtd); -} - - -static void yaffs_MarkSuperBlockDirty(void *vsb) -{ -	struct super_block *sb = (struct super_block *)vsb; -	 -	T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_MarkSuperBlockDirty() sb = %p\n",sb)); -//	if(sb) -//		sb->s_dirt = 1; -} - -typedef struct { -	int inband_tags; -	int skip_checkpoint_read; -	int skip_checkpoint_write; -	int no_cache; -} yaffs_options; - -#define MAX_OPT_LEN 20 -static int yaffs_parse_options(yaffs_options *options, const char *options_str) -{ -	char cur_opt[MAX_OPT_LEN+1]; -	int p; -	int error = 0; -	 -	/* Parse through the options which is a comma seperated list */ -	 -	while(options_str && *options_str && !error){ -		memset(cur_opt,0,MAX_OPT_LEN+1); -		p = 0; -		 -		while(*options_str && *options_str != ','){ -			if(p < MAX_OPT_LEN){ -				cur_opt[p] = *options_str; -				p++; -			} -			options_str++; -		} -		 -		if(!strcmp(cur_opt,"inband-tags")) -			options->inband_tags = 1; -		else if(!strcmp(cur_opt,"no-cache")) -			options->no_cache = 1; -		else if(!strcmp(cur_opt,"no-checkpoint-read")) -			options->skip_checkpoint_read = 1; -		else if(!strcmp(cur_opt,"no-checkpoint-write")) -			options->skip_checkpoint_write = 1; -		else if(!strcmp(cur_opt,"no-checkpoint")){ -			options->skip_checkpoint_read = 1; -			options->skip_checkpoint_write = 1; -		} else { -			printk(KERN_INFO "yaffs: Bad mount option \"%s\"\n",cur_opt); -			error = 1; -		} -		 -	} - -	return error; -} - -static struct super_block *yaffs_internal_read_super(int yaffsVersion, -						     struct super_block *sb, -						     void *data, int silent) -{ -	int nBlocks; -	struct inode *inode = NULL; -	struct dentry *root; -	yaffs_Device *dev = 0; -	char devname_buf[BDEVNAME_SIZE + 1]; -	struct mtd_info *mtd; -	int err; -	char *data_str = (char *)data; -	 -	yaffs_options options; - -	sb->s_magic = YAFFS_MAGIC; -	sb->s_op = &yaffs_super_ops; - -	if (!sb) -		printk(KERN_INFO "yaffs: sb is NULL\n"); -	else if (!sb->s_dev) -		printk(KERN_INFO "yaffs: sb->s_dev is NULL\n"); -	else if (!yaffs_devname(sb, devname_buf)) -		printk(KERN_INFO "yaffs: devname is NULL\n"); -	else -		printk(KERN_INFO "yaffs: dev is %d name is \"%s\"\n", -		       sb->s_dev, -		       yaffs_devname(sb, devname_buf)); -		     -	if(!data_str) -		data_str = ""; -    -	printk(KERN_INFO "yaffs: passed flags \"%s\"\n",data_str); -	 -	memset(&options,0,sizeof(options)); -	 -	if(yaffs_parse_options(&options,data_str)){ -		/* Option parsing failed */ -		return NULL; -	} - - -	sb->s_blocksize = PAGE_CACHE_SIZE; -	sb->s_blocksize_bits = PAGE_CACHE_SHIFT; -	T(YAFFS_TRACE_OS, ("yaffs_read_super: Using yaffs%d\n", yaffsVersion)); -	T(YAFFS_TRACE_OS, -	  ("yaffs_read_super: block size %d\n", (int)(sb->s_blocksize))); - -#ifdef CONFIG_YAFFS_DISABLE_WRITE_VERIFY -	T(YAFFS_TRACE_OS, -	  ("yaffs: Write verification disabled. All guarantees " -	   "null and void\n")); -#endif - -	T(YAFFS_TRACE_ALWAYS, ("yaffs: Attempting MTD mount on %u.%u, " -			       "\"%s\"\n", -			       MAJOR(sb->s_dev), MINOR(sb->s_dev), -			       yaffs_devname(sb, devname_buf))); - -	/* Check it's an mtd device..... */ -	if (MAJOR(sb->s_dev) != MTD_BLOCK_MAJOR) { -		return NULL;	/* This isn't an mtd device */ -	} -	/* Get the device */ -	mtd = get_mtd_device(NULL, MINOR(sb->s_dev)); -	if (!mtd) { -		T(YAFFS_TRACE_ALWAYS, -		  ("yaffs: MTD device #%u doesn't appear to exist\n", -		   MINOR(sb->s_dev))); -		return NULL; -	} -	/* Check it's NAND */ -	if (mtd->type != MTD_NANDFLASH) { -		T(YAFFS_TRACE_ALWAYS, -		  ("yaffs: MTD device is not NAND it's type %d\n", mtd->type)); -		return NULL; -	} - -	T(YAFFS_TRACE_OS, (" erase %p\n", mtd->erase)); -	T(YAFFS_TRACE_OS, (" read %p\n", mtd->read)); -	T(YAFFS_TRACE_OS, (" write %p\n", mtd->write)); -	T(YAFFS_TRACE_OS, (" readoob %p\n", mtd->read_oob)); -	T(YAFFS_TRACE_OS, (" writeoob %p\n", mtd->write_oob)); -	T(YAFFS_TRACE_OS, (" block_isbad %p\n", mtd->block_isbad)); -	T(YAFFS_TRACE_OS, (" block_markbad %p\n", mtd->block_markbad)); -	T(YAFFS_TRACE_OS, (" %s %d\n", WRITE_SIZE_STR, WRITE_SIZE(mtd))); -	T(YAFFS_TRACE_OS, (" oobsize %d\n", mtd->oobsize)); -	T(YAFFS_TRACE_OS, (" erasesize %d\n", mtd->erasesize)); -	T(YAFFS_TRACE_OS, (" size %d\n", mtd->size)); -	 -#ifdef CONFIG_YAFFS_AUTO_YAFFS2 - -	if (yaffsVersion == 1 &&  -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -	    mtd->writesize >= 2048) { -#else -	    mtd->oobblock >= 2048) { -#endif -	    T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs2\n")); -	    yaffsVersion = 2; -	}	 -	 -	/* Added NCB 26/5/2006 for completeness */ -	if (yaffsVersion == 2 &&  -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -	    mtd->writesize == 512) { -#else -	    mtd->oobblock == 512) { -#endif -	    T(YAFFS_TRACE_ALWAYS,("yaffs: auto selecting yaffs1\n")); -	    yaffsVersion = 1; -	}	 - -#endif - -	if (yaffsVersion == 2) { -		/* Check for version 2 style functions */ -		if (!mtd->erase || -		    !mtd->block_isbad || -		    !mtd->block_markbad || -		    !mtd->read || -		    !mtd->write || -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -		    !mtd->read_oob || !mtd->write_oob) { -#else -		    !mtd->write_ecc || -		    !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { -#endif -			T(YAFFS_TRACE_ALWAYS, -			  ("yaffs: MTD device does not support required " -			   "functions\n"));; -			return NULL; -		} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -		if (mtd->writesize < YAFFS_MIN_YAFFS2_CHUNK_SIZE || -#else -		if (mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE || -#endif -		    mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) { -			T(YAFFS_TRACE_ALWAYS, -			  ("yaffs: MTD device does not have the " -			   "right page sizes\n")); -			return NULL; -		} -	} else { -		/* Check for V1 style functions */ -		if (!mtd->erase || -		    !mtd->read || -		    !mtd->write || -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -		    !mtd->read_oob || !mtd->write_oob) { -#else -		    !mtd->write_ecc || -		    !mtd->read_ecc || !mtd->read_oob || !mtd->write_oob) { -#endif -			T(YAFFS_TRACE_ALWAYS, -			  ("yaffs: MTD device does not support required " -			   "functions\n"));; -			return NULL; -		} - -		if (WRITE_SIZE(mtd) < YAFFS_BYTES_PER_CHUNK || -		    mtd->oobsize != YAFFS_BYTES_PER_SPARE) { -			T(YAFFS_TRACE_ALWAYS, -			  ("yaffs: MTD device does not support have the " -			   "right page sizes\n")); -			return NULL; -		} -	} - -	/* OK, so if we got here, we have an MTD that's NAND and looks -	 * like it has the right capabilities -	 * Set the yaffs_Device up for mtd -	 */ - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -	sb->s_fs_info = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL); -#else -	sb->u.generic_sbp = dev = kmalloc(sizeof(yaffs_Device), GFP_KERNEL); -#endif -	if (!dev) { -		/* Deep shit could not allocate device structure */ -		T(YAFFS_TRACE_ALWAYS, -		  ("yaffs_read_super: Failed trying to allocate " -		   "yaffs_Device. \n")); -		return NULL; -	} - -	memset(dev, 0, sizeof(yaffs_Device)); -	dev->genericDevice = mtd; -	dev->name = mtd->name; - -	/* Set up the memory size parameters.... */ - -	nBlocks = mtd->size / (YAFFS_CHUNKS_PER_BLOCK * YAFFS_BYTES_PER_CHUNK); -	dev->startBlock = 0; -	dev->endBlock = nBlocks - 1; -	dev->nChunksPerBlock = YAFFS_CHUNKS_PER_BLOCK; -	dev->nDataBytesPerChunk = YAFFS_BYTES_PER_CHUNK; -	dev->nReservedBlocks = 5; -	dev->nShortOpCaches = (options.no_cache) ? 0 : 10; - -	/* ... and the functions. */ -	if (yaffsVersion == 2) { -		dev->writeChunkWithTagsToNAND = -		    nandmtd2_WriteChunkWithTagsToNAND; -		dev->readChunkWithTagsFromNAND = -		    nandmtd2_ReadChunkWithTagsFromNAND; -		dev->markNANDBlockBad = nandmtd2_MarkNANDBlockBad; -		dev->queryNANDBlock = nandmtd2_QueryNANDBlock; -		dev->spareBuffer = YMALLOC(mtd->oobsize); -		dev->isYaffs2 = 1; -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -		dev->nDataBytesPerChunk = mtd->writesize; -		dev->nChunksPerBlock = mtd->erasesize / mtd->writesize; -#else -		dev->nDataBytesPerChunk = mtd->oobblock; -		dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock; -#endif -		nBlocks = mtd->size / mtd->erasesize; - -		dev->nCheckpointReservedBlocks = CONFIG_YAFFS_CHECKPOINT_RESERVED_BLOCKS; -		dev->startBlock = 0; -		dev->endBlock = nBlocks - 1; -	} else { -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -		/* use the MTD interface in yaffs_mtdif1.c */ -		dev->writeChunkWithTagsToNAND = -			nandmtd1_WriteChunkWithTagsToNAND; -		dev->readChunkWithTagsFromNAND = -			nandmtd1_ReadChunkWithTagsFromNAND; -		dev->markNANDBlockBad = nandmtd1_MarkNANDBlockBad; -		dev->queryNANDBlock = nandmtd1_QueryNANDBlock; -#else -		dev->writeChunkToNAND = nandmtd_WriteChunkToNAND; -		dev->readChunkFromNAND = nandmtd_ReadChunkFromNAND; -#endif -		dev->isYaffs2 = 0; -	} -	/* ... and common functions */ -	dev->eraseBlockInNAND = nandmtd_EraseBlockInNAND; -	dev->initialiseNAND = nandmtd_InitialiseNAND; - -	dev->putSuperFunc = yaffs_MTDPutSuper; -	 -	dev->superBlock = (void *)sb; -	dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty; -	 - -#ifndef CONFIG_YAFFS_DOES_ECC -	dev->useNANDECC = 1; -#endif - -#ifdef CONFIG_YAFFS_DISABLE_WIDE_TNODES -	dev->wideTnodesDisabled = 1; -#endif - -	dev->skipCheckpointRead = options.skip_checkpoint_read; -	dev->skipCheckpointWrite = options.skip_checkpoint_write; -	 -	/* we assume this is protected by lock_kernel() in mount/umount */ -	list_add_tail(&dev->devList, &yaffs_dev_list); - -	init_MUTEX(&dev->grossLock); - -	yaffs_GrossLock(dev); - -	err = yaffs_GutsInitialise(dev); - -	T(YAFFS_TRACE_OS, -	  ("yaffs_read_super: guts initialised %s\n", -	   (err == YAFFS_OK) ? "OK" : "FAILED")); -	 -	/* Release lock before yaffs_get_inode() */ -	yaffs_GrossUnlock(dev); - -	/* Create root inode */ -	if (err == YAFFS_OK) -		inode = yaffs_get_inode(sb, S_IFDIR | 0755, 0, -					yaffs_Root(dev)); - -	if (!inode) -		return NULL; - -	inode->i_op = &yaffs_dir_inode_operations; -	inode->i_fop = &yaffs_dir_operations; - -	T(YAFFS_TRACE_OS, ("yaffs_read_super: got root inode\n")); - -	root = d_alloc_root(inode); - -	T(YAFFS_TRACE_OS, ("yaffs_read_super: d_alloc_root done\n")); - -	if (!root) { -		iput(inode); -		return NULL; -	} -	sb->s_root = root; - -	T(YAFFS_TRACE_OS, ("yaffs_read_super: done\n")); -	return sb; -} - - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs_internal_read_super_mtd(struct super_block *sb, void *data, -					 int silent) -{ -	return yaffs_internal_read_super(1, sb, data, silent) ? 0 : -EINVAL; -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static int yaffs_read_super(struct file_system_type *fs, -			    int flags, const char *dev_name, -			    void *data, struct vfsmount *mnt) -{ - -	return get_sb_bdev(fs, flags, dev_name, data, -			   yaffs_internal_read_super_mtd, mnt); -} -#else -static struct super_block *yaffs_read_super(struct file_system_type *fs, -					    int flags, const char *dev_name, -					    void *data) -{ - -	return get_sb_bdev(fs, flags, dev_name, data, -			   yaffs_internal_read_super_mtd); -} -#endif - -static struct file_system_type yaffs_fs_type = { -	.owner = THIS_MODULE, -	.name = "yaffs", -	.get_sb = yaffs_read_super, -	.kill_sb = kill_block_super, -	.fs_flags = FS_REQUIRES_DEV, -}; -#else -static struct super_block *yaffs_read_super(struct super_block *sb, void *data, -					    int silent) -{ -	return yaffs_internal_read_super(1, sb, data, silent); -} - -static DECLARE_FSTYPE(yaffs_fs_type, "yaffs", yaffs_read_super, -		      FS_REQUIRES_DEV); -#endif - - -#ifdef CONFIG_YAFFS_YAFFS2 - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)) -static int yaffs2_internal_read_super_mtd(struct super_block *sb, void *data, -					  int silent) -{ -	return yaffs_internal_read_super(2, sb, data, silent) ? 0 : -EINVAL; -} - -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) -static int yaffs2_read_super(struct file_system_type *fs, -			int flags, const char *dev_name, void *data, -			struct vfsmount *mnt) -{ -	return get_sb_bdev(fs, flags, dev_name, data, -			yaffs2_internal_read_super_mtd, mnt); -} -#else -static struct super_block *yaffs2_read_super(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); -} -#endif - -static struct file_system_type yaffs2_fs_type = { -	.owner = THIS_MODULE, -	.name = "yaffs2", -	.get_sb = yaffs2_read_super, -	.kill_sb = kill_block_super, -	.fs_flags = FS_REQUIRES_DEV, -}; -#else -static struct super_block *yaffs2_read_super(struct super_block *sb, -					     void *data, int silent) -{ -	return yaffs_internal_read_super(2, sb, data, silent); -} - -static DECLARE_FSTYPE(yaffs2_fs_type, "yaffs2", yaffs2_read_super, -		      FS_REQUIRES_DEV); -#endif - -#endif				/* CONFIG_YAFFS_YAFFS2 */ - -static struct proc_dir_entry *my_proc_entry; - -static char *yaffs_dump_dev(char *buf, yaffs_Device * dev) -{ -	buf += sprintf(buf, "startBlock......... %d\n", dev->startBlock); -	buf += sprintf(buf, "endBlock........... %d\n", dev->endBlock); -	buf += sprintf(buf, "nDataBytesPerChunk. %d\n", dev->nDataBytesPerChunk); -	buf += sprintf(buf, "chunkGroupBits..... %d\n", dev->chunkGroupBits); -	buf += sprintf(buf, "chunkGroupSize..... %d\n", dev->chunkGroupSize); -	buf += sprintf(buf, "nErasedBlocks...... %d\n", dev->nErasedBlocks); -	buf += sprintf(buf, "nReservedBlocks.... %d\n", dev->nReservedBlocks); -	buf += sprintf(buf, "nCheckptResBlocks.. %d\n", dev->nCheckpointReservedBlocks); -	buf += sprintf(buf, "blocksInCheckpoint. %d\n", dev->blocksInCheckpoint); -	buf += sprintf(buf, "nTnodesCreated..... %d\n", dev->nTnodesCreated); -	buf += sprintf(buf, "nFreeTnodes........ %d\n", dev->nFreeTnodes); -	buf += sprintf(buf, "nObjectsCreated.... %d\n", dev->nObjectsCreated); -	buf += sprintf(buf, "nFreeObjects....... %d\n", dev->nFreeObjects); -	buf += sprintf(buf, "nFreeChunks........ %d\n", dev->nFreeChunks); -	buf += sprintf(buf, "nPageWrites........ %d\n", dev->nPageWrites); -	buf += sprintf(buf, "nPageReads......... %d\n", dev->nPageReads); -	buf += sprintf(buf, "nBlockErasures..... %d\n", dev->nBlockErasures); -	buf += sprintf(buf, "nGCCopies.......... %d\n", dev->nGCCopies); -	buf += -	    sprintf(buf, "garbageCollections. %d\n", dev->garbageCollections); -	buf += -	    sprintf(buf, "passiveGCs......... %d\n", -		    dev->passiveGarbageCollections); -	buf += sprintf(buf, "nRetriedWrites..... %d\n", dev->nRetriedWrites); -	buf += sprintf(buf, "nShortOpCaches..... %d\n", dev->nShortOpCaches); -	buf += sprintf(buf, "nRetireBlocks...... %d\n", dev->nRetiredBlocks); -	buf += sprintf(buf, "eccFixed........... %d\n", dev->eccFixed); -	buf += sprintf(buf, "eccUnfixed......... %d\n", dev->eccUnfixed); -	buf += sprintf(buf, "tagsEccFixed....... %d\n", dev->tagsEccFixed); -	buf += sprintf(buf, "tagsEccUnfixed..... %d\n", dev->tagsEccUnfixed); -	buf += sprintf(buf, "cacheHits.......... %d\n", dev->cacheHits); -	buf += sprintf(buf, "nDeletedFiles...... %d\n", dev->nDeletedFiles); -	buf += sprintf(buf, "nUnlinkedFiles..... %d\n", dev->nUnlinkedFiles); -	buf += -	    sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions); -	buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC); -	buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2); - -	return buf; -} - -static int yaffs_proc_read(char *page, -			   char **start, -			   off_t offset, int count, int *eof, void *data) -{ -	struct list_head *item; -	char *buf = page; -	int step = offset; -	int n = 0; - -	/* Get proc_file_read() to step 'offset' by one on each sucessive call. -	 * We use 'offset' (*ppos) to indicate where we are in devList. -	 * This also assumes the user has posted a read buffer large -	 * enough to hold the complete output; but that's life in /proc. -	 */ - -	*(int *)start = 1; - -	/* Print header first */ -	if (step == 0) { -		buf += sprintf(buf, "YAFFS built:" __DATE__ " " __TIME__ -			       "\n%s\n%s\n", yaffs_fs_c_version, -			       yaffs_guts_c_version); -	} - -	/* hold lock_kernel while traversing yaffs_dev_list */ -	lock_kernel(); - -	/* Locate and print the Nth entry.  Order N-squared but N is small. */ -	list_for_each(item, &yaffs_dev_list) { -		yaffs_Device *dev = list_entry(item, yaffs_Device, devList); -		if (n < step) { -			n++; -			continue; -		} -		buf += sprintf(buf, "\nDevice %d \"%s\"\n", n, dev->name); -		buf = yaffs_dump_dev(buf, dev); -		break; -	} -	unlock_kernel(); - -	return buf - page < count ? buf - page : count; -} - -/** - * Set the verbosity of the warnings and error messages. - * - * Note that the names can only be a..z or _ with the current code. - */ - -static struct { -	char *mask_name; -	unsigned mask_bitfield; -} mask_flags[] = { -	{"allocate", YAFFS_TRACE_ALLOCATE}, -	{"always", YAFFS_TRACE_ALWAYS}, -	{"bad_blocks", YAFFS_TRACE_BAD_BLOCKS}, -	{"buffers", YAFFS_TRACE_BUFFERS}, -	{"bug", YAFFS_TRACE_BUG}, -	{"checkpt", YAFFS_TRACE_CHECKPOINT}, -	{"deletion", YAFFS_TRACE_DELETION}, -	{"erase", YAFFS_TRACE_ERASE}, -	{"error", YAFFS_TRACE_ERROR}, -	{"gc_detail", YAFFS_TRACE_GC_DETAIL}, -	{"gc", YAFFS_TRACE_GC}, -	{"mtd", YAFFS_TRACE_MTD}, -	{"nandaccess", YAFFS_TRACE_NANDACCESS}, -	{"os", YAFFS_TRACE_OS}, -	{"scan_debug", YAFFS_TRACE_SCAN_DEBUG}, -	{"scan", YAFFS_TRACE_SCAN}, -	{"tracing", YAFFS_TRACE_TRACING}, - -	{"verify", YAFFS_TRACE_VERIFY}, -	{"verify_nand", YAFFS_TRACE_VERIFY_NAND}, -	{"verify_full", YAFFS_TRACE_VERIFY_FULL}, -	{"verify_all", YAFFS_TRACE_VERIFY_ALL}, - -	{"write", YAFFS_TRACE_WRITE}, -	{"all", 0xffffffff}, -	{"none", 0}, -	{NULL, 0}, -}; - -#define MAX_MASK_NAME_LENGTH 40 -static int yaffs_proc_write(struct file *file, const char *buf, -					 unsigned long count, void *data) -{ -	unsigned rg = 0, mask_bitfield; -	char *end; -	char *mask_name; -	const char *x;  -	char substring[MAX_MASK_NAME_LENGTH+1]; -	int i; -	int done = 0; -	int add, len = 0; -	int pos = 0; - -	rg = yaffs_traceMask; - -	while (!done && (pos < count)) { -		done = 1; -		while ((pos < count) && isspace(buf[pos])) { -			pos++; -		} - -		switch (buf[pos]) { -		case '+': -		case '-': -		case '=': -			add = buf[pos]; -			pos++; -			break; - -		default: -			add = ' '; -			break; -		} -		mask_name = NULL; -		 -		mask_bitfield = simple_strtoul(buf + pos, &end, 0); -		if (end > buf + pos) { -			mask_name = "numeral"; -			len = end - (buf + pos); -			pos += len; -			done = 0; -		} else { -			for(x = buf + pos, i = 0;  -			    (*x == '_' || (*x >='a' && *x <= 'z')) && -			    i <MAX_MASK_NAME_LENGTH; x++, i++, pos++) -			    substring[i] = *x; -			substring[i] = '\0'; -			 -			for (i = 0; mask_flags[i].mask_name != NULL; i++) { -				if(strcmp(substring,mask_flags[i].mask_name) == 0){ -					mask_name = mask_flags[i].mask_name; -					mask_bitfield = mask_flags[i].mask_bitfield; -					done = 0; -					break; -				} -			} -		} - -		if (mask_name != NULL) { -			done = 0; -			switch(add) { -			case '-': -				rg &= ~mask_bitfield; -				break; -			case '+': -				rg |= mask_bitfield; -				break; -			case '=': -				rg = mask_bitfield; -				break; -			default: -				rg |= mask_bitfield; -				break; -			} -		} -	} - -	yaffs_traceMask = rg | YAFFS_TRACE_ALWAYS; -	 -	printk("new trace = 0x%08X\n",yaffs_traceMask); -	 -	if (rg & YAFFS_TRACE_ALWAYS) { -		for (i = 0; mask_flags[i].mask_name != NULL; i++) { -			char flag; -			flag = ((rg & mask_flags[i].mask_bitfield) == mask_flags[i].mask_bitfield) ? '+' : '-'; -			printk("%c%s\n", flag, mask_flags[i].mask_name); -		} -	} - -	return count; -} - -/* Stuff to handle installation of file systems */ -struct file_system_to_install { -	struct file_system_type *fst; -	int installed; -}; - -static struct file_system_to_install fs_to_install[] = { -//#ifdef CONFIG_YAFFS_YAFFS1 -	{&yaffs_fs_type, 0}, -//#endif -//#ifdef CONFIG_YAFFS_YAFFS2 -	{&yaffs2_fs_type, 0}, -//#endif -	{NULL, 0} -}; - -static int __init init_yaffs_fs(void) -{ -	int error = 0; -	struct file_system_to_install *fsinst; - -	T(YAFFS_TRACE_ALWAYS, -	  ("yaffs " __DATE__ " " __TIME__ " Installing. \n")); - -	/* Install the proc_fs entry */ -	my_proc_entry = create_proc_entry("yaffs", -					       S_IRUGO | S_IFREG, -					       &proc_root); - -	if (my_proc_entry) { -		my_proc_entry->write_proc = yaffs_proc_write; -		my_proc_entry->read_proc = yaffs_proc_read; -		my_proc_entry->data = NULL; -	} else { -		return -ENOMEM; -	} - -	/* Now add the file system entries */ - -	fsinst = fs_to_install; - -	while (fsinst->fst && !error) { -		error = register_filesystem(fsinst->fst); -		if (!error) { -			fsinst->installed = 1; -		} -		fsinst++; -	} - -	/* Any errors? uninstall  */ -	if (error) { -		fsinst = fs_to_install; - -		while (fsinst->fst) { -			if (fsinst->installed) { -				unregister_filesystem(fsinst->fst); -				fsinst->installed = 0; -			} -			fsinst++; -		} -	} - -	return error; -} - -static void __exit exit_yaffs_fs(void) -{ - -	struct file_system_to_install *fsinst; - -	T(YAFFS_TRACE_ALWAYS, ("yaffs " __DATE__ " " __TIME__ -			       " removing. \n")); - -	remove_proc_entry("yaffs", &proc_root); - -	fsinst = fs_to_install; - -	while (fsinst->fst) { -		if (fsinst->installed) { -			unregister_filesystem(fsinst->fst); -			fsinst->installed = 0; -		} -		fsinst++; -	} - -} - -module_init(init_yaffs_fs) -module_exit(exit_yaffs_fs) - -MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system"); -MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2006"); -MODULE_LICENSE("GPL"); diff --git a/fs/yaffs2/yaffs_mtdif1.c b/fs/yaffs2/yaffs_mtdif1.c deleted file mode 100644 index 36185b68e..000000000 --- a/fs/yaffs2/yaffs_mtdif1.c +++ /dev/null @@ -1,369 +0,0 @@ -/* - * YAFFS: Yet another FFS. A NAND-flash specific file system. - * yaffs_mtdif1.c  NAND mtd interface functions for small-page NAND. - * - * Copyright (C) 2002 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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. - */ - -/* - * This module provides the interface between yaffs_nand.c and the - * MTD API.  This version is used when the MTD interface supports the - * 'mtd_oob_ops' style calls to read_oob and write_oob, circa 2.6.17, - * and we have small-page NAND device. - * - * These functions are invoked via function pointers in yaffs_nand.c. - * This replaces functionality provided by functions in yaffs_mtdif.c - * and the yaffs_TagsCompatability functions in yaffs_tagscompat.c that are - * called in yaffs_mtdif.c when the function pointers are NULL. - * We assume the MTD layer is performing ECC (useNANDECC is true). - */ - -#include "yportenv.h" -#include "yaffs_guts.h" -#include "yaffs_packedtags1.h" -#include "yaffs_tagscompat.h"	// for yaffs_CalcTagsECC - -#include "linux/kernel.h" -#include "linux/version.h" -#include "linux/types.h" -#include "linux/mtd/mtd.h" - -/* Don't compile this module if we don't have MTD's mtd_oob_ops interface */ -#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,17)) - -const char *yaffs_mtdif1_c_version = "$Id: yaffs_mtdif1.c,v 1.5 2007/10/29 14:59:57 imcd Exp $"; - -#ifndef CONFIG_YAFFS_9BYTE_TAGS -# define YTAG1_SIZE 8 -#else -# define YTAG1_SIZE 9 -#endif - -#if 0 -/* Use the following nand_ecclayout with MTD when using - * CONFIG_YAFFS_9BYTE_TAGS and the older on-NAND tags layout. - * If you have existing Yaffs images and the byte order differs from this, - * adjust 'oobfree' to match your existing Yaffs data. - * - * This nand_ecclayout scatters/gathers to/from the old-yaffs layout with the - * pageStatus byte (at NAND spare offset 4) scattered/gathered from/to - * the 9th byte. - * - * Old-style on-NAND format: T0,T1,T2,T3,P,B,T4,T5,E0,E1,E2,T6,T7,E3,E4,E5 - * We have/need PackedTags1 plus pageStatus: T0,T1,T2,T3,T4,T5,T6,T7,P - * where Tn are the tag bytes, En are MTD's ECC bytes, P is the pageStatus - * byte and B is the small-page bad-block indicator byte. - */ -static struct nand_ecclayout nand_oob_16 = { -	.eccbytes = 6, -	.eccpos = { 8, 9, 10, 13, 14, 15 }, -	.oobavail = 9, -	.oobfree = { { 0, 4 }, { 6, 2 }, { 11, 2 }, { 4, 1 } } -}; -#endif - -/* Write a chunk (page) of data to NAND. - * - * Caller always provides ExtendedTags data which are converted to a more - * compact (packed) form for storage in NAND.  A mini-ECC runs over the - * contents of the tags meta-data; used to valid the tags when read. - * - *  - Pack ExtendedTags to PackedTags1 form - *  - Compute mini-ECC for PackedTags1 - *  - Write data and packed tags to NAND. - * - * Note: Due to the use of the PackedTags1 meta-data which does not include - * a full sequence number (as found in the larger PackedTags2 form) it is - * necessary for Yaffs to re-write a chunk/page (just once) to mark it as - * discarded and dirty.  This is not ideal: newer NAND parts are supposed - * to be written just once.  When Yaffs performs this operation, this - * function is called with a NULL data pointer -- calling MTD write_oob - * without data is valid usage (2.6.17). - * - * Any underlying MTD error results in YAFFS_FAIL. - * Returns YAFFS_OK or YAFFS_FAIL. - */ -int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device *dev, -	int chunkInNAND, const __u8 * data, const yaffs_ExtendedTags * etags) -{ -	struct mtd_info * mtd = dev->genericDevice; -	int chunkBytes = dev->nDataBytesPerChunk; -	loff_t addr = ((loff_t)chunkInNAND) * chunkBytes; -	struct mtd_oob_ops ops; -	yaffs_PackedTags1 pt1; -	int retval; - -	/* we assume that PackedTags1 and yaffs_Tags are compatible */ -	compile_time_assertion(sizeof(yaffs_PackedTags1) == 12); -	compile_time_assertion(sizeof(yaffs_Tags) == 8); - -	dev->nPageWrites++; - -	yaffs_PackTags1(&pt1, etags); -	yaffs_CalcTagsECC((yaffs_Tags *)&pt1); - -	/* When deleting a chunk, the upper layer provides only skeletal -	 * etags, one with chunkDeleted set.  However, we need to update the -	 * tags, not erase them completely.  So we use the NAND write property -	 * that only zeroed-bits stick and set tag bytes to all-ones and -	 * zero just the (not) deleted bit. -	 */ -#ifndef CONFIG_YAFFS_9BYTE_TAGS -	if (etags->chunkDeleted) { -		memset(&pt1, 0xff, 8); -		/* clear delete status bit to indicate deleted */ -		pt1.deleted = 0; -	} -#else -	((__u8 *)&pt1)[8] = 0xff; -	if (etags->chunkDeleted) { -		memset(&pt1, 0xff, 8); -		/* zero pageStatus byte to indicate deleted */ -		((__u8 *)&pt1)[8] = 0; -	} -#endif - -	memset(&ops, 0, sizeof(ops)); -	ops.mode = MTD_OOB_AUTO; -	ops.len = (data) ? chunkBytes : 0; -	ops.ooblen = YTAG1_SIZE; -	ops.datbuf = (__u8 *)data; -	ops.oobbuf = (__u8 *)&pt1; - -	retval = mtd->write_oob(mtd, addr, &ops); -	if (retval) { -		yaffs_trace(YAFFS_TRACE_MTD, -			"write_oob failed, chunk %d, mtd error %d\n", -			chunkInNAND, retval); -	} -	return retval ? YAFFS_FAIL : YAFFS_OK; -} - -/* Return with empty ExtendedTags but add eccResult. - */ -static int rettags(yaffs_ExtendedTags * etags, int eccResult, int retval) -{ -	if (etags) { -		memset(etags, 0, sizeof(*etags)); -		etags->eccResult = eccResult; -	} -	return retval; -} - -/* Read a chunk (page) from NAND. - * - * Caller expects ExtendedTags data to be usable even on error; that is, - * all members except eccResult and blockBad are zeroed. - * - *  - Check ECC results for data (if applicable) - *  - Check for blank/erased block (return empty ExtendedTags if blank) - *  - Check the PackedTags1 mini-ECC (correct if necessary/possible) - *  - Convert PackedTags1 to ExtendedTags - *  - Update eccResult and blockBad members to refect state. - * - * Returns YAFFS_OK or YAFFS_FAIL. - */ -int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device *dev, -	int chunkInNAND, __u8 * data, yaffs_ExtendedTags * etags) -{ -	struct mtd_info * mtd = dev->genericDevice; -	int chunkBytes = dev->nDataBytesPerChunk; -	loff_t addr = ((loff_t)chunkInNAND) * chunkBytes; -	int eccres = YAFFS_ECC_RESULT_NO_ERROR; -	struct mtd_oob_ops ops; -	yaffs_PackedTags1 pt1; -	int retval; -	int deleted; - -	dev->nPageReads++; - -	memset(&ops, 0, sizeof(ops)); -	ops.mode = MTD_OOB_AUTO; -	ops.len = (data) ? chunkBytes : 0; -	ops.ooblen = YTAG1_SIZE; -	ops.datbuf = data; -	ops.oobbuf = (__u8 *)&pt1; - -#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20)) -	/* In MTD 2.6.18 to 2.6.19 nand_base.c:nand_do_read_oob() has a bug; -	 * help it out with ops.len = ops.ooblen when ops.datbuf == NULL. -	 */ -	ops.len = (ops.datbuf) ? ops.len : ops.ooblen; -#endif -	/* Read page and oob using MTD. -	 * Check status and determine ECC result. -	 */ -	retval = mtd->read_oob(mtd, addr, &ops); -	if (retval) { -		yaffs_trace(YAFFS_TRACE_MTD, -			"read_oob failed, chunk %d, mtd error %d\n", -			chunkInNAND, retval); -	} - -	switch (retval) { -	case 0: -		/* no error */ -		break; - -	case -EUCLEAN: -		/* MTD's ECC fixed the data */ -		eccres = YAFFS_ECC_RESULT_FIXED; -		dev->eccFixed++; -		break; - -	case -EBADMSG: -		/* MTD's ECC could not fix the data */ -		dev->eccUnfixed++; -		/* fall into... */ -	default: -		rettags(etags, YAFFS_ECC_RESULT_UNFIXED, 0); -		etags->blockBad = (mtd->block_isbad)(mtd, addr); -		return YAFFS_FAIL; -	} - -	/* Check for a blank/erased chunk. -	 */ -	if (yaffs_CheckFF((__u8 *)&pt1, 8)) { -		/* when blank, upper layers want eccResult to be <= NO_ERROR */ -		return rettags(etags, YAFFS_ECC_RESULT_NO_ERROR, YAFFS_OK); -	} - -#ifndef CONFIG_YAFFS_9BYTE_TAGS -	/* Read deleted status (bit) then return it to it's non-deleted -	 * state before performing tags mini-ECC check. pt1.deleted is -	 * inverted. -	 */ -	deleted = !pt1.deleted; -	pt1.deleted = 1; -#else -	deleted = (yaffs_CountBits(((__u8 *)&pt1)[8]) < 7); -#endif - -	/* Check the packed tags mini-ECC and correct if necessary/possible. -	 */ -	retval = yaffs_CheckECCOnTags((yaffs_Tags *)&pt1); -	switch (retval) { -	case 0: -		/* no tags error, use MTD result */ -		break; -	case 1: -		/* recovered tags-ECC error */ -		dev->tagsEccFixed++; -		if (eccres == YAFFS_ECC_RESULT_NO_ERROR) -			eccres = YAFFS_ECC_RESULT_FIXED; -		break; -	default: -		/* unrecovered tags-ECC error */ -		dev->tagsEccUnfixed++; -		return rettags(etags, YAFFS_ECC_RESULT_UNFIXED, YAFFS_FAIL); -	} - -	/* Unpack the tags to extended form and set ECC result. -	 * [set shouldBeFF just to keep yaffs_UnpackTags1 happy] -	 */ -	pt1.shouldBeFF = 0xFFFFFFFF; -	yaffs_UnpackTags1(etags, &pt1); -	etags->eccResult = eccres; - -	/* Set deleted state */ -	etags->chunkDeleted = deleted; -	return YAFFS_OK; -} - -/* Mark a block bad. - * - * This is a persistant state. - * Use of this function should be rare. - * - * Returns YAFFS_OK or YAFFS_FAIL. - */ -int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo) -{ -	struct mtd_info * mtd = dev->genericDevice; -	int blocksize = dev->nChunksPerBlock * dev->nDataBytesPerChunk; -	int retval; - -	yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, "marking block %d bad\n", blockNo); - -	retval = mtd->block_markbad(mtd, (loff_t)blocksize * blockNo); -	return (retval) ? YAFFS_FAIL : YAFFS_OK; -} - -/* Check any MTD prerequists. - *  - * Returns YAFFS_OK or YAFFS_FAIL. - */ -static int nandmtd1_TestPrerequists(struct mtd_info * mtd) -{ -	/* 2.6.18 has mtd->ecclayout->oobavail */ -	/* 2.6.21 has mtd->ecclayout->oobavail and mtd->oobavail */ -	int oobavail = mtd->ecclayout->oobavail; - -	if (oobavail < YTAG1_SIZE) { -		yaffs_trace(YAFFS_TRACE_ERROR, -			"mtd device has only %d bytes for tags, need %d\n", -			oobavail, YTAG1_SIZE); -		return YAFFS_FAIL; -	} -	return YAFFS_OK; -} - -/* Query for the current state of a specific block. - * - * Examine the tags of the first chunk of the block and return the state: - *  - YAFFS_BLOCK_STATE_DEAD, the block is marked bad - *  - YAFFS_BLOCK_STATE_NEEDS_SCANNING, the block is in use - *  - YAFFS_BLOCK_STATE_EMPTY, the block is clean - * - * Always returns YAFFS_OK. - */ -int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, -	yaffs_BlockState * pState, int *pSequenceNumber) -{ -	struct mtd_info * mtd = dev->genericDevice; -	int chunkNo = blockNo * dev->nChunksPerBlock; -	loff_t addr = (loff_t)chunkNo * dev->nDataBytesPerChunk; -	yaffs_ExtendedTags etags; -	int state = YAFFS_BLOCK_STATE_DEAD; -	int seqnum = 0; -	int retval; - -	/* 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_TestPrerequists(mtd) != YAFFS_OK) { -		return YAFFS_FAIL; -	} - -	retval = nandmtd1_ReadChunkWithTagsFromNAND(dev, chunkNo, NULL, &etags); -	etags.blockBad = (mtd->block_isbad)(mtd, addr); -	if (etags.blockBad) { -		yaffs_trace(YAFFS_TRACE_BAD_BLOCKS, -			"block %d is marked bad\n", blockNo); -		state = YAFFS_BLOCK_STATE_DEAD; -	} -	else if (etags.eccResult != YAFFS_ECC_RESULT_NO_ERROR) { -		/* bad tags, need to look more closely */ -		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; -	} -	else if (etags.chunkUsed) { -		state = YAFFS_BLOCK_STATE_NEEDS_SCANNING; -		seqnum = etags.sequenceNumber; -	} -	else { -		state = YAFFS_BLOCK_STATE_EMPTY; -	} - -	*pState = state; -	*pSequenceNumber = seqnum; - -	/* query always succeeds */ -	return YAFFS_OK; -} - -#endif /*KERNEL_VERSION*/ diff --git a/fs/yaffs2/yaffs_mtdif1.h b/fs/yaffs2/yaffs_mtdif1.h deleted file mode 100644 index c4f6197d6..000000000 --- a/fs/yaffs2/yaffs_mtdif1.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * YAFFS: Yet another Flash File System. A NAND-flash specific file system. - * - * Copyright (C) 2002-2007 Aleph One Ltd. - *   for Toby Churchill Ltd and Brightstar Engineering - * - * 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 __YAFFS_MTDIF1_H__ -#define __YAFFS_MTDIF1_H__ - -int nandmtd1_WriteChunkWithTagsToNAND(yaffs_Device * dev, int chunkInNAND, -	const __u8 * data, const yaffs_ExtendedTags * tags); - -int nandmtd1_ReadChunkWithTagsFromNAND(yaffs_Device * dev, int chunkInNAND, -	__u8 * data, yaffs_ExtendedTags * tags); - -int nandmtd1_MarkNANDBlockBad(struct yaffs_DeviceStruct *dev, int blockNo); - -int nandmtd1_QueryNANDBlock(struct yaffs_DeviceStruct *dev, int blockNo, -	yaffs_BlockState * state, int *sequenceNumber); - -#endif |