diff options
Diffstat (limited to 'fs/jfs/jfs_logmgr.c')
-rw-r--r-- | fs/jfs/jfs_logmgr.c | 150 |
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 | */ | ||
1060 | void 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 | ||