From patchwork Tue May 20 22:31:10 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andreas Dilger X-Patchwork-Id: 350897 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id A98F714007C for ; Wed, 21 May 2014 08:31:06 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751011AbaETWbF (ORCPT ); Tue, 20 May 2014 18:31:05 -0400 Received: from mga11.intel.com ([192.55.52.93]:44128 "EHLO mga11.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750987AbaETWbE (ORCPT ); Tue, 20 May 2014 18:31:04 -0400 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga102.fm.intel.com with ESMTP; 20 May 2014 15:31:04 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.98,876,1392192000"; d="scan'208";a="542398180" Received: from kmnelson-mobl1.amr.corp.intel.com (HELO adilger-mac01.local.com) ([10.252.131.161]) by fmsmga002.fm.intel.com with ESMTP; 20 May 2014 15:31:03 -0700 From: Andreas Dilger To: tytso@mit.edu Cc: linux-ext4@vger.kernel.org, Andreas Dilger Subject: [PATCH] debugfs: fix string_to_time for MacOS strptime() Date: Tue, 20 May 2014 16:31:10 -0600 Message-Id: <1400625070-61813-1-git-send-email-adilger@dilger.ca> X-Mailer: git-send-email 1.9.3 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org The strptime() function does not update fields in struct tm that are not specified in the input format. The glibc implementation sets the tm_yday field (%j) when any of the year (%Y), month (%m), or day (%d) fields are changed, but the MacOS strptime() does not set tm_yday in this case. This caused string_to_time() to calculate the wrong Unix epoch on MacOS. If tm_yday is unset, compute it in string_to_time(). Signed-off-by: Andreas Dilger --- debugfs/util.c | 14 ++++++++++++++ tests/f_dup_resize/script | 2 +- tests/f_uninit_last_uninit/script | 2 +- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/debugfs/util.c b/debugfs/util.c index 9ddfe0b..20c6c61 100644 --- a/debugfs/util.c +++ b/debugfs/util.c @@ -245,6 +245,20 @@ time_t string_to_time(const char *arg) ts.tm_mday = 0; #endif ts.tm_isdst = -1; + /* strptime() may only update the specified fields, which does not + * necessarily include ts.tm_yday (%j). Calculate this if unset: + * + * Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec + * 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 + * + * Start with 31 days per month. Even months have only 30 days, but + * reverse in August, subtract one day for those months. February has + * only 28 days, not 30, subtract two days. Add day of month, minus + * one, since day is not finished yet. Leap years handled afterward. */ + if (ts.tm_yday == 0) + ts.tm_yday = (ts.tm_mon * 31) - + ((ts.tm_mon - (ts.tm_mon > 7)) / 2) - + 2 * (ts.tm_mon > 1) + ts.tm_mday - 1; ret = ts.tm_sec + ts.tm_min*60 + ts.tm_hour*3600 + ts.tm_yday*86400 + (ts.tm_year-70)*31536000 + ((ts.tm_year-69)/4)*86400 - ((ts.tm_year-1)/100)*86400 + ((ts.tm_year+299)/400)*86400; diff --git a/tests/f_dup_resize/script b/tests/f_dup_resize/script index 659c92e..19fa120 100644 --- a/tests/f_dup_resize/script +++ b/tests/f_dup_resize/script @@ -12,7 +12,7 @@ freeb 4 4 freeb 8195 4 write $TEST_DATA debugfs set_current_time 20050411000000 -set_inode_field debugfs mtime 2005041100000000 +set_inode_field debugfs mtime 20050411000000 q EOF diff --git a/tests/f_uninit_last_uninit/script b/tests/f_uninit_last_uninit/script index 2fe4f3a..376c978 100644 --- a/tests/f_uninit_last_uninit/script +++ b/tests/f_uninit_last_uninit/script @@ -5,7 +5,7 @@ SKIP_GUNZIP="true" touch $TMPFILE $MKE2FS -N 32 -F -o Linux -O uninit_bg -b 1024 $TMPFILE 10000 > /dev/null 2>&1 $DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1 -set_current_time 200704102100 +set_current_time 20070410210000 set_super_value lastcheck 0 set_super_value hash_seed null set_super_value mkfs_time 0