aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/inode.c
diff options
context:
space:
mode:
authorYan, Zheng <zheng.yan@oracle.com>2009-11-12 04:36:34 -0500
committerChris Mason <chris.mason@oracle.com>2009-12-17 12:33:35 -0500
commit24bbcf0442ee04660a5a030efdbb6d03f1c275cb (patch)
treeaa57d77d29cc5150b272cc3f6465f10262fcbaac /fs/btrfs/inode.c
parentf34f57a3ab4e73304d78c125682f1a53cd3975f2 (diff)
Btrfs: Add delayed iput
iput() can trigger new transactions if we are dropping the final reference, so calling it in btrfs_commit_transaction may end up deadlock. This patch adds delayed iput to avoid the issue. Signed-off-by: Yan Zheng <zheng.yan@oracle.com> Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r--fs/btrfs/inode.c55
1 files changed, 53 insertions, 2 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 82740a3c628a..168e8c040aab 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2022,6 +2022,54 @@ zeroit:
2022 return -EIO; 2022 return -EIO;
2023} 2023}
2024 2024
2025struct delayed_iput {
2026 struct list_head list;
2027 struct inode *inode;
2028};
2029
2030void btrfs_add_delayed_iput(struct inode *inode)
2031{
2032 struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
2033 struct delayed_iput *delayed;
2034
2035 if (atomic_add_unless(&inode->i_count, -1, 1))
2036 return;
2037
2038 delayed = kmalloc(sizeof(*delayed), GFP_NOFS | __GFP_NOFAIL);
2039 delayed->inode = inode;
2040
2041 spin_lock(&fs_info->delayed_iput_lock);
2042 list_add_tail(&delayed->list, &fs_info->delayed_iputs);
2043 spin_unlock(&fs_info->delayed_iput_lock);
2044}
2045
2046void btrfs_run_delayed_iputs(struct btrfs_root *root)
2047{
2048 LIST_HEAD(list);
2049 struct btrfs_fs_info *fs_info = root->fs_info;
2050 struct delayed_iput *delayed;
2051 int empty;
2052
2053 spin_lock(&fs_info->delayed_iput_lock);
2054 empty = list_empty(&fs_info->delayed_iputs);
2055 spin_unlock(&fs_info->delayed_iput_lock);
2056 if (empty)
2057 return;
2058
2059 down_read(&root->fs_info->cleanup_work_sem);
2060 spin_lock(&fs_info->delayed_iput_lock);
2061 list_splice_init(&fs_info->delayed_iputs, &list);
2062 spin_unlock(&fs_info->delayed_iput_lock);
2063
2064 while (!list_empty(&list)) {
2065 delayed = list_entry(list.next, struct delayed_iput, list);
2066 list_del(&delayed->list);
2067 iput(delayed->inode);
2068 kfree(delayed);
2069 }
2070 up_read(&root->fs_info->cleanup_work_sem);
2071}
2072
2025/* 2073/*
2026 * This creates an orphan entry for the given inode in case something goes 2074 * This creates an orphan entry for the given inode in case something goes
2027 * wrong in the middle of an unlink/truncate. 2075 * wrong in the middle of an unlink/truncate.
@@ -5568,7 +5616,7 @@ out_fail:
5568 * some fairly slow code that needs optimization. This walks the list 5616 * some fairly slow code that needs optimization. This walks the list
5569 * of all the inodes with pending delalloc and forces them to disk. 5617 * of all the inodes with pending delalloc and forces them to disk.
5570 */ 5618 */
5571int btrfs_start_delalloc_inodes(struct btrfs_root *root) 5619int btrfs_start_delalloc_inodes(struct btrfs_root *root, int delay_iput)
5572{ 5620{
5573 struct list_head *head = &root->fs_info->delalloc_inodes; 5621 struct list_head *head = &root->fs_info->delalloc_inodes;
5574 struct btrfs_inode *binode; 5622 struct btrfs_inode *binode;
@@ -5587,7 +5635,10 @@ int btrfs_start_delalloc_inodes(struct btrfs_root *root)
5587 spin_unlock(&root->fs_info->delalloc_lock); 5635 spin_unlock(&root->fs_info->delalloc_lock);
5588 if (inode) { 5636 if (inode) {
5589 filemap_flush(inode->i_mapping); 5637 filemap_flush(inode->i_mapping);
5590 iput(inode); 5638 if (delay_iput)
5639 btrfs_add_delayed_iput(inode);
5640 else
5641 iput(inode);
5591 } 5642 }
5592 cond_resched(); 5643 cond_resched();
5593 spin_lock(&root->fs_info->delalloc_lock); 5644 spin_lock(&root->fs_info->delalloc_lock);