From patchwork Fri Feb 12 09:52:48 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Deepa Dinamani X-Patchwork-Id: 8289951 Return-Path: X-Original-To: patchwork-linux-fsdevel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 4FCF6BEEE5 for ; Fri, 12 Feb 2016 09:57:26 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 24189203AC for ; Fri, 12 Feb 2016 09:57:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id CAA06201F2 for ; Fri, 12 Feb 2016 09:57:23 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752046AbcBLJzY (ORCPT ); Fri, 12 Feb 2016 04:55:24 -0500 Received: from mail-pf0-f169.google.com ([209.85.192.169]:35413 "EHLO mail-pf0-f169.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751707AbcBLJzN (ORCPT ); Fri, 12 Feb 2016 04:55:13 -0500 Received: by mail-pf0-f169.google.com with SMTP id c10so45917891pfc.2; Fri, 12 Feb 2016 01:55:13 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=pVoSt2K3jRLdUolxOyYI5DsAwZCyn3pwIEx6YMu3Iuc=; b=tjKHVnw7D1lK/hUI1o0L0lhcM3kKsl7tLovM/C+ixV2vDFao33YarsAsWsLi1Lp9KI htE4fFHFfS7kkFpg0ihdzoQdLvzf/AmunGvZqatr1+JIzMdj3GXas3C01e62mcR5dPYS h8wOY9L2asJkn6//sSuIcC7a6Xn5nqLMikTKkwGZdy8NL5DXYoHfdc0dey84KnpKg+Ij +57cinisxZDD+Y5kaVtfxSPl+Zrkx3Id6Sjal1/OyI72On/R6KbwMQ2NbWcqtUbx1HFz 8O9D3j8Cu1DnMmUfTCyuSp8jGkev6mLLE0PqEnr8Aw88nhawgiJVwL53Cdha7CmM+/6p bcyA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=pVoSt2K3jRLdUolxOyYI5DsAwZCyn3pwIEx6YMu3Iuc=; b=R5DlkVSqy3HxKowpo3Q/yZkDAb9QOK9lFrxkGAwqNPgt5r2Avco831KxcHUuECoMpL EH5LxRI7bJGJ2bGN1ePZTKOtm9Ykekb6VSQPOO8M5X19nr4xuZhCJXerXWnWtFjEiIqL TGfpNhaFfCF2OyKR5bApsVKOTGqxB85LybnTnWCPkHqyV72D93YgPZQOsa2lYtRg4peM wBpQdlzJn0Ur4DdIxwAfW7HIvDXodP1fd/7xCBePUIfJSfqCDBSDBqWXT2+BhxVBgWN3 jNHdr1U8JVwsqyGEfESbftDkLou43pLouNgvRBBe/xmisPDRc/WpRaFLxCFrDu9l1xf4 rQqA== X-Gm-Message-State: AG10YOSZAbteowMs5pY91HPAIaUcg2F/UkMtztfi9UglYb2n0oCveb4WYADzffD1a39tCw== X-Received: by 10.98.68.212 with SMTP id m81mr759365pfi.135.1455270913385; Fri, 12 Feb 2016 01:55:13 -0800 (PST) Received: from localhost.localdomain ([106.51.31.162]) by smtp.gmail.com with ESMTPSA id xz6sm18090024pab.42.2016.02.12.01.54.59 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 12 Feb 2016 01:55:12 -0800 (PST) From: Deepa Dinamani To: linux-fsdevel@vger.kernel.org, y2038@lists.linaro.org Cc: Arnd Bergmann , Dave Chinner , "Theodore Ts'o" , linux-kernel@vger.kernel.org Subject: [RFC v2c 3/8] fs: cifs: Change cifs_fattr timestamps data type to timespec64 Date: Fri, 12 Feb 2016 01:52:48 -0800 Message-Id: <1455270773-3249-4-git-send-email-deepa.kernel@gmail.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1455270773-3249-1-git-send-email-deepa.kernel@gmail.com> References: <20160212092153.GA2368@deepa-ubuntu> <1455270773-3249-1-git-send-email-deepa.kernel@gmail.com> Sender: linux-fsdevel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-fsdevel@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP The VFS inode timestamps are not y2038 safe as they use struct timespec. These will be changed to use struct timespec64 instead and that is y2038 safe. But, since the above data type conversion will break the end file systems, use timespec64 and conversion functions here to access inode times. This change is safe because cifs_fattr is accessed in following ways: 1. Assigning to/ from/ compared with struct inode timestamps, which will match vfs_time alias. 2. Assigned from cifs_NTtimeToUnix(). And, this function does not care about the data type sizes of tv_sec and tv_nsec fields. 3. Assigned from current_fs_time(), which will match vfs_time alias. 4. Assigned from cnvrtDosUnixTm(). And, this function does not care about the data type sizes of tv_sec and tv_nsec fields. Signed-off-by: Deepa Dinamani --- fs/cifs/cifsencrypt.c | 4 ++-- fs/cifs/cifsglob.h | 6 +++--- fs/cifs/cifsproto.h | 6 +++--- fs/cifs/cifssmb.c | 6 +++--- fs/cifs/inode.c | 35 ++++++++++++++++++++--------------- fs/cifs/netmisc.c | 11 ++++++----- 6 files changed, 37 insertions(+), 31 deletions(-) diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c index f86e07d..2917d1d 100644 --- a/fs/cifs/cifsencrypt.c +++ b/fs/cifs/cifsencrypt.c @@ -460,7 +460,7 @@ find_timestamp(struct cifs_ses *ses) unsigned char *blobptr; unsigned char *blobend; struct ntlmssp2_name *attrptr; - struct timespec ts; + struct timespec64 ts; if (!ses->auth_key.len || !ses->auth_key.response) return 0; @@ -485,7 +485,7 @@ find_timestamp(struct cifs_ses *ses) blobptr += attrsize; /* advance attr value */ } - ktime_get_real_ts(&ts); + ktime_get_real_ts64(&ts); return cpu_to_le64(cifs_UnixTimeToNT(ts)); } diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index a25b251..7dfb0e2 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -1393,9 +1393,9 @@ struct cifs_fattr { dev_t cf_rdev; unsigned int cf_nlink; unsigned int cf_dtype; - struct timespec cf_atime; - struct timespec cf_mtime; - struct timespec cf_ctime; + struct timespec64 cf_atime; + struct timespec64 cf_mtime; + struct timespec64 cf_ctime; }; static inline void free_dfs_info_param(struct dfs_info3_param *param) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index eed7ff5..2d78814 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -126,9 +126,9 @@ extern enum securityEnum select_sectype(struct TCP_Server_Info *server, enum securityEnum requested); extern int CIFS_SessSetup(const unsigned int xid, struct cifs_ses *ses, const struct nls_table *nls_cp); -extern struct timespec cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); -extern u64 cifs_UnixTimeToNT(struct timespec); -extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, +extern struct timespec64 cifs_NTtimeToUnix(__le64 utc_nanoseconds_since_1601); +extern u64 cifs_UnixTimeToNT(struct timespec64); +extern struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset); extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock); extern int cifs_get_writer(struct cifsInodeInfo *cinode); diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 1a9e43d..db268ff 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -478,8 +478,8 @@ decode_lanman_negprot_rsp(struct TCP_Server_Info *server, NEGOTIATE_RSP *pSMBr) * this requirement. */ int val, seconds, remain, result; - struct timespec ts; - unsigned long utc = get_seconds(); + struct timespec64 ts; + unsigned long utc = ktime_get_real_seconds(); ts = cnvrtDosUnixTm(rsp->SrvTime.Date, rsp->SrvTime.Time, 0); cifs_dbg(FYI, "SrvTime %d sec since 1970 (utc: %d) diff: %d\n", @@ -4000,7 +4000,7 @@ QInfRetry: if (rc) { cifs_dbg(FYI, "Send error in QueryInfo = %d\n", rc); } else if (data) { - struct timespec ts; + struct timespec64 ts; __u32 time = le32_to_cpu(pSMBr->last_write_time); /* decode response */ diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index fa72359..1ead483 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c @@ -92,6 +92,7 @@ static void cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) { struct cifsInodeInfo *cifs_i = CIFS_I(inode); + struct timespec64 mtime; cifs_dbg(FYI, "%s: revalidating inode %llu\n", __func__, cifs_i->uniqueid); @@ -109,8 +110,9 @@ cifs_revalidate_cache(struct inode *inode, struct cifs_fattr *fattr) return; } + mtime = vfs_time_to_timespec64(inode->i_mtime); /* revalidate if mtime or size have changed */ - if (timespec_equal(&inode->i_mtime, &fattr->cf_mtime) && + if (timespec64_equal(&mtime, &fattr->cf_mtime) && cifs_i->server_eof == fattr->cf_eof) { cifs_dbg(FYI, "%s: inode %llu is unchanged\n", __func__, cifs_i->uniqueid); @@ -159,9 +161,9 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr) cifs_revalidate_cache(inode, fattr); spin_lock(&inode->i_lock); - inode->i_atime = fattr->cf_atime; - inode->i_mtime = fattr->cf_mtime; - inode->i_ctime = fattr->cf_ctime; + inode->i_atime = timespec64_to_vfs_time(fattr->cf_atime); + inode->i_mtime = timespec64_to_vfs_time(fattr->cf_mtime); + inode->i_ctime = timespec64_to_vfs_time(fattr->cf_ctime); inode->i_rdev = fattr->cf_rdev; cifs_nlink_fattr_to_inode(inode, fattr); inode->i_uid = fattr->cf_uid; @@ -321,7 +323,7 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb) fattr->cf_uid = cifs_sb->mnt_uid; fattr->cf_gid = cifs_sb->mnt_gid; fattr->cf_atime = fattr->cf_ctime = - fattr->cf_mtime = current_fs_time(sb); + fattr->cf_mtime = vfs_time_to_timespec64(current_fs_time(sb)); fattr->cf_nlink = 2; fattr->cf_flags |= CIFS_FATTR_DFS_REFERRAL; } @@ -597,7 +599,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info, if (info->LastAccessTime) fattr->cf_atime = cifs_NTtimeToUnix(info->LastAccessTime); else - fattr->cf_atime = current_fs_time(sb); + fattr->cf_atime = vfs_time_to_timespec64(current_fs_time(sb)); fattr->cf_ctime = cifs_NTtimeToUnix(info->ChangeTime); fattr->cf_mtime = cifs_NTtimeToUnix(info->LastWriteTime); @@ -1066,15 +1068,15 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid, if (attrs->ia_valid & ATTR_ATIME) { set_time = true; - info_buf.LastAccessTime = - cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_atime)); + info_buf.LastAccessTime = cpu_to_le64( + cifs_UnixTimeToNT(vfs_time_to_timespec64(attrs->ia_atime))); } else info_buf.LastAccessTime = 0; if (attrs->ia_valid & ATTR_MTIME) { set_time = true; - info_buf.LastWriteTime = - cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_mtime)); + info_buf.LastWriteTime = cpu_to_le64( + cifs_UnixTimeToNT(vfs_time_to_timespec64(attrs->ia_mtime))); } else info_buf.LastWriteTime = 0; @@ -1086,8 +1088,8 @@ cifs_set_file_info(struct inode *inode, struct iattr *attrs, unsigned int xid, */ if (set_time && (attrs->ia_valid & ATTR_CTIME)) { cifs_dbg(FYI, "CIFS - CTIME changed\n"); - info_buf.ChangeTime = - cpu_to_le64(cifs_UnixTimeToNT(attrs->ia_ctime)); + info_buf.ChangeTime = cpu_to_le64( + cifs_UnixTimeToNT(vfs_time_to_timespec64(attrs->ia_ctime))); } else info_buf.ChangeTime = 0; @@ -2193,17 +2195,20 @@ cifs_setattr_unix(struct dentry *direntry, struct iattr *attrs) args->gid = INVALID_GID; /* no change */ if (attrs->ia_valid & ATTR_ATIME) - args->atime = cifs_UnixTimeToNT(attrs->ia_atime); + args->atime = cifs_UnixTimeToNT( + vfs_time_to_timespec64(attrs->ia_atime)); else args->atime = NO_CHANGE_64; if (attrs->ia_valid & ATTR_MTIME) - args->mtime = cifs_UnixTimeToNT(attrs->ia_mtime); + args->mtime = cifs_UnixTimeToNT( + vfs_time_to_timespec64(attrs->ia_mtime)); else args->mtime = NO_CHANGE_64; if (attrs->ia_valid & ATTR_CTIME) - args->ctime = cifs_UnixTimeToNT(attrs->ia_ctime); + args->ctime = cifs_UnixTimeToNT( + vfs_time_to_timespec64(attrs->ia_ctime)); else args->ctime = NO_CHANGE_64; diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index abae6dd..bf1b52e 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -918,10 +918,11 @@ smbCalcSize(void *buf) * Convert the NT UTC (based 1601-01-01, in hundred nanosecond units) * into Unix UTC (based 1970-01-01, in seconds). */ -struct timespec +struct timespec64 cifs_NTtimeToUnix(__le64 ntutc) { - struct timespec ts; + struct timespec64 ts; + /* BB what about the timezone? BB */ /* Subtract the NTFS time offset, then convert to 1s intervals. */ @@ -949,7 +950,7 @@ cifs_NTtimeToUnix(__le64 ntutc) /* Convert the Unix UTC into NT UTC. */ u64 -cifs_UnixTimeToNT(struct timespec t) +cifs_UnixTimeToNT(struct timespec64 t) { /* Convert to 100ns intervals and then add the NTFS time offset. */ return (u64) t.tv_sec * 10000000 + t.tv_nsec/100 + NTFS_TIME_OFFSET; @@ -959,9 +960,9 @@ static const int total_days_of_prev_months[] = { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 }; -struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) +struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset) { - struct timespec ts; + struct timespec64 ts; int sec, min, days, month, year; u16 date = le16_to_cpu(le_date); u16 time = le16_to_cpu(le_time);