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 | ||
