Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3a69e0cd authored by Artem B. Bityutskiy's avatar Artem B. Bityutskiy Committed by Thomas Gleixner
Browse files

[JFFS2] Fix JFFS2 [mc]time handling



From: David Woodhouse <dwmw2@infradead.org>

Signed-off-by: default avatarArtem B. Bityutskiy <dedekind@infradead.org>
Signed-off-by: default avatarThomas Gleixner <tglx@linutronix.de>
parent 01d445f8
Loading
Loading
Loading
Loading
+16 −5
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 * $Id: dir.c,v 1.87 2005/07/17 11:13:46 dedekind Exp $
 * $Id: dir.c,v 1.88 2005/08/17 13:46:22 dedekind Exp $
 *
 */

@@ -232,11 +232,14 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
	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 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
	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 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
	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 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
	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 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
	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 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,

	/* 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 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
		/* 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;
}
+10 −2
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 * $Id: gc.c,v 1.152 2005/07/24 15:14:14 dedekind Exp $
 * $Id: gc.c,v 1.153 2005/08/17 13:46:22 dedekind Exp $
 *
 */

@@ -771,7 +771,12 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
	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 @@ static int jffs2_garbage_collect_deletion_dirent(struct jffs2_sb_info *c, struct
		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) {
+3 −3
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 * $Id: nodelist.h,v 1.137 2005/08/01 12:05:19 dedekind Exp $
 * $Id: nodelist.h,v 1.138 2005/08/17 13:46:23 dedekind Exp $
 *
 */

@@ -336,8 +336,8 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
			    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 */
+2 −2
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 * $Id: readinode.c,v 1.139 2005/08/04 11:41:31 dedekind Exp $
 * $Id: readinode.c,v 1.140 2005/08/17 13:46:23 dedekind Exp $
 *
 */

@@ -139,7 +139,7 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
	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);
	}
+6 −5
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *
 * For licensing information, see the file 'LICENCE' in this directory.
 *
 * $Id: write.c,v 1.94 2005/07/20 15:50:51 dedekind Exp $
 * $Id: write.c,v 1.95 2005/08/17 13:46:23 dedekind Exp $
 *
 */

@@ -533,7 +533,8 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str


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 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
		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_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_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_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 @@ int jffs2_do_link (struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, uint
	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;