From patchwork Mon Sep 8 07:00:36 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Steve French X-Patchwork-Id: 4860091 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 58F5BC0338 for ; Mon, 8 Sep 2014 07:01:01 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 2DC38200E9 for ; Mon, 8 Sep 2014 07:01:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id EF344200D4 for ; Mon, 8 Sep 2014 07:00:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752277AbaIHHA6 (ORCPT ); Mon, 8 Sep 2014 03:00:58 -0400 Received: from mail-qa0-f45.google.com ([209.85.216.45]:41329 "EHLO mail-qa0-f45.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751891AbaIHHA5 (ORCPT ); Mon, 8 Sep 2014 03:00:57 -0400 Received: by mail-qa0-f45.google.com with SMTP id v10so1802280qac.4 for ; Mon, 08 Sep 2014 00:00:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:from:date:message-id:subject:to:cc:content-type; bh=FjEFDxD/CtDrVLWUjC2WHiTuxXfFinpYWf9gwKA0AG8=; b=hqAjM3sVj+IYuCq6kjADvMNAQofhAOs96Xn3CXvrPS6mvOG9pIgFAcxRuz1Pi49LNR mZdB3gJnUgUsxRbO4x6mTZJF/gLTYJyspO7VkqM11mugNARkfgDrDk7Pk1k3eQknzA/Q K0JqWDMBKGy5vPcYtQryKNWedTJh7jQCy3uxDOE1ytsloAU0Np5TFmOxRgRyDUbIOCdS cH4xe7D1FhxlJOEyMYgpcCBut+OxatdUqrdw6AbgJMP3OZOff68ZALlCSDjQ2xtwADfZ kpzZXCnQFSk+MMKeYnzbgltfy1FZn2V4HVTeqHCM+AFTLrhb7iHVH7JxF+wGNNgkM7ZZ Fgsw== X-Received: by 10.140.97.247 with SMTP id m110mr11361166qge.80.1410159656718; Mon, 08 Sep 2014 00:00:56 -0700 (PDT) MIME-Version: 1.0 Received: by 10.140.32.116 with HTTP; Mon, 8 Sep 2014 00:00:36 -0700 (PDT) From: Steve French Date: Mon, 8 Sep 2014 02:00:36 -0500 Message-ID: Subject: A pair of negative time problems: cifs.ko and Samba To: "linux-cifs@vger.kernel.org" , samba-technical Cc: linux-fsdevel Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org X-Spam-Status: No, score=-9.3 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=ham 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 There are at least two unrelated problems uncovered by xfstest generic/258 Samba does not actually process set info requests for times prior to 1970 (the set info does not return an error but doesn't update the time) although it will report the correct time if a file is created and set locally on ext4 (eg touch -t 196001010101 testfile) to a time before 1970. This works to Windows over CIFS and SMB3. I opened Samba bug 10802 to track this. In addition there is a bug in the cifs kernel client (and probably the same bug in NTFS on linux) in displaying file times before 1970. The cifs kernel client (and Linux ntfs) assume the input to do_div is unsigned during time conversion. Is there an alternative to do_div in kernel? The following change fixes the problem but would be cleaner if there were a signed/unsigned aware equivalent of do_div fs/ntfs/time.h seems to have the same bug in its equivalent function ie in ntfs2utc() Is there a better function to call? (In user space I thought that div/ldiv/lldiv handled negative numbers but presumably we don't have the equivalents in kernel). diff --git a/fs/cifs/netmisc.c b/fs/cifs/netmisc.c index 6834b9c..3e17e9b 100644 --- a/fs/cifs/netmisc.c +++ b/fs/cifs/netmisc.c @@ -925,11 +925,19 @@ cifs_NTtimeToUnix(__le64 ntutc) /* BB what about the timezone? BB */ /* Subtract the NTFS time offset, then convert to 1s intervals. */ - u64 t; + s64 t; t = le64_to_cpu(ntutc) - NTFS_TIME_OFFSET; - ts.tv_nsec = do_div(t, 10000000) * 100; - ts.tv_sec = t; + + if (t < 0) { + t = -t; + ts.tv_nsec = -(do_div(t, 10000000) * 100); + ts.tv_sec = -t; + } else { + ts.tv_nsec = do_div(t, 10000000) * 100; + ts.tv_sec = t; + } + return ts; }