From patchwork Sun Oct 21 00:44:42 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jeff Layton X-Patchwork-Id: 1622221 Return-Path: X-Original-To: patchwork-cifs-client@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork1.kernel.org (Postfix) with ESMTP id D87FE40ADA for ; Sun, 21 Oct 2012 00:44:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752603Ab2JUAov (ORCPT ); Sat, 20 Oct 2012 20:44:51 -0400 Received: from mail-gg0-f174.google.com ([209.85.161.174]:34897 "EHLO mail-gg0-f174.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752266Ab2JUAou (ORCPT ); Sat, 20 Oct 2012 20:44:50 -0400 Received: by mail-gg0-f174.google.com with SMTP id k5so300821ggd.19 for ; Sat, 20 Oct 2012 17:44:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer :x-gm-message-state; bh=cEq+K3Yyt93Kn5Z+HdC73JZXwHh1pF0M/JnUpAxMsFY=; b=nSoHf1sfDyButhoDBKKnTiYBQTLgqIRPrg0GUP1hZNoPqOQ6Vy11mhUFb0KcQ2LCN2 ltAu442dwithgHL0fNlkE2u0YZYqdfhuygtCBxNVfKPxyZGEzX+Cw+QUkvg5I+DDp0zT Pif/vT0hZ9cX/h/taz97AmqwbFN6tilVHLmMXK9JEGrRZjAwR2U9ds4hd1rv3ttnXnXK EADAczUpVLUEAG1gw2t620F+be+idPiNSFdk5/vVpuHvLYMU9U/zAaE0F4fvAKsJ0DoN OGyj8m0wEv40VA+HlNxxVFhAqjAG+bLeaAu7ZfqzGq7XOI62f/LYRMocPJdO0lp78Pev IoMw== Received: by 10.236.142.48 with SMTP id h36mr5002156yhj.110.1350780289475; Sat, 20 Oct 2012 17:44:49 -0700 (PDT) Received: from salusa.poochiereds.net (cpe-107-015-110-129.nc.res.rr.com. [107.15.110.129]) by mx.google.com with ESMTPS id o5sm4803301anm.10.2012.10.20.17.44.47 (version=SSLv3 cipher=OTHER); Sat, 20 Oct 2012 17:44:48 -0700 (PDT) From: Jeff Layton To: smfrench@gmail.com Cc: linux-cifs@vger.kernel.org, vit.zahradka@tiscali.cz, linux-fsdevel@vger.kernel.org Subject: [PATCH] cifs: don't call cifs_lookup from atomic open with a hashed negative dentry Date: Sat, 20 Oct 2012 20:44:42 -0400 Message-Id: <1350780282-10385-1-git-send-email-jlayton@redhat.com> X-Mailer: git-send-email 1.7.11.7 X-Gm-Message-State: ALoCoQm6y5CNyzDIO4mRZW98L3GMrbqilPsSpqQTaSg8Go7zM90JbRDeZNqkbmF/poPCwrxhU71z Sender: linux-cifs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-cifs@vger.kernel.org The following oops was reported by Vit Zahradka. The BUG is this in __d_rehash(): BUG_ON(!d_unhashed(entry)); :kernel BUG at fs/dcache.c:2138! :invalid opcode: 0000 [#1] SMP :Modules linked in: fuse ebtable_nat ebtables ipt_MASQUERADE iptable_nat nf_nat des_generic xt_CHECKSUM iptable_mangle md4 bridge stp llc nls_utf8 cifs dns_resolver fscache lockd sunrpc rfcomm bnep be2iscsi iscsi_boot_sysfs bnx2i cnic uio cxgb4i cxgb4 cxgb3i cxgb3 mdio libcxgbi ib_iser rdma_cm ib_addr iw_cm ib_cm ib_sa ib_mad ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi ip6t_REJECT nf_conntrack_ipv6 nf_defrag_ipv6 ip6table_filter ip6_tables nf_conntrack_ipv4 nf_defrag_ipv4 xt_state nf_conntrack snd_hda_codec_conexant btusb bluetooth snd_hda_intel snd_hda_codec snd_hwdep snd_seq snd_seq_device snd_pcm thinkpad_acpi snd_page_alloc arc4 snd_timer iwldvm mac80211 iwlwifi cfg80211 uvcvideo videobuf2_vmalloc videobuf2_memops videobuf2_core videodev snd media rfkill soundcore i2c_i801 mei r592 memstick iTCO_wdt iTCO_vendor_support lpc_ich tg3 coretemp microcode ppdev parport_pc parport vhost_net tun macvtap macvlan kvm_intel kvm uinput binfmt_misc firewire_oh :ci firewire_core crc_itu_t sdhci_pci sdhci mmc_core yenta_socket wmi video radeon i2c_algo_bit drm_kms_helper ttm drm i2c_core :Pid: 2219, comm: eclipse Not tainted 3.6.1-1.fc17.i686 #1 LENOVO 27326FG/27326FG :EIP: 0060:[] EFLAGS: 00010282 CPU: 1 :EIP is at __d_rehash+0x57/0x60 :EAX: ee641c80 EBX: 0000096a ECX: f7338208 EDX: f7338208 :ESI: fffffffe EDI: f6339f60 EBP: f0481d84 ESP: f0481d80 : DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068 :CR0: 8005003b CR2: 06567f84 CR3: 30710000 CR4: 000027d0 :DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000 :DR6: ffff0ff0 DR7: 00000400 :Process eclipse (pid: 2219, ti=f0480000 task=f0490c90 task.ti=f0480000) :Stack: : 0000096a f0481d90 c05575b2 ee641c80 f0481d9c c05575da 00000000 f0481dd8 : f9c01e32 f0734000 00004213 00000000 f0734000 f0481df4 f11ce600 00004213 : f6b07c60 00000000 00000000 f0481ef8 ee641c80 ef1781e0 f0481e20 f9c01f52 :Call Trace: : [] _d_rehash+0x32/0x40 : [] d_rehash+0x1a/0x30 : [] cifs_lookup+0x212/0x300 [cifs] : [] cifs_atomic_open+0x32/0x200 [cifs] : [] ? d_lookup+0x2f/0x50 : [] do_last+0x42c/0xbd0 : [] ? link_path_walk+0x1dc/0x750 : [] path_openat+0x9d/0x3b0 : [] ? wake_up_state+0xf/0x20 : [] ? wake_futex+0x32/0x50 : [] ? __dequeue_entity+0x25/0x40 : [] do_filp_open+0x31/0x80 : [] ? alloc_fd+0x3c/0xe0 : [] ? getname_flags+0x40/0xd0 : [] do_sys_open+0xe5/0x1c0 : [] sys_openat+0x30/0x40 : [] sysenter_do_call+0x12/0x28 :Code: 48 08 74 03 89 59 04 f6 c3 01 89 50 0c 75 20 f6 02 01 74 19 83 cb 01 89 1a 0f ba 32 00 5b 5d c3 f3 90 8b 0a 80 e1 01 75 f7 eb b9 <0f> 0b 0f 0b 0f 0b 8d 76 00 55 89 e5 53 66 66 66 66 90 8b 0d fc :EIP: [] __d_rehash+0x57/0x60 SS:ESP 0068:f0481d80 I think what happened is something like the following: openat() was called on the file without O_CREAT. A negative dentry was already in the cache, and was successfully revalidated. At that point a hashed, negative dentry was passed to cifs_atomic_open. Since O_CREAT wasn't set, it punted it over to cifs_lookup which did a lookup and then tried to rehash the result and tripped over the bug. Fix this by simply returning -ENOENT in this case instead of calling cifs_lookup. For the longer term, I think cifs_atomic_open could use some cleanup. There is probably no reason to limit atomic opens to the O_CREAT case. Cc: # 3.6.x Reported-and-Tested-by: Vit Zahradka Signed-off-by: Jeff Layton --- fs/cifs/dir.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fs/cifs/dir.c b/fs/cifs/dir.c index 7c0a812..5da95d3 100644 --- a/fs/cifs/dir.c +++ b/fs/cifs/dir.c @@ -398,7 +398,12 @@ cifs_atomic_open(struct inode *inode, struct dentry *direntry, * in network traffic in the other paths. */ if (!(oflags & O_CREAT)) { - struct dentry *res = cifs_lookup(inode, direntry, 0); + struct dentry *res; + + if (!direntry->d_inode) + return -ENOENT; + + res = cifs_lookup(inode, direntry, 0); if (IS_ERR(res)) return PTR_ERR(res);