Re: [Y2038] [PATCH] include: ceph: Fix encode and decode type conversions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Monday 15 February 2016 21:02:33 Deepa Dinamani wrote:
> > Actually I was thinking we'd do the opposite and document the
> > existing 64-bit behavior, and then make sure we do it the same
> > on 32-bit machines once we have the new syscalls.
> 
> I'm not sure I follow what is opposite here.
> You just want to document the behavior and fix it later when the time
> range is extended beyond 2038?

What I meant was that rather than changing the returned range from
1970..2106 to 1902..2038, I would make the current behavior explicit
and document that it is correct.

> >>  static inline void ceph_decode_timespec(struct timespec *ts,
> >>                                         const struct ceph_timespec *tv)
> >>  {
> >> -       ts->tv_sec = (__kernel_time_t)le32_to_cpu(tv->tv_sec);
> >> -       ts->tv_nsec = (long)le32_to_cpu(tv->tv_nsec);
> >> +       ts->tv_sec = (s32)(s64)le32_to_cpu(tv->tv_sec);
> >> +       ts->tv_nsec = (s32)(s64)le32_to_cpu(tv->tv_nsec);
> >>  }
> >
> > Why did you choose to express this as "(s32)(s64)..." rather than
> > "(s64)(s32)..."? The result is the same (just the s32 cast by itself
> > would be sufficient), I just don't see yet how it clarifies what is
> > going on.
> 
> Let's say we encode -1.
> so when you pass the same value to decode, ceph_timespec is {0xFFFFFFFF,0}.
> 0xFFFFFFFF is greater than INT_MAX. And, according to c99 the result
> is implementation dependent if this cast to a s32.
> 
> Quoting from http://c0x.coding-guidelines.com/6.3.1.3.html :
> 6.3.1.3 Signed and unsigned integers
> 1 When a value with integer type is converted to another integer type
> other than _Bool, if the value can be represented by the newtype, it
> is unchanged.
> 2 Otherwise, if the newtype is unsigned, the value is converted by
> repeatedly adding or subtracting one more than the maximum value that
> can be represented in the newtype until the value is in the range of
> the newtype.49)
> 3 Otherwise, the newtype is signed and the value cannot be represented
> in it; either the result is implementation-defined or an
> implementation-defined signal is raised
> 
> GCC does guarantee the behavior.
> Quoting from GCC manual
> (https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html):
> The result of, or the signal raised by, converting an integer to a
> signed integer type when the value cannot be represented in an object
> of that type (C90 6.2.1.2, C99 and C11 6.3.1.3).
> For conversion to a type of width N, the value is reduced modulo 2^N
> to be within range of the type; no signal is raised.
> 
> But, as the C standard suggests, behavior is implementation dependent.
> This is why I cast it to s64 before casting it to s32.
> I explained in the commit text, but missed GCC part.

Ok, fair enough. I always assumed that "implementation specific"
in this context meant that on any architectures that implement
negative numbers as twos-complement (anything that Linux runs on)
we get the expected result. I'm sure we rely on that behavior in
a lot of places in the kernel, but you are correct that the C
standard makes your code well-defined, and the other one not.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe ceph-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [CEPH Users]     [Ceph Large]     [Information on CEPH]     [Linux BTRFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]
  Powered by Linux