From patchwork Thu Nov 7 23:26:47 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Turner X-Patchwork-Id: 289529 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 1EF2D2C00BD for ; Fri, 8 Nov 2013 10:26:52 +1100 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753834Ab3KGX0u (ORCPT ); Thu, 7 Nov 2013 18:26:50 -0500 Received: from caiajhbdcaib.dreamhost.com ([208.97.132.81]:46397 "EHLO homiemail-a22.g.dreamhost.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753085Ab3KGX0t (ORCPT ); Thu, 7 Nov 2013 18:26:49 -0500 Received: from homiemail-a22.g.dreamhost.com (localhost [127.0.0.1]) by homiemail-a22.g.dreamhost.com (Postfix) with ESMTP id C42711A8071; Thu, 7 Nov 2013 15:26:48 -0800 (PST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=novalis.org; h=message-id:subject :from:to:cc:date:in-reply-to:references:content-type :mime-version:content-transfer-encoding; q=dns; s=novalis.org; b=agwGyzLryz6kta+JwjNJnOkvrp3MBvbC24eJTuKhe/wxB/Cvh4Yg+3SJ/sSFA 2rRrbqdNlDVHDKaYGimfGG5WFGCuoOrACR9PagRbVf0lGQ2TRlyGtf00KArT9lw+ SUpTEQywn+EGTFjNgtFCheewksLHKz23ax1pYj+dTreVT4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=novalis.org; h=message-id :subject:from:to:cc:date:in-reply-to:references:content-type :mime-version:content-transfer-encoding; s=novalis.org; bh=eNRJr mc4nMFINSXSBK9vF9Yje34=; b=BUCGinKzqs9QMGZAL9/N0CZU2u3+/zTclrqVl gReqv7/cM1N/zOa+Tu7jgbmhIS6P0PYxbXvMlYU3I4oM/CGJS1NnuCegNJYeSY8N 6CZ1BueViW+KYo9hScf5XYjih+zG93cs0XW1nw5e9D5gajw7j/PUnUkvwZCETSbj g1Y3eQ= Received: from [10.0.1.4] (ool-4579628d.dyn.optonline.net [69.121.98.141]) (using SSLv3 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: novalis@novalis.org) by homiemail-a22.g.dreamhost.com (Postfix) with ESMTPSA id 2E5481A8069; Thu, 7 Nov 2013 15:26:48 -0800 (PST) Message-ID: <1383866807.23882.41.camel@chiang> Subject: [PATCH v3] ext4: Fix reading of extended tv_sec (bug 23732) From: David Turner To: Jan Kara Cc: linux-ext4@vger.kernel.org, linux-kernel@vger.kernel.org, Andreas Dilger , Theodore Ts'o Date: Thu, 07 Nov 2013 18:26:47 -0500 In-Reply-To: <20131107231445.GG2054@quack.suse.cz> References: <1383808590.23882.13.camel@chiang> <20131107160341.GA3850@quack.suse.cz> <1383864864.23882.33.camel@chiang> <20131107231445.GG2054@quack.suse.cz> X-Mailer: Evolution 3.6.4-0ubuntu1 Mime-Version: 1.0 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org On Fri, 2013-11-08 at 00:14 +0100, Jan Kara wrote: > Still unnecessary type cast here (but that's a cosmetic issue). ... > Otherwise the patch looks good. You can add: > Reviewed-by: Jan Kara Thanks. A version with this correction and the reviewed-by follows. --- In ext4, the bottom two bits of {a,c,m}time_extra are used to extend the {a,c,m}time fields, deferring the year 2038 problem to the year 2446. The representation (which this patch does not alter) is a bit hackish, in that the most-significant bit is no longer (alone) sufficient to indicate the sign. That's because we're representing an asymmetric range, with seven times as many positive values as negative. When decoding these extended fields, for times whose bottom 32 bits would represent a negative number, sign extension causes the 64-bit extended timestamp to be negative as well, which is not what's intended. This patch corrects that issue, so that the only negative {a,c,m}times are those between 1901 and 1970 (as per 32-bit signed timestamps). Signed-off-by: David Turner Reported-by: Mark Harris Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=23732 Reviewed-by: Jan Kara --- fs/ext4/ext4.h | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index af815ea..3c2d0b3 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -722,10 +722,15 @@ static inline __le32 ext4_encode_extra_time(struct timespec *time) static inline void ext4_decode_extra_time(struct timespec *time, __le32 extra) { - if (sizeof(time->tv_sec) > 4) - time->tv_sec |= (__u64)(le32_to_cpu(extra) & EXT4_EPOCH_MASK) - << 32; - time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; + if (sizeof(time->tv_sec) > 4) { + u64 extra_bits = le32_to_cpu(extra) & EXT4_EPOCH_MASK; + if (time->tv_sec > 0 || extra_bits != EXT4_EPOCH_MASK) { + time->tv_sec &= 0xFFFFFFFF; + time->tv_sec |= extra_bits << 32; + } + } + time->tv_nsec = (le32_to_cpu(extra) & EXT4_NSEC_MASK) >> + EXT4_EPOCH_BITS; } #define EXT4_INODE_SET_XTIME(xtime, inode, raw_inode) \