Commit bca30265 authored by Arnd Bergmann's avatar Arnd Bergmann
Browse files

hostfs: pass 64-bit timestamps to/from user space



The use of 'struct timespec' is deprecated in the kernel, so we
want to avoid the conversions from/to the proper timespec64
structure.

On the user space side, we have a 'struct timespec' that is defined
by the C library and that will be incompatible with the kernel's
view on 32-bit architectures once they move to a 64-bit time_t,
breaking the shared binary layout of hostfs_iattr and hostfs_stat.

This changes the two structures to use a new hostfs_timespec structure
with fixed 64-bit seconds/nanoseconds for passing the timestamps
between hostfs_kern.c and hostfs_user.c. With a new enough user
space side, this will allow timestamps beyond year 2038.

Signed-off-by: default avatarArnd Bergmann <arnd@arndb.de>
parent d413fcb4
Loading
Loading
Loading
Loading
+13 −9
Original line number Diff line number Diff line
@@ -37,6 +37,10 @@
 * is on, and remove the appropriate bits from attr->ia_mode (attr is a
 * "struct iattr *"). -BlaisorBlade
 */
struct hostfs_timespec {
	long long tv_sec;
	long long tv_nsec;
};

struct hostfs_iattr {
	unsigned int		ia_valid;
@@ -44,9 +48,9 @@ struct hostfs_iattr {
	uid_t			ia_uid;
	gid_t			ia_gid;
	loff_t			ia_size;
	struct timespec	ia_atime;
	struct timespec	ia_mtime;
	struct timespec	ia_ctime;
	struct hostfs_timespec	ia_atime;
	struct hostfs_timespec	ia_mtime;
	struct hostfs_timespec	ia_ctime;
};

struct hostfs_stat {
@@ -56,7 +60,7 @@ struct hostfs_stat {
	unsigned int uid;
	unsigned int gid;
	unsigned long long size;
	struct timespec atime, mtime, ctime;
	struct hostfs_timespec atime, mtime, ctime;
	unsigned int blksize;
	unsigned long long blocks;
	unsigned int maj;
+9 −6
Original line number Diff line number Diff line
@@ -549,9 +549,9 @@ static int read_name(struct inode *ino, char *name)
	set_nlink(ino, st.nlink);
	i_uid_write(ino, st.uid);
	i_gid_write(ino, st.gid);
	ino->i_atime = timespec_to_timespec64(st.atime);
	ino->i_mtime = timespec_to_timespec64(st.mtime);
	ino->i_ctime = timespec_to_timespec64(st.ctime);
	ino->i_atime = (struct timespec64){ st.atime.tv_sec, st.atime.tv_nsec };
	ino->i_mtime = (struct timespec64){ st.mtime.tv_sec, st.mtime.tv_nsec };
	ino->i_ctime = (struct timespec64){ st.ctime.tv_sec, st.ctime.tv_nsec };
	ino->i_size = st.size;
	ino->i_blocks = st.blocks;
	return 0;
@@ -820,15 +820,18 @@ static int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
	}
	if (attr->ia_valid & ATTR_ATIME) {
		attrs.ia_valid |= HOSTFS_ATTR_ATIME;
		attrs.ia_atime = timespec64_to_timespec(attr->ia_atime);
		attrs.ia_atime = (struct hostfs_timespec)
			{ attr->ia_atime.tv_sec, attr->ia_atime.tv_nsec };
	}
	if (attr->ia_valid & ATTR_MTIME) {
		attrs.ia_valid |= HOSTFS_ATTR_MTIME;
		attrs.ia_mtime = timespec64_to_timespec(attr->ia_mtime);
		attrs.ia_mtime = (struct hostfs_timespec)
			{ attr->ia_mtime.tv_sec, attr->ia_mtime.tv_nsec };
	}
	if (attr->ia_valid & ATTR_CTIME) {
		attrs.ia_valid |= HOSTFS_ATTR_CTIME;
		attrs.ia_ctime = timespec64_to_timespec(attr->ia_ctime);
		attrs.ia_ctime = (struct hostfs_timespec)
			{ attr->ia_ctime.tv_sec, attr->ia_ctime.tv_nsec };
	}
	if (attr->ia_valid & ATTR_ATIME_SET) {
		attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;