*/
const char *yaffs_fs_c_version =
- "$Id: yaffs_fs.c,v 1.41 2006-01-27 23:54:21 tpoynor Exp $";
+ "$Id: yaffs_fs.c,v 1.48 2006-05-21 09:39:12 charles Exp $";
extern const char *yaffs_guts_c_version;
#include <linux/config.h>
#include "yportenv.h"
#include "yaffs_guts.h"
-unsigned yaffs_traceMask = YAFFS_TRACE_ALWAYS | YAFFS_TRACE_BAD_BLOCKS /* | 0xFFFFFFFF */;
+unsigned yaffs_traceMask = YAFFS_TRACE_ALWAYS |
+ YAFFS_TRACE_BAD_BLOCKS |
+ YAFFS_TRACE_CHECKPOINT
+ /* | 0xFFFFFFFF */;
#include <linux/mtd/mtd.h>
#include "yaffs_mtdif.h"
struct inode *new_dir, struct dentry *new_dentry);
static int yaffs_setattr(struct dentry *dentry, struct iattr *attr);
+static int yaffs_sync_fs(struct super_block *sb);
+static int yaffs_write_super(struct super_block *sb);
+
#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0))
static int yaffs_statfs(struct super_block *sb, struct kstatfs *buf);
#else
.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)
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) {
retVal = yaffs_Unlink(yaffs_InodeToObject(dir), dentry->d_name.name);
- yaffs_GrossUnlock(dev);
-
if (retVal == YAFFS_OK) {
dentry->d_inode->i_nlink--;
+ dir->i_version++;
+ yaffs_GrossUnlock(dev);
mark_inode_dirty(dentry->d_inode);
return 0;
- } else {
- return -ENOTEMPTY;
}
+ yaffs_GrossUnlock(dev);
+ return -ENOTEMPTY;
}
/*
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;
+}
+
+
+static int yaffs_write_super(struct super_block *sb)
+{
+
+ T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_write_super\n"));
+ return 0; /* yaffs_do_sync_fs(sb);*/
+
+}
+
+
+static int yaffs_sync_fs(struct super_block *sb)
+{
+
+ 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
{
yaffs_Device *dev = yaffs_SuperToDevice(sb);
+ T(YAFFS_TRACE_OS, (KERN_DEBUG "yaffs_put_super\n"));
+
yaffs_GrossLock(dev);
+
+ yaffs_FlushEntireDeviceCache(dev);
+
if (dev->putSuperFunc) {
dev->putSuperFunc(sb);
}
+
+ yaffs_CheckpointSave(dev);
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_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;
+}
+
static struct super_block *yaffs_internal_read_super(int yaffsVersion,
struct super_block *sb,
void *data, int silent)
if (mtd->oobblock < YAFFS_MIN_YAFFS2_CHUNK_SIZE ||
mtd->oobsize < YAFFS_MIN_YAFFS2_SPARE_SIZE) {
T(YAFFS_TRACE_ALWAYS,
- ("yaffs: MTD device does not support have the "
+ ("yaffs: MTD device does not have the "
"right page sizes\n"));
return NULL;
}
dev->nBytesPerChunk = mtd->oobblock;
dev->nChunksPerBlock = mtd->erasesize / mtd->oobblock;
nBlocks = mtd->size / mtd->erasesize;
+
+ dev->nCheckpointReservedBlocks = 10;
dev->startBlock = 0;
dev->endBlock = nBlocks - 1;
} else {
dev->initialiseNAND = nandmtd_InitialiseNAND;
dev->putSuperFunc = yaffs_MTDPutSuper;
+
+ dev->superBlock = (void *)sb;
+ dev->markSuperBlockDirty = yaffs_MarkSuperBlockDirty;
+
#ifndef CONFIG_YAFFS_DOES_ECC
dev->useNANDECC = 1;
module_exit(exit_yaffs_fs)
MODULE_DESCRIPTION("YAFFS2 - a NAND specific flash file system");
-MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002,2003,2004");
+MODULE_AUTHOR("Charles Manning, Aleph One Ltd., 2002-2006");
MODULE_LICENSE("GPL");