diff mbox series

[2/2] jffs2: use unsigned 32-bit timstamps consistently

Message ID 20180619155925.4107498-2-arnd@arndb.de
State Accepted
Commit 5f7a01e222635cba7e4889ad4ebd891835e8b2eb
Headers show
Series None | expand

Commit Message

Arnd Bergmann June 19, 2018, 3:59 p.m. UTC
Most users of jffs2 are 32-bit systems that traditionally only support
timestamps using a 32-bit signed time_t, in the range from years 1902 to
2038. On 64-bit systems, jffs2 however interpreted the same timestamps
as unsigned values, reading back negative times (before 1970) as times
between 2038 and 2106.

Now that Linux supports 64-bit inode timestamps even on 32-bit systems,
let's use the second interpretation everywhere to allow jffs2 to be
used on 32-bit systems beyond 2038 without a fundamental change to the
inode format.

This has a slight risk of regressions, when existing files with timestamps
before 1970 are present in file system images and are now interpreted
as future time stamps. I considered moving the wraparound point a bit,
e.g. to 1960, in order to deal with timestamps that ended up on Dec 31,
1969 due to incorrect timezone handling. However, this would complicate
the implementation unnecessarily, so I went with the simplest possible
method of extending the timestamps.

Writing files with timestamps before 1970 or after 2106 now results
in those times being clamped in the file system.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>

---
 fs/jffs2/os-linux.h | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

-- 
2.9.0

Comments

kernel test robot June 19, 2018, 9:09 p.m. UTC | #1
Hi Arnd,

I love your patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v4.18-rc1 next-20180619]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Arnd-Bergmann/jffs2-use-64-bit-intermediate-timestamps/20180620-015800
reproduce:
        # apt-get install sparse
        make ARCH=x86_64 allmodconfig
        make C=1 CF=-D__CHECK_ENDIAN__


sparse warnings: (new ones prefixed by >>)

>> fs/jffs2/dir.c:263:15: sparse: expression using sizeof(void)

>> fs/jffs2/dir.c:263:15: sparse: expression using sizeof(void)

>> fs/jffs2/dir.c:263:15: sparse: expression using sizeof(void)

>> fs/jffs2/dir.c:263:15: sparse: expression using sizeof(void)

>> fs/jffs2/dir.c:263:15: sparse: expression using sizeof(void)

>> fs/jffs2/dir.c:263:15: sparse: expression using sizeof(void)

>> fs/jffs2/dir.c:263:15: sparse: expression using sizeof(void)

   fs/jffs2/dir.c:230:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:230:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:230:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:230:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:230:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:230:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:230:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:403:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:403:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:403:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:403:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:403:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:403:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:403:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:546:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:546:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:546:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:546:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:546:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:546:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:546:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:591:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:591:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:591:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:591:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:591:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:591:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:591:24: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:715:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:715:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:715:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:715:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:715:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:715:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:715:22: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:800:15: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:800:15: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:800:15: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:800:15: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:800:15: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:800:15: sparse: expression using sizeof(void)
   fs/jffs2/dir.c:800:15: sparse: expression using sizeof(void)
--
>> fs/jffs2/fs.c:115:21: sparse: expression using sizeof(void)

>> fs/jffs2/fs.c:115:21: sparse: expression using sizeof(void)

>> fs/jffs2/fs.c:115:21: sparse: expression using sizeof(void)

>> fs/jffs2/fs.c:115:21: sparse: expression using sizeof(void)

>> fs/jffs2/fs.c:115:21: sparse: expression using sizeof(void)

>> fs/jffs2/fs.c:115:21: sparse: expression using sizeof(void)

>> fs/jffs2/fs.c:115:21: sparse: expression using sizeof(void)

   fs/jffs2/fs.c:116:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:116:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:116:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:116:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:116:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:116:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:116:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:117:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:117:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:117:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:117:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:117:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:117:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:117:21: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:476:45: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:476:45: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:476:45: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:476:45: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:476:45: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:476:45: sparse: expression using sizeof(void)
   fs/jffs2/fs.c:476:45: sparse: expression using sizeof(void)
   include/linux/slab.h:631:13: sparse: undefined identifier '__builtin_mul_overflow'
   include/linux/slab.h:631:13: sparse: call with no type!

vim +263 fs/jffs2/dir.c

