Skip to content

Commit

Permalink
hostfs: pass 64-bit timestamps to/from user space
Browse files Browse the repository at this point in the history
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: Arnd Bergmann <[email protected]>
  • Loading branch information
arndb committed Dec 18, 2019
1 parent d413fcb commit bca3026
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 15 deletions.
22 changes: 13 additions & 9 deletions fs/hostfs/hostfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,20 @@
* 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;
unsigned short ia_mode;
uid_t ia_uid;
gid_t ia_gid;
loff_t ia_size;
struct timespec ia_atime;
struct timespec ia_mtime;
struct timespec ia_ctime;
unsigned int ia_valid;
unsigned short ia_mode;
uid_t ia_uid;
gid_t ia_gid;
loff_t ia_size;
struct hostfs_timespec ia_atime;
struct hostfs_timespec ia_mtime;
struct hostfs_timespec ia_ctime;
};

struct hostfs_stat {
Expand All @@ -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;
Expand Down
15 changes: 9 additions & 6 deletions fs/hostfs/hostfs_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit bca3026

Please sign in to comment.