diff options
author | Roman Zippel <zippel@linux-m68k.org> | 2008-04-09 17:44:07 +0200 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-10 13:37:51 -0700 |
commit | 76b0c26af2736b7e5b87e6ed7ab63901483d5736 (patch) | |
tree | 5d5178cdbf82bcc2ab581826bef033377fa1e210 /fs | |
parent | f4be31ec9690cfe6e94fcbed6ae60a6a38b3c3ed (diff) | |
download | op-kernel-dev-76b0c26af2736b7e5b87e6ed7ab63901483d5736.zip op-kernel-dev-76b0c26af2736b7e5b87e6ed7ab63901483d5736.tar.gz |
HFS+: fix unlink of links
Some time ago while attempting to handle invalid link counts, I botched
the unlink of links itself, so this patch fixes this now correctly, so
that only the link count of nodes that don't point to links is ignored.
Thanks to Vlado Plaga <rechner@vlado-do.de> to notify me of this
problem.
Signed-off-by: Roman Zippel <zippel@linux-m68k.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/hfsplus/dir.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/fs/hfsplus/dir.c b/fs/hfsplus/dir.c index 2968364..5f40236 100644 --- a/fs/hfsplus/dir.c +++ b/fs/hfsplus/dir.c @@ -340,16 +340,23 @@ static int hfsplus_unlink(struct inode *dir, struct dentry *dentry) if (inode->i_nlink > 0) drop_nlink(inode); - hfsplus_delete_inode(inode); - if (inode->i_ino != cnid && !inode->i_nlink) { - if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { - res = hfsplus_delete_cat(inode->i_ino, HFSPLUS_SB(sb).hidden_dir, NULL); - if (!res) - hfsplus_delete_inode(inode); + if (inode->i_ino == cnid) + clear_nlink(inode); + if (!inode->i_nlink) { + if (inode->i_ino != cnid) { + HFSPLUS_SB(sb).file_count--; + if (!atomic_read(&HFSPLUS_I(inode).opencnt)) { + res = hfsplus_delete_cat(inode->i_ino, + HFSPLUS_SB(sb).hidden_dir, + NULL); + if (!res) + hfsplus_delete_inode(inode); + } else + inode->i_flags |= S_DEAD; } else - inode->i_flags |= S_DEAD; + hfsplus_delete_inode(inode); } else - clear_nlink(inode); + HFSPLUS_SB(sb).file_count--; inode->i_ctime = CURRENT_TIME_SEC; mark_inode_dirty(inode); |