^1da177e Linus Torvalds      2005-04-16  241  
^1da177e Linus Torvalds      2005-04-16  242  
^1da177e Linus Torvalds      2005-04-16  243  static int jffs2_link (struct dentry *old_dentry, struct inode *dir_i, struct dentry *dentry)
^1da177e Linus Torvalds      2005-04-16  244  {
fc64005c Al Viro             2016-04-10  245  	struct jffs2_sb_info *c = JFFS2_SB_INFO(old_dentry->d_sb);
2b0143b5 David Howells       2015-03-17  246  	struct jffs2_inode_info *f = JFFS2_INODE_INFO(d_inode(old_dentry));
^1da177e Linus Torvalds      2005-04-16  247  	struct jffs2_inode_info *dir_f = JFFS2_INODE_INFO(dir_i);
^1da177e Linus Torvalds      2005-04-16  248  	int ret;
^1da177e Linus Torvalds      2005-04-16  249  	uint8_t type;
3a69e0cd Artem B. Bityutskiy 2005-08-17  250  	uint32_t now;
^1da177e Linus Torvalds      2005-04-16  251  
^1da177e Linus Torvalds      2005-04-16  252  	/* Don't let people make hard links to bad inodes. */
^1da177e Linus Torvalds      2005-04-16  253  	if (!f->inocache)
^1da177e Linus Torvalds      2005-04-16  254  		return -EIO;
^1da177e Linus Torvalds      2005-04-16  255  
e36cb0b8 David Howells       2015-01-29  256  	if (d_is_dir(old_dentry))
^1da177e Linus Torvalds      2005-04-16  257  		return -EPERM;
^1da177e Linus Torvalds      2005-04-16  258  
^1da177e Linus Torvalds      2005-04-16  259  	/* XXX: This is ugly */
2b0143b5 David Howells       2015-03-17  260  	type = (d_inode(old_dentry)->i_mode & S_IFMT) >> 12;
^1da177e Linus Torvalds      2005-04-16  261  	if (!type) type = DT_REG;
^1da177e Linus Torvalds      2005-04-16  262  
a7cab044 Arnd Bergmann       2018-06-19 @263  	now = JFFS2_NOW();
3a69e0cd Artem B. Bityutskiy 2005-08-17  264  	ret = jffs2_do_link(c, dir_f, f->inocache->ino, type, dentry->d_name.name, dentry->d_name.len, now);
^1da177e Linus Torvalds      2005-04-16  265  
^1da177e Linus Torvalds      2005-04-16  266  	if (!ret) {
ced22070 David Woodhouse     2008-04-22  267  		mutex_lock(&f->sem);
2b0143b5 David Howells       2015-03-17  268  		set_nlink(d_inode(old_dentry), ++f->inocache->pino_nlink);
ced22070 David Woodhouse     2008-04-22  269  		mutex_unlock(&f->sem);
2b0143b5 David Howells       2015-03-17  270  		d_instantiate(dentry, d_inode(old_dentry));
a7cab044 Arnd Bergmann       2018-06-19  271  		dir_i->i_mtime = dir_i->i_ctime = ITIME(now);
2b0143b5 David Howells       2015-03-17  272  		ihold(d_inode(old_dentry));
^1da177e Linus Torvalds      2005-04-16  273  	}
^1da177e Linus Torvalds      2005-04-16  274  	return ret;
^1da177e Linus Torvalds      2005-04-16  275  }
^1da177e Linus Torvalds      2005-04-16  276  

:::::: The code at line 263 was first introduced by commit
:::::: a7cab044350466ac53107fa859f1f2cbc4d5112b jffs2: use 64-bit intermediate timestamps

:::::: TO: Arnd Bergmann <arnd@arndb.de>
:::::: CC: 0day robot <lkp@intel.com>

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox series

Patch

diff --git a/fs/jffs2/os-linux.h b/fs/jffs2/os-linux.h
index acbe1f722f2d..a2dbbb3f4c74 100644
--- a/fs/jffs2/os-linux.h
+++ b/fs/jffs2/os-linux.h
@@ -31,13 +31,13 @@  struct kvec;
 #define JFFS2_F_I_GID(f) (i_gid_read(OFNI_EDONI_2SFFJ(f)))
 #define JFFS2_F_I_RDEV(f) (OFNI_EDONI_2SFFJ(f)->i_rdev)
 
-#define ITIME(sec) ((struct timespec64){(int32_t)sec, 0})
-#define JFFS2_NOW() (ktime_get_real_seconds())
-#define I_SEC(tv) ((tv).tv_sec)
-#define JFFS2_F_I_CTIME(f) (OFNI_EDONI_2SFFJ(f)->i_ctime.tv_sec)
-#define JFFS2_F_I_MTIME(f) (OFNI_EDONI_2SFFJ(f)->i_mtime.tv_sec)
-#define JFFS2_F_I_ATIME(f) (OFNI_EDONI_2SFFJ(f)->i_atime.tv_sec)
-
+#define JFFS2_CLAMP_TIME(t) ((uint32_t)clamp_t(time64_t, (t), 0, U32_MAX))
+#define ITIME(sec) ((struct timespec64){sec, 0})
+#define JFFS2_NOW() JFFS2_CLAMP_TIME(ktime_get_real_seconds())
+#define I_SEC(tv) JFFS2_CLAMP_TIME((tv).tv_sec)
+#define JFFS2_F_I_CTIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_ctime)
+#define JFFS2_F_I_MTIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_mtime)
+#define JFFS2_F_I_ATIME(f) I_SEC(OFNI_EDONI_2SFFJ(f)->i_atime)
 #define sleep_on_spinunlock(wq, s)				\
 	do {							\
 		DECLARE_WAITQUEUE(__wait, current);		\