diff options
author | Yiwen Jiang <jiangyiwen@huawei.com> | 2014-01-21 18:48:39 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-21 19:19:42 -0500 |
commit | 75f82eaa502c75d881c1db7979f3c2bf2da6865f (patch) | |
tree | 5cab335b78604a35db9407a1c7afb3abc30fa87f | |
parent | a2a3b39824e152ecf0e7357ccc7b9d6fd4b9fe7e (diff) |
ocfs2: fix NULL pointer dereference when dismount and ocfs2rec simultaneously
2 nodes cluster, say Node A and Node B, mount the same ocfs2 volume, and
create a file 1.
Node A Node B
open 1, get open lock
rm 1, and then add 1 to orphan_dir
storage link down,
o2hb_write_timeout
->o2quo_disk_timeout
->emergency_restart
at the moment, Node B dismount and do
ocfs2rec simultaneously
1) ocfs2_dismount_volume
->ocfs2_recovery_exit
->wait_event(osb->recovery_event)
->flush_workqueue(ocfs2_wq)
2) ocfs2rec
->queue_work(&journal->j_recovery_work)
->ocfs2_recover_orphans
->ocfs2_commit_truncate
->queue_delayed_work(&osb->osb_truncate_log_wq)
In ocfs2_recovery_exit, it flushes workqueue and then releases system
inodes. When doing ocfs2rec, it will call ocfs2_flush_truncate_log
which will try to get sys_root_inode, and NULL pointer dereference
occurs.
Signed-off-by: Yiwen Jiang <jiangyiwen@huawei.com>
Signed-off-by: joyce <xuejiufei@huawei.com>
Signed-off-by: Joseph Qi <joseph.qi@huawei.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Mark Fasheh <mfasheh@suse.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r-- | fs/ocfs2/super.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c index 5445d72eb8e5..49d84f80f36c 100644 --- a/fs/ocfs2/super.c +++ b/fs/ocfs2/super.c | |||
@@ -1945,11 +1945,15 @@ static void ocfs2_dismount_volume(struct super_block *sb, int mnt_err) | |||
1945 | 1945 | ||
1946 | ocfs2_shutdown_local_alloc(osb); | 1946 | ocfs2_shutdown_local_alloc(osb); |
1947 | 1947 | ||
1948 | ocfs2_truncate_log_shutdown(osb); | ||
1949 | |||
1950 | /* This will disable recovery and flush any recovery work. */ | 1948 | /* This will disable recovery and flush any recovery work. */ |
1951 | ocfs2_recovery_exit(osb); | 1949 | ocfs2_recovery_exit(osb); |
1952 | 1950 | ||
1951 | /* | ||
1952 | * During dismount, when it recovers another node it will call | ||
1953 | * ocfs2_recover_orphans and queue delayed work osb_truncate_log_wq. | ||
1954 | */ | ||
1955 | ocfs2_truncate_log_shutdown(osb); | ||
1956 | |||
1953 | ocfs2_journal_shutdown(osb); | 1957 | ocfs2_journal_shutdown(osb); |
1954 | 1958 | ||
1955 | ocfs2_sync_blockdev(sb); | 1959 | ocfs2_sync_blockdev(sb); |