From: Greg KH <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
alan@lxorguk.ukuu.org.uk, Jan Schmidt <list.btrfs@jan-o-sch.net>,
Chris Mason <chris.mason@oracle.com>
Subject: [ 01/75] Btrfs: fix regression in scrub path resolving
Date: Thu, 19 Apr 2012 14:03:04 -0700 [thread overview]
Message-ID: <20120419210303.221572189@linuxfoundation.org> (raw)
In-Reply-To: <20120419210322.GA6478@kroah.com>
3.3-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Schmidt <list.btrfs@jan-o-sch.net>
commit 7a3ae2f8c8c8432e65467b7fc84d5deab04061a0 upstream.
In commit 4692cf58 we introduced new backref walking code for btrfs. This
assumes we're searching live roots, which requires a transaction context.
While scrubbing, however, we must not join a transaction because this could
deadlock with the commit path. Additionally, what scrub really wants to do
is resolving a logical address in the commit root it's currently checking.
This patch adds support for logical to path resolving on commit roots and
makes scrub use that.
Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/btrfs/backref.c | 115 ++++++++++++++++++++++++++++++-----------------------
fs/btrfs/backref.h | 5 +-
fs/btrfs/ioctl.c | 4 -
fs/btrfs/scrub.c | 4 -
4 files changed, 73 insertions(+), 55 deletions(-)
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -116,6 +116,7 @@ add_parent:
* to a logical address
*/
static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info,
+ int search_commit_root,
struct __prelim_ref *ref,
struct ulist *parents)
{
@@ -131,6 +132,7 @@ static int __resolve_indirect_ref(struct
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
+ path->search_commit_root = !!search_commit_root;
root_key.objectid = ref->root_id;
root_key.type = BTRFS_ROOT_ITEM_KEY;
@@ -188,6 +190,7 @@ out:
* resolve all indirect backrefs from the list
*/
static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info,
+ int search_commit_root,
struct list_head *head)
{
int err;
@@ -212,7 +215,8 @@ static int __resolve_indirect_refs(struc
continue;
if (ref->count == 0)
continue;
- err = __resolve_indirect_ref(fs_info, ref, parents);
+ err = __resolve_indirect_ref(fs_info, search_commit_root,
+ ref, parents);
if (err) {
if (ret == 0)
ret = err;
@@ -586,6 +590,7 @@ static int find_parent_nodes(struct btrf
struct btrfs_delayed_ref_head *head;
int info_level = 0;
int ret;
+ int search_commit_root = (trans == BTRFS_BACKREF_SEARCH_COMMIT_ROOT);
struct list_head prefs_delayed;
struct list_head prefs;
struct __prelim_ref *ref;
@@ -600,6 +605,7 @@ static int find_parent_nodes(struct btrf
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
+ path->search_commit_root = !!search_commit_root;
/*
* grab both a lock on the path and a lock on the delayed ref head.
@@ -614,35 +620,39 @@ again:
goto out;
BUG_ON(ret == 0);
- /*
- * look if there are updates for this ref queued and lock the head
- */
- delayed_refs = &trans->transaction->delayed_refs;
- spin_lock(&delayed_refs->lock);
- head = btrfs_find_delayed_ref_head(trans, bytenr);
- if (head) {
- if (!mutex_trylock(&head->mutex)) {
- atomic_inc(&head->node.refs);
- spin_unlock(&delayed_refs->lock);
-
- btrfs_release_path(path);
-
- /*
- * Mutex was contended, block until it's
- * released and try again
- */
- mutex_lock(&head->mutex);
- mutex_unlock(&head->mutex);
- btrfs_put_delayed_ref(&head->node);
- goto again;
- }
- ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed);
- if (ret) {
- spin_unlock(&delayed_refs->lock);
- goto out;
+ if (trans != BTRFS_BACKREF_SEARCH_COMMIT_ROOT) {
+ /*
+ * look if there are updates for this ref queued and lock the
+ * head
+ */
+ delayed_refs = &trans->transaction->delayed_refs;
+ spin_lock(&delayed_refs->lock);
+ head = btrfs_find_delayed_ref_head(trans, bytenr);
+ if (head) {
+ if (!mutex_trylock(&head->mutex)) {
+ atomic_inc(&head->node.refs);
+ spin_unlock(&delayed_refs->lock);
+
+ btrfs_release_path(path);
+
+ /*
+ * Mutex was contended, block until it's
+ * released and try again
+ */
+ mutex_lock(&head->mutex);
+ mutex_unlock(&head->mutex);
+ btrfs_put_delayed_ref(&head->node);
+ goto again;
+ }
+ ret = __add_delayed_refs(head, seq, &info_key,
+ &prefs_delayed);
+ if (ret) {
+ spin_unlock(&delayed_refs->lock);
+ goto out;
+ }
}
+ spin_unlock(&delayed_refs->lock);
}
- spin_unlock(&delayed_refs->lock);
if (path->slots[0]) {
struct extent_buffer *leaf;
@@ -679,7 +689,7 @@ again:
if (ret)
goto out;
- ret = __resolve_indirect_refs(fs_info, &prefs);
+ ret = __resolve_indirect_refs(fs_info, search_commit_root, &prefs);
if (ret)
goto out;
@@ -1074,8 +1084,7 @@ int tree_backref_for_extent(unsigned lon
return 0;
}
-static int iterate_leaf_refs(struct btrfs_fs_info *fs_info,
- struct btrfs_path *path, u64 logical,
+static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, u64 logical,
u64 orig_extent_item_objectid,
u64 extent_item_pos, u64 root,
iterate_extent_inodes_t *iterate, void *ctx)
@@ -1143,35 +1152,38 @@ static int iterate_leaf_refs(struct btrf
* calls iterate() for every inode that references the extent identified by
* the given parameters.
* when the iterator function returns a non-zero value, iteration stops.
- * path is guaranteed to be in released state when iterate() is called.
*/
int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
- struct btrfs_path *path,
u64 extent_item_objectid, u64 extent_item_pos,
+ int search_commit_root,
iterate_extent_inodes_t *iterate, void *ctx)
{
int ret;
struct list_head data_refs = LIST_HEAD_INIT(data_refs);
struct list_head shared_refs = LIST_HEAD_INIT(shared_refs);
struct btrfs_trans_handle *trans;
- struct ulist *refs;
- struct ulist *roots;
+ struct ulist *refs = NULL;
+ struct ulist *roots = NULL;
struct ulist_node *ref_node = NULL;
struct ulist_node *root_node = NULL;
struct seq_list seq_elem;
- struct btrfs_delayed_ref_root *delayed_refs;
-
- trans = btrfs_join_transaction(fs_info->extent_root);
- if (IS_ERR(trans))
- return PTR_ERR(trans);
+ struct btrfs_delayed_ref_root *delayed_refs = NULL;
pr_debug("resolving all inodes for extent %llu\n",
extent_item_objectid);
- delayed_refs = &trans->transaction->delayed_refs;
- spin_lock(&delayed_refs->lock);
- btrfs_get_delayed_seq(delayed_refs, &seq_elem);
- spin_unlock(&delayed_refs->lock);
+ if (search_commit_root) {
+ trans = BTRFS_BACKREF_SEARCH_COMMIT_ROOT;
+ } else {
+ trans = btrfs_join_transaction(fs_info->extent_root);
+ if (IS_ERR(trans))
+ return PTR_ERR(trans);
+
+ delayed_refs = &trans->transaction->delayed_refs;
+ spin_lock(&delayed_refs->lock);
+ btrfs_get_delayed_seq(delayed_refs, &seq_elem);
+ spin_unlock(&delayed_refs->lock);
+ }
ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid,
extent_item_pos, seq_elem.seq,
@@ -1188,7 +1200,7 @@ int iterate_extent_inodes(struct btrfs_f
while (!ret && (root_node = ulist_next(roots, root_node))) {
pr_debug("root %llu references leaf %llu\n",
root_node->val, ref_node->val);
- ret = iterate_leaf_refs(fs_info, path, ref_node->val,
+ ret = iterate_leaf_refs(fs_info, ref_node->val,
extent_item_objectid,
extent_item_pos, root_node->val,
iterate, ctx);
@@ -1198,8 +1210,11 @@ int iterate_extent_inodes(struct btrfs_f
ulist_free(refs);
ulist_free(roots);
out:
- btrfs_put_delayed_seq(delayed_refs, &seq_elem);
- btrfs_end_transaction(trans, fs_info->extent_root);
+ if (!search_commit_root) {
+ btrfs_put_delayed_seq(delayed_refs, &seq_elem);
+ btrfs_end_transaction(trans, fs_info->extent_root);
+ }
+
return ret;
}
@@ -1210,6 +1225,7 @@ int iterate_inodes_from_logical(u64 logi
int ret;
u64 extent_item_pos;
struct btrfs_key found_key;
+ int search_commit_root = path->search_commit_root;
ret = extent_from_logical(fs_info, logical, path,
&found_key);
@@ -1220,8 +1236,9 @@ int iterate_inodes_from_logical(u64 logi
return ret;
extent_item_pos = logical - found_key.objectid;
- ret = iterate_extent_inodes(fs_info, path, found_key.objectid,
- extent_item_pos, iterate, ctx);
+ ret = iterate_extent_inodes(fs_info, found_key.objectid,
+ extent_item_pos, search_commit_root,
+ iterate, ctx);
return ret;
}
--- a/fs/btrfs/backref.h
+++ b/fs/btrfs/backref.h
@@ -22,6 +22,8 @@
#include "ioctl.h"
#include "ulist.h"
+#define BTRFS_BACKREF_SEARCH_COMMIT_ROOT ((struct btrfs_trans_handle *)0)
+
struct inode_fs_paths {
struct btrfs_path *btrfs_path;
struct btrfs_root *fs_root;
@@ -44,9 +46,8 @@ int tree_backref_for_extent(unsigned lon
u64 *out_root, u8 *out_level);
int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
- struct btrfs_path *path,
u64 extent_item_objectid,
- u64 extent_offset,
+ u64 extent_offset, int search_commit_root,
iterate_extent_inodes_t *iterate, void *ctx);
int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
--- a/fs/btrfs/ioctl.c
+++ b/fs/btrfs/ioctl.c
@@ -3066,8 +3066,8 @@ static long btrfs_ioctl_logical_to_ino(s
goto out;
extent_item_pos = loi->logical - key.objectid;
- ret = iterate_extent_inodes(root->fs_info, path, key.objectid,
- extent_item_pos, build_ino_list,
+ ret = iterate_extent_inodes(root->fs_info, key.objectid,
+ extent_item_pos, 0, build_ino_list,
inodes);
if (ret < 0)
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -352,8 +352,8 @@ static void scrub_print_warning(const ch
} while (ret != 1);
} else {
swarn.path = path;
- iterate_extent_inodes(fs_info, path, found_key.objectid,
- extent_item_pos,
+ iterate_extent_inodes(fs_info, found_key.objectid,
+ extent_item_pos, 1,
scrub_print_warning_inode, &swarn);
}
next prev parent reply other threads:[~2012-04-19 21:12 UTC|newest]
Thread overview: 76+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-04-19 21:03 [ 00/75] 3.3.3-stable review Greg KH
2012-04-19 21:03 ` Greg KH [this message]
2012-04-19 21:03 ` [ 02/75] drm/radeon/kms: fix DVO setup on some r4xx chips Greg KH
2012-04-19 21:03 ` [ 03/75] drm/i915: Removed IVB forced enable of sprite dest key Greg KH
2012-04-19 21:03 ` [ 04/75] drm/i915/ringbuffer: Exclude last 2 cachlines of ring on 845g Greg KH
2012-04-19 21:03 ` [ 05/75] drm/radeon: only add the mm i2c bus if the hw_i2c module param is set Greg KH
2012-04-19 21:03 ` [ 06/75] drm/i915: properly compute dp dithering for user-created modes Greg KH
2012-04-19 21:03 ` [ 07/75] drm/i915: make rc6 module parameter read-only Greg KH
2012-04-19 21:03 ` [ 08/75] rtlwifi: Preallocate USB read buffers and eliminate kalloc in read routine Greg KH
2012-04-19 21:03 ` [ 09/75] rtlwifi: Add missing DMA buffer unmapping for PCI drivers Greg KH
2012-04-19 21:03 ` [ 10/75] ARM: 7379/1: DT: fix atags_to_fdt() second call site Greg KH
2012-04-19 21:03 ` [ 11/75] ARM: 7384/1: ThumbEE: Disable userspace TEEHBR access for !CONFIG_ARM_THUMBEE Greg KH
2012-04-19 21:03 ` [ 12/75] md/raid1,raid10: Fix calculation of vcnt when processing error recovery Greg KH
2012-04-19 21:03 ` [ 13/75] md/bitmap: prevent bitmap_daemon_work running while initialising bitmap Greg KH
2012-04-19 21:03 ` [ 14/75] [PATCH] Bluetooth: uart-ldisc: Fix memory leak Greg KH
2012-04-19 21:03 ` [ 15/75] Bluetooth: hci_ldisc: fix NULL-pointer dereference on tty_close Greg KH
2012-04-19 21:03 ` [ 16/75] Bluetooth: hci_core: fix NULL-pointer dereference at unregister Greg KH
2012-04-19 21:03 ` [ 17/75] Bluetooth: Remove unneeded locking Greg KH
2012-04-19 21:03 ` [ 18/75] Revert "Btrfs: increase the global block reserve estimates" Greg KH
2012-04-19 21:03 ` [ 19/75] ALSA: hda/realtek - Add a fixup entry for Acer Aspire 8940G Greg KH
2012-04-19 21:03 ` [ 20/75] ext4: address scalability issue by removing extent cache statistics Greg KH
2012-04-19 21:03 ` [ 21/75] ia64: fix futex_atomic_cmpxchg_inatomic() Greg KH
2012-04-19 21:03 ` [ 22/75] panic: fix stack dump print on direct call to panic() Greg KH
2012-04-19 21:03 ` [ 23/75] drivers/rtc/rtc-pl031.c: enable clock on all ST variants Greg KH
2012-04-19 21:03 ` [ 24/75] hugetlb: fix race condition in hugetlb_fault() Greg KH
2012-04-19 21:03 ` [ 25/75] staging: iio: hmc5843: Fix crash in probe function Greg KH
2012-04-19 21:03 ` [ 26/75] Revert "serial/8250_pci: init-quirk msi support for kt serial controller" Greg KH
2012-04-19 21:03 ` [ 27/75] serial: samsung: fix omission initialize ulcon in reset port fn() Greg KH
2012-04-19 21:03 ` [ 28/75] Revert "serial/8250_pci: setup-quirk workaround for the kt serial controller" Greg KH
2012-04-19 21:03 ` [ 29/75] serial/8250_pci: add a "force background timer" flag and use it for the "kt" serial port Greg KH
2012-04-19 21:03 ` [ 30/75] tty: serial: altera_uart: Check for NULL platform_data in probe Greg KH
2012-04-19 21:03 ` [ 31/75] sparc64: Eliminate obsolete __handle_softirq() function Greg KH
2012-04-19 21:03 ` [ 32/75] sparc64: Fix bootup crash on sun4v Greg KH
2012-04-19 21:03 ` [ 33/75] cciss: Initialize scsi host max_sectors for tape drive support Greg KH
2012-04-19 21:03 ` [ 34/75] cciss: Fix scsi tape io with more than 255 scatter gather elements Greg KH
2012-04-19 21:03 ` [ 35/75] perf hists: Catch and handle out-of-date hist entry maps Greg KH
2012-04-19 21:03 ` [ 36/75] video:uvesafb: Fix oops that uvesafb try to execute NX-protected page Greg KH
2012-04-19 21:03 ` [ 37/75] IB/srpt: Set srq_type to IB_SRQT_BASIC Greg KH
2012-04-19 21:03 ` [ 38/75] nohz: Fix stale jiffies update in tick_nohz_restart() Greg KH
2012-04-19 21:03 ` [ 39/75] pch_uart: Fix MSI setting issue Greg KH
2012-04-19 21:03 ` [ 40/75] x86: Use correct byte-sized register constraint in __xchg_op() Greg KH
2012-04-19 21:03 ` [ 41/75] x86: Use correct byte-sized register constraint in __add() Greg KH
2012-04-19 21:03 ` [ 42/75] USB: serial: fix race between probe and open Greg KH
2012-04-19 21:03 ` [ 43/75] USB: pl2303: fix DTR/RTS being raised on baud rate change Greg KH
2012-04-19 21:03 ` [ 44/75] USB: option: re-add NOVATELWIRELESS_PRODUCT_HSPA_HIGHSPEED to option_id array Greg KH
2012-04-19 21:03 ` [ 45/75] USB: ftdi_sio: fix status line change handling for TIOCMIWAIT and TIOCGICOUNT Greg KH
2012-04-19 21:03 ` [ 46/75] USB: ftdi_sio: fix race condition in TIOCMIWAIT, and abort of TIOCMIWAIT when the device is removed Greg KH
2012-04-19 21:03 ` [ 47/75] USB: sierra: add support for Sierra Wireless MC7710 Greg KH
2012-04-19 21:03 ` [ 48/75] USB: dont clear urb->dev in scatter-gather library Greg KH
2012-04-19 21:03 ` [ 49/75] USB: dont ignore suspend errors for root hubs Greg KH
2012-04-19 21:03 ` [ 50/75] xhci: dont re-enable IE constantly Greg KH
2012-04-19 21:03 ` [ 51/75] xhci: Dont write zeroed pointers to xHC registers Greg KH
2012-04-19 21:03 ` [ 52/75] xhci: Restore event ring dequeue pointer on resume Greg KH
2012-04-19 21:03 ` [ 53/75] USB: fix bug of device descriptor got from superspeed device Greg KH
2012-04-19 21:03 ` [ 54/75] xHCI: add XHCI_RESET_ON_RESUME quirk for VIA xHCI host Greg KH
2012-04-19 21:03 ` [ 55/75] xHCI: Correct the #define XHCI_LEGACY_DISABLE_SMI Greg KH
2012-04-19 21:03 ` [ 56/75] [S390] fix tlb flushing for page table pages Greg KH
2012-04-19 21:04 ` [ 57/75] memcg: fix Bad page state after replace_page_cache Greg KH
2012-04-19 21:04 ` [ 58/75] serial: PL011: clear pending interrupts Greg KH
2012-04-19 21:04 ` [ 59/75] serial: PL011: move interrupt clearing Greg KH
2012-04-19 21:04 ` [ 60/75] fcaps: clear the same personality flags as suid when fcaps are used Greg KH
2012-04-19 21:04 ` [ 61/75] xhci: Fix register save/restore order Greg KH
2012-04-19 21:04 ` [ 62/75] usb: gadget: pch_udc: Fix disconnect issue Greg KH
2012-04-19 21:04 ` [ 63/75] usb: gadget: pch_udc: Fix wrong return value Greg KH
2012-04-19 21:04 ` [ 64/75] usb: gadget: pch_udc: Fix USB suspend issue Greg KH
2012-04-19 21:04 ` [ 65/75] usb: gadget: pch_udc: Fix usb/gadget/pch_udc: Fix ether gadget connect/disconnect issue Greg KH
2012-04-19 21:04 ` [ 66/75] usb: gadget: pch_udc: Reduce redundant interrupt Greg KH
2012-04-19 21:04 ` [ 67/75] security: fix compile error in commoncap.c Greg KH
2012-04-19 21:04 ` [ 68/75] spi-topcliff-pch: fix -Wuninitialized warning Greg KH
2012-04-19 21:04 ` [ 69/75] Bluetooth: Adding USB device 13d3:3375 as an Atheros AR3012 Greg KH
2012-04-19 21:04 ` [ 70/75] Bluetooth: Add Atheros maryann PIDVID support Greg KH
2012-04-19 21:04 ` [ 71/75] futex: Do not leak robust list to unprivileged process Greg KH
2012-04-19 21:04 ` [ 72/75] drm/i915: Hold mode_config lock whilst changing mode for lastclose() Greg KH
2012-04-19 21:04 ` [ 73/75] drm/radeon/kms: fix the regression of DVI connector check Greg KH
2012-04-19 21:04 ` [ 74/75] drm/radeon: disable MSI on RV515 Greg KH
2012-04-19 21:04 ` [ 75/75] drm/radeon: fix load detect on rn50 with hardcoded EDIDs Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120419210303.221572189@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=chris.mason@oracle.com \
--cc=linux-kernel@vger.kernel.org \
--cc=list.btrfs@jan-o-sch.net \
--cc=stable@vger.kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.