mtd/fs/jffs2 dir.c, 1.87, 1.88 gc.c, 1.152, 1.153 nodelist.h, 1.137,
1.138 readinode.c, 1.139, 1.140 write.c, 1.94, 1.95
Artem Bityuckiy
dedekind at infradead.org
Wed Aug 17 09:46:26 EDT 2005
Update of /home/cvs/mtd/fs/jffs2
In directory phoenix.infradead.org:/tmp/cvs-serv9465
Modified Files:
dir.c gc.c nodelist.h readinode.c write.c
Log Message:
[JFFS2] Fix JFFS2 [mc]time handling
From: David Woodhouse <dwmw2 at infradead.org>
Index: dir.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/dir.c,v
retrieving revision 1.87
retrieving revision 1.88
diff -u -r1.87 -r1.88
--- dir.c 17 Jul 2005 11:13:46 -0000 1.87
+++ dir.c 17 Aug 2005 13:46:22 -0000 1.88
@@ -232,11 +232,14 @@
struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode);
int ret;
+ uint32_t now = get_seconds();
ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
- dentry->d_name.len, dead_f);
+ dentry->d_name.len, dead_f, now);
if (dead_f->inocache)
dentry->d_inode->i_nlink = dead_f->inocache->nlink;
+ if (!ret)
+ dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
return ret;
}
/***********************************************************************/
@@ -249,6 +252,7 @@
struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
int ret;
uint8_t type;
+ uint32_t now;
/* Don't let people make hard links to bad inodes. */
if (!f->inocache)
@@ -261,13 +265,15 @@
type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
if (!type) type = DT_REG;
- ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len);
+ now = get_seconds();
+ ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);
if (!ret) {
down(&f->sem);
old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
up(&f->sem);
d_instantiate(dentry, old_dentry->d_inode);
+ dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
atomic_inc(&old_dentry->d_inode->i_count);
}
return ret;
@@ -716,6 +722,7 @@
struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
struct jffs2_inode_info *victim_f = NULL;
uint8_t type;
+ uint32_t now;
/* The VFS will check for us and prevent trying to rename a
* file over a directory and vice versa, but if it's a directory,
@@ -749,9 +756,10 @@
type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
if (!type) type = DT_REG;
+ now = get_seconds();
ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
old_dentry->d_inode->i_ino, type,
- new_dentry->d_name.name, new_dentry->d_name.len);
+ new_dentry->d_name.name, new_dentry->d_name.len, now);
if (ret)
return ret;
@@ -775,7 +783,7 @@
/* Unlink the original */
ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
- old_dentry->d_name.name, old_dentry->d_name.len, NULL);
+ old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
/* We don't touch inode->i_nlink */
@@ -792,12 +800,15 @@
/* Might as well let the VFS know */
d_instantiate(new_dentry, old_dentry->d_inode);
atomic_inc(&old_dentry->d_inode->i_count);
+ new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
return ret;
}
if (S_ISDIR(old_dentry->d_inode->i_mode))
old_dir_i->i_nlink--;
+ new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
+
return 0;
}
Index: gc.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/gc.c,v
retrieving revision 1.152
retrieving revision 1.153
diff -u -r1.152 -r1.153
--- gc.c 24 Jul 2005 15:14:14 -0000 1.152
+++ gc.c 17 Aug 2005 13:46:22 -0000 1.153
@@ -771,7 +771,12 @@
rd.pino = cpu_to_je32(f->inocache->ino);
rd.version = cpu_to_je32(++f->highest_version);
rd.ino = cpu_to_je32(fd->ino);
- rd.mctime = cpu_to_je32(max(JFFS2_F_I_MTIME(f), JFFS2_F_I_CTIME(f)));
+ /* If the times on this inode were set by explicit utime() they can be different,
+ so refrain from splatting them. */
+ if (JFFS2_F_I_MTIME(f) == JFFS2_F_I_CTIME(f))
+ rd.mctime = cpu_to_je32(JFFS2_F_I_MTIME(f));
+ else
+ rd.mctime = cpu_to_je32(0);
rd.type = fd->type;
rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize));
@@ -883,6 +888,9 @@
kfree(rd);
}
+ /* FIXME: If we're deleting a dirent which contains the current mtime and ctime,
+ we should update the metadata node with those times accordingly */
+
/* No need for it any more. Just mark it obsolete and remove it from the list */
while (*fdp) {
if ((*fdp) == fd) {
Index: nodelist.h
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/nodelist.h,v
retrieving revision 1.137
retrieving revision 1.138
diff -u -r1.137 -r1.138
--- nodelist.h 1 Aug 2005 12:05:19 -0000 1.137
+++ nodelist.h 17 Aug 2005 13:46:23 -0000 1.138
@@ -336,8 +336,8 @@
struct jffs2_raw_inode *ri, unsigned char *buf,
uint32_t offset, uint32_t writelen, uint32_t *retlen);
int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, struct jffs2_inode_info *f, struct jffs2_raw_inode *ri, const char *name, int namelen);
-int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f);
-int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen);
+int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, const char *name, int namelen, struct jffs2_inode_info *dead_f, uint32_t time);
+int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time);
/* readinode.c */
Index: readinode.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/readinode.c,v
retrieving revision 1.139
retrieving revision 1.140
diff -u -r1.139 -r1.140
--- readinode.c 4 Aug 2005 11:41:31 -0000 1.139
+++ readinode.c 17 Aug 2005 13:46:23 -0000 1.140
@@ -139,7 +139,7 @@
fd->type = rd->type;
/* Pick out the mctime of the latest dirent */
- if(fd->version > *mctime_ver) {
+ if(fd->version > *mctime_ver && je32_to_cpu(rd->mctime)) {
*mctime_ver = fd->version;
*latest_mctime = je32_to_cpu(rd->mctime);
}
Index: write.c
===================================================================
RCS file: /home/cvs/mtd/fs/jffs2/write.c,v
retrieving revision 1.94
retrieving revision 1.95
diff -u -r1.94 -r1.95
--- write.c 20 Jul 2005 15:50:51 -0000 1.94
+++ write.c 17 Aug 2005 13:46:23 -0000 1.95
@@ -533,7 +533,8 @@
int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
- const char *name, int namelen, struct jffs2_inode_info *dead_f)
+ const char *name, int namelen, struct jffs2_inode_info *dead_f,
+ uint32_t time)
{
struct jffs2_raw_dirent *rd;
struct jffs2_full_dirent *fd;
@@ -565,7 +566,7 @@
rd->pino = cpu_to_je32(dir_f->inocache->ino);
rd->version = cpu_to_je32(++dir_f->highest_version);
rd->ino = cpu_to_je32(0);
- rd->mctime = cpu_to_je32(get_seconds());
+ rd->mctime = cpu_to_je32(time);
rd->nsize = namelen;
rd->type = DT_UNKNOWN;
rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8));
@@ -646,7 +647,7 @@
}
-int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen)
+int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint32_t ino, uint8_t type, const char *name, int namelen, uint32_t time)
{
struct jffs2_raw_dirent *rd;
struct jffs2_full_dirent *fd;
@@ -674,7 +675,7 @@
rd->pino = cpu_to_je32(dir_f->inocache->ino);
rd->version = cpu_to_je32(++dir_f->highest_version);
rd->ino = cpu_to_je32(ino);
- rd->mctime = cpu_to_je32(get_seconds());
+ rd->mctime = cpu_to_je32(time);
rd->nsize = namelen;
rd->type = type;
More information about the linux-mtd-cvs
mailing list