Received: by 2002:a25:4158:0:0:0:0:0 with SMTP id o85csp448576yba; Thu, 18 Apr 2019 04:10:57 -0700 (PDT) X-Google-Smtp-Source: APXvYqznShZ9R2jWlvdguuXDTJvrGaUxgvmDzj7jyTchK6iJkrgHVcRZrkz8qHMClcKhTfuXCKcS X-Received: by 2002:a17:902:bb84:: with SMTP id m4mr55064687pls.302.1555585857663; Thu, 18 Apr 2019 04:10:57 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1555585857; cv=none; d=google.com; s=arc-20160816; b=y8PHovpxy23vpZcSYyzwWrGhK3I4JaIYDNSufgYdDv0PToyBlSDLDoDEBa8bZK40Sx HbmMgjrgvC9hVT5RDtkkhMPxbvgfiOzV8hbve1Ej6o/UdHJaPbMzVwBXrcOAbdxgr/hm saDzq2Z9LwlqmtI1Ct31wf0GuiNFfa4x1GCuoEaJ0NhYGPPwvr1hTz0l5rU7Ko98JZPP uZuAqGpegjZpGeaywrhKTmHjdpD4eNek/ctoL1mnwyqAbSJQsX56ssRo2TD+PyBBcObH 5T40DceV0hUK/jp6mk8ktLyYg143gCvxtYpP6nU1zth+Q3N0xemz/T94OFimlPIJRcpp dsAQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:message-id:date:subject:cc:to:from :dkim-signature; bh=+p4hmUoOzGvSUCMj7Ea2jxUQ9gNsUw3Zf6GnGrJzpMo=; b=tWOXZ6TtpqCHbebo9mDCuYNdG9Ayl+6XA0uljt2qBdBZnB5DjxDanJPDx7zV2jWtSD BqDp+chaX9Bzm8u0TmfERPpOWwopEW+LvyHvEJ3FY83fRTwMSFPePW66Dqmie7jP67Dt Ss+1yAv/z3Ne1AtHcSKecTghI1AEP/5qD9NSnrd1IJSd58KEv9cOHZlj/GghyUCyGuU+ i3TgFrH6wjPz/9908cUymzGtPsMzluqEqNU4fZyuvYwfM19YeD/jbQ1rqmrfBvaI7znl zVozAneipw6OjDrFb5nBN/S8jie2ZMmQ83TYNM+TWOpkLbS6GuavKOqly5As0pYVThNN aagA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@163.com header.s=s110527 header.b=H3COmsMF; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=163.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k13si1843814pll.200.2019.04.18.04.10.41; Thu, 18 Apr 2019 04:10:57 -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; dkim=pass header.i=@163.com header.s=s110527 header.b=H3COmsMF; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=163.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388721AbfDRLHG (ORCPT + 99 others); Thu, 18 Apr 2019 07:07:06 -0400 Received: from m50-133.163.com ([123.125.50.133]:48682 "EHLO m50-133.163.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2387519AbfDRLHG (ORCPT ); Thu, 18 Apr 2019 07:07:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=163.com; s=s110527; h=From:Subject:Date:Message-Id; bh=+p4hmUoOzGvSUCMj7E a2jxUQ9gNsUw3Zf6GnGrJzpMo=; b=H3COmsMFfiseARRoMbHogsUI/gipWm+XFi W2Z17n0vQtpVl6ucsVQpU7td22FKYGXaCrE4In0ieqGTQAG6ov+OJo1GI5TztlTq v+9OmFAA8FLlVVuDn+0EQvO9f+w5mP+wsDMzq6diB91NOOJJjG2JJg3s48cFic+f yMrQDZXzc= Received: from bp.localdomain (unknown [218.106.182.174]) by smtp3 (Coremail) with SMTP id DdGowAA3PyMxWrhc30UvAA--.663S3; Thu, 18 Apr 2019 19:06:27 +0800 (CST) From: Pan Bian To: Chris Mason , Josef Bacik , David Sterba Cc: linux-btrfs@vger.kernel.org, linux-kernel@vger.kernel.org, Pan Bian Subject: [V2] btrfs: drop inode reference count on error path Date: Thu, 18 Apr 2019 19:06:16 +0800 Message-Id: <1555585576-31045-1-git-send-email-bianpan2016@163.com> X-Mailer: git-send-email 2.7.4 X-CM-TRANSID: DdGowAA3PyMxWrhc30UvAA--.663S3 X-Coremail-Antispam: 1Uf129KBjvJXoWxZr17uw17KF17Cr48Gr4kWFg_yoW5Xr17pF yfCwn5K395XryDurs2qF4jvr4Fq3Wvgw4UJrs09ws5ta1UAwsaqryYvr10ya43trWkCrWj qr4Ykw4UGFsrCw7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UseOXUUUUU= X-Originating-IP: [218.106.182.174] X-CM-SenderInfo: held01tdqsiiqw6rljoofrz/1tbiQBOaclSIaHS-VAAAsQ Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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); + 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); - } btrfs_btree_balance_dirty(fs_info); return err; } -- 2.7.4