From patchwork Tue Sep 6 18:22:28 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Milko Krachounov X-Patchwork-Id: 1126852 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p86IMbcN013062 for ; Tue, 6 Sep 2011 18:22:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753892Ab1IFSWe (ORCPT ); Tue, 6 Sep 2011 14:22:34 -0400 Received: from mail-bw0-f46.google.com ([209.85.214.46]:54580 "EHLO mail-bw0-f46.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753729Ab1IFSWd (ORCPT ); Tue, 6 Sep 2011 14:22:33 -0400 Received: by bke11 with SMTP id 11so5669022bke.19 for ; Tue, 06 Sep 2011 11:22:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=from:to:subject:date:user-agent:references:in-reply-to:mime-version :content-type:content-transfer-encoding:message-id; bh=LNU2ccaKHzv0kpZL6lqdMceJ5L24LQ9cnyqjryJqQpQ=; b=QOXLuqnnJm49MQcWjdO6sQW4qo/QXlfVHVZUZKNBqgblr63UUG8OVfgF0SbH5HjZcm Wh2LUnh6ucWriqoJ6RbAu/Nj5cRXy5VVryMrpjBtfTkAzxtSwUtyQLFnjQ/Ve+ntdaiX z5y9lN+ZmvtW989v7gAZkwFQB/PFxp8eG0Z54= Received: by 10.204.150.205 with SMTP id z13mr3120832bkv.302.1315333352570; Tue, 06 Sep 2011 11:22:32 -0700 (PDT) Received: from obelix.localnet ([83.142.23.69]) by mx.google.com with ESMTPS id a3sm1256721bkd.11.2011.09.06.11.22.29 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 06 Sep 2011 11:22:30 -0700 (PDT) From: Milko Krachounov To: linux-btrfs@vger.kernel.org Subject: [PATCH] make btrfs_orphan_cleanup process bad inodes Date: Tue, 6 Sep 2011 21:22:28 +0300 User-Agent: KMail/1.13.7 (Linux/3.1.0-rc4-amd64; KDE/4.6.5; x86_64; ; ) References: In-Reply-To: MIME-Version: 1.0 Message-Id: <201109062122.28357.sombre@gmail.com> Sender: linux-btrfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-btrfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Tue, 06 Sep 2011 18:22:37 +0000 (UTC) When btrfs_orphan_cleanup encounters an inode marked as bad, instead of going down the code path that handles such inodes, it fails with the following error message: btrfs: could not do orphan cleanup -116 This happens as the called btrfs_iget returns an error when encountering such inode. This patch attempts to correct this issue by calling btrfs_iget_locked instead, and handling inodes in I_NEW state manually, while leaving bad inodes to the handling that's already present in the function. Signed-off-by: Milko Krachounov --- -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff -pru linux-2.6-3.1.0~rc4.original/fs/btrfs/inode.c linux-2.6-3.1.0~rc4.fixed/fs/btrfs/inode.c --- linux-2.6-3.1.0~rc4.original/fs/btrfs/inode.c 2011-08-29 07:16:01.000000000 +0300 +++ linux-2.6-3.1.0~rc4.fixed/fs/btrfs/inode.c 2011-09-06 19:26:58.490416217 +0300 @@ -94,6 +94,12 @@ static noinline int cow_file_range(struc u64 start, u64 end, int *page_started, unsigned long *nr_written, int unlock); +static struct inode *btrfs_iget_locked(struct super_block *s, + u64 objectid, + struct btrfs_root *root); +static void btrfs_read_locked_inode(struct inode *inode); +static void inode_tree_add(struct inode *inode); + static int btrfs_init_inode_security(struct btrfs_trans_handle *trans, struct inode *inode, struct inode *dir, const struct qstr *qstr) @@ -2367,15 +2373,27 @@ int btrfs_orphan_cleanup(struct btrfs_ro * crossing root thing. we store the inode number in the * offset of the orphan item. */ - found_key.objectid = found_key.offset; - found_key.type = BTRFS_INODE_ITEM_KEY; - found_key.offset = 0; - inode = btrfs_iget(root->fs_info->sb, &found_key, root, NULL); - if (IS_ERR(inode)) { - ret = PTR_ERR(inode); + inode = btrfs_iget_locked(root->fs_info->sb, + found_key.offset, root); + if (!inode) { + ret = -ENOMEM; goto out; } + if (inode->i_state & I_NEW) { + BTRFS_I(inode)->root = root; + BTRFS_I(inode)->location.objectid = found_key.offset; + BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY; + BTRFS_I(inode)->location.offset = 0; + + btrfs_read_locked_inode(inode); + + if (!is_bad_inode(inode)) + inode_tree_add(inode); + + unlock_new_inode(inode); + } + /* * add this inode to the orphan list so btrfs_orphan_del does * the proper thing when we hit it