From d3344b2c734c5475e6bf0e399d886f9928209f06 Mon Sep 17 00:00:00 2001 From: charles Date: Tue, 20 Aug 2002 23:59:44 +0000 Subject: [PATCH] *** empty log message *** --- Makefile | 4 +- yaffs_fs.c | 143 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 115 insertions(+), 32 deletions(-) diff --git a/Makefile b/Makefile index c873129..ceea8f7 100644 --- a/Makefile +++ b/Makefile @@ -18,9 +18,9 @@ KERNELDIR = /usr/src/kernel-headers-2.4.18 USE_RAM_FOR_TEST = -DYAFFS_RAM_ENABLED USE_MTD = -DYAFFS_MTD_ENABLED +YAFFS_CONFIGS = -DCONFIG_YAFFS_USE_GENERIC_RW - -CFLAGS = -D__KERNEL__ -DMODULE $(USE_RAM_FOR_TEST) $(USE_MTD) -I$(KERNELDIR)/include -O2 -Wall +CFLAGS = -D__KERNEL__ -DMODULE $(USE_RAM_FOR_TEST) $(USE_MTD) $(YAFFS_CONFIGS) -I$(KERNELDIR)/include -O2 -Wall OBJS = yaffs_fs.o yaffs_guts.o yaffs_ramem.o yaffs_mtdif.o nand_ecc.o diff --git a/yaffs_fs.c b/yaffs_fs.c index 1a9460e..8bea30d 100644 --- a/yaffs_fs.c +++ b/yaffs_fs.c @@ -17,6 +17,12 @@ * Special notes: * >> sb->u.generic_sbp points to the yaffs_Device associated with this superblock * >> inode->u.generic_ip points to the associated yaffs_Object. + * + * + * Acknowledgements: + * * Luc van OostenRyck for O_APPEND patch. + * * Nick Bane for patches marked NCB. + * * Some code bodily lifted from JFFS2. */ @@ -85,6 +91,8 @@ static struct super_block *yaffs_read_super(struct super_block * sb, void * data static void yaffs_put_inode (struct inode *inode); static int yaffs_readpage(struct file *file, struct page * page); +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 *buffer, int buflen); static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); @@ -94,15 +102,20 @@ static int yaffs_follow_link(struct dentry *dentry, struct nameidata *nd); static struct address_space_operations yaffs_file_address_operations = { - readpage: yaffs_readpage, -// prepare_write: yaffs_prepare_write, -// commit_write: yaffs_commit_write + readpage: yaffs_readpage, + prepare_write: yaffs_prepare_write, + commit_write: yaffs_commit_write }; static struct file_operations yaffs_file_operations = { +#if CONFIG_YAFFS_USE_GENERIC_RW + read: generic_file_read, + write: generic_file_write, +#else read: yaffs_file_read, write: yaffs_file_write, +#endif mmap: generic_file_mmap, fsync: yaffs_sync_object, }; @@ -236,8 +249,10 @@ static void yaffs_put_inode(struct inode *inode) -static int yaffs_readpage(struct file *f, struct page * pg) +static int yaffs_readpage_nolock(struct file *f, struct page * pg) { + // Lifted from jffs2 + yaffs_Object *obj; unsigned char *pg_buf; int ret; @@ -270,7 +285,7 @@ static int yaffs_readpage(struct file *f, struct page * pg) flush_dcache_page(pg); kunmap(pg); - UnlockPage(pg); + //up(&obj->sem); @@ -278,28 +293,58 @@ static int yaffs_readpage(struct file *f, struct page * pg) return ret; } -#ifdef YAFFS_ADDRESS_OPS +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_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) +static int yaffs_readpage(struct file *f, struct page * pg) { - T((KERN_DEBUG"yaffs_prepare_write\n")); + return yaffs_readpage_unlock(f,pg); +} + + +static int yaffs_prepare_write(struct file *f, struct page *pg, unsigned offset, unsigned to) +{ + + T((KERN_DEBUG"yaffs_prepair_write\n")); + if(!Page_Uptodate(pg) && (offset || to < PAGE_CACHE_SIZE)) + return yaffs_readpage_nolock(f,pg); - //TODO return 0; + } -static int yaffs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) +static int yaffs_commit_write(struct file *f, struct page *pg, unsigned offset, unsigned to) { - struct inode *inode = page->mapping->host; - loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + 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 = addr; + + T((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((KERN_DEBUG"yaffs_commit_write not same size nWritten %d nBytes %d\n",nWritten,nBytes)); + SetPageError(pg); + ClearPageUptodate(pg); + } - T((KERN_DEBUG"yaffs_commit_write\n")); + T((KERN_DEBUG"yaffs_commit_write returning %d\n",nWritten)); + + return nWritten /* != nBytes ? -ENOMEM : 0 */ ; - return 0; } -#endif //YAFFS_ADDRESS_OPS static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj) @@ -310,7 +355,7 @@ static void yaffs_FillInodeFromObject(struct inode *inode, yaffs_Object *obj) inode->i_mode = obj->st_mode; inode->i_uid = obj->st_uid; inode->i_gid = obj->st_gid; - inode->i_blksize = YAFFS_BYTES_PER_CHUNK; + inode->i_blksize = inode->i_sb->s_blocksize; inode->i_blocks = 0; inode->i_rdev = obj->st_rdev;; inode->i_atime = obj->st_atime; @@ -408,17 +453,39 @@ static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n, loff_ obj = yaffs_DentryToObject(f->f_dentry); inode = f->f_dentry->d_inode; - nWritten = yaffs_WriteDataToFile(obj,buf,*pos,n); - ipos = *pos; + + if(!S_ISBLK(inode->i_mode) && f->f_flags & O_APPEND) + { + ipos = inode->i_size; + } + else + { + ipos = *pos; + } + + + if(!obj) + { + T((KERN_DEBUG"yaffs_file_write: hey obj is null!\n")); + } + else + { + T((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); + T((KERN_DEBUG"yaffs_file_write writing %d bytes, %d written at %d\n",n,nWritten,ipos)); if(nWritten > 0) { - *pos += nWritten; - ipos = *pos; - if(*pos > inode->i_size) + ipos += nWritten; + *pos = ipos; + if(ipos > inode->i_size) { - inode->i_size = *pos; - T((KERN_DEBUG"yaffs_file_write size updated to %d\n",ipos)); + inode->i_size = ipos; + inode->i_blocks = (ipos + inode->i_blksize - 1)/ inode->i_blksize; + + T((KERN_DEBUG"yaffs_file_write size updated to %d bytes, %d blocks\n",ipos,inode->i_blocks)); } } @@ -711,12 +778,15 @@ static int yaffs_statfs(struct super_block *sb, struct statfs *buf) T((KERN_DEBUG"yaffs_statfs\n")); buf->f_type = YAFFS_MAGIC; - buf->f_bsize = YAFFS_BYTES_PER_CHUNK; + buf->f_bsize = sb->s_blocksize; buf->f_namelen = 255; - buf->f_blocks = yaffs_SuperToDevice(sb)->nBlocks * YAFFS_CHUNKS_PER_BLOCK; + buf->f_blocks = yaffs_SuperToDevice(sb)->nBlocks * YAFFS_CHUNKS_PER_BLOCK/ + (sb->s_blocksize/YAFFS_BYTES_PER_CHUNK); buf->f_files = 0; buf->f_ffree = 0; - buf->f_bavail = buf->f_bfree = yaffs_GetNumberOfFreeChunks(yaffs_SuperToDevice(sb)); + buf->f_bfree = yaffs_GetNumberOfFreeChunks(yaffs_SuperToDevice(sb))/ + (sb->s_blocksize/YAFFS_BYTES_PER_CHUNK); + buf->f_bavail = buf->f_bfree; return 0; } @@ -767,10 +837,6 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl struct dentry * root; yaffs_Device *dev; - - T(("yaffs_read_super: %s\n", useRam ? "RAM" : "MTD")); - sb->s_blocksize = YAFFS_BYTES_PER_CHUNK; - sb->s_blocksize_bits = YAFFS_CHUNK_SIZE_SHIFT; sb->s_magic = YAFFS_MAGIC; sb->s_op = &yaffs_super_ops; @@ -784,6 +850,16 @@ static struct super_block *yaffs_internal_read_super(int useRam, struct super_bl printk(KERN_INFO"yaffs: dev is %d name is \"%s\"\n", sb->s_dev, kdevname(sb->s_dev)); + +#if CONFIG_YAFFS_USE_CHUNK_SIZE + sb->s_blocksize = YAFFS_BYTES_PER_CHUNK; + sb->s_blocksize_bits = YAFFS_CHUNK_SIZE_SHIFT; +#else + sb->s_blocksize = PAGE_CACHE_SIZE; + sb->s_blocksize_bits = PAGE_CACHE_SHIFT; +#endif + T(("yaffs_read_super: %s block size %d\n", useRam ? "RAM" : "MTD",sb->s_blocksize)); + if(useRam) { @@ -974,6 +1050,13 @@ static int __init init_yaffs_fs(void) int error = 0; printk(KERN_DEBUG "yaffs " __DATE__ " " __TIME__ " Initialisation\n"); +#if CONFIG_YAFFS_USE_GENERIC_RW + printk(KERN_DEBUG "yaffs is using generic read/write (caching)\n"); +#else + printk(KERN_DEBUG "yaffs is using direct read/write (uncached)\n"); +#endif + + /* Install the proc_fs entry */ my_proc_entry = create_proc_read_entry("yaffs", S_IRUGO | S_IFREG, -- 2.30.2