From 2cd282a1bc6b9d111b8beee63bea0af735a8a1aa Mon Sep 17 00:00:00 2001 From: Sergei Antonov Date: Fri, 6 Jun 2014 14:36:28 -0700 Subject: 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 Cc: Anton Altaparmakov Cc: Al Viro Cc: Christoph Hellwig Cc: Vyacheslav Dubeyko Cc: Hin-Tak Leung Cc: Kyle Laracey Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- fs/hfsplus/extents.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'fs/hfsplus/extents.c') diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c index a7aafb35b624..a09fcb68c364 100644 --- a/fs/hfsplus/extents.c +++ b/fs/hfsplus/extents.c @@ -235,7 +235,7 @@ int hfsplus_get_block(struct inode *inode, sector_t iblock, if (iblock > hip->fs_blocks || !create) return -EIO; if (ablock >= hip->alloc_blocks) { - res = hfsplus_file_extend(inode); + res = hfsplus_file_extend(inode, false); if (res) return res; } @@ -425,7 +425,7 @@ int hfsplus_free_fork(struct super_block *sb, u32 cnid, return res; } -int hfsplus_file_extend(struct inode *inode) +int hfsplus_file_extend(struct inode *inode, bool zeroout) { struct super_block *sb = inode->i_sb; struct hfsplus_sb_info *sbi = HFSPLUS_SB(sb); @@ -463,6 +463,12 @@ int hfsplus_file_extend(struct inode *inode) } } + if (zeroout) { + res = sb_issue_zeroout(sb, start, len, GFP_NOFS); + if (res) + goto out; + } + hfs_dbg(EXTENT, "extend %lu: %u,%u\n", inode->i_ino, start, len); if (hip->alloc_blocks <= hip->first_blocks) { -- cgit v1.2.3-70-g09d2