diff options
Diffstat (limited to 'fs/cifs/netmisc.c')
-rw-r--r-- | fs/cifs/netmisc.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index ce87550e918f..992e80edc720 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c | |||
@@ -909,3 +909,61 @@ cifs_UnixTimeToNT(struct timespec t) | |||
909 | /* Convert to 100ns intervals and then add the NTFS time offset. */ | 909 | /* Convert to 100ns intervals and then add the NTFS time offset. */ |
910 | return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; | 910 | return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; |
911 | } | 911 | } |
912 | |||
913 | static int total_days_of_prev_months[] = | ||
914 | {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; | ||
915 | |||
916 | |||
917 | __le64 cnvrtDosCifsTm(__u16 date, __u16 time) | ||
918 | { | ||
919 | return cpu_to_le64(cifs_UnixTimeToNT(cnvrtDosUnixTm(date, time))); | ||
920 | } | ||
921 | |||
922 | struct timespec cnvrtDosUnixTm(__u16 date, __u16 time) | ||
923 | { | ||
924 | struct timespec ts; | ||
925 | int sec, min, days, month, year; | ||
926 | SMB_TIME * st = (SMB_TIME *)&time; | ||
927 | SMB_DATE * sd = (SMB_DATE *)&date; | ||
928 | |||
929 | cFYI(1,("date %d time %d",date, time)); | ||
930 | |||
931 | sec = 2 * st->TwoSeconds; | ||
932 | min = st->Minutes; | ||
933 | if((sec > 59) || (min > 59)) | ||
934 | cERROR(1,("illegal time min %d sec %d", min, sec)); | ||
935 | sec += (min * 60); | ||
936 | sec += 60 * 60 * st->Hours; | ||
937 | if(st->Hours > 24) | ||
938 | cERROR(1,("illegal hours %d",st->Hours)); | ||
939 | days = sd->Day; | ||
940 | month = sd->Month; | ||
941 | if((days > 31) || (month > 12)) | ||
942 | cERROR(1,("illegal date, month %d day: %d", month, days)); | ||
943 | month -= 1; | ||
944 | days += total_days_of_prev_months[month]; | ||
945 | days += 3652; /* account for difference in days between 1980 and 1970 */ | ||
946 | year = sd->Year; | ||
947 | days += year * 365; | ||
948 | days += (year/4); /* leap year */ | ||
949 | /* generalized leap year calculation is more complex, ie no leap year | ||
950 | for years/100 except for years/400, but since the maximum number for DOS | ||
951 | year is 2**7, the last year is 1980+127, which means we need only | ||
952 | consider 2 special case years, ie the years 2000 and 2100, and only | ||
953 | adjust for the lack of leap year for the year 2100, as 2000 was a | ||
954 | leap year (divisable by 400) */ | ||
955 | if(year >= 120) /* the year 2100 */ | ||
956 | days = days - 1; /* do not count leap year for the year 2100 */ | ||
957 | |||
958 | /* adjust for leap year where we are still before leap day */ | ||
959 | if(year != 120) | ||
960 | days -= ((year & 0x03) == 0) && (month < 2 ? 1 : 0); | ||
961 | sec += 24 * 60 * 60 * days; | ||
962 | |||
963 | ts.tv_sec = sec; | ||
964 | |||
965 | /* cFYI(1,("sec after cnvrt dos to unix time %d",sec)); */ | ||
966 | |||
967 | ts.tv_nsec = 0; | ||
968 | return ts; | ||
969 | } | ||