aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2014-09-14 18:06:36 -0400
committerSteve French <smfrench@gmail.com>2014-09-14 18:06:36 -0400
commit2ae83bf93882d1ec0cd775c489bd1bee611f792e (patch)
tree16bad22e1b184520d2ed3af34d4895e002c77016 /fs
parent1536340e7c67694b134cbbc07168e5a524e49d08 (diff)
[CIFS] Fix setting time before epoch (negative time values)
xfstest generic/258 sets the time on a file to a negative value (before 1970) which fails since do_div can not handle negative numbers. In addition 'normal' division of 64 bit values does not build on 32 bit arch so have to workaround this by special casing negative values in cifs_NTtimeToUnix Samba server also has a bug with this (see samba bugzilla 7771) but it works to Windows server. Signed-off-by: Steve French <smfrench@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/netmisc.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c
index 6834b9c3bec1..b333ff60781d 100644
--- a/fs/cifs/netmisc.c
+++ b/fs/cifs/netmisc.c
@@ -925,11 +925,23 @@ cifs_NTtimeToUnix(__le64 ntutc)
925 /* BB what about the timezone? BB */ 925 /* BB what about the timezone? BB */
926 926
927 /* Subtract the NTFS time offset, then convert to 1s intervals. */ 927 /* Subtract the NTFS time offset, then convert to 1s intervals. */
928 u64 t; 928 s64 t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET;
929
930 /*
931 * Unfortunately can not use normal 64 bit division on 32 bit arch, but
932 * the alternative, do_div, does not work with negative numbers so have
933 * to special case them
934 */
935 if (t < 0) {
936 t = -t;
937 ts.tv_nsec = (long)(do_div(t, 10000000) * 100);
938 ts.tv_nsec = -ts.tv_nsec;
939 ts.tv_sec = -t;
940 } else {
941 ts.tv_nsec = (long)do_div(t, 10000000) * 100;
942 ts.tv_sec = t;
943 }
929 944
930 t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET;
931 ts.tv_nsec = do_div(t, 10000000) * 100;
932 ts.tv_sec = t;
933 return ts; 945 return ts;
934} 946}
935 947