aboutsummaryrefslogtreecommitdiffstats
path: root/fs/hfsplus/bnode.c
diff options
context:
space:
mode:
authorSergei Antonov <saproj@gmail.com>2014-06-06 17:36:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-06-06 19:08:10 -0400
commit2cd282a1bc6b9d111b8beee63bea0af735a8a1aa (patch)
tree80dff1bb5f089868bdbee433b0308098b2c2e6b4 /fs/hfsplus/bnode.c
parent915ab236d3c491f9bb0f6596d03e25b37f4d5a20 (diff)
hfsplus: fix "unused node is not erased" error
Zero newly allocated extents in the catalog tree if volume attributes tell us to. Not doing so we risk getting the "unused node is not erased" error. See kHFSUnusedNodeFix flag in Apple's source code for reference. There was a previous commit clearing the node when it is freed: commit 899bed05e9f6 ("hfsplus: fix issue with unzeroed unused b-tree nodes"). But it did not handle newly allocated extents (this patch fixes it). And it zeroed nodes in all trees unconditionally which is an overkill. This patch adds a condition and also switches to 'tree->node_size' as a simpler method of getting the length to zero. Signed-off-by: Sergei Antonov <saproj@gmail.com> Cc: Anton Altaparmakov <aia21@cam.ac.uk> Cc: Al Viro <viro@zeniv.linux.org.uk> Cc: Christoph Hellwig <hch@infradead.org> Cc: Vyacheslav Dubeyko <slava@dubeyko.com> Cc: Hin-Tak Leung <htl10@users.sourceforge.net> Cc: Kyle Laracey <kalaracey@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/hfsplus/bnode.c')
-rw-r--r--fs/hfsplus/bnode.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/fs/hfsplus/bnode.c b/fs/hfsplus/bnode.c
index 285502af8df1..759708fd9331 100644
--- a/fs/hfsplus/bnode.c
+++ b/fs/hfsplus/bnode.c
@@ -646,8 +646,8 @@ void hfs_bnode_put(struct hfs_bnode *node)
646 if (test_bit(HFS_BNODE_DELETED, &node->flags)) { 646 if (test_bit(HFS_BNODE_DELETED, &node->flags)) {
647 hfs_bnode_unhash(node); 647 hfs_bnode_unhash(node);
648 spin_unlock(&tree->hash_lock); 648 spin_unlock(&tree->hash_lock);
649 hfs_bnode_clear(node, 0, 649 if (hfs_bnode_need_zeroout(tree))
650 PAGE_CACHE_SIZE * tree->pages_per_bnode); 650 hfs_bnode_clear(node, 0, tree->node_size);
651 hfs_bmap_free(node); 651 hfs_bmap_free(node);
652 hfs_bnode_free(node); 652 hfs_bnode_free(node);
653 return; 653 return;
@@ -656,3 +656,16 @@ void hfs_bnode_put(struct hfs_bnode *node)
656 } 656 }
657} 657}
658 658
659/*
660 * Unused nodes have to be zeroed if this is the catalog tree and
661 * a corresponding flag in the volume header is set.
662 */
663bool hfs_bnode_need_zeroout(struct hfs_btree *tree)
664{
665 struct super_block *sb = tree->inode->i_sb;
666 struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb);
667 const u32 volume_attr = be32_to_cpu(sbi->s_vhdr->attributes);
668
669 return tree->cnid == HFSPLUS_CAT_CNID &&
670 volume_attr & HFSPLUS_VOL_UNUSED_NODE_FIX;
671}