Commit 3a3d1e51 authored by Arnd Bergmann's avatar Arnd Bergmann Committed by Linus Torvalds

ocfs2: dlmglue: clean up timestamp handling

The handling of timestamps outside of the 1970..2038 range in the dlm
glue is rather inconsistent: on 32-bit architectures, this has always
wrapped around to negative timestamps in the 1902..1969 range, while on
64-bit kernels all timestamps are interpreted as positive 34 bit numbers
in the 1970..2514 year range.

Now that the VFS code handles 64-bit timestamps on all architectures, we
can make the behavior more consistent here, and return the same result
that we had on 64-bit already, making the file system y2038 safe in the
process.  Outside of dlmglue, it already uses 64-bit on-disk timestamps
anway, so that part is fine.

For consistency, I'm changing ocfs2_pack_timespec() to clamp anything
outside of the supported range to the minimum and maximum values.  This
avoids a possible ambiguity of values before 1970 in particular, which
used to be interpreted as times at the end of the 2514 range previously.

Link: http://lkml.kernel.org/r/20180619155826.4106487-1-arnd@arndb.deSigned-off-by: default avatarArnd Bergmann <arnd@arndb.de>
Reviewed-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Joseph Qi <jiangqi903@gmail.com>
Cc: Changwei Ge <ge.changwei@h3c.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent cf76c785
...@@ -2123,10 +2123,10 @@ static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb, ...@@ -2123,10 +2123,10 @@ static void ocfs2_downconvert_on_unlock(struct ocfs2_super *osb,
/* LVB only has room for 64 bits of time here so we pack it for /* LVB only has room for 64 bits of time here so we pack it for
* now. */ * now. */
static u64 ocfs2_pack_timespec(struct timespec *spec) static u64 ocfs2_pack_timespec(struct timespec64 *spec)
{ {
u64 res; u64 res;
u64 sec = spec->tv_sec; u64 sec = clamp_t(time64_t, spec->tv_sec, 0, 0x3ffffffffull);
u32 nsec = spec->tv_nsec; u32 nsec = spec->tv_nsec;
res = (sec << OCFS2_SEC_SHIFT) | (nsec & OCFS2_NSEC_MASK); res = (sec << OCFS2_SEC_SHIFT) | (nsec & OCFS2_NSEC_MASK);
...@@ -2142,7 +2142,6 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode) ...@@ -2142,7 +2142,6 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
struct ocfs2_inode_info *oi = OCFS2_I(inode); struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres; struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
struct ocfs2_meta_lvb *lvb; struct ocfs2_meta_lvb *lvb;
struct timespec ts;
lvb = ocfs2_dlm_lvb(&lockres->l_lksb); lvb = ocfs2_dlm_lvb(&lockres->l_lksb);
...@@ -2163,15 +2162,12 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode) ...@@ -2163,15 +2162,12 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
lvb->lvb_igid = cpu_to_be32(i_gid_read(inode)); lvb->lvb_igid = cpu_to_be32(i_gid_read(inode));
lvb->lvb_imode = cpu_to_be16(inode->i_mode); lvb->lvb_imode = cpu_to_be16(inode->i_mode);
lvb->lvb_inlink = cpu_to_be16(inode->i_nlink); lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
ts = timespec64_to_timespec(inode->i_atime);
lvb->lvb_iatime_packed = lvb->lvb_iatime_packed =
cpu_to_be64(ocfs2_pack_timespec(&ts)); cpu_to_be64(ocfs2_pack_timespec(&inode->i_atime));
ts = timespec64_to_timespec(inode->i_ctime);
lvb->lvb_ictime_packed = lvb->lvb_ictime_packed =
cpu_to_be64(ocfs2_pack_timespec(&ts)); cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime));
ts = timespec64_to_timespec(inode->i_mtime);
lvb->lvb_imtime_packed = lvb->lvb_imtime_packed =
cpu_to_be64(ocfs2_pack_timespec(&ts)); cpu_to_be64(ocfs2_pack_timespec(&inode->i_mtime));
lvb->lvb_iattr = cpu_to_be32(oi->ip_attr); lvb->lvb_iattr = cpu_to_be32(oi->ip_attr);
lvb->lvb_idynfeatures = cpu_to_be16(oi->ip_dyn_features); lvb->lvb_idynfeatures = cpu_to_be16(oi->ip_dyn_features);
lvb->lvb_igeneration = cpu_to_be32(inode->i_generation); lvb->lvb_igeneration = cpu_to_be32(inode->i_generation);
...@@ -2180,7 +2176,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode) ...@@ -2180,7 +2176,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
mlog_meta_lvb(0, lockres); mlog_meta_lvb(0, lockres);
} }
static void ocfs2_unpack_timespec(struct timespec *spec, static void ocfs2_unpack_timespec(struct timespec64 *spec,
u64 packed_time) u64 packed_time)
{ {
spec->tv_sec = packed_time >> OCFS2_SEC_SHIFT; spec->tv_sec = packed_time >> OCFS2_SEC_SHIFT;
...@@ -2189,7 +2185,6 @@ static void ocfs2_unpack_timespec(struct timespec *spec, ...@@ -2189,7 +2185,6 @@ static void ocfs2_unpack_timespec(struct timespec *spec,
static void ocfs2_refresh_inode_from_lvb(struct inode *inode) static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
{ {
struct timespec ts;
struct ocfs2_inode_info *oi = OCFS2_I(inode); struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres; struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
struct ocfs2_meta_lvb *lvb; struct ocfs2_meta_lvb *lvb;
...@@ -2217,15 +2212,12 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode) ...@@ -2217,15 +2212,12 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
i_gid_write(inode, be32_to_cpu(lvb->lvb_igid)); i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
inode->i_mode = be16_to_cpu(lvb->lvb_imode); inode->i_mode = be16_to_cpu(lvb->lvb_imode);
set_nlink(inode, be16_to_cpu(lvb->lvb_inlink)); set_nlink(inode, be16_to_cpu(lvb->lvb_inlink));
ocfs2_unpack_timespec(&ts, ocfs2_unpack_timespec(&inode->i_atime,
be64_to_cpu(lvb->lvb_iatime_packed)); be64_to_cpu(lvb->lvb_iatime_packed));
inode->i_atime = timespec_to_timespec64(ts); ocfs2_unpack_timespec(&inode->i_mtime,
ocfs2_unpack_timespec(&ts,
be64_to_cpu(lvb->lvb_imtime_packed)); be64_to_cpu(lvb->lvb_imtime_packed));
inode->i_mtime = timespec_to_timespec64(ts); ocfs2_unpack_timespec(&inode->i_ctime,
ocfs2_unpack_timespec(&ts,
be64_to_cpu(lvb->lvb_ictime_packed)); be64_to_cpu(lvb->lvb_ictime_packed));
inode->i_ctime = timespec_to_timespec64(ts);
spin_unlock(&oi->ip_lock); spin_unlock(&oi->ip_lock);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment