Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp7293477yba; Thu, 2 May 2019 07:33:07 -0700 (PDT) X-Google-Smtp-Source: APXvYqwk2FBkMqSg8wZlVe8ce4x5D1veWwVhRfTNTyEWNTrxGVUvvOLoS8ZPzfFnwmKA79T3f+Sg X-Received: by 2002:a17:902:9693:: with SMTP id n19mr4117902plp.92.1556807586978; Thu, 02 May 2019 07:33:06 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1556807586; cv=none; d=google.com; s=arc-20160816; b=UFx4EXiFW5mjsKEsvL17/jxAymimflmHZMUfcvVBmqB6MJswC7P967krhm3/jdxxvK ZFz3qZN1wpknhpvrzWGB0HQ56AAaS1SIQPD88YDKIk+GeKFb/j7E+DoTG+GM3FuYAE8P b56SHxRhAAqTmu5QUqNaymgnRNHXIXNmRoLR+HCxWC5RhnIC60e0nqFpjYrTTz4qXKwt qw5XuJ4I9ZI9E5kIa4TDccFHuGSlsVpsupWHW6appbA2iz2NnFSooGhkQn+GcdPxDozD lpt8WYCCRSzfJtLw5wiLyBF3Xalv5K9YFL9Jm40Em3FD6iMjLNYSqss1v4a0G7dzkEEu W7Ww== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:user-agent:in-reply-to :content-disposition:mime-version:references:mail-followup-to :reply-to:message-id:subject:cc:to:from:date; bh=0Pbsu5Igkt0jKJmov15/U9FHwkVgIjOumdbzBzw+gKM=; b=EJZL8IB2EhI4SCwM5USt5CmUwm2ywyHsJcew9khVROM+TOimU8cY2J0yQGgtOg2/8x Te76nYPffjGw6ZZcxZq+a53nAV3Nb7KfWqk+d8ZEwNdLf5Gs0dtgfWqxzjsy/9uLCG8E 0JPDCXEHdhgYyyE00rdGKQublRBMaty2cSNrgCSf0H3BabY88OtewwMBxcu3jb93LLgQ rPj/4EGL3RtpsvDpYQZRkttFHZKvDZeIR2CLkHjJH7kAsRGCG0XqXCRmmjHhFQl9Rhqg gXCBUUHoYXEFoEQh3sKNWISjPj6oTcU1qgcfel5x/08KKeNVqVJA8Y83sf04l1CYCwdy 0oIg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 31si2542720pli.242.2019.05.02.07.32.51; Thu, 02 May 2019 07:33:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726435AbfEBOb0 (ORCPT + 99 others); Thu, 2 May 2019 10:31:26 -0400 Received: from mx2.suse.de ([195.135.220.15]:54950 "EHLO mx1.suse.de" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726203AbfEBOb0 (ORCPT ); Thu, 2 May 2019 10:31:26 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 0085DAE47; Thu, 2 May 2019 14:31:23 +0000 (UTC) Received: by ds.suse.cz (Postfix, from userid 10065) id 9AB56DA871; Thu, 2 May 2019 16:32:24 +0200 (CEST) Date: Thu, 2 May 2019 16:32:22 +0200 From: David Sterba To: Pan Bian Cc: Chris Mason , Josef Bacik , David Sterba , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [V2] btrfs: drop inode reference count on error path Message-ID: <20190502143222.GC20156@twin.jikos.cz> Reply-To: dsterba@suse.cz Mail-Followup-To: dsterba@suse.cz, Pan Bian , Chris Mason , Josef Bacik , David Sterba , linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org References: <1555585576-31045-1-git-send-email-bianpan2016@163.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1555585576-31045-1-git-send-email-bianpan2016@163.com> User-Agent: Mutt/1.5.23.1 (2014-03-12) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, Apr 18, 2019 at 07:06:16PM +0800, Pan Bian wrote: > The reference count of inode is incremented by ihold. It should be > dropped if not used. However, the reference count is not dropped if > error occurs during updating the inode or deleting orphan items. This > patch fixes the bug. > > Signed-off-by: Pan Bian > --- > V2: move ihold just before device_initialize to make code clearer There's nothing like device_initialize, what does this refer to? > --- > fs/btrfs/inode.c | 54 +++++++++++++++++++++++++----------------------------- > 1 file changed, 25 insertions(+), 29 deletions(-) > > diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c > index 82fdda8..d6630df 100644 > --- a/fs/btrfs/inode.c > +++ b/fs/btrfs/inode.c > @@ -6579,7 +6579,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, > struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); > u64 index; > int err; > - int drop_inode = 0; > + int log_mode; > > /* do not allow sys_link's with other subvols of the same device */ > if (root->root_key.objectid != BTRFS_I(inode)->root->root_key.objectid) > @@ -6616,41 +6616,37 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, > err = btrfs_add_nondir(trans, BTRFS_I(dir), dentry, BTRFS_I(inode), > 1, index); > > - if (err) { > - drop_inode = 1; > - } else { > - struct dentry *parent = dentry->d_parent; > - int ret; > + if (err) > + goto err_link; > > - err = btrfs_update_inode(trans, root, inode); > + err = btrfs_update_inode(trans, root, inode); > + if (err) > + goto err_link; > + if (inode->i_nlink == 1) { > + /* > + * If new hard link count is 1, it's a file created > + * with open(2) O_TMPFILE flag. > + */ > + err = btrfs_orphan_del(trans, BTRFS_I(inode)); > if (err) > - goto fail; > - if (inode->i_nlink == 1) { > - /* > - * If new hard link count is 1, it's a file created > - * with open(2) O_TMPFILE flag. > - */ > - err = btrfs_orphan_del(trans, BTRFS_I(inode)); > - if (err) > - goto fail; > - } > - BTRFS_I(inode)->last_link_trans = trans->transid; > - d_instantiate(dentry, inode); > - ret = btrfs_log_new_name(trans, BTRFS_I(inode), NULL, parent, > - true, NULL); > - if (ret == BTRFS_NEED_TRANS_COMMIT) { > - err = btrfs_commit_transaction(trans); > - trans = NULL; > - } > + goto err_link; > + } > + BTRFS_I(inode)->last_link_trans = trans->transid; > + ihold(inode); > + d_instantiate(dentry, inode); So this ihold pairs with d_instantiate, and there's another ihold in the function, before call to btrfs_add_nondir. Isn't this leaking the references? In normal case it's 2x ihold, in error case 1x. 6645 /* There are several dir indexes for this inode, clear the cache. */ 6646 BTRFS_I(inode)->dir_index = 0ULL; 6647 inc_nlink(inode); 6648 inode_inc_iversion(inode); 6649 inode->i_ctime = current_time(inode); 6650 ihold(inode); 6651 set_bit(BTRFS_INODE_COPY_EVERYTHING, &BTRFS_I(inode)->runtime_flags); > + log_mode = btrfs_log_new_name(trans, BTRFS_I(inode), NULL, > + dentry->d_parent, true, NULL); > + if (log_mode == BTRFS_NEED_TRANS_COMMIT) { > + err = btrfs_commit_transaction(trans); > + trans = NULL; > } > > +err_link: > + if (err) > + inode_dec_link_count(inode); > fail: > if (trans) > btrfs_end_transaction(trans); > - if (drop_inode) { > - inode_dec_link_count(inode); > - iput(inode); Ie. this iput does not have any replacement in the new code. > - } > btrfs_btree_balance_dirty(fs_info); > return err; > } > -- > 2.7.4 >