aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-01-07 17:03:21 -0500
committerJosef Bacik <josef@toxicpanda.com>2013-01-14 13:52:52 -0500
commitf3fe820c20a1a36c790545184e734e78d61cd68d (patch)
tree852fcc814680ebcc272011dd4767222f5f8a3d88
parent72bcd99d450cb1dde8bf13c3b65fc5883b2a3893 (diff)
Btrfs: add orphan before truncating pagecache
Running xfstests 83 in a loop would sometimes fail the fsck. This happens because if we invalidate a page that already has an ordered extent setup for it we will complete the ordered extent ourselves, assuming that the truncate will clean everything up. The problem with this is there is plenty of time for the truncate to fail after we've done this work. So to fix this we need to add the orphan item first to make sure the cleanup gets done properly, and then we can truncate the pagecache and all that stuff and be safe. This fixes the btrfsck failures I was seeing while running 83 in a loop. Thanks, Signed-off-by: Josef Bacik <jbacik@fusionio.com>
-rw-r--r--fs/btrfs/inode.c53
1 files changed, 38 insertions, 15 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 67ed24ae86bb..4ddcf79e7894 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2478,6 +2478,18 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
2478 continue; 2478 continue;
2479 } 2479 }
2480 nr_truncate++; 2480 nr_truncate++;
2481
2482 /* 1 for the orphan item deletion. */
2483 trans = btrfs_start_transaction(root, 1);
2484 if (IS_ERR(trans)) {
2485 ret = PTR_ERR(trans);
2486 goto out;
2487 }
2488 ret = btrfs_orphan_add(trans, inode);
2489 btrfs_end_transaction(trans, root);
2490 if (ret)
2491 goto out;
2492
2481 ret = btrfs_truncate(inode); 2493 ret = btrfs_truncate(inode);
2482 } else { 2494 } else {
2483 nr_unlink++; 2495 nr_unlink++;
@@ -3783,9 +3795,34 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize)
3783 set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, 3795 set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
3784 &BTRFS_I(inode)->runtime_flags); 3796 &BTRFS_I(inode)->runtime_flags);
3785 3797
3798 /*
3799 * 1 for the orphan item we're going to add
3800 * 1 for the orphan item deletion.
3801 */
3802 trans = btrfs_start_transaction(root, 2);
3803 if (IS_ERR(trans))
3804 return PTR_ERR(trans);
3805
3806 /*
3807 * We need to do this in case we fail at _any_ point during the
3808 * actual truncate. Once we do the truncate_setsize we could
3809 * invalidate pages which forces any outstanding ordered io to
3810 * be instantly completed which will give us extents that need
3811 * to be truncated. If we fail to get an orphan inode down we
3812 * could have left over extents that were never meant to live,
3813 * so we need to garuntee from this point on that everything
3814 * will be consistent.
3815 */
3816 ret = btrfs_orphan_add(trans, inode);
3817 btrfs_end_transaction(trans, root);
3818 if (ret)
3819 return ret;
3820
3786 /* we don't support swapfiles, so vmtruncate shouldn't fail */ 3821 /* we don't support swapfiles, so vmtruncate shouldn't fail */
3787 truncate_setsize(inode, newsize); 3822 truncate_setsize(inode, newsize);
3788 ret = btrfs_truncate(inode); 3823 ret = btrfs_truncate(inode);
3824 if (ret && inode->i_nlink)
3825 btrfs_orphan_del(NULL, inode);
3789 } 3826 }
3790 3827
3791 return ret; 3828 return ret;
@@ -6929,11 +6966,9 @@ static int btrfs_truncate(struct inode *inode)
6929 6966
6930 /* 6967 /*
6931 * 1 for the truncate slack space 6968 * 1 for the truncate slack space
6932 * 1 for the orphan item we're going to add
6933 * 1 for the orphan item deletion
6934 * 1 for updating the inode. 6969 * 1 for updating the inode.
6935 */ 6970 */
6936 trans = btrfs_start_transaction(root, 4); 6971 trans = btrfs_start_transaction(root, 2);
6937 if (IS_ERR(trans)) { 6972 if (IS_ERR(trans)) {
6938 err = PTR_ERR(trans); 6973 err = PTR_ERR(trans);
6939 goto out; 6974 goto out;
@@ -6944,12 +6979,6 @@ static int btrfs_truncate(struct inode *inode)
6944 min_size); 6979 min_size);
6945 BUG_ON(ret); 6980 BUG_ON(ret);
6946 6981
6947 ret = btrfs_orphan_add(trans, inode);
6948 if (ret) {
6949 btrfs_end_transaction(trans, root);
6950 goto out;
6951 }
6952
6953 /* 6982 /*
6954 * setattr is responsible for setting the ordered_data_close flag, 6983 * setattr is responsible for setting the ordered_data_close flag,
6955 * but that is only tested during the last file release. That 6984 * but that is only tested during the last file release. That
@@ -7018,12 +7047,6 @@ static int btrfs_truncate(struct inode *inode)
7018 ret = btrfs_orphan_del(trans, inode); 7047 ret = btrfs_orphan_del(trans, inode);
7019 if (ret) 7048 if (ret)
7020 err = ret; 7049 err = ret;
7021 } else if (ret && inode->i_nlink > 0) {
7022 /*
7023 * Failed to do the truncate, remove us from the in memory
7024 * orphan list.
7025 */
7026 ret = btrfs_orphan_del(NULL, inode);
7027 } 7050 }
7028 7051
7029 if (trans) { 7052 if (trans) {