Skip to content

Commit a60dca7

Browse files
okanatovkleikamp
authored andcommitted
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 <[email protected]> Signed-off-by: Dave Kleikamp <[email protected]>
1 parent d0e482c commit a60dca7

File tree

2 files changed

+5
-1
lines changed

2 files changed

+5
-1
lines changed

fs/jfs/jfs_imap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -310,8 +310,8 @@ int diRead(struct inode *ip)
310310
iagno = INOTOIAG(ip->i_ino);
311311

312312
/* read the iag */
313-
imap = JFS_IP(ipimap)->i_imap;
314313
IREAD_LOCK(ipimap, RDWRLOCK_IMAP);
314+
imap = JFS_IP(ipimap)->i_imap;
315315
rc = diIAGRead(imap, iagno, &mp);
316316
IREAD_UNLOCK(ipimap);
317317
if (rc) {

fs/jfs/jfs_mount.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -234,11 +234,15 @@ int jfs_mount_rw(struct super_block *sb, int remount)
234234

235235
truncate_inode_pages(sbi->ipimap->i_mapping, 0);
236236
truncate_inode_pages(sbi->ipbmap->i_mapping, 0);
237+
238+
IWRITE_LOCK(sbi->ipimap, RDWRLOCK_IMAP);
237239
diUnmount(sbi->ipimap, 1);
238240
if ((rc = diMount(sbi->ipimap))) {
241+
IWRITE_UNLOCK(sbi->ipimap);
239242
jfs_err("jfs_mount_rw: diMount failed!");
240243
return rc;
241244
}
245+
IWRITE_UNLOCK(sbi->ipimap);
242246

243247
dbUnmount(sbi->ipbmap, 1);
244248
if ((rc = dbMount(sbi->ipbmap))) {

0 commit comments

Comments
 (0)