txCommit calls diWrite, which can fail (diWrite -> read_metapage ->
read_cache_page). txAbortCommit will be called in that case. Kernel will
panic in LogSyncRelease on assert(log) because the "lo"g fields for some
metapages are NULL. If we are going to kernel panic anyway, we should
panic at the first place without doing all these works to abort a
transcation.
int diWrite(tid_t tid, struct inode *ip)
{
...
retry:
mp = read_metapage(ipimap, pageno << sbi->l2nbperpage, PSIZE, 1);
if (mp == 0)
Fail --> return -EIO;
...
}
static void txAbortCommit(struct commit * cd)
{
...
if (mp->xflag & COMMIT_PAGE)
--> LogSgyncRelease(mp);
...
}
static void LogSyncRelease(struct metapage * mp)
{
struct jfs_log *log = mp->log;
assert(atomic_read(&mp->nohomeok));
Panic -->
assert(log);
atomic_dec(&mp->nohomeok);
if (atomic_read(&mp->nohomeok))
return;
hold_metapage(mp, 0);
LOGSYNC_LOCK(log);
mp->log = NULL;
mp->lsn = 0;
mp->clsn = 0;
log->count--;
list_del_init(&mp->synclist);
LOGSYNC_UNLOCK(log);
release_metapage(mp);
}