Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932683AbbLGStK (ORCPT ); Mon, 7 Dec 2015 13:49:10 -0500 Received: from mail-ig0-f175.google.com ([209.85.213.175]:36233 "EHLO mail-ig0-f175.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932228AbbLGStG (ORCPT ); Mon, 7 Dec 2015 13:49:06 -0500 MIME-Version: 1.0 In-Reply-To: <1449511503-7543-1-git-send-email-suzuki.poulose@arm.com> References: <1449511503-7543-1-git-send-email-suzuki.poulose@arm.com> Date: Mon, 7 Dec 2015 10:49:05 -0800 X-Google-Sender-Auth: XL-Nx801mSO3_VPo6xBYhU68Tbo Message-ID: Subject: Re: [PATCH] blkdev: Fix blkdev_open to release the bdev on error From: Linus Torvalds To: "Suzuki K. Poulose" Cc: Al Viro , Linux Kernel Mailing List , linux-fsdevel , Marc Zyngier , Tejun Heo , stable Content-Type: text/plain; charset=UTF-8 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 1562 Lines: 42 On Mon, Dec 7, 2015 at 10:05 AM, Suzuki K. Poulose wrote: > blkdev_open() doesn't release the bdev, it attached to a given > inode, if blkdev_get() fails (e.g, due to absence of a device). > This can cause kernel crashes when the original filesystem > tries to flush the data during evict_inode. Ugh. This code is a mess. Al, can you please comment? So what happens is that when "blkdev_get()" fails, it will do a bdput() on the bdev. But blkdev_open() hasn't done a bdget(). It's done a bd_acquire(). Which will do the whole "add inodes to bd_inodes". And yes, bd_forget() will undo that. HOWEVER. bd_forget() will undo that unconditionally, but bd_acquire() has *not* unconditionally done that bd_inodes list operation. It might already have been there. So as far as I can tell, the patch here undoes things potentially too much. Shouldn't the last bdput() already end up doing a bd_forget()? We'd have bdput -> iput -> iput_final -> evict -> bd_forget. but the fact that Suzuki shows an oops clearly shows that something is badly wrong. IOW, the path looks simple and apparently fixes an oops, but I'd like much more of an explanation for what happens, because it all feels wrong to me. Why doesn't the bdput() end up undoing the bd_acquire() properly? Linus -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/