aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jfs/jfs_logmgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jfs/jfs_logmgr.c')
-rw-r--r--fs/jfs/jfs_logmgr.c150
1 files changed, 90 insertions, 60 deletions
diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c
index b6a6869ebb4f..dfa1200daa61 100644
--- a/fs/jfs/jfs_logmgr.c
+++ b/fs/jfs/jfs_logmgr.c
@@ -234,6 +234,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
234 int lsn; 234 int lsn;
235 int diffp, difft; 235 int diffp, difft;
236 struct metapage *mp = NULL; 236 struct metapage *mp = NULL;
237 unsigned long flags;
237 238
238 jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p", 239 jfs_info("lmLog: log:0x%p tblk:0x%p, lrd:0x%p tlck:0x%p",
239 log, tblk, lrd, tlck); 240 log, tblk, lrd, tlck);
@@ -254,7 +255,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
254 */ 255 */
255 lsn = log->lsn; 256 lsn = log->lsn;
256 257
257 LOGSYNC_LOCK(log); 258 LOGSYNC_LOCK(log, flags);
258 259
259 /* 260 /*
260 * initialize page lsn if first log write of the page 261 * initialize page lsn if first log write of the page
@@ -310,7 +311,7 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
310 } 311 }
311 } 312 }
312 313
313 LOGSYNC_UNLOCK(log); 314 LOGSYNC_UNLOCK(log, flags);
314 315
315 /* 316 /*
316 * write the log record 317 * write the log record
@@ -334,7 +335,6 @@ int lmLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
334 return lsn; 335 return lsn;
335} 336}
336 337
337
338/* 338/*
339 * NAME: lmWriteRecord() 339 * NAME: lmWriteRecord()
340 * 340 *
@@ -927,9 +927,8 @@ static void lmPostGC(struct lbuf * bp)
927 * calculate new value of i_nextsync which determines when 927 * calculate new value of i_nextsync which determines when
928 * this code is called again. 928 * this code is called again.
929 * 929 *
930 * this is called only from lmLog(). 930 * PARAMETERS: log - log structure
931 * 931 * nosyncwait - 1 if called asynchronously
932 * PARAMETER: ip - pointer to logs inode.
933 * 932 *
934 * RETURN: 0 933 * RETURN: 0
935 * 934 *
@@ -945,6 +944,15 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
945 struct lrd lrd; 944 struct lrd lrd;
946 int lsn; 945 int lsn;
947 struct logsyncblk *lp; 946 struct logsyncblk *lp;
947 struct jfs_sb_info *sbi;
948 unsigned long flags;
949
950 /* push dirty metapages out to disk */
951 list_for_each_entry(sbi, &log->sb_list, log_list) {
952 filemap_flush(sbi->ipbmap->i_mapping);
953 filemap_flush(sbi->ipimap->i_mapping);
954 filemap_flush(sbi->direct_inode->i_mapping);
955 }
948 956
949 /* 957 /*
950 * forward syncpt 958 * forward syncpt
@@ -954,10 +962,7 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
954 */ 962 */
955 963
956 if (log->sync == log->syncpt) { 964 if (log->sync == log->syncpt) {
957 LOGSYNC_LOCK(log); 965 LOGSYNC_LOCK(log, flags);
958 /* ToDo: push dirty metapages out to disk */
959// bmLogSync(log);
960
961 if (list_empty(&log->synclist)) 966 if (list_empty(&log->synclist))
962 log->sync = log->lsn; 967 log->sync = log->lsn;
963 else { 968 else {
@@ -965,7 +970,7 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
965 struct logsyncblk, synclist); 970 struct logsyncblk, synclist);
966 log->sync = lp->lsn; 971 log->sync = lp->lsn;
967 } 972 }
968 LOGSYNC_UNLOCK(log); 973 LOGSYNC_UNLOCK(log, flags);
969 974
970 } 975 }
971 976
@@ -974,27 +979,6 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
974 * reset syncpt = sync 979 * reset syncpt = sync
975 */ 980 */
976 if (log->sync != log->syncpt) { 981 if (log->sync != log->syncpt) {
977 struct jfs_sb_info *sbi;
978
979 /*
980 * We need to make sure all of the "written" metapages
981 * actually make it to disk
982 */
983 list_for_each_entry(sbi, &log->sb_list, log_list) {
984 if (sbi->flag & JFS_NOINTEGRITY)
985 continue;
986 filemap_fdatawrite(sbi->ipbmap->i_mapping);
987 filemap_fdatawrite(sbi->ipimap->i_mapping);
988 filemap_fdatawrite(sbi->sb->s_bdev->bd_inode->i_mapping);
989 }
990 list_for_each_entry(sbi, &log->sb_list, log_list) {
991 if (sbi->flag & JFS_NOINTEGRITY)
992 continue;
993 filemap_fdatawait(sbi->ipbmap->i_mapping);
994 filemap_fdatawait(sbi->ipimap->i_mapping);
995 filemap_fdatawait(sbi->sb->s_bdev->bd_inode->i_mapping);
996 }
997
998 lrd.logtid = 0; 982 lrd.logtid = 0;
999 lrd.backchain = 0; 983 lrd.backchain = 0;
1000 lrd.type = cpu_to_le16(LOG_SYNCPT); 984 lrd.type = cpu_to_le16(LOG_SYNCPT);
@@ -1066,6 +1050,18 @@ static int lmLogSync(struct jfs_log * log, int nosyncwait)
1066 return lsn; 1050 return lsn;
1067} 1051}
1068 1052
1053/*
1054 * NAME: jfs_syncpt
1055 *
1056 * FUNCTION: write log SYNCPT record for specified log
1057 *
1058 * PARAMETERS: log - log structure
1059 */
1060void jfs_syncpt(struct jfs_log *log)
1061{ LOG_LOCK(log);
1062 lmLogSync(log, 1);
1063 LOG_UNLOCK(log);
1064}
1069 1065
1070/* 1066/*
1071 * NAME: lmLogOpen() 1067 * NAME: lmLogOpen()
@@ -1547,6 +1543,7 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
1547{ 1543{
1548 int i; 1544 int i;
1549 struct tblock *target = NULL; 1545 struct tblock *target = NULL;
1546 struct jfs_sb_info *sbi;
1550 1547
1551 /* jfs_write_inode may call us during read-only mount */ 1548 /* jfs_write_inode may call us during read-only mount */
1552 if (!log) 1549 if (!log)
@@ -1608,12 +1605,18 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
1608 if (wait < 2) 1605 if (wait < 2)
1609 return; 1606 return;
1610 1607
1608 list_for_each_entry(sbi, &log->sb_list, log_list) {
1609 filemap_fdatawrite(sbi->ipbmap->i_mapping);
1610 filemap_fdatawrite(sbi->ipimap->i_mapping);
1611 filemap_fdatawrite(sbi->direct_inode->i_mapping);
1612 }
1613
1611 /* 1614 /*
1612 * If there was recent activity, we may need to wait 1615 * If there was recent activity, we may need to wait
1613 * for the lazycommit thread to catch up 1616 * for the lazycommit thread to catch up
1614 */ 1617 */
1615 if ((!list_empty(&log->cqueue)) || !list_empty(&log->synclist)) { 1618 if ((!list_empty(&log->cqueue)) || !list_empty(&log->synclist)) {
1616 for (i = 0; i < 800; i++) { /* Too much? */ 1619 for (i = 0; i < 200; i++) { /* Too much? */
1617 msleep(250); 1620 msleep(250);
1618 if (list_empty(&log->cqueue) && 1621 if (list_empty(&log->cqueue) &&
1619 list_empty(&log->synclist)) 1622 list_empty(&log->synclist))
@@ -1621,7 +1624,24 @@ void jfs_flush_journal(struct jfs_log *log, int wait)
1621 } 1624 }
1622 } 1625 }
1623 assert(list_empty(&log->cqueue)); 1626 assert(list_empty(&log->cqueue));
1624 assert(list_empty(&log->synclist)); 1627 if (!list_empty(&log->synclist)) {
1628 struct logsyncblk *lp;
1629
1630 list_for_each_entry(lp, &log->synclist, synclist) {
1631 if (lp->xflag & COMMIT_PAGE) {
1632 struct metapage *mp = (struct metapage *)lp;
1633 dump_mem("orphan metapage", lp,
1634 sizeof(struct metapage));
1635 dump_mem("page", mp->page, sizeof(struct page));
1636 }
1637 else
1638 dump_mem("orphan tblock", lp,
1639 sizeof(struct tblock));
1640 }
1641// current->state = TASK_INTERRUPTIBLE;
1642// schedule();
1643 }
1644 //assert(list_empty(&log->synclist));
1625 clear_bit(log_FLUSH, &log->flag); 1645 clear_bit(log_FLUSH, &log->flag);
1626} 1646}
1627 1647
@@ -1669,6 +1689,7 @@ int lmLogShutdown(struct jfs_log * log)
1669 lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor); 1689 lp->h.eor = lp->t.eor = cpu_to_le16(bp->l_eor);
1670 lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0); 1690 lbmWrite(log, log->bp, lbmWRITE | lbmRELEASE | lbmSYNC, 0);
1671 lbmIOWait(log->bp, lbmFREE); 1691 lbmIOWait(log->bp, lbmFREE);
1692 log->bp = NULL;
1672 1693
1673 /* 1694 /*
1674 * synchronous update log superblock 1695 * synchronous update log superblock
@@ -1819,20 +1840,34 @@ static int lbmLogInit(struct jfs_log * log)
1819 1840
1820 log->lbuf_free = NULL; 1841 log->lbuf_free = NULL;
1821 1842
1822 for (i = 0; i < LOGPAGES; i++) { 1843 for (i = 0; i < LOGPAGES;) {
1823 lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL); 1844 char *buffer;
1824 if (lbuf == 0) 1845 uint offset;
1825 goto error; 1846 struct page *page;
1826 lbuf->l_ldata = (char *) get_zeroed_page(GFP_KERNEL); 1847
1827 if (lbuf->l_ldata == 0) { 1848 buffer = (char *) get_zeroed_page(GFP_KERNEL);
1828 kfree(lbuf); 1849 if (buffer == NULL)
1829 goto error; 1850 goto error;
1851 page = virt_to_page(buffer);
1852 for (offset = 0; offset < PAGE_SIZE; offset += LOGPSIZE) {
1853 lbuf = kmalloc(sizeof(struct lbuf), GFP_KERNEL);
1854 if (lbuf == NULL) {
1855 if (offset == 0)
1856 free_page((unsigned long) buffer);
1857 goto error;
1858 }
1859 if (offset) /* we already have one reference */
1860 get_page(page);
1861 lbuf->l_offset = offset;
1862 lbuf->l_ldata = buffer + offset;
1863 lbuf->l_page = page;
1864 lbuf->l_log = log;
1865 init_waitqueue_head(&lbuf->l_ioevent);
1866
1867 lbuf->l_freelist = log->lbuf_free;
1868 log->lbuf_free = lbuf;
1869 i++;
1830 } 1870 }
1831 lbuf->l_log = log;
1832 init_waitqueue_head(&lbuf->l_ioevent);
1833
1834 lbuf->l_freelist = log->lbuf_free;
1835 log->lbuf_free = lbuf;
1836 } 1871 }
1837 1872
1838 return (0); 1873 return (0);
@@ -1857,12 +1892,10 @@ static void lbmLogShutdown(struct jfs_log * log)
1857 lbuf = log->lbuf_free; 1892 lbuf = log->lbuf_free;
1858 while (lbuf) { 1893 while (lbuf) {
1859 struct lbuf *next = lbuf->l_freelist; 1894 struct lbuf *next = lbuf->l_freelist;
1860 free_page((unsigned long) lbuf->l_ldata); 1895 __free_page(lbuf->l_page);
1861 kfree(lbuf); 1896 kfree(lbuf);
1862 lbuf = next; 1897 lbuf = next;
1863 } 1898 }
1864
1865 log->bp = NULL;
1866} 1899}
1867 1900
1868 1901
@@ -1974,9 +2007,9 @@ static int lbmRead(struct jfs_log * log, int pn, struct lbuf ** bpp)
1974 2007
1975 bio->bi_sector = bp->l_blkno << (log->l2bsize - 9); 2008 bio->bi_sector = bp->l_blkno << (log->l2bsize - 9);
1976 bio->bi_bdev = log->bdev; 2009 bio->bi_bdev = log->bdev;
1977 bio->bi_io_vec[0].bv_page = virt_to_page(bp->l_ldata); 2010 bio->bi_io_vec[0].bv_page = bp->l_page;
1978 bio->bi_io_vec[0].bv_len = LOGPSIZE; 2011 bio->bi_io_vec[0].bv_len = LOGPSIZE;
1979 bio->bi_io_vec[0].bv_offset = 0; 2012 bio->bi_io_vec[0].bv_offset = bp->l_offset;
1980 2013
1981 bio->bi_vcnt = 1; 2014 bio->bi_vcnt = 1;
1982 bio->bi_idx = 0; 2015 bio->bi_idx = 0;
@@ -2115,9 +2148,9 @@ static void lbmStartIO(struct lbuf * bp)
2115 bio = bio_alloc(GFP_NOFS, 1); 2148 bio = bio_alloc(GFP_NOFS, 1);
2116 bio->bi_sector = bp->l_blkno << (log->l2bsize - 9); 2149 bio->bi_sector = bp->l_blkno << (log->l2bsize - 9);
2117 bio->bi_bdev = log->bdev; 2150 bio->bi_bdev = log->bdev;
2118 bio->bi_io_vec[0].bv_page = virt_to_page(bp->l_ldata); 2151 bio->bi_io_vec[0].bv_page = bp->l_page;
2119 bio->bi_io_vec[0].bv_len = LOGPSIZE; 2152 bio->bi_io_vec[0].bv_len = LOGPSIZE;
2120 bio->bi_io_vec[0].bv_offset = 0; 2153 bio->bi_io_vec[0].bv_offset = bp->l_offset;
2121 2154
2122 bio->bi_vcnt = 1; 2155 bio->bi_vcnt = 1;
2123 bio->bi_idx = 0; 2156 bio->bi_idx = 0;
@@ -2127,16 +2160,13 @@ static void lbmStartIO(struct lbuf * bp)
2127 bio->bi_private = bp; 2160 bio->bi_private = bp;
2128 2161
2129 /* check if journaling to disk has been disabled */ 2162 /* check if journaling to disk has been disabled */
2130 if (!log->no_integrity) { 2163 if (log->no_integrity) {
2164 bio->bi_size = 0;
2165 lbmIODone(bio, 0, 0);
2166 } else {
2131 submit_bio(WRITE_SYNC, bio); 2167 submit_bio(WRITE_SYNC, bio);
2132 INCREMENT(lmStat.submitted); 2168 INCREMENT(lmStat.submitted);
2133 } 2169 }
2134 else {
2135 bio->bi_size = 0;
2136 lbmIODone(bio, 0, 0); /* 2nd argument appears to not be used => 0
2137 * 3rd argument appears to not be used => 0
2138 */
2139 }
2140} 2170}
2141 2171
2142 2172