JFS: Take logsync lock before testing mp->lsn

This fixes a race where lsn could be cleared before taking the lock

Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
This commit is contained in:
Dave Kleikamp 2006-03-08 10:59:15 -06:00
parent 5b3030e390
commit be0bf7da19
2 changed files with 4 additions and 9 deletions

View file

@ -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,
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. */

View file

@ -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,
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);
} }