aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2009-03-24 10:24:13 -0400
committerChris Mason <chris.mason@oracle.com>2009-03-24 16:14:51 -0400
commita74ac3220774d33db967088906dc3351829e2d3a (patch)
tree292fe0b88a5917d3b282b6a1cdfca170f9405132
parenta4b6e07d1a8a9b907e82b9acbf51a026fbb9301c (diff)
Btrfs: Make sure i_nlink doesn't hit zero too soon during log replay
During log replay, inodes are copied from the log to the main filesystem btrees. Sometimes they have a zero link count in the log but they actually gain links during the replay or have some in the main btree. This patch updates the link count to be at least one after copying the inode out of the log. This makes sure the inode is deleted during an iput while the rest of the replay code is still working on it. The log replay has fixup code to make sure that link counts are correct at the end of the replay, so we could use any non-zero number here and it would work fine. Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/tree-log.c11
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index a93934fc93bd..405439ca4c45 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -1532,6 +1532,17 @@ static int replay_one_buffer(struct btrfs_root *log, struct extent_buffer *eb,
1532 root, inode, inode->i_size, 1532 root, inode, inode->i_size,
1533 BTRFS_EXTENT_DATA_KEY); 1533 BTRFS_EXTENT_DATA_KEY);
1534 BUG_ON(ret); 1534 BUG_ON(ret);
1535
1536 /* if the nlink count is zero here, the iput
1537 * will free the inode. We bump it to make
1538 * sure it doesn't get freed until the link
1539 * count fixup is done
1540 */
1541 if (inode->i_nlink == 0) {
1542 btrfs_inc_nlink(inode);
1543 btrfs_update_inode(wc->trans,
1544 root, inode);
1545 }
1535 iput(inode); 1546 iput(inode);
1536 } 1547 }
1537 ret = link_to_fixup_dir(wc->trans, root, 1548 ret = link_to_fixup_dir(wc->trans, root,