aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jffs2
diff options
context:
space:
mode:
authorArtem B. Bityutskiy <dedekind@infradead.org>2005-08-17 09:46:26 -0400
committerThomas Gleixner <tglx@mtd.linutronix.de>2005-11-06 14:25:59 -0500
commit3a69e0cd22cf34920508a4032d53e41251925f53 (patch)
treef6f862aa743e3de98e348c20d84a26772da06195 /fs/jffs2
parent01d445f89d68187c9ada7b58ca939dbb987c9fbd (diff)
[JFFS2] Fix JFFS2 [mc]time handling
From: David Woodhouse <dwmw2@infradead.org> Signed-off-by: Artem B. Bityutskiy <dedekind@infradead.org> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/jffs2')
-rw-r--r--fs/jffs2/dir.c21
-rw-r--r--fs/jffs2/gc.c12
-rw-r--r--fs/jffs2/nodelist.h6
-rw-r--r--fs/jffs2/readinode.c4
-rw-r--r--fs/jffs2/write.c11
5 files changed, 37 insertions, 17 deletions
diff --git a/fs/jffs2/dir.c b/fs/jffs2/dir.c
index 5738df223775..0fd15aaf2458 100644
--- a/fs/jffs2/dir.c
+++ b/fs/jffs2/dir.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: dir.c,v 1.87 2005/07/17 11:13:46 dedekind Exp $ 10 * $Id: dir.c,v 1.88 2005/08/17 13:46:22 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -232,11 +232,14 @@ static int jffs2_unlink(struct inode *dir_i, struct dentry *dentry)
232 struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); 232 struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
233 struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode); 233 struct jffs2_inode_info *dead_f = JFFS2_INODE_INFO(dentry->d_inode);
234 int ret; 234 int ret;
235 uint32_t now = get_seconds();
235 236
236 ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name, 237 ret = jffs2_do_unlink(c, dir_f, dentry->d_name.name,
237 dentry->d_name.len, dead_f); 238 dentry->d_name.len, dead_f, now);
238 if (dead_f->inocache) 239 if (dead_f->inocache)
239 dentry->d_inode->i_nlink = dead_f->inocache->nlink; 240 dentry->d_inode->i_nlink = dead_f->inocache->nlink;
241 if (!ret)
242 dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
240 return ret; 243 return ret;
241} 244}
242/***********************************************************************/ 245/***********************************************************************/
@@ -249,6 +252,7 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
249 struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i); 252 struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
250 int ret; 253 int ret;
251 uint8_t type; 254 uint8_t type;
255 uint32_t now;
252 256
253 /* Don't let people make hard links to bad inodes. */ 257 /* Don't let people make hard links to bad inodes. */
254 if (!f->inocache) 258 if (!f->inocache)
@@ -261,13 +265,15 @@ static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct de
261 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; 265 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
262 if (!type) type = DT_REG; 266 if (!type) type = DT_REG;
263 267
264 ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len); 268 now = get_seconds();
269 ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);
265 270
266 if (!ret) { 271 if (!ret) {
267 down(&f->sem); 272 down(&f->sem);
268 old_dentry->d_inode->i_nlink = ++f->inocache->nlink; 273 old_dentry->d_inode->i_nlink = ++f->inocache->nlink;
269 up(&f->sem); 274 up(&f->sem);
270 d_instantiate(dentry, old_dentry->d_inode); 275 d_instantiate(dentry, old_dentry->d_inode);
276 dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
271 atomic_inc(&old_dentry->d_inode->i_count); 277 atomic_inc(&old_dentry->d_inode->i_count);
272 } 278 }
273 return ret; 279 return ret;
@@ -716,6 +722,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
716 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb); 722 struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dir_i->i_sb);
717 struct jffs2_inode_info *victim_f = NULL; 723 struct jffs2_inode_info *victim_f = NULL;
718 uint8_t type; 724 uint8_t type;
725 uint32_t now;
719 726
720 /* The VFS will check for us and prevent trying to rename a 727 /* The VFS will check for us and prevent trying to rename a
721 * file over a directory and vice versa, but if it's a directory, 728 * 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,
749 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12; 756 type = (old_dentry->d_inode->i_mode & S_IFMT) >> 12;
750 if (!type) type = DT_REG; 757 if (!type) type = DT_REG;
751 758
759 now = get_seconds();
752 ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i), 760 ret = jffs2_do_link(c, JFFS2_INODE_INFO(new_dir_i),
753 old_dentry->d_inode->i_ino, type, 761 old_dentry->d_inode->i_ino, type,
754 new_dentry->d_name.name, new_dentry->d_name.len); 762 new_dentry->d_name.name, new_dentry->d_name.len, now);
755 763
756 if (ret) 764 if (ret)
757 return ret; 765 return ret;
@@ -775,7 +783,7 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
775 783
776 /* Unlink the original */ 784 /* Unlink the original */
777 ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i), 785 ret = jffs2_do_unlink(c, JFFS2_INODE_INFO(old_dir_i),
778 old_dentry->d_name.name, old_dentry->d_name.len, NULL); 786 old_dentry->d_name.name, old_dentry->d_name.len, NULL, now);
779 787
780 /* We don't touch inode->i_nlink */ 788 /* We don't touch inode->i_nlink */
781 789
@@ -792,12 +800,15 @@ static int jffs2_rename (struct inode *old_dir_i, struct dentry *old_dentry,
792 /* Might as well let the VFS know */ 800 /* Might as well let the VFS know */
793 d_instantiate(new_dentry, old_dentry->d_inode); 801 d_instantiate(new_dentry, old_dentry->d_inode);
794 atomic_inc(&old_dentry->d_inode->i_count); 802 atomic_inc(&old_dentry->d_inode->i_count);
803 new_dir_i->i_mtime = new_dir_i->i_ctime = ITIME(now);
795 return ret; 804 return ret;
796 } 805 }
797 806
798 if (S_ISDIR(old_dentry->d_inode->i_mode)) 807 if (S_ISDIR(old_dentry->d_inode->i_mode))
799 old_dir_i->i_nlink--; 808 old_dir_i->i_nlink--;
800 809
810 new_dir_i->i_mtime = new_dir_i->i_ctime = old_dir_i->i_mtime = old_dir_i->i_ctime = ITIME(now);
811
801 return 0; 812 return 0;
802} 813}
803 814
diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
index 362cfeed7327..def97157ecbd 100644
--- a/fs/jffs2/gc.c
+++ b/fs/jffs2/gc.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: gc.c,v 1.152 2005/07/24 15:14:14 dedekind Exp $ 10 * $Id: gc.c,v 1.153 2005/08/17 13:46:22 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -771,7 +771,12 @@ static int jffs2_garbage_collect_dirent(struct jffs2_sb_info *c, struct jffs2_er
771 rd.pino = cpu_to_je32(f->inocache->ino); 771 rd.pino = cpu_to_je32(f->inocache->ino);
772 rd.version = cpu_to_je32(++f->highest_version); 772 rd.version = cpu_to_je32(++f->highest_version);
773 rd.ino = cpu_to_je32(fd->ino); 773 rd.ino = cpu_to_je32(fd->ino);
774 rd.mctime = cpu_to_je32(max(JFFS2_F_I_MTIME(f), JFFS2_F_I_CTIME(f))); 774 /* If the times on this inode were set by explicit utime() they can be different,
775 so refrain from splatting them. */
776 if (JFFS2_F_I_MTIME(f) == JFFS2_F_I_CTIME(f))
777 rd.mctime = cpu_to_je32(JFFS2_F_I_MTIME(f));
778 else
779 rd.mctime = cpu_to_je32(0);
775 rd.type = fd->type; 780 rd.type = fd->type;
776 rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8)); 781 rd.node_crc = cpu_to_je32(crc32(0, &rd, sizeof(rd)-8));
777 rd.name_crc = cpu_to_je32(crc32(0, fd->name, rd.nsize)); 782 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
883 kfree(rd); 888 kfree(rd);
884 } 889 }
885 890
891 /* FIXME: If we're deleting a dirent which contains the current mtime and ctime,
892 we should update the metadata node with those times accordingly */
893
886 /* No need for it any more. Just mark it obsolete and remove it from the list */ 894 /* No need for it any more. Just mark it obsolete and remove it from the list */
887 while (*fdp) { 895 while (*fdp) {
888 if ((*fdp) == fd) { 896 if ((*fdp) == fd) {
diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
index adee3c6eb448..ce47d5530a70 100644
--- a/fs/jffs2/nodelist.h
+++ b/fs/jffs2/nodelist.h
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: nodelist.h,v 1.137 2005/08/01 12:05:19 dedekind Exp $ 10 * $Id: nodelist.h,v 1.138 2005/08/17 13:46:23 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -336,8 +336,8 @@ int jffs2_write_inode_range(struct jffs2_sb_info *c, struct jffs2_inode_info *f,
336 struct jffs2_raw_inode *ri, unsigned char *buf, 336 struct jffs2_raw_inode *ri, unsigned char *buf,
337 uint32_t offset, uint32_t writelen, uint32_t *retlen); 337 uint32_t offset, uint32_t writelen, uint32_t *retlen);
338int 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); 338int 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);
339int 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); 339int 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);
340int 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); 340int 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);
341 341
342 342
343/* readinode.c */ 343/* readinode.c */
diff --git a/fs/jffs2/readinode.c b/fs/jffs2/readinode.c
index 50a62dd33e3e..6d5adaba4062 100644
--- a/fs/jffs2/readinode.c
+++ b/fs/jffs2/readinode.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: readinode.c,v 1.139 2005/08/04 11:41:31 dedekind Exp $ 10 * $Id: readinode.c,v 1.140 2005/08/17 13:46:23 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -139,7 +139,7 @@ static inline int read_direntry(struct jffs2_sb_info *c, struct jffs2_raw_node_r
139 fd->type = rd->type; 139 fd->type = rd->type;
140 140
141 /* Pick out the mctime of the latest dirent */ 141 /* Pick out the mctime of the latest dirent */
142 if(fd->version > *mctime_ver) { 142 if(fd->version > *mctime_ver && je32_to_cpu(rd->mctime)) {
143 *mctime_ver = fd->version; 143 *mctime_ver = fd->version;
144 *latest_mctime = je32_to_cpu(rd->mctime); 144 *latest_mctime = je32_to_cpu(rd->mctime);
145 } 145 }
diff --git a/fs/jffs2/write.c b/fs/jffs2/write.c
index 4c418e69cfc6..0a194759bbbd 100644
--- a/fs/jffs2/write.c
+++ b/fs/jffs2/write.c
@@ -7,7 +7,7 @@
7 * 7 *
8 * For licensing information, see the file 'LICENCE' in this directory. 8 * For licensing information, see the file 'LICENCE' in this directory.
9 * 9 *
10 * $Id: write.c,v 1.94 2005/07/20 15:50:51 dedekind Exp $ 10 * $Id: write.c,v 1.95 2005/08/17 13:46:23 dedekind Exp $
11 * 11 *
12 */ 12 */
13 13
@@ -533,7 +533,8 @@ int jffs2_do_create(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, str
533 533
534 534
535int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f, 535int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
536 const char *name, int namelen, struct jffs2_inode_info *dead_f) 536 const char *name, int namelen, struct jffs2_inode_info *dead_f,
537 uint32_t time)
537{ 538{
538 struct jffs2_raw_dirent *rd; 539 struct jffs2_raw_dirent *rd;
539 struct jffs2_full_dirent *fd; 540 struct jffs2_full_dirent *fd;
@@ -565,7 +566,7 @@ int jffs2_do_unlink(struct jffs2_sb_info *c, struct jffs2_inode_info *dir_f,
565 rd->pino = cpu_to_je32(dir_f->inocache->ino); 566 rd->pino = cpu_to_je32(dir_f->inocache->ino);
566 rd->version = cpu_to_je32(++dir_f->highest_version); 567 rd->version = cpu_to_je32(++dir_f->highest_version);
567 rd->ino = cpu_to_je32(0); 568 rd->ino = cpu_to_je32(0);
568 rd->mctime = cpu_to_je32(get_seconds()); 569 rd->mctime = cpu_to_je32(time);
569 rd->nsize = namelen; 570 rd->nsize = namelen;
570 rd->type = DT_UNKNOWN; 571 rd->type = DT_UNKNOWN;
571 rd->node_crc = cpu_to_je32(crc32(0, rd, sizeof(*rd)-8)); 572 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,
646} 647}
647 648
648 649
649int 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) 650int 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)
650{ 651{
651 struct jffs2_raw_dirent *rd; 652 struct jffs2_raw_dirent *rd;
652 struct jffs2_full_dirent *fd; 653 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
674 rd->pino = cpu_to_je32(dir_f->inocache->ino); 675 rd->pino = cpu_to_je32(dir_f->inocache->ino);
675 rd->version = cpu_to_je32(++dir_f->highest_version); 676 rd->version = cpu_to_je32(++dir_f->highest_version);
676 rd->ino = cpu_to_je32(ino); 677 rd->ino = cpu_to_je32(ino);
677 rd->mctime = cpu_to_je32(get_seconds()); 678 rd->mctime = cpu_to_je32(time);
678 rd->nsize = namelen; 679 rd->nsize = namelen;
679 680
680 rd->type = type; 681 rd->type = type;