Skip to content

Commit

Permalink
ocfs2: dlmglue: clean up timestamp handling
Browse files Browse the repository at this point in the history
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.de
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Andrew 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: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Arnd Bergmann authored and Linus Torvalds committed Nov 3, 2018
1 parent cf76c78 commit 3a3d1e5
Showing 1 changed file with 9 additions and 17 deletions.
26 changes: 9 additions & 17 deletions fs/ocfs2/dlmglue.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
* now. */
static u64 ocfs2_pack_timespec(struct timespec *spec)
static u64 ocfs2_pack_timespec(struct timespec64 *spec)
{
u64 res;
u64 sec = spec->tv_sec;
u64 sec = clamp_t(time64_t, spec->tv_sec, 0, 0x3ffffffffull);
u32 nsec = spec->tv_nsec;

res = (sec << OCFS2_SEC_SHIFT) | (nsec & OCFS2_NSEC_MASK);
Expand All @@ -2142,7 +2142,6 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
struct ocfs2_meta_lvb *lvb;
struct timespec ts;

lvb = ocfs2_dlm_lvb(&lockres->l_lksb);

Expand All @@ -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_imode = cpu_to_be16(inode->i_mode);
lvb->lvb_inlink = cpu_to_be16(inode->i_nlink);
ts = timespec64_to_timespec(inode->i_atime);
lvb->lvb_iatime_packed =
cpu_to_be64(ocfs2_pack_timespec(&ts));
ts = timespec64_to_timespec(inode->i_ctime);
cpu_to_be64(ocfs2_pack_timespec(&inode->i_atime));
lvb->lvb_ictime_packed =
cpu_to_be64(ocfs2_pack_timespec(&ts));
ts = timespec64_to_timespec(inode->i_mtime);
cpu_to_be64(ocfs2_pack_timespec(&inode->i_ctime));
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_idynfeatures = cpu_to_be16(oi->ip_dyn_features);
lvb->lvb_igeneration = cpu_to_be32(inode->i_generation);
Expand All @@ -2180,7 +2176,7 @@ static void __ocfs2_stuff_meta_lvb(struct inode *inode)
mlog_meta_lvb(0, lockres);
}

static void ocfs2_unpack_timespec(struct timespec *spec,
static void ocfs2_unpack_timespec(struct timespec64 *spec,
u64 packed_time)
{
spec->tv_sec = packed_time >> OCFS2_SEC_SHIFT;
Expand All @@ -2189,7 +2185,6 @@ static void ocfs2_unpack_timespec(struct timespec *spec,

static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
{
struct timespec ts;
struct ocfs2_inode_info *oi = OCFS2_I(inode);
struct ocfs2_lock_res *lockres = &oi->ip_inode_lockres;
struct ocfs2_meta_lvb *lvb;
Expand Down Expand Up @@ -2217,15 +2212,12 @@ static void ocfs2_refresh_inode_from_lvb(struct inode *inode)
i_gid_write(inode, be32_to_cpu(lvb->lvb_igid));
inode->i_mode = be16_to_cpu(lvb->lvb_imode);
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));
inode->i_atime = timespec_to_timespec64(ts);
ocfs2_unpack_timespec(&ts,
ocfs2_unpack_timespec(&inode->i_mtime,
be64_to_cpu(lvb->lvb_imtime_packed));
inode->i_mtime = timespec_to_timespec64(ts);
ocfs2_unpack_timespec(&ts,
ocfs2_unpack_timespec(&inode->i_ctime,
be64_to_cpu(lvb->lvb_ictime_packed));
inode->i_ctime = timespec_to_timespec64(ts);
spin_unlock(&oi->ip_lock);
}

Expand Down

0 comments on commit 3a3d1e5

Please sign in to comment.