diff options
author | David Howells <dhowells@redhat.com> | 2006-10-11 04:22:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-10-11 14:14:25 -0400 |
commit | edc666e2ff9ec2e4e9510f1127c68c22cffc93f6 (patch) | |
tree | 21d139e520a4a7fa79464bbe46e3df145a231d27 /fs/reiserfs/super.c | |
parent | 9e42ef777f62277ea9bb70976be65bb374e00b9c (diff) |
[PATCH] ReiserFS: Make sure all dentries refs are released before calling kill_block_super()
Make sure all dentries refs are released before calling kill_block_super()
so that the assumption that generic_shutdown_super() can completely destroy
the dentry tree for there will be no external references holds true.
What was being done in the put_super() superblock op, is now done in the
kill_sb() filesystem op instead, prior to calling kill_block_super().
Changes made in [try #2]:
(*) reiserfs_kill_sb() now checks that the superblock FS info pointer is set
before trying to dereference it.
Signed-off-by: David Howells <dhowells@redhat.com>
Cc: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: <reiserfs-dev@namesys.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/reiserfs/super.c')
-rw-r--r-- | fs/reiserfs/super.c | 31 |
1 files changed, 20 insertions, 11 deletions
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index c89aa2338191..9041802df832 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -430,20 +430,29 @@ int remove_save_link(struct inode *inode, int truncate) | |||
430 | return journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT); | 430 | return journal_end(&th, inode->i_sb, JOURNAL_PER_BALANCE_CNT); |
431 | } | 431 | } |
432 | 432 | ||
433 | static void reiserfs_put_super(struct super_block *s) | 433 | static void reiserfs_kill_sb(struct super_block *s) |
434 | { | 434 | { |
435 | struct reiserfs_transaction_handle th; | 435 | if (REISERFS_SB(s)) { |
436 | th.t_trans_id = 0; | 436 | if (REISERFS_SB(s)->xattr_root) { |
437 | d_invalidate(REISERFS_SB(s)->xattr_root); | ||
438 | dput(REISERFS_SB(s)->xattr_root); | ||
439 | REISERFS_SB(s)->xattr_root = NULL; | ||
440 | } | ||
437 | 441 | ||
438 | if (REISERFS_SB(s)->xattr_root) { | 442 | if (REISERFS_SB(s)->priv_root) { |
439 | d_invalidate(REISERFS_SB(s)->xattr_root); | 443 | d_invalidate(REISERFS_SB(s)->priv_root); |
440 | dput(REISERFS_SB(s)->xattr_root); | 444 | dput(REISERFS_SB(s)->priv_root); |
445 | REISERFS_SB(s)->priv_root = NULL; | ||
446 | } | ||
441 | } | 447 | } |
442 | 448 | ||
443 | if (REISERFS_SB(s)->priv_root) { | 449 | kill_block_super(s); |
444 | d_invalidate(REISERFS_SB(s)->priv_root); | 450 | } |
445 | dput(REISERFS_SB(s)->priv_root); | 451 | |
446 | } | 452 | static void reiserfs_put_super(struct super_block *s) |
453 | { | ||
454 | struct reiserfs_transaction_handle th; | ||
455 | th.t_trans_id = 0; | ||
447 | 456 | ||
448 | /* change file system state to current state if it was mounted with read-write permissions */ | 457 | /* change file system state to current state if it was mounted with read-write permissions */ |
449 | if (!(s->s_flags & MS_RDONLY)) { | 458 | if (!(s->s_flags & MS_RDONLY)) { |
@@ -2156,7 +2165,7 @@ struct file_system_type reiserfs_fs_type = { | |||
2156 | .owner = THIS_MODULE, | 2165 | .owner = THIS_MODULE, |
2157 | .name = "reiserfs", | 2166 | .name = "reiserfs", |
2158 | .get_sb = get_super_block, | 2167 | .get_sb = get_super_block, |
2159 | .kill_sb = kill_block_super, | 2168 | .kill_sb = reiserfs_kill_sb, |
2160 | .fs_flags = FS_REQUIRES_DEV, | 2169 | .fs_flags = FS_REQUIRES_DEV, |
2161 | }; | 2170 | }; |
2162 | 2171 | ||