*/
const char *yaffs_fs_c_version =
- "$Id: yaffs_fs.c,v 1.80 2009-05-12 02:23:51 charles Exp $";
+ "$Id: yaffs_fs.c,v 1.84 2009-10-14 00:01:56 charles Exp $";
extern const char *yaffs_guts_c_version;
#include <linux/version.h>
#define yaffs_SuperToDevice(sb) ((yaffs_Device *)sb->u.generic_sbp)
#endif
+
+#define update_dir_time(dir) do {\
+ (dir)->i_ctime = (dir)->i_mtime = CURRENT_TIME; \
+ } while(0)
+
static void yaffs_put_super(struct super_block *sb);
static ssize_t yaffs_file_write(struct file *f, const char *buf, size_t n,
yaffs_GrossLock(dev);
- yaffs_FlushFile(obj, 1);
+ yaffs_FlushFile(obj, 1,0);
yaffs_GrossUnlock(dev);
T(YAFFS_TRACE_OS, ("start yaffs_write_begin\n"));
/* Get a page */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 28)
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 28)
pg = grab_cache_page_write_begin(mapping, index, flags);
#else
pg = __grab_cache_page(mapping, index);
if (obj) {
inode = yaffs_get_inode(dir->i_sb, mode, rdev, obj);
d_instantiate(dentry, inode);
+ update_dir_time(dir);
T(YAFFS_TRACE_OS,
("yaffs_mknod created object %d count = %d\n",
obj->objectId, atomic_read(&inode->i_count)));
dir->i_version++;
yaffs_GrossUnlock(dev);
mark_inode_dirty(dentry->d_inode);
+ update_dir_time(dir);
return 0;
}
yaffs_GrossUnlock(dev);
yaffs_GrossUnlock(dev);
- if (link)
+ if (link){
+ update_dir_time(dir);
return 0;
+ }
return -EPERM;
}
inode = yaffs_get_inode(dir->i_sb, obj->yst_mode, 0, obj);
d_instantiate(dentry, inode);
+ update_dir_time(dir);
T(YAFFS_TRACE_OS, ("symlink created OK\n"));
return 0;
} else {
T(YAFFS_TRACE_OS, ("yaffs_sync_object\n"));
yaffs_GrossLock(dev);
- yaffs_FlushFile(obj, 1);
+ yaffs_FlushFile(obj, 1, datasync);
yaffs_GrossUnlock(dev);
return 0;
}
new_dentry->d_inode->i_nlink--;
mark_inode_dirty(new_dentry->d_inode);
}
-
+
+ update_dir_time(old_dir);
+ if(old_dir != new_dir)
+ update_dir_time(new_dir);
return 0;
} else {
return -ENOTEMPTY;
}
+
+static void yaffs_flush_sb_inodes(struct super_block *sb)
+{
+ struct inode *iptr;
+ yaffs_Object *obj;
+
+ list_for_each_entry(iptr,&sb->s_inodes, i_sb_list){
+ obj = yaffs_InodeToObject(iptr);
+ if(obj){
+ T(YAFFS_TRACE_OS, ("flushing obj %d\n",obj->objectId));
+ yaffs_FlushFile(obj,1,0);
+ }
+ }
+}
+
static int yaffs_do_sync_fs(struct super_block *sb)
{
if (dev) {
yaffs_FlushEntireDeviceCache(dev);
+ yaffs_flush_sb_inodes(sb);
yaffs_CheckpointSave(dev);
}
int skip_checkpoint_read;
int skip_checkpoint_write;
int no_cache;
+ int tags_ecc_on;
+ int tags_ecc_overridden;
} yaffs_options;
#define MAX_OPT_LEN 20
memset(cur_opt, 0, MAX_OPT_LEN + 1);
p = 0;
+ while(*options_str == ',')
+ options_str++;
+
while (*options_str && *options_str != ',') {
if (p < MAX_OPT_LEN) {
cur_opt[p] = *options_str;
if (!strcmp(cur_opt, "inband-tags"))
options->inband_tags = 1;
- else if (!strcmp(cur_opt, "no-cache"))
+ else if (!strcmp(cur_opt, "tags-ecc-off")){
+ options->tags_ecc_on = 0;
+ options->tags_ecc_overridden=1;
+ } else if (!strcmp(cur_opt, "tags-ecc-on")){
+ options->tags_ecc_on = 1;
+ options->tags_ecc_overridden = 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;
dev->nShortOpCaches = (options.no_cache) ? 0 : 10;
dev->inbandTags = options.inband_tags;
+#ifdef CONFIG_YAFFS_DISABLE_TAGS_ECC
+ dev->noTagsECC = 1;
+#endif
+ if(options.tags_ecc_overridden)
+ dev->noTagsECC = !options.tags_ecc_on;
+
/* ... and the functions. */
if (yaffsVersion == 2) {
dev->writeChunkWithTagsToNAND =
buf +=
sprintf(buf, "nBackgroudDeletions %d\n", dev->nBackgroundDeletions);
buf += sprintf(buf, "useNANDECC......... %d\n", dev->useNANDECC);
+ buf += sprintf(buf, "noTagsECC.......... %d\n", dev->noTagsECC);
buf += sprintf(buf, "isYaffs2........... %d\n", dev->isYaffs2);
buf += sprintf(buf, "inbandTags......... %d\n", dev->inbandTags);