From patchwork Fri Sep 6 15:09:05 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnd Bergmann X-Patchwork-Id: 173248 Delivered-To: patch@linaro.org Received: by 2002:a05:6e02:ce:0:0:0:0 with SMTP id r14csp844747ilq; Fri, 6 Sep 2019 08:09:46 -0700 (PDT) X-Google-Smtp-Source: APXvYqwtSVKz4bFvbkidCFLr6lZuCx0vFCTPA3tJXSicKZwTuNtIdFiOxGfPwOFgIi44Iu5nGcyh X-Received: by 2002:a17:90a:a6e:: with SMTP id o101mr10445749pjo.71.1567782586093; Fri, 06 Sep 2019 08:09:46 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1567782586; cv=none; d=google.com; s=arc-20160816; b=KOf3IPn+plxGNEcWSlnp5SKp8MdRYXtmxDQ5fv0Cl07hXptLnQRC9ctGqzwLStv9vt MBYlZyI3Jwc6yGJPS1qSioV26LqRom7Rz12wi/0ASqxeF26chOBvJdj4trHhouZaAfYC rMIVHlVzJHNjh+S6I7BEZjwu7e2Vc4P3k7KdJLekvWZLofzgbUO7I1mKcl09lpDs73ie UY6374wwHZ3ylI50EyU2WJ4E0oPGwgYX6NAp8vhaJ4YK2wSzERWXfzs3Krd1nYdgGES+ ybXME9DoNY/JBM2h/NLLHR7pQPjTKiEdNmLZIBg9DdFSxAYoEYJ1L+9UGYnEdTtb2E/K JhIQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=B8VH93+BQ8GzFusRL8q9AmNPE98hGSwarvo29fJp6Yg=; b=Z/ZrkWW4PnVa0Sdx8EwknmilBiXET+IWxVGSvqo6V17aexyShWQBzomVKOAgaTq5tq Kq58QNnRYLcrT3wVEC0ZNF2ugYO7qcFBlMop3LQaKGM7KO9TzscdY7aBg75njQkRshhQ 2eHk1TTkta9YgPI5GAfQGLjQCyNSp61jgjIxyHaFQE9uC30sEc/7k6H7iSgLpUm04rji ZiWziV5MuwQogsa4sd/ODX4i+qGKom4tVmVlEH04D9tW9Zv6XiLVJUR27YJqDqS/HbcZ oGSJM2ycX47ESpMj4M3sY+ooc0n8QT83hvrgJgaxnqbjlXWM9EiyDibXg4/CaZWjUAI2 PX+w== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 66si5969671pfb.238.2019.09.06.08.09.45; Fri, 06 Sep 2019 08:09:46 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2394710AbfIFPJp (ORCPT + 28 others); Fri, 6 Sep 2019 11:09:45 -0400 Received: from mout.kundenserver.de ([212.227.126.135]:48965 "EHLO mout.kundenserver.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726073AbfIFPJo (ORCPT ); Fri, 6 Sep 2019 11:09:44 -0400 Received: from threadripper.lan ([149.172.19.189]) by mrelayeu.kundenserver.de (mreue009 [212.227.15.129]) with ESMTPA (Nemesis) id 1MIxBa-1hqFBB1WFm-00KR0F; Fri, 06 Sep 2019 17:09:31 +0200 From: Arnd Bergmann To: Valdis Kletnieks , Greg Kroah-Hartman Cc: Arnd Bergmann , Valentin Vidic , Colin Ian King , devel@driverdev.osuosl.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] exfat: stop using 32-bit time_t Date: Fri, 6 Sep 2019 17:09:05 +0200 Message-Id: <20190906150917.1025250-2-arnd@arndb.de> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20190906150917.1025250-1-arnd@arndb.de> References: <20190906150917.1025250-1-arnd@arndb.de> MIME-Version: 1.0 X-Provags-ID: V03:K1:UIMrIG7mtL2D3EjfnDs7nzByw34qqSgASrD2j2WILhDOKSfQ0t3 /43vTZJ0IVYmAdA4Y99oPOKLDsm+X6klu6XtGWpemjllvc3IEaAJNRnKsS0AJGFRpVa2EWJ Upblf01PURlRK7I2J/uYVP++Fz5+rdTnsh1hJ+XMw1H2ECnN8kuIHvNULaMcvpyaT0M3Xdv 66tsssxwcBzEBkbwVrDMQ== X-Spam-Flag: NO X-UI-Out-Filterresults: notjunk:1; V03:K0:g0SVBQh1K0k=:D/s+8TRAHcIpv7CTzMytoX +Wr/iT3PpbPL28nNgwctNOMvK+hs5KKI80ErECKnhJuMUXdD1CfC8NIKO3n8K5BRMbsa6B1GG Sd6fkJoZT5QbbeOo6QdcLMpykuK+FgeuSYLXyRYnLAdZ7/RJyi6bZcpJVTh8xDzSccy7Ju/fF ubTqFabPvo7ruIRh/GHedTKX/qMCx15QZQS8n9aPgWmoiexBXujWXqITaiOxcPARnnHuF4Ni9 NJzGE6xMIqEQzmSzxBLgeohPp8rX3vxhK1yafo1/5ZB/AhilHU0L5jY6+Y6cJhob/1zja/I+C xXN31KFpjK9MW4/7VbNRcgNhkpRFYtNGHGE7FB9JbixY2+RyGnbYWe5W3skDEvz34aOk/CgG9 UYXtxsDUtEplsTkR+yjoCR9RMYlEwXqzZmlQ2IldwlagY/UnQdlBKE8S4WPHzbL71ZFrsRbKU aA1xuzXLyjQP6EsDS1k/ABLmO/1Ggt6OBqVLykvEgCvGrajtWLf95A809MUBZ40iQSDTZb4Ph 3tptzTZPci+mpqgvQ500/quazMMb1ywN/LOHxL/psK5MGjCE/5ZybFpitznBEYfosVLobKA2/ 8fHO+4WAmPRcRpNfZ1j9PPLgupszcqatHHq/5FyuGMZ/jmwKCZgl4oG2Gn+HUbiYpRK0EQFGP Y6cn2xTSoxNzRhkTa7icU69fXcTeahDe6g/dwGBH9oRnF8SNetZXwrVQaTYLUyEje+oitx1DR /SR4KUoAVAdm+qyfTO87a1P29bARdqw2wCTrR3UzU8XWU/qTWWQoxbvPYKhXg9VZfY54tK6X6 jgzijJVWG+KPSyhrGZDiyc27vD/1FPB19tcOF1V1hDBF9ccFQU= Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org time_t suffers from overflow problems and should not be used. In exfat, it is currently used in two open-coded time64_to_tm() implementations. Changes those to use the existing function instead. Signed-off-by: Arnd Bergmann --- drivers/staging/exfat/exfat_super.c | 164 +++++++--------------------- 1 file changed, 38 insertions(+), 126 deletions(-) -- 2.20.0 diff --git a/drivers/staging/exfat/exfat_super.c b/drivers/staging/exfat/exfat_super.c index 37e78620723f..7fd56654498f 100644 --- a/drivers/staging/exfat/exfat_super.c +++ b/drivers/staging/exfat/exfat_super.c @@ -55,129 +55,65 @@ static int exfat_write_inode(struct inode *inode, static void exfat_write_super(struct super_block *sb); #define UNIX_SECS_1980 315532800L - -#if BITS_PER_LONG == 64 #define UNIX_SECS_2108 4354819200L -#endif - -/* days between 1.1.70 and 1.1.80 (2 leap days) */ -#define DAYS_DELTA_DECADE (365 * 10 + 2) -/* 120 (2100 - 1980) isn't leap year */ -#define NO_LEAP_YEAR_2100 (120) -#define IS_LEAP_YEAR(y) (!((y) & 0x3) && (y) != NO_LEAP_YEAR_2100) - -#define SECS_PER_MIN (60) -#define SECS_PER_HOUR (60 * SECS_PER_MIN) -#define SECS_PER_DAY (24 * SECS_PER_HOUR) - -#define MAKE_LEAP_YEAR(leap_year, year) \ - do { \ - if (unlikely(year > NO_LEAP_YEAR_2100)) \ - leap_year = ((year + 3) / 4) - 1; \ - else \ - leap_year = ((year + 3) / 4); \ - } while (0) - -/* Linear day numbers of the respective 1sts in non-leap years. */ -static time_t accum_days_in_year[] = { - /* Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ - 0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 0, 0, 0, -}; /* Convert a FAT time/date pair to a UNIX date (seconds since 1 1 70). */ static void exfat_time_fat2unix(struct exfat_sb_info *sbi, struct timespec64 *ts, struct date_time_t *tp) { - time_t year = tp->Year; - time_t ld; - - MAKE_LEAP_YEAR(ld, year); - - if (IS_LEAP_YEAR(year) && (tp->Month) > 2) - ld++; - - ts->tv_sec = tp->Second + - tp->Minute * SECS_PER_MIN + - tp->Hour * SECS_PER_HOUR + - (ld + accum_days_in_year[(tp->Month)] + - (tp->Day - 1)) * SECS_PER_DAY + - (year * 365 + DAYS_DELTA_DECADE) * SECS_PER_DAY + - sys_tz.tz_minuteswest * SECS_PER_MIN; + ts->tv_sec = mktime64(tp->Year + 1980, tp->Month + 1, tp->Day, + tp->Hour, tp->Minute, tp->Second); - ts->tv_nsec = 0; + ts->tv_nsec = tp->MilliSecond * NSEC_PER_MSEC; } /* Convert linear UNIX date to a FAT time/date pair. */ static void exfat_time_unix2fat(struct exfat_sb_info *sbi, struct timespec64 *ts, struct date_time_t *tp) { - time_t second = ts->tv_sec; - time_t day, month, year; - time_t ld; + time64_t second = ts->tv_sec; + struct tm tm; - second -= sys_tz.tz_minuteswest * SECS_PER_MIN; + time64_to_tm(second, 0, &tm); - /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */ if (second < UNIX_SECS_1980) { - tp->Second = 0; - tp->Minute = 0; - tp->Hour = 0; - tp->Day = 1; - tp->Month = 1; - tp->Year = 0; + tp->MilliSecond = 0; + tp->Second = 0; + tp->Minute = 0; + tp->Hour = 0; + tp->Day = 1; + tp->Month = 1; + tp->Year = 0; return; } -#if (BITS_PER_LONG == 64) + if (second >= UNIX_SECS_2108) { - tp->Second = 59; - tp->Minute = 59; - tp->Hour = 23; - tp->Day = 31; - tp->Month = 12; - tp->Year = 127; + tp->MilliSecond = 999; + tp->Second = 59; + tp->Minute = 59; + tp->Hour = 23; + tp->Day = 31; + tp->Month = 12; + tp->Year = 127; return; } -#endif - day = second / SECS_PER_DAY - DAYS_DELTA_DECADE; - year = day / 365; - MAKE_LEAP_YEAR(ld, year); - if (year * 365 + ld > day) - year--; - - MAKE_LEAP_YEAR(ld, year); - day -= year * 365 + ld; - if (IS_LEAP_YEAR(year) && day == accum_days_in_year[3]) { - month = 2; - } else { - if (IS_LEAP_YEAR(year) && day > accum_days_in_year[3]) - day--; - for (month = 1; month < 12; month++) { - if (accum_days_in_year[month + 1] > day) - break; - } - } - day -= accum_days_in_year[month]; - - tp->Second = second % SECS_PER_MIN; - tp->Minute = (second / SECS_PER_MIN) % 60; - tp->Hour = (second / SECS_PER_HOUR) % 24; - tp->Day = day + 1; - tp->Month = month; - tp->Year = year; + tp->MilliSecond = ts->tv_nsec / NSEC_PER_MSEC; + tp->Second = tm.tm_sec; + tp->Minute = tm.tm_min; + tp->Hour = tm.tm_hour; + tp->Day = tm.tm_mday; + tp->Month = tm.tm_mon + 1; + tp->Year = tm.tm_year + 1900 - 1980; } struct timestamp_t *tm_current(struct timestamp_t *tp) { - struct timespec64 ts; - time_t second, day, leap_day, month, year; - - ktime_get_real_ts64(&ts); + time64_t second = ktime_get_real_seconds(); + struct tm tm; - second = ts.tv_sec; - second -= sys_tz.tz_minuteswest * SECS_PER_MIN; + time64_to_tm(second, 0, &tm); - /* Jan 1 GMT 00:00:00 1980. But what about another time zone? */ if (second < UNIX_SECS_1980) { tp->sec = 0; tp->min = 0; @@ -187,7 +123,7 @@ struct timestamp_t *tm_current(struct timestamp_t *tp) tp->year = 0; return tp; } -#if BITS_PER_LONG == 64 + if (second >= UNIX_SECS_2108) { tp->sec = 59; tp->min = 59; @@ -197,37 +133,13 @@ struct timestamp_t *tm_current(struct timestamp_t *tp) tp->year = 127; return tp; } -#endif - - day = second / SECS_PER_DAY - DAYS_DELTA_DECADE; - year = day / 365; - - MAKE_LEAP_YEAR(leap_day, year); - if (year * 365 + leap_day > day) - year--; - MAKE_LEAP_YEAR(leap_day, year); - - day -= year * 365 + leap_day; - - if (IS_LEAP_YEAR(year) && day == accum_days_in_year[3]) { - month = 2; - } else { - if (IS_LEAP_YEAR(year) && day > accum_days_in_year[3]) - day--; - for (month = 1; month < 12; month++) { - if (accum_days_in_year[month + 1] > day) - break; - } - } - day -= accum_days_in_year[month]; - - tp->sec = second % SECS_PER_MIN; - tp->min = (second / SECS_PER_MIN) % 60; - tp->hour = (second / SECS_PER_HOUR) % 24; - tp->day = day + 1; - tp->mon = month; - tp->year = year; + tp->sec = tm.tm_sec; + tp->min = tm.tm_min; + tp->hour = tm.tm_hour; + tp->day = tm.tm_mday; + tp->mon = tm.tm_mon + 1; + tp->year = tm.tm_year + 1900 - 1980; return tp; }