mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-06 13:13:51 +00:00
jfs: makes diUnmount/diMount in jfs_mount_rw atomic
jfs_mount_rw can call diUnmount and then diMount. These calls change the imap pointer. Between these two calls there may be calls of function jfs_lookup(). The jfs_lookup() function calls jfs_iget(), which, in turn calls diRead(). The latter references the imap pointer. That may cause diRead() to refer to a pointer freed in diUnmount(). This commit makes the calls to diUnmount()/diMount() atomic so that nothing will read the imap pointer until the whole remount is completed. Signed-off-by: Oleg Kanatov <okanatov@gmail.com> Signed-off-by: Dave Kleikamp <dave.kleikamp@oracle.com>
This commit is contained in:
parent
d0e482c45c
commit
a60dca73a1
@ -310,8 +310,8 @@ int diRead(struct inode *ip)
|
||||
iagno = INOTOIAG(ip->i_ino);
|
||||
|
||||
/* read the iag */
|
||||
imap = JFS_IP(ipimap)->i_imap;
|
||||
IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
|
||||
imap = JFS_IP(ipimap)->i_imap;
|
||||
rc = diIAGRead(imap, iagno, &mp);
|
||||
IREAD_UNLOCK(ipimap);
|
||||
if (rc) {
|
||||
|
@ -234,11 +234,15 @@ int jfs_mount_rw(struct super_block *sb, int remount)
|
||||
|
||||
truncate_inode_pages(sbi->ipimap->i_mapping, 0);
|
||||
truncate_inode_pages(sbi->ipbmap->i_mapping, 0);
|
||||
|
||||
IWRITE_LOCK(sbi->ipimap, RDWRLOCK_IMAP);
|
||||
diUnmount(sbi->ipimap, 1);
|
||||
if ((rc = diMount(sbi->ipimap))) {
|
||||
IWRITE_UNLOCK(sbi->ipimap);
|
||||
jfs_err("jfs_mount_rw: diMount failed!");
|
||||
return rc;
|
||||
}
|
||||
IWRITE_UNLOCK(sbi->ipimap);
|
||||
|
||||
dbUnmount(sbi->ipbmap, 1);
|
||||
if ((rc = dbMount(sbi->ipbmap))) {
|
||||
|
Loading…
Reference in New Issue
Block a user