Commit 95996ddf authored by Dave Kleikamp's avatar Dave Kleikamp

Merge bk://linux.bkbits.net/linux-2.5

into hostme.bitkeeper.com:/repos/j/jfs/linux-2.5
parents b159a68b 215211de
...@@ -2055,7 +2055,7 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip) ...@@ -2055,7 +2055,7 @@ static int diAllocExt(struct inomap * imap, int agno, struct inode *ip)
static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
{ {
int extno, bitno, agno, sword, rc; int extno, bitno, agno, sword, rc;
struct metapage *amp, *bmp; struct metapage *amp = NULL, *bmp = NULL;
struct iag *aiagp = 0, *biagp = 0; struct iag *aiagp = 0, *biagp = 0;
u32 mask; u32 mask;
...@@ -2065,8 +2065,6 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino) ...@@ -2065,8 +2065,6 @@ static int diAllocBit(struct inomap * imap, struct iag * iagp, int ino)
* it on the list. * it on the list.
*/ */
if (iagp->nfreeinos == cpu_to_le32(1)) { if (iagp->nfreeinos == cpu_to_le32(1)) {
amp = bmp = NULL;
if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) { if ((int) le32_to_cpu(iagp->inofreefwd) >= 0) {
if ((rc = if ((rc =
diIAGRead(imap, le32_to_cpu(iagp->inofreefwd), diIAGRead(imap, le32_to_cpu(iagp->inofreefwd),
......
/* /*
* Copyright (c) International Business Machines Corp., 2000-2003 * Copyright (C) International Business Machines Corp., 2000-2004
* Portions Copyright (c) Christoph Hellwig, 2001-2002 * Portions Copyright (C) Christoph Hellwig, 2001-2002
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -133,12 +133,14 @@ enum cflags { ...@@ -133,12 +133,14 @@ enum cflags {
* JFS-private superblock information. * JFS-private superblock information.
*/ */
struct jfs_sb_info { struct jfs_sb_info {
struct super_block *sb; /* Point back to vfs super block */
unsigned long mntflag; /* aggregate attributes */ unsigned long mntflag; /* aggregate attributes */
struct inode *ipbmap; /* block map inode */ struct inode *ipbmap; /* block map inode */
struct inode *ipaimap; /* aggregate inode map inode */ struct inode *ipaimap; /* aggregate inode map inode */
struct inode *ipaimap2; /* secondary aimap inode */ struct inode *ipaimap2; /* secondary aimap inode */
struct inode *ipimap; /* aggregate inode map inode */ struct inode *ipimap; /* aggregate inode map inode */
struct jfs_log *log; /* log */ struct jfs_log *log; /* log */
struct list_head log_list; /* volumes associated with a journal */
short bsize; /* logical block size */ short bsize; /* logical block size */
short l2bsize; /* log2 logical block size */ short l2bsize; /* log2 logical block size */
short nbperpage; /* blocks per page */ short nbperpage; /* blocks per page */
......
/* /*
* Copyright (c) International Business Machines Corp., 2000-2003 * Copyright (C) International Business Machines Corp., 2000-2004
* Portions Copyright (c) Christoph Hellwig, 2001-2002 * Portions Copyright (C) Christoph Hellwig, 2001-2002
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -158,6 +158,13 @@ do { \ ...@@ -158,6 +158,13 @@ do { \
*/ */
#define lbmDIRECT 0x0100 #define lbmDIRECT 0x0100
/*
* Global list of active external journals
*/
LIST_HEAD(jfs_external_logs);
struct jfs_log *dummy_log = NULL;
DECLARE_MUTEX(jfs_log_sem);
/* /*
* external references * external references
*/ */
...@@ -172,8 +179,11 @@ static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk, ...@@ -172,8 +179,11 @@ static int lmWriteRecord(struct jfs_log * log, struct tblock * tblk,
struct lrd * lrd, struct tlock * tlck); struct lrd * lrd, struct tlock * tlck);
static int lmNextPage(struct jfs_log * log); static int lmNextPage(struct jfs_log * log);
static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate); static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi,
int activate);
static int open_inline_log(struct super_block *sb);
static int open_dummy_log(struct super_block *sb);
static int lbmLogInit(struct jfs_log * log); static int lbmLogInit(struct jfs_log * log);
static void lbmLogShutdown(struct jfs_log * log); static void lbmLogShutdown(struct jfs_log * log);
static struct lbuf *lbmAllocate(struct jfs_log * log, int); static struct lbuf *lbmAllocate(struct jfs_log * log, int);
...@@ -962,19 +972,24 @@ int lmLogSync(struct jfs_log * log, int nosyncwait) ...@@ -962,19 +972,24 @@ int lmLogSync(struct jfs_log * log, int nosyncwait)
* reset syncpt = sync * reset syncpt = sync
*/ */
if (log->sync != log->syncpt) { if (log->sync != log->syncpt) {
struct super_block *sb = log->sb; struct jfs_sb_info *sbi;
struct jfs_sb_info *sbi = JFS_SBI(sb);
/* /*
* We need to make sure all of the "written" metapages * We need to make sure all of the "written" metapages
* actually make it to disk * actually make it to disk
*/ */
filemap_fdatawrite(sbi->ipbmap->i_mapping); down(&jfs_log_sem);
filemap_fdatawrite(sbi->ipimap->i_mapping); list_for_each_entry(sbi, &log->sb_list, log_list) {
filemap_fdatawrite(sb->s_bdev->bd_inode->i_mapping); filemap_fdatawrite(sbi->ipbmap->i_mapping);
filemap_fdatawait(sbi->ipbmap->i_mapping); filemap_fdatawrite(sbi->ipimap->i_mapping);
filemap_fdatawait(sbi->ipimap->i_mapping); filemap_fdatawrite(sbi->sb->s_bdev->bd_inode->i_mapping);
filemap_fdatawait(sb->s_bdev->bd_inode->i_mapping); }
list_for_each_entry(sbi, &log->sb_list, log_list) {
filemap_fdatawait(sbi->ipbmap->i_mapping);
filemap_fdatawait(sbi->ipimap->i_mapping);
filemap_fdatawait(sbi->sb->s_bdev->bd_inode->i_mapping);
}
up(&jfs_log_sem);
lrd.logtid = 0; lrd.logtid = 0;
lrd.backchain = 0; lrd.backchain = 0;
...@@ -1061,51 +1076,53 @@ int lmLogSync(struct jfs_log * log, int nosyncwait) ...@@ -1061,51 +1076,53 @@ int lmLogSync(struct jfs_log * log, int nosyncwait)
* *
* serialization: * serialization:
*/ */
int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr) int lmLogOpen(struct super_block *sb)
{ {
int rc; int rc;
struct block_device *bdev; struct block_device *bdev;
struct jfs_log *log; struct jfs_log *log;
struct jfs_sb_info *sbi = JFS_SBI(sb);
if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL))) if (sbi->flag & JFS_NOINTEGRITY)
return open_dummy_log(sb);
if (sbi->mntflag & JFS_INLINELOG)
return open_inline_log(sb);
down(&jfs_log_sem);
list_for_each_entry(log, &jfs_external_logs, journal_list) {
if (log->bdev->bd_dev == sbi->logdev) {
if (memcmp(log->uuid, sbi->loguuid,
sizeof(log->uuid))) {
jfs_warn("wrong uuid on JFS journal\n");
up(&jfs_log_sem);
return -EINVAL;
}
/*
* add file system to log active file system list
*/
if ((rc = lmLogFileSystem(log, sbi, 1))) {
up(&jfs_log_sem);
return rc;
}
goto journal_found;
}
}
if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL))) {
up(&jfs_log_sem);
return -ENOMEM; return -ENOMEM;
}
memset(log, 0, sizeof(struct jfs_log)); memset(log, 0, sizeof(struct jfs_log));
init_waitqueue_head(&log->syncwait); INIT_LIST_HEAD(&log->sb_list);
log->sb = sb; /* This should be a list */
if (!(JFS_SBI(sb)->mntflag & JFS_INLINELOG))
goto externalLog;
/*
* in-line log in host file system
*
* file system to log have 1-to-1 relationship;
*/
set_bit(log_INLINELOG, &log->flag);
log->bdev = sb->s_bdev;
log->base = addressPXD(&JFS_SBI(sb)->logpxd);
log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >>
(L2LOGPSIZE - sb->s_blocksize_bits);
log->l2bsize = sb->s_blocksize_bits;
ASSERT(L2LOGPSIZE >= sb->s_blocksize_bits);
/*
* initialize log.
*/
if ((rc = lmLogInit(log)))
goto free;
goto out;
/* /*
* external log as separate logical volume * external log as separate logical volume
* *
* file systems to log may have n-to-1 relationship; * file systems to log may have n-to-1 relationship;
*/ */
externalLog:
bdev = open_by_devnum(JFS_SBI(sb)->logdev, FMODE_READ|FMODE_WRITE); bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE);
if (IS_ERR(bdev)) { if (IS_ERR(bdev)) {
rc = -PTR_ERR(bdev); rc = -PTR_ERR(bdev);
goto free; goto free;
...@@ -1116,7 +1133,7 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr) ...@@ -1116,7 +1133,7 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr)
} }
log->bdev = bdev; log->bdev = bdev;
memcpy(log->uuid, JFS_SBI(sb)->loguuid, sizeof(log->uuid)); memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid));
/* /*
* initialize log: * initialize log:
...@@ -1124,20 +1141,26 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr) ...@@ -1124,20 +1141,26 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr)
if ((rc = lmLogInit(log))) if ((rc = lmLogInit(log)))
goto unclaim; goto unclaim;
list_add(&log->journal_list, &jfs_external_logs);
/* /*
* add file system to log active file system list * add file system to log active file system list
*/ */
if ((rc = lmLogFileSystem(log, JFS_SBI(sb)->uuid, 1))) if ((rc = lmLogFileSystem(log, sbi, 1)))
goto shutdown; goto shutdown;
out: journal_found:
*logptr = log; list_add(&sbi->log_list, &log->sb_list);
sbi->log = log;
up(&jfs_log_sem);
return 0; return 0;
/* /*
* unwind on error * unwind on error
*/ */
shutdown: /* unwind lbmLogInit() */ shutdown: /* unwind lbmLogInit() */
list_del(&log->journal_list);
lbmLogShutdown(log); lbmLogShutdown(log);
unclaim: unclaim:
...@@ -1147,12 +1170,78 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr) ...@@ -1147,12 +1170,78 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr)
blkdev_put(bdev); blkdev_put(bdev);
free: /* free log descriptor */ free: /* free log descriptor */
up(&jfs_log_sem);
kfree(log); kfree(log);
jfs_warn("lmLogOpen: exit(%d)", rc); jfs_warn("lmLogOpen: exit(%d)", rc);
return rc; return rc;
} }
static int open_inline_log(struct super_block *sb)
{
struct jfs_log *log;
int rc;
if (!(log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL)))
return -ENOMEM;
memset(log, 0, sizeof(struct jfs_log));
INIT_LIST_HEAD(&log->sb_list);
set_bit(log_INLINELOG, &log->flag);
log->bdev = sb->s_bdev;
log->base = addressPXD(&JFS_SBI(sb)->logpxd);
log->size = lengthPXD(&JFS_SBI(sb)->logpxd) >>
(L2LOGPSIZE - sb->s_blocksize_bits);
log->l2bsize = sb->s_blocksize_bits;
ASSERT(L2LOGPSIZE >= sb->s_blocksize_bits);
/*
* initialize log.
*/
if ((rc = lmLogInit(log))) {
kfree(log);
jfs_warn("lmLogOpen: exit(%d)", rc);
return rc;
}
list_add(&JFS_SBI(sb)->log_list, &log->sb_list);
JFS_SBI(sb)->log = log;
return rc;
}
static int open_dummy_log(struct super_block *sb)
{
int rc;
down(&jfs_log_sem);
if (!dummy_log) {
dummy_log = kmalloc(sizeof(struct jfs_log), GFP_KERNEL);
if (!dummy_log) {
up(&jfs_log_sem);
return -ENOMEM;
}
memset(dummy_log, 0, sizeof(struct jfs_log));
INIT_LIST_HEAD(&dummy_log->sb_list);
dummy_log->no_integrity = 1;
/* Make up some stuff */
dummy_log->base = 0;
dummy_log->size = 1024;
rc = lmLogInit(dummy_log);
if (rc) {
kfree(dummy_log);
dummy_log = NULL;
up(&jfs_log_sem);
return rc;
}
}
list_add(&JFS_SBI(sb)->log_list, &dummy_log->sb_list);
JFS_SBI(sb)->log = dummy_log;
up(&jfs_log_sem);
return 0;
}
/* /*
* NAME: lmLogInit() * NAME: lmLogInit()
...@@ -1160,7 +1249,7 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr) ...@@ -1160,7 +1249,7 @@ int lmLogOpen(struct super_block *sb, struct jfs_log ** logptr)
* FUNCTION: log initialization at first log open. * FUNCTION: log initialization at first log open.
* *
* logredo() (or logformat()) should have been run previously. * logredo() (or logformat()) should have been run previously.
* initialize the log inode from log superblock. * initialize the log from log superblock.
* set the log state in the superblock to LOGMOUNT and * set the log state in the superblock to LOGMOUNT and
* write SYNCPT log record. * write SYNCPT log record.
* *
...@@ -1180,14 +1269,26 @@ int lmLogInit(struct jfs_log * log) ...@@ -1180,14 +1269,26 @@ int lmLogInit(struct jfs_log * log)
struct lbuf *bpsuper; struct lbuf *bpsuper;
struct lbuf *bp; struct lbuf *bp;
struct logpage *lp; struct logpage *lp;
int lsn; int lsn = 0;
jfs_info("lmLogInit: log:0x%p", log); jfs_info("lmLogInit: log:0x%p", log);
/* /* initialize the group commit serialization lock */
* log inode is overlaid on generic inode where LOGGC_LOCK_INIT(log);
* dinode have been zeroed out by iRead();
*/ /* allocate/initialize the log write serialization lock */
LOG_LOCK_INIT(log);
LOGSYNC_LOCK_INIT(log);
INIT_LIST_HEAD(&log->synclist);
init_waitqueue_head(&log->syncwait);
log->cqueue.head = log->cqueue.tail = NULL;
log->flush_tblk = NULL;
log->count = 0;
/* /*
* initialize log i/o * initialize log i/o
...@@ -1195,111 +1296,121 @@ int lmLogInit(struct jfs_log * log) ...@@ -1195,111 +1296,121 @@ int lmLogInit(struct jfs_log * log)
if ((rc = lbmLogInit(log))) if ((rc = lbmLogInit(log)))
return rc; return rc;
/*
* validate log superblock
*/
if (!test_bit(log_INLINELOG, &log->flag)) if (!test_bit(log_INLINELOG, &log->flag))
log->l2bsize = 12; /* XXX kludge alert XXX */ log->l2bsize = L2LOGPSIZE;
if ((rc = lbmRead(log, 1, &bpsuper)))
goto errout10; /* check for disabled journaling to disk */
if (log->no_integrity) {
logsuper = (struct logsuper *) bpsuper->l_ldata; /*
* Journal pages will still be filled. When the time comes
if (logsuper->magic != cpu_to_le32(LOGMAGIC)) { * to actually do the I/O, the write is not done, and the
jfs_warn("*** Log Format Error ! ***"); * endio routine is called directly.
rc = -EINVAL; */
goto errout20; bp = lbmAllocate(log , 0);
} log->bp = bp;
bp->l_pn = bp->l_eor = 0;
} else {
/*
* validate log superblock
*/
if ((rc = lbmRead(log, 1, &bpsuper)))
goto errout10;
/* logredo() should have been run successfully. */ logsuper = (struct logsuper *) bpsuper->l_ldata;
if (logsuper->state != cpu_to_le32(LOGREDONE)) {
jfs_warn("*** Log Is Dirty ! ***");
rc = -EINVAL;
goto errout20;
}
/* initialize log inode from log superblock */ if (logsuper->magic != cpu_to_le32(LOGMAGIC)) {
if (test_bit(log_INLINELOG,&log->flag)) { jfs_warn("*** Log Format Error ! ***");
if (log->size != le32_to_cpu(logsuper->size)) {
rc = -EINVAL; rc = -EINVAL;
goto errout20; goto errout20;
} }
jfs_info("lmLogInit: inline log:0x%p base:0x%Lx size:0x%x",
log, (unsigned long long) log->base, log->size); /* logredo() should have been run successfully. */
} else { if (logsuper->state != cpu_to_le32(LOGREDONE)) {
if (memcmp(logsuper->uuid, log->uuid, 16)) { jfs_warn("*** Log Is Dirty ! ***");
jfs_warn("wrong uuid on JFS log device"); rc = -EINVAL;
goto errout20; goto errout20;
} }
log->size = le32_to_cpu(logsuper->size);
log->l2bsize = le32_to_cpu(logsuper->l2bsize);
jfs_info("lmLogInit: external log:0x%p base:0x%Lx size:0x%x",
log, (unsigned long long) log->base, log->size);
}
log->page = le32_to_cpu(logsuper->end) / LOGPSIZE; /* initialize log from log superblock */
log->eor = le32_to_cpu(logsuper->end) - (LOGPSIZE * log->page); if (test_bit(log_INLINELOG,&log->flag)) {
if (log->size != le32_to_cpu(logsuper->size)) {
/* check for disabled journaling to disk */ rc = -EINVAL;
if (JFS_SBI(log->sb)->flag & JFS_NOINTEGRITY) { goto errout20;
log->no_integrity = 1; }
log->ni_page = log->page; jfs_info("lmLogInit: inline log:0x%p base:0x%Lx "
log->ni_eor = log->eor; "size:0x%x", log,
} (unsigned long long) log->base, log->size);
else } else {
log->no_integrity = 0; if (memcmp(logsuper->uuid, log->uuid, 16)) {
jfs_warn("wrong uuid on JFS log device");
goto errout20;
}
log->size = le32_to_cpu(logsuper->size);
log->l2bsize = le32_to_cpu(logsuper->l2bsize);
jfs_info("lmLogInit: external log:0x%p base:0x%Lx "
"size:0x%x", log,
(unsigned long long) log->base, log->size);
}
/* log->page = le32_to_cpu(logsuper->end) / LOGPSIZE;
* initialize for log append write mode log->eor = le32_to_cpu(logsuper->end) - (LOGPSIZE * log->page);
*/
/* establish current/end-of-log page/buffer */
if ((rc = lbmRead(log, log->page, &bp)))
goto errout20;
lp = (struct logpage *) bp->l_ldata; /*
* initialize for log append write mode
*/
/* establish current/end-of-log page/buffer */
if ((rc = lbmRead(log, log->page, &bp)))
goto errout20;
jfs_info("lmLogInit: lsn:0x%x page:%d eor:%d:%d", lp = (struct logpage *) bp->l_ldata;
le32_to_cpu(logsuper->end), log->page, log->eor,
le16_to_cpu(lp->h.eor));
// ASSERT(log->eor == lp->h.eor); jfs_info("lmLogInit: lsn:0x%x page:%d eor:%d:%d",
le32_to_cpu(logsuper->end), log->page, log->eor,
le16_to_cpu(lp->h.eor));
log->bp = bp; /* if current page is full, move on to next page */
bp->l_pn = log->page; if (log->eor >= LOGPSIZE - LOGPTLRSIZE)
bp->l_eor = log->eor; lmNextPage(log);
/* initialize the group commit serialization lock */ log->bp = bp;
LOGGC_LOCK_INIT(log); bp->l_pn = log->page;
bp->l_eor = log->eor;
/* if current page is full, move on to next page */
if (log->eor >= LOGPSIZE - LOGPTLRSIZE)
lmNextPage(log);
/* allocate/initialize the log write serialization lock */ /*
LOG_LOCK_INIT(log); * initialize log syncpoint
*/
/*
* write the first SYNCPT record with syncpoint = 0
* (i.e., log redo up to HERE !);
* remove current page from lbm write queue at end of pageout
* (to write log superblock update), but do not release to
* freelist;
*/
lrd.logtid = 0;
lrd.backchain = 0;
lrd.type = cpu_to_le16(LOG_SYNCPT);
lrd.length = 0;
lrd.log.syncpt.sync = 0;
lsn = lmWriteRecord(log, NULL, &lrd, NULL);
bp = log->bp;
bp->l_ceor = bp->l_eor;
lp = (struct logpage *) bp->l_ldata;
lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
lbmWrite(log, bp, lbmWRITE | lbmSYNC, 0);
if ((rc = lbmIOWait(bp, 0)))
goto errout30;
/* /*
* initialize log syncpoint * update/write superblock
*/ */
/* logsuper->state = cpu_to_le32(LOGMOUNT);
* write the first SYNCPT record with syncpoint = 0 log->serial = le32_to_cpu(logsuper->serial) + 1;
* (i.e., log redo up to HERE !); logsuper->serial = cpu_to_le32(log->serial);
* remove current page from lbm write queue at end of pageout lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
* (to write log superblock update), but do not release to freelist; if ((rc = lbmIOWait(bpsuper, lbmFREE)))
*/ goto errout30;
lrd.logtid = 0; }
lrd.backchain = 0;
lrd.type = cpu_to_le16(LOG_SYNCPT);
lrd.length = 0;
lrd.log.syncpt.sync = 0;
lsn = lmWriteRecord(log, NULL, &lrd, NULL);
bp = log->bp;
bp->l_ceor = bp->l_eor;
lp = (struct logpage *) bp->l_ldata;
lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
lbmWrite(log, bp, lbmWRITE | lbmSYNC, 0);
if ((rc = lbmIOWait(bp, 0)))
goto errout30;
/* initialize logsync parameters */ /* initialize logsync parameters */
log->logsize = (log->size - 2) << L2LOGPSIZE; log->logsize = (log->size - 2) << L2LOGPSIZE;
...@@ -1311,30 +1422,11 @@ int lmLogInit(struct jfs_log * log) ...@@ -1311,30 +1422,11 @@ int lmLogInit(struct jfs_log * log)
jfs_info("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x", jfs_info("lmLogInit: lsn:0x%x syncpt:0x%x sync:0x%x",
log->lsn, log->syncpt, log->sync); log->lsn, log->syncpt, log->sync);
LOGSYNC_LOCK_INIT(log);
INIT_LIST_HEAD(&log->synclist);
log->cqueue.head = log->cqueue.tail = NULL;
log->flush_tblk = NULL;
log->count = 0;
/* /*
* initialize for lazy/group commit * initialize for lazy/group commit
*/ */
log->clsn = lsn; log->clsn = lsn;
/*
* update/write superblock
*/
logsuper->state = cpu_to_le32(LOGMOUNT);
log->serial = le32_to_cpu(logsuper->serial) + 1;
logsuper->serial = cpu_to_le32(log->serial);
lbmDirectWrite(log, bpsuper, lbmWRITE | lbmRELEASE | lbmSYNC);
if ((rc = lbmIOWait(bpsuper, lbmFREE)))
goto errout30;
return 0; return 0;
/* /*
...@@ -1361,39 +1453,66 @@ int lmLogInit(struct jfs_log * log) ...@@ -1361,39 +1453,66 @@ int lmLogInit(struct jfs_log * log)
* and close it on last close. * and close it on last close.
* *
* PARAMETER: sb - superblock * PARAMETER: sb - superblock
* log - log inode
* *
* RETURN: errors from subroutines * RETURN: errors from subroutines
* *
* serialization: * serialization:
*/ */
int lmLogClose(struct super_block *sb, struct jfs_log * log) int lmLogClose(struct super_block *sb)
{ {
struct block_device *bdev = log->bdev; struct jfs_sb_info *sbi = JFS_SBI(sb);
int rc; struct jfs_log *log = sbi->log;
struct block_device *bdev;
int rc = 0;
jfs_info("lmLogClose: log:0x%p", log); jfs_info("lmLogClose: log:0x%p", log);
if (!test_bit(log_INLINELOG, &log->flag)) down(&jfs_log_sem);
goto externalLog; list_del(&sbi->log_list);
sbi->log = NULL;
/* /*
* in-line log in host file system * We need to make sure all of the "written" metapages
* actually make it to disk
*/ */
rc = lmLogShutdown(log); sync_blockdev(sb->s_bdev);
goto out;
if (test_bit(log_INLINELOG, &log->flag)) {
/*
* in-line log in host file system
*/
rc = lmLogShutdown(log);
goto out;
}
if (!log->no_integrity)
lmLogFileSystem(log, sbi, 0);
if (!list_empty(&log->sb_list))
goto out;
/*
* TODO: ensure that the dummy_log is in a state to allow
* lbmLogShutdown to deallocate all the buffers and call
* kfree against dummy_log. For now, leave dummy_log & its
* buffers in memory, and resuse if another no-integrity mount
* is requested.
*/
if (log->no_integrity)
goto out;
/* /*
* external log as separate logical volume * external log as separate logical volume
*/ */
externalLog: list_del(&log->journal_list);
lmLogFileSystem(log, JFS_SBI(sb)->uuid, 0); bdev = log->bdev;
rc = lmLogShutdown(log); rc = lmLogShutdown(log);
bd_release(bdev); bd_release(bdev);
blkdev_put(bdev); blkdev_put(bdev);
out: out:
up(&jfs_log_sem);
jfs_info("lmLogClose: exit(%d)", rc); jfs_info("lmLogClose: exit(%d)", rc);
return rc; return rc;
} }
...@@ -1521,12 +1640,6 @@ int lmLogShutdown(struct jfs_log * log) ...@@ -1521,12 +1640,6 @@ int lmLogShutdown(struct jfs_log * log)
jfs_flush_journal(log, 2); jfs_flush_journal(log, 2);
/*
* We need to make sure all of the "written" metapages
* actually make it to disk
*/
sync_blockdev(log->sb->s_bdev);
/* /*
* write the last SYNCPT record with syncpoint = 0 * write the last SYNCPT record with syncpoint = 0
* (i.e., log redo up to HERE !) * (i.e., log redo up to HERE !)
...@@ -1537,13 +1650,6 @@ int lmLogShutdown(struct jfs_log * log) ...@@ -1537,13 +1650,6 @@ int lmLogShutdown(struct jfs_log * log)
lrd.length = 0; lrd.length = 0;
lrd.log.syncpt.sync = 0; lrd.log.syncpt.sync = 0;
/* check for disabled journaling to disk */
if (JFS_SBI(log->sb)->flag & JFS_NOINTEGRITY) {
log->no_integrity = 0;
log->page = log->ni_page;
log->eor = log->ni_eor;
}
lsn = lmWriteRecord(log, NULL, &lrd, NULL); lsn = lmWriteRecord(log, NULL, &lrd, NULL);
bp = log->bp; bp = log->bp;
lp = (struct logpage *) bp->l_ldata; lp = (struct logpage *) bp->l_ldata;
...@@ -1595,12 +1701,14 @@ int lmLogShutdown(struct jfs_log * log) ...@@ -1595,12 +1701,14 @@ int lmLogShutdown(struct jfs_log * log)
* RETURN: 0 - success * RETURN: 0 - success
* errors returned by vms_iowait(). * errors returned by vms_iowait().
*/ */
static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate) static int lmLogFileSystem(struct jfs_log * log, struct jfs_sb_info *sbi,
int activate)
{ {
int rc = 0; int rc = 0;
int i; int i;
struct logsuper *logsuper; struct logsuper *logsuper;
struct lbuf *bpsuper; struct lbuf *bpsuper;
char *uuid = sbi->uuid;
/* /*
* insert/remove file system device to log active file system list. * insert/remove file system device to log active file system list.
...@@ -1613,6 +1721,7 @@ static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate) ...@@ -1613,6 +1721,7 @@ static int lmLogFileSystem(struct jfs_log * log, char *uuid, int activate)
for (i = 0; i < MAX_ACTIVE; i++) for (i = 0; i < MAX_ACTIVE; i++)
if (!memcmp(logsuper->active[i].uuid, NULL_UUID, 16)) { if (!memcmp(logsuper->active[i].uuid, NULL_UUID, 16)) {
memcpy(logsuper->active[i].uuid, uuid, 16); memcpy(logsuper->active[i].uuid, uuid, 16);
sbi->aggregate = i;
break; break;
} }
if (i == MAX_ACTIVE) { if (i == MAX_ACTIVE) {
...@@ -2251,7 +2360,7 @@ int jfsIOWait(void *arg) ...@@ -2251,7 +2360,7 @@ int jfsIOWait(void *arg)
int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize) int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
{ {
int rc = -EIO; int rc = -EIO;
struct jfs_sb_info *sbi = JFS_SBI(log->sb); struct jfs_sb_info *sbi;
struct logsuper *logsuper; struct logsuper *logsuper;
struct logpage *lp; struct logpage *lp;
int lspn; /* log sequence page number */ int lspn; /* log sequence page number */
...@@ -2262,6 +2371,8 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize) ...@@ -2262,6 +2371,8 @@ int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize)
jfs_info("lmLogFormat: logAddress:%Ld logSize:%d", jfs_info("lmLogFormat: logAddress:%Ld logSize:%d",
(long long)logAddress, logSize); (long long)logAddress, logSize);
sbi = list_entry(log->sb_list.next, struct jfs_sb_info, log_list);
/* allocate a log buffer */ /* allocate a log buffer */
bp = lbmAllocate(log, 1); bp = lbmAllocate(log, 1);
......
/* /*
* Copyright (c) International Business Machines Corp., 2000-2003 * Copyright (C) International Business Machines Corp., 2000-2004
* Portions Copyright (c) Christoph Hellwig, 2001-2002 * Portions Copyright (C) Christoph Hellwig, 2001-2002
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -367,11 +367,10 @@ struct lvd { ...@@ -367,11 +367,10 @@ struct lvd {
*/ */
struct jfs_log { struct jfs_log {
struct super_block *sb; /* 4: This is used to sync metadata struct list_head sb_list;/* This is used to sync metadata
* before writing syncpt. Will * before writing syncpt.
* need to be a list if we share
* the log between fs's
*/ */
struct list_head journal_list; /* Global list */
struct block_device *bdev; /* 4: log lv pointer */ struct block_device *bdev; /* 4: log lv pointer */
s32 serial; /* 4: log mount serial number */ s32 serial; /* 4: log mount serial number */
...@@ -419,8 +418,6 @@ struct jfs_log { ...@@ -419,8 +418,6 @@ struct jfs_log {
char uuid[16]; /* 16: 128-bit uuid of log device */ char uuid[16]; /* 16: 128-bit uuid of log device */
int no_integrity; /* 3: flag to disable journaling to disk */ int no_integrity; /* 3: flag to disable journaling to disk */
int ni_page; /* 4: backup of page for nointegrity option */
int ni_eor; /* 4: backup of eor for nointegrity option */
}; };
/* /*
...@@ -506,8 +503,8 @@ struct logsyncblk { ...@@ -506,8 +503,8 @@ struct logsyncblk {
diff += (log)->logsize;\ diff += (log)->logsize;\
} }
extern int lmLogOpen(struct super_block *sb, struct jfs_log ** log); extern int lmLogOpen(struct super_block *sb);
extern int lmLogClose(struct super_block *sb, struct jfs_log * log); extern int lmLogClose(struct super_block *sb);
extern int lmLogSync(struct jfs_log * log, int nosyncwait); extern int lmLogSync(struct jfs_log * log, int nosyncwait);
extern int lmLogShutdown(struct jfs_log * log); extern int lmLogShutdown(struct jfs_log * log);
extern int lmLogInit(struct jfs_log * log); extern int lmLogInit(struct jfs_log * log);
......
/* /*
* Copyright (c) International Business Machines Corp., 2000-2003 * Copyright (C) International Business Machines Corp., 2000-2004
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -242,7 +242,6 @@ int jfs_mount(struct super_block *sb) ...@@ -242,7 +242,6 @@ int jfs_mount(struct super_block *sb)
int jfs_mount_rw(struct super_block *sb, int remount) int jfs_mount_rw(struct super_block *sb, int remount)
{ {
struct jfs_sb_info *sbi = JFS_SBI(sb); struct jfs_sb_info *sbi = JFS_SBI(sb);
struct jfs_log *log;
int rc; int rc;
/* /*
...@@ -272,18 +271,15 @@ int jfs_mount_rw(struct super_block *sb, int remount) ...@@ -272,18 +271,15 @@ int jfs_mount_rw(struct super_block *sb, int remount)
/* /*
* open/initialize log * open/initialize log
*/ */
if ((rc = lmLogOpen(sb, &log))) if ((rc = lmLogOpen(sb)))
return rc; return rc;
JFS_SBI(sb)->log = log;
/* /*
* update file system superblock; * update file system superblock;
*/ */
if ((rc = updateSuper(sb, FM_MOUNT))) { if ((rc = updateSuper(sb, FM_MOUNT))) {
jfs_err("jfs_mount: updateSuper failed w/rc = %d", rc); jfs_err("jfs_mount: updateSuper failed w/rc = %d", rc);
lmLogClose(sb, log); lmLogClose(sb);
JFS_SBI(sb)->log = 0;
return rc; return rc;
} }
......
/* /*
* Copyright (C) International Business Machines Corp., 2000-2003 * Copyright (C) International Business Machines Corp., 2000-2004
* Portions Copyright (C) Christoph Hellwig, 2001-2002 * Portions Copyright (C) Christoph Hellwig, 2001-2002
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -1354,7 +1354,7 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd) ...@@ -1354,7 +1354,7 @@ static int txLog(struct jfs_log * log, struct tblock * tblk, struct commit * cd)
/* initialize lrd common */ /* initialize lrd common */
ip = tlck->ip; ip = tlck->ip;
lrd->aggregate = cpu_to_le32(new_encode_dev(ip->i_sb->s_bdev->bd_dev)); lrd->aggregate = cpu_to_le32(JFS_SBI(ip->i_sb)->aggregate);
lrd->log.redopage.fileset = cpu_to_le32(JFS_IP(ip)->fileset); lrd->log.redopage.fileset = cpu_to_le32(JFS_IP(ip)->fileset);
lrd->log.redopage.inode = cpu_to_le32(ip->i_ino); lrd->log.redopage.inode = cpu_to_le32(ip->i_ino);
......
/* /*
* Copyright (c) International Business Machines Corp., 2000-2002 * Copyright (C) International Business Machines Corp., 2000-2004
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
...@@ -128,7 +128,7 @@ int jfs_umount(struct super_block *sb) ...@@ -128,7 +128,7 @@ int jfs_umount(struct super_block *sb)
* *
* remove file system from log active file system list. * remove file system from log active file system list.
*/ */
rc = lmLogClose(sb, log); rc = lmLogClose(sb);
} }
jfs_info("UnMount JFS Complete: rc = %d", rc); jfs_info("UnMount JFS Complete: rc = %d", rc);
return rc; return rc;
...@@ -167,7 +167,6 @@ int jfs_umount_rw(struct super_block *sb) ...@@ -167,7 +167,6 @@ int jfs_umount_rw(struct super_block *sb)
filemap_fdatawait(bdev_mapping); filemap_fdatawait(bdev_mapping);
updateSuper(sb, FM_CLEAN); updateSuper(sb, FM_CLEAN);
sbi->log = NULL;
return lmLogClose(sb, log); return lmLogClose(sb);
} }
...@@ -381,6 +381,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -381,6 +381,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
return -ENOSPC; return -ENOSPC;
memset(sbi, 0, sizeof (struct jfs_sb_info)); memset(sbi, 0, sizeof (struct jfs_sb_info));
sb->s_fs_info = sbi; sb->s_fs_info = sbi;
sbi->sb = sb;
/* initialize the mount flag and determine the default error handler */ /* initialize the mount flag and determine the default error handler */
flag = JFS_ERR_REMOUNT_RO; flag = JFS_ERR_REMOUNT_RO;
......
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