Commit a488edc9 authored by Dave Kleikamp's avatar Dave Kleikamp Committed by Linus Torvalds

[PATCH] JFS: Take logsync lock before testing mp->lsn

This fixes a race where lsn could be cleared before taking the lock
Signed-off-by: default avatarDave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0f511ea7
...@@ -532,10 +532,10 @@ dbUpdatePMap(struct inode *ipbmap, ...@@ -532,10 +532,10 @@ dbUpdatePMap(struct inode *ipbmap,
lastlblkno = lblkno; lastlblkno = lblkno;
LOGSYNC_LOCK(log, flags);
if (mp->lsn != 0) { if (mp->lsn != 0) {
/* inherit older/smaller lsn */ /* inherit older/smaller lsn */
logdiff(diffp, mp->lsn, log); logdiff(diffp, mp->lsn, log);
LOGSYNC_LOCK(log, flags);
if (difft < diffp) { if (difft < diffp) {
mp->lsn = lsn; mp->lsn = lsn;
...@@ -548,20 +548,17 @@ dbUpdatePMap(struct inode *ipbmap, ...@@ -548,20 +548,17 @@ dbUpdatePMap(struct inode *ipbmap,
logdiff(diffp, mp->clsn, log); logdiff(diffp, mp->clsn, log);
if (difft > diffp) if (difft > diffp)
mp->clsn = tblk->clsn; mp->clsn = tblk->clsn;
LOGSYNC_UNLOCK(log, flags);
} else { } else {
mp->log = log; mp->log = log;
mp->lsn = lsn; mp->lsn = lsn;
/* insert bp after tblock in logsync list */ /* insert bp after tblock in logsync list */
LOGSYNC_LOCK(log, flags);
log->count++; log->count++;
list_add(&mp->synclist, &tblk->synclist); list_add(&mp->synclist, &tblk->synclist);
mp->clsn = tblk->clsn; mp->clsn = tblk->clsn;
LOGSYNC_UNLOCK(log, flags);
} }
LOGSYNC_UNLOCK(log, flags);
} }
/* write the last buffer. */ /* write the last buffer. */
......
...@@ -2844,11 +2844,11 @@ diUpdatePMap(struct inode *ipimap, ...@@ -2844,11 +2844,11 @@ diUpdatePMap(struct inode *ipimap,
*/ */
lsn = tblk->lsn; lsn = tblk->lsn;
log = JFS_SBI(tblk->sb)->log; log = JFS_SBI(tblk->sb)->log;
LOGSYNC_LOCK(log, flags);
if (mp->lsn != 0) { if (mp->lsn != 0) {
/* inherit older/smaller lsn */ /* inherit older/smaller lsn */
logdiff(difft, lsn, log); logdiff(difft, lsn, log);
logdiff(diffp, mp->lsn, log); logdiff(diffp, mp->lsn, log);
LOGSYNC_LOCK(log, flags);
if (difft < diffp) { if (difft < diffp) {
mp->lsn = lsn; mp->lsn = lsn;
/* move mp after tblock in logsync list */ /* move mp after tblock in logsync list */
...@@ -2860,17 +2860,15 @@ diUpdatePMap(struct inode *ipimap, ...@@ -2860,17 +2860,15 @@ diUpdatePMap(struct inode *ipimap,
logdiff(diffp, mp->clsn, log); logdiff(diffp, mp->clsn, log);
if (difft > diffp) if (difft > diffp)
mp->clsn = tblk->clsn; mp->clsn = tblk->clsn;
LOGSYNC_UNLOCK(log, flags);
} else { } else {
mp->log = log; mp->log = log;
mp->lsn = lsn; mp->lsn = lsn;
/* insert mp after tblock in logsync list */ /* insert mp after tblock in logsync list */
LOGSYNC_LOCK(log, flags);
log->count++; log->count++;
list_add(&mp->synclist, &tblk->synclist); list_add(&mp->synclist, &tblk->synclist);
mp->clsn = tblk->clsn; mp->clsn = tblk->clsn;
LOGSYNC_UNLOCK(log, flags);
} }
LOGSYNC_UNLOCK(log, flags);
write_metapage(mp); write_metapage(mp);
return (0); return (0);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment