From patchwork Sat Sep 13 22:14:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Darrick Wong X-Patchwork-Id: 389000 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 370F61400E6 for ; Sun, 14 Sep 2014 08:14:53 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752402AbaIMWOw (ORCPT ); Sat, 13 Sep 2014 18:14:52 -0400 Received: from aserp1040.oracle.com ([141.146.126.69]:24631 "EHLO aserp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752399AbaIMWOw (ORCPT ); Sat, 13 Sep 2014 18:14:52 -0400 Received: from ucsinet22.oracle.com (ucsinet22.oracle.com [156.151.31.94]) by aserp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id s8DMEmUF009399 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Sat, 13 Sep 2014 22:14:51 GMT Received: from aserz7022.oracle.com (aserz7022.oracle.com [141.146.126.231]) by ucsinet22.oracle.com (8.14.5+Sun/8.14.5) with ESMTP id s8DMEl5F004497 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 13 Sep 2014 22:14:48 GMT Received: from abhmp0001.oracle.com (abhmp0001.oracle.com [141.146.116.7]) by aserz7022.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id s8DMEjhU006572; Sat, 13 Sep 2014 22:14:45 GMT Received: from localhost (/24.21.154.84) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Sat, 13 Sep 2014 15:14:45 -0700 Subject: [PATCH 31/34] fuse2fs: handle 64-bit dates correctly From: "Darrick J. Wong" To: tytso@mit.edu, darrick.wong@oracle.com Cc: linux-ext4@vger.kernel.org Date: Sat, 13 Sep 2014 15:14:43 -0700 Message-ID: <20140913221443.13646.20722.stgit@birch.djwong.org> In-Reply-To: <20140913221112.13646.3873.stgit@birch.djwong.org> References: <20140913221112.13646.3873.stgit@birch.djwong.org> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-Source-IP: ucsinet22.oracle.com [156.151.31.94] Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org Fix fuse2fs' interpretation of 64-bit date quantities to match the kernel. Signed-off-by: Darrick J. Wong --- misc/fuse2fs.c | 31 ++++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe linux-ext4" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/misc/fuse2fs.c b/misc/fuse2fs.c index 7c443b3..cadf93d 100644 --- a/misc/fuse2fs.c +++ b/misc/fuse2fs.c @@ -353,15 +353,24 @@ static int __translate_error(ext2_filsys fs, errcode_t err, ext2_ino_t ino, static inline __u32 ext4_encode_extra_time(const struct timespec *time) { - return (sizeof(time->tv_sec) > 4 ? - (time->tv_sec >> 32) & EXT4_EPOCH_MASK : 0) | - ((time->tv_nsec << EXT4_EPOCH_BITS) & EXT4_NSEC_MASK); + __u32 extra = sizeof(time->tv_sec) > 4 ? + ((time->tv_sec - (__s32)time->tv_sec) >> 32) & + EXT4_EPOCH_MASK : 0; + return extra | (time->tv_nsec << EXT4_EPOCH_BITS); } static inline void ext4_decode_extra_time(struct timespec *time, __u32 extra) { - if (sizeof(time->tv_sec) > 4) - time->tv_sec |= (__u64)((extra) & EXT4_EPOCH_MASK) << 32; + if (sizeof(time->tv_sec) > 4 && (extra & EXT4_EPOCH_MASK)) { + __u64 extra_bits = extra & EXT4_EPOCH_MASK; + /* + * Prior to kernel 3.14?, we had a broken decode function, + * wherein we effectively did this: + * if (extra_bits == 3) + * extra_bits = 0; + */ + time->tv_sec += extra_bits << 32; + } time->tv_nsec = ((extra) & EXT4_NSEC_MASK) >> EXT4_EPOCH_BITS; } @@ -387,7 +396,7 @@ do { \ (timespec)->tv_sec = (signed)((raw_inode)->xtime); \ if (EXT4_FITS_IN_INODE(raw_inode, xtime ## _extra)) \ ext4_decode_extra_time((timespec), \ - raw_inode->xtime ## _extra); \ + (raw_inode)->xtime ## _extra); \ else \ (timespec)->tv_nsec = 0; \ } while (0) @@ -749,6 +758,7 @@ static int stat_inode(ext2_filsys fs, ext2_ino_t ino, struct stat *statbuf) dev_t fakedev = 0; errcode_t err; int ret = 0; + struct timespec tv; memset(&inode, 0, sizeof(inode)); err = ext2fs_read_inode_full(fs, ino, (struct ext2_inode *)&inode, @@ -766,9 +776,12 @@ static int stat_inode(ext2_filsys fs, ext2_ino_t ino, struct stat *statbuf) statbuf->st_size = EXT2_I_SIZE(&inode); statbuf->st_blksize = fs->blocksize; statbuf->st_blocks = blocks_from_inode(fs, &inode); - statbuf->st_atime = inode.i_atime; - statbuf->st_mtime = inode.i_mtime; - statbuf->st_ctime = inode.i_ctime; + EXT4_INODE_GET_XTIME(i_atime, &tv, &inode); + statbuf->st_atime = tv.tv_sec; + EXT4_INODE_GET_XTIME(i_mtime, &tv, &inode); + statbuf->st_mtime = tv.tv_sec; + EXT4_INODE_GET_XTIME(i_ctime, &tv, &inode); + statbuf->st_ctime = tv.tv_sec; if (LINUX_S_ISCHR(inode.i_mode) || LINUX_S_ISBLK(inode.i_mode)) { if (inode.i_block[0])