aboutsummaryrefslogtreecommitdiffstats
path: root/fs/jfs
diff options
context:
space:
mode:
Diffstat (limited to 'fs/jfs')
-rw-r--r--fs/jfs/inode.c35
-rw-r--r--fs/jfs/jfs_dmap.c12
-rw-r--r--fs/jfs/jfs_dtree.c6
-rw-r--r--fs/jfs/jfs_imap.c84
-rw-r--r--fs/jfs/jfs_incore.h1
-rw-r--r--fs/jfs/jfs_logmgr.c150
-rw-r--r--fs/jfs/jfs_logmgr.h9
-rw-r--r--fs/jfs/jfs_metapage.c908
-rw-r--r--fs/jfs/jfs_metapage.h80
-rw-r--r--fs/jfs/jfs_mount.c5
-rw-r--r--fs/jfs/jfs_txnmgr.c166
-rw-r--r--fs/jfs/jfs_umount.c16
-rw-r--r--fs/jfs/jfs_xtree.c61
-rw-r--r--fs/jfs/resize.c3
-rw-r--r--fs/jfs/super.c37
15 files changed, 993 insertions, 580 deletions
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 7bc906677b0d..24a689179af2 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -175,31 +175,22 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
175{ 175{
176 s64 lblock64 = lblock; 176 s64 lblock64 = lblock;
177 int rc = 0; 177 int rc = 0;
178 int take_locks;
179 xad_t xad; 178 xad_t xad;
180 s64 xaddr; 179 s64 xaddr;
181 int xflag; 180 int xflag;
182 s32 xlen; 181 s32 xlen = max_blocks;
183
184 /*
185 * If this is a special inode (imap, dmap)
186 * the lock should already be taken
187 */
188 take_locks = (JFS_IP(ip)->fileset != AGGREGATE_I);
189 182
190 /* 183 /*
191 * Take appropriate lock on inode 184 * Take appropriate lock on inode
192 */ 185 */
193 if (take_locks) { 186 if (create)
194 if (create) 187 IWRITE_LOCK(ip);
195 IWRITE_LOCK(ip); 188 else
196 else 189 IREAD_LOCK(ip);
197 IREAD_LOCK(ip);
198 }
199 190
200 if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) && 191 if (((lblock64 << ip->i_sb->s_blocksize_bits) < ip->i_size) &&
201 (xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0) 192 (!xtLookup(ip, lblock64, max_blocks, &xflag, &xaddr, &xlen, 0)) &&
202 == 0) && xlen) { 193 xaddr) {
203 if (xflag & XAD_NOTRECORDED) { 194 if (xflag & XAD_NOTRECORDED) {
204 if (!create) 195 if (!create)
205 /* 196 /*
@@ -238,7 +229,7 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
238#ifdef _JFS_4K 229#ifdef _JFS_4K
239 if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad))) 230 if ((rc = extHint(ip, lblock64 << ip->i_sb->s_blocksize_bits, &xad)))
240 goto unlock; 231 goto unlock;
241 rc = extAlloc(ip, max_blocks, lblock64, &xad, FALSE); 232 rc = extAlloc(ip, xlen, lblock64, &xad, FALSE);
242 if (rc) 233 if (rc)
243 goto unlock; 234 goto unlock;
244 235
@@ -258,12 +249,10 @@ jfs_get_blocks(struct inode *ip, sector_t lblock, unsigned long max_blocks,
258 /* 249 /*
259 * Release lock on inode 250 * Release lock on inode
260 */ 251 */
261 if (take_locks) { 252 if (create)
262 if (create) 253 IWRITE_UNLOCK(ip);
263 IWRITE_UNLOCK(ip); 254 else
264 else 255 IREAD_UNLOCK(ip);
265 IREAD_UNLOCK(ip);
266 }
267 return rc; 256 return rc;
268} 257}
269 258
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index d86e467c6e42..69007fd546ef 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -471,6 +471,7 @@ dbUpdatePMap(struct inode *ipbmap,
471 struct metapage *mp; 471 struct metapage *mp;
472 struct jfs_log *log; 472 struct jfs_log *log;
473 int lsn, difft, diffp; 473 int lsn, difft, diffp;
474 unsigned long flags;
474 475
475 /* the blocks better be within the mapsize. */ 476 /* the blocks better be within the mapsize. */
476 if (blkno + nblocks > bmp->db_mapsize) { 477 if (blkno + nblocks > bmp->db_mapsize) {
@@ -504,6 +505,7 @@ dbUpdatePMap(struct inode *ipbmap,
504 0); 505 0);
505 if (mp == NULL) 506 if (mp == NULL)
506 return -EIO; 507 return -EIO;
508 metapage_wait_for_io(mp);
507 } 509 }
508 dp = (struct dmap *) mp->data; 510 dp = (struct dmap *) mp->data;
509 511
@@ -578,34 +580,32 @@ dbUpdatePMap(struct inode *ipbmap,
578 if (mp->lsn != 0) { 580 if (mp->lsn != 0) {
579 /* inherit older/smaller lsn */ 581 /* inherit older/smaller lsn */
580 logdiff(diffp, mp->lsn, log); 582 logdiff(diffp, mp->lsn, log);
583 LOGSYNC_LOCK(log, flags);
581 if (difft < diffp) { 584 if (difft < diffp) {
582 mp->lsn = lsn; 585 mp->lsn = lsn;
583 586
584 /* move bp after tblock in logsync list */ 587 /* move bp after tblock in logsync list */
585 LOGSYNC_LOCK(log);
586 list_move(&mp->synclist, &tblk->synclist); 588 list_move(&mp->synclist, &tblk->synclist);
587 LOGSYNC_UNLOCK(log);
588 } 589 }
589 590
590 /* inherit younger/larger clsn */ 591 /* inherit younger/larger clsn */
591 LOGSYNC_LOCK(log);
592 logdiff(difft, tblk->clsn, log); 592 logdiff(difft, tblk->clsn, log);
593 logdiff(diffp, mp->clsn, log); 593 logdiff(diffp, mp->clsn, log);
594 if (difft > diffp) 594 if (difft > diffp)
595 mp->clsn = tblk->clsn; 595 mp->clsn = tblk->clsn;
596 LOGSYNC_UNLOCK(log); 596 LOGSYNC_UNLOCK(log, flags);
597 } else { 597 } else {
598 mp->log = log; 598 mp->log = log;
599 mp->lsn = lsn; 599 mp->lsn = lsn;
600 600
601 /* insert bp after tblock in logsync list */ 601 /* insert bp after tblock in logsync list */
602 LOGSYNC_LOCK(log); 602 LOGSYNC_LOCK(log, flags);
603 603
604 log->count++; 604 log->count++;
605 list_add(&mp->synclist, &tblk->synclist); 605 list_add(&mp->synclist, &tblk->synclist);
606 606
607 mp->clsn = tblk->clsn; 607 mp->clsn = tblk->clsn;
608 LOGSYNC_UNLOCK(log); 608 LOGSYNC_UNLOCK(log, flags);
609 } 609 }
610 } 610 }
611 611
diff --git a/fs/jfs/jfs_dtree.c b/fs/jfs/jfs_dtree.c
index e357890adfb2..ac41f72d6d50 100644
--- a/fs/jfs/jfs_dtree.c
+++ b/fs/jfs/jfs_dtree.c
@@ -212,7 +212,7 @@ static struct metapage *read_index_page(struct inode *inode, s64 blkno)
212 s32 xlen; 212 s32 xlen;
213 213
214 rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); 214 rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
215 if (rc || (xlen == 0)) 215 if (rc || (xaddr == 0))
216 return NULL; 216 return NULL;
217 217
218 return read_metapage(inode, xaddr, PSIZE, 1); 218 return read_metapage(inode, xaddr, PSIZE, 1);
@@ -231,7 +231,7 @@ static struct metapage *get_index_page(struct inode *inode, s64 blkno)
231 s32 xlen; 231 s32 xlen;
232 232
233 rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1); 233 rc = xtLookup(inode, blkno, 1, &xflag, &xaddr, &xlen, 1);
234 if (rc || (xlen == 0)) 234 if (rc || (xaddr == 0))
235 return NULL; 235 return NULL;
236 236
237 return get_metapage(inode, xaddr, PSIZE, 1); 237 return get_metapage(inode, xaddr, PSIZE, 1);
@@ -3181,7 +3181,7 @@ int jfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
3181 d = (struct ldtentry *) & p->slot[stbl[i]]; 3181 d = (struct ldtentry *) & p->slot[stbl[i]];
3182 3182
3183 if (((long) jfs_dirent + d->namlen + 1) > 3183 if (((long) jfs_dirent + d->namlen + 1) >
3184 (dirent_buf + PSIZE)) { 3184 (dirent_buf + PAGE_SIZE)) {
3185 /* DBCS codepages could overrun dirent_buf */ 3185 /* DBCS codepages could overrun dirent_buf */
3186 index = i; 3186 index = i;
3187 overflow = 1; 3187 overflow = 1;
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 783831301625..7acff2ce3c80 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -502,7 +502,7 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
502 502
503 } 503 }
504 504
505 ip->i_mapping->a_ops = &jfs_aops; 505 ip->i_mapping->a_ops = &jfs_metapage_aops;
506 mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS); 506 mapping_set_gfp_mask(ip->i_mapping, GFP_NOFS);
507 507
508 /* Allocations to metadata inodes should not affect quotas */ 508 /* Allocations to metadata inodes should not affect quotas */
@@ -2573,9 +2573,18 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2573 goto out; 2573 goto out;
2574 } 2574 }
2575 2575
2576 /* assign a buffer for the page */ 2576 /*
2577 mp = get_metapage(ipimap, xaddr, PSIZE, 1); 2577 * start transaction of update of the inode map
2578 if (!mp) { 2578 * addressing structure pointing to the new iag page;
2579 */
2580 tid = txBegin(sb, COMMIT_FORCE);
2581 down(&JFS_IP(ipimap)->commit_sem);
2582
2583 /* update the inode map addressing structure to point to it */
2584 if ((rc =
2585 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
2586 txEnd(tid);
2587 up(&JFS_IP(ipimap)->commit_sem);
2579 /* Free the blocks allocated for the iag since it was 2588 /* Free the blocks allocated for the iag since it was
2580 * not successfully added to the inode map 2589 * not successfully added to the inode map
2581 */ 2590 */
@@ -2584,6 +2593,29 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2584 /* release the inode map lock */ 2593 /* release the inode map lock */
2585 IWRITE_UNLOCK(ipimap); 2594 IWRITE_UNLOCK(ipimap);
2586 2595
2596 goto out;
2597 }
2598
2599 /* update the inode map's inode to reflect the extension */
2600 ipimap->i_size += PSIZE;
2601 inode_add_bytes(ipimap, PSIZE);
2602
2603 /* assign a buffer for the page */
2604 mp = get_metapage(ipimap, blkno, PSIZE, 0);
2605 if (!mp) {
2606 /*
2607 * This is very unlikely since we just created the
2608 * extent, but let's try to handle it correctly
2609 */
2610 xtTruncate(tid, ipimap, ipimap->i_size - PSIZE,
2611 COMMIT_PWMAP);
2612
2613 txAbort(tid, 0);
2614 txEnd(tid);
2615
2616 /* release the inode map lock */
2617 IWRITE_UNLOCK(ipimap);
2618
2587 rc = -EIO; 2619 rc = -EIO;
2588 goto out; 2620 goto out;
2589 } 2621 }
@@ -2605,41 +2637,11 @@ diNewIAG(struct inomap * imap, int *iagnop, int agno, struct metapage ** mpp)
2605 iagp->inosmap[i] = cpu_to_le32(ONES); 2637 iagp->inosmap[i] = cpu_to_le32(ONES);
2606 2638
2607 /* 2639 /*
2608 * Invalidate the page after writing and syncing it. 2640 * Write and sync the metapage
2609 * After it's initialized, we access it in a different
2610 * address space
2611 */ 2641 */
2612 set_bit(META_discard, &mp->flag);
2613 flush_metapage(mp); 2642 flush_metapage(mp);
2614 2643
2615 /* 2644 /*
2616 * start tyransaction of update of the inode map
2617 * addressing structure pointing to the new iag page;
2618 */
2619 tid = txBegin(sb, COMMIT_FORCE);
2620 down(&JFS_IP(ipimap)->commit_sem);
2621
2622 /* update the inode map addressing structure to point to it */
2623 if ((rc =
2624 xtInsert(tid, ipimap, 0, blkno, xlen, &xaddr, 0))) {
2625 txEnd(tid);
2626 up(&JFS_IP(ipimap)->commit_sem);
2627 /* Free the blocks allocated for the iag since it was
2628 * not successfully added to the inode map
2629 */
2630 dbFree(ipimap, xaddr, (s64) xlen);
2631
2632 /* release the inode map lock */
2633 IWRITE_UNLOCK(ipimap);
2634
2635 goto out;
2636 }
2637
2638 /* update the inode map's inode to reflect the extension */
2639 ipimap->i_size += PSIZE;
2640 inode_add_bytes(ipimap, PSIZE);
2641
2642 /*
2643 * txCommit(COMMIT_FORCE) will synchronously write address 2645 * txCommit(COMMIT_FORCE) will synchronously write address
2644 * index pages and inode after commit in careful update order 2646 * index pages and inode after commit in careful update order
2645 * of address index pages (right to left, bottom up); 2647 * of address index pages (right to left, bottom up);
@@ -2789,6 +2791,7 @@ diUpdatePMap(struct inode *ipimap,
2789 u32 mask; 2791 u32 mask;
2790 struct jfs_log *log; 2792 struct jfs_log *log;
2791 int lsn, difft, diffp; 2793 int lsn, difft, diffp;
2794 unsigned long flags;
2792 2795
2793 imap = JFS_IP(ipimap)->i_imap; 2796 imap = JFS_IP(ipimap)->i_imap;
2794 /* get the iag number containing the inode */ 2797 /* get the iag number containing the inode */
@@ -2805,6 +2808,7 @@ diUpdatePMap(struct inode *ipimap,
2805 IREAD_UNLOCK(ipimap); 2808 IREAD_UNLOCK(ipimap);
2806 if (rc) 2809 if (rc)
2807 return (rc); 2810 return (rc);
2811 metapage_wait_for_io(mp);
2808 iagp = (struct iag *) mp->data; 2812 iagp = (struct iag *) mp->data;
2809 /* get the inode number and extent number of the inode within 2813 /* get the inode number and extent number of the inode within
2810 * the iag and the inode number within the extent. 2814 * the iag and the inode number within the extent.
@@ -2868,30 +2872,28 @@ diUpdatePMap(struct inode *ipimap,
2868 /* inherit older/smaller lsn */ 2872 /* inherit older/smaller lsn */
2869 logdiff(difft, lsn, log); 2873 logdiff(difft, lsn, log);
2870 logdiff(diffp, mp->lsn, log); 2874 logdiff(diffp, mp->lsn, log);
2875 LOGSYNC_LOCK(log, flags);
2871 if (difft < diffp) { 2876 if (difft < diffp) {
2872 mp->lsn = lsn; 2877 mp->lsn = lsn;
2873 /* move mp after tblock in logsync list */ 2878 /* move mp after tblock in logsync list */
2874 LOGSYNC_LOCK(log);
2875 list_move(&mp->synclist, &tblk->synclist); 2879 list_move(&mp->synclist, &tblk->synclist);
2876 LOGSYNC_UNLOCK(log);
2877 } 2880 }
2878 /* inherit younger/larger clsn */ 2881 /* inherit younger/larger clsn */
2879 LOGSYNC_LOCK(log);
2880 assert(mp->clsn); 2882 assert(mp->clsn);
2881 logdiff(difft, tblk->clsn, log); 2883 logdiff(difft, tblk->clsn, log);
2882 logdiff(diffp, mp->clsn, log); 2884 logdiff(diffp, mp->clsn, log);
2883 if (difft > diffp) 2885 if (difft > diffp)
2884 mp->clsn = tblk->clsn; 2886 mp->clsn = tblk->clsn;
2885 LOGSYNC_UNLOCK(log); 2887 LOGSYNC_UNLOCK(log, flags);
2886 } else { 2888 } else {
2887 mp->log = log; 2889 mp->log = log;
2888 mp->lsn = lsn; 2890 mp->lsn = lsn;
2889 /* insert mp after tblock in logsync list */ 2891 /* insert mp after tblock in logsync list */
2890 LOGSYNC_LOCK(log); 2892 LOGSYNC_LOCK(log, flags);
2891 log->count++; 2893 log->count++;
2892 list_add(&mp->synclist, &tblk->synclist); 2894 list_add(&mp->synclist, &tblk->synclist);
2893 mp->clsn = tblk->clsn; 2895 mp->clsn = tblk->clsn;
2894 LOGSYNC_UNLOCK(log); 2896 LOGSYNC_UNLOCK(log, flags);
2895 } 2897 }
2896 write_metapage(mp); 2898 write_metapage(mp);
2897 return (0); 2899 return (0);
diff --git a/fs/jfs/jfs_incore.h b/fs/jfs/jfs_incore.h
index ebd77c1bed66..c0fd7b3eadc6 100644
--- a/fs/jfs/jfs_incore.h
+++ b/fs/jfs/jfs_incore.h
@@ -165,6 +165,7 @@ struct jfs_sb_info {
165 /* Formerly in ipbmap */ 165 /* Formerly in ipbmap */
166 struct bmap *bmap; /* incore bmap descriptor */ 166 struct bmap *bmap; /* incore bmap descriptor */
167 struct nls_table *nls_tab; /* current codepage */ 167 struct nls_table *nls_tab; /* current codepage */
168 struct inode *direct_inode; /* metadata inode */
168 uint state; /* mount/recovery state */ 169 uint state; /* mount/recovery state */
169 unsigned long flag; /* mount time flags */ 170 unsigned long flag; /* mount time flags */
170 uint p_state; /* state prior to going no integrity */ 171 uint p_state; /* state prior to going no integrity */
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
diff --git a/fs/jfs/jfs_logmgr.h b/fs/jfs/jfs_logmgr.h
index 141ad74010c9..51291fbc420c 100644
--- a/fs/jfs/jfs_logmgr.h
+++ b/fs/jfs/jfs_logmgr.h
@@ -463,9 +463,10 @@ struct lbuf {
463 463
464 s64 l_blkno; /* 8: log page block number */ 464 s64 l_blkno; /* 8: log page block number */
465 caddr_t l_ldata; /* 4: data page */ 465 caddr_t l_ldata; /* 4: data page */
466 struct page *l_page; /* The page itself */
467 uint l_offset; /* Offset of l_ldata within the page */
466 468
467 wait_queue_head_t l_ioevent; /* 4: i/o done event */ 469 wait_queue_head_t l_ioevent; /* 4: i/o done event */
468 struct page *l_page; /* The page itself */
469}; 470};
470 471
471/* Reuse l_freelist for redrive list */ 472/* Reuse l_freelist for redrive list */
@@ -489,8 +490,9 @@ struct logsyncblk {
489 */ 490 */
490 491
491#define LOGSYNC_LOCK_INIT(log) spin_lock_init(&(log)->synclock) 492#define LOGSYNC_LOCK_INIT(log) spin_lock_init(&(log)->synclock)
492#define LOGSYNC_LOCK(log) spin_lock(&(log)->synclock) 493#define LOGSYNC_LOCK(log, flags) spin_lock_irqsave(&(log)->synclock, flags)
493#define LOGSYNC_UNLOCK(log) spin_unlock(&(log)->synclock) 494#define LOGSYNC_UNLOCK(log, flags) \
495 spin_unlock_irqrestore(&(log)->synclock, flags)
494 496
495/* compute the difference in bytes of lsn from sync point */ 497/* compute the difference in bytes of lsn from sync point */
496#define logdiff(diff, lsn, log)\ 498#define logdiff(diff, lsn, log)\
@@ -506,5 +508,6 @@ extern int lmLogShutdown(struct jfs_log * log);
506extern int lmLogInit(struct jfs_log * log); 508extern int lmLogInit(struct jfs_log * log);
507extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize); 509extern int lmLogFormat(struct jfs_log *log, s64 logAddress, int logSize);
508extern void jfs_flush_journal(struct jfs_log * log, int wait); 510extern void jfs_flush_journal(struct jfs_log * log, int wait);
511extern void jfs_syncpt(struct jfs_log *log);
509 512
510#endif /* _H_JFS_LOGMGR */ 513#endif /* _H_JFS_LOGMGR */
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 4c0a3ac75c08..41bf078dce05 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) International Business Machines Corp., 2000-2003 2 * Copyright (C) International Business Machines Corp., 2000-2005
3 * Portions Copyright (C) Christoph Hellwig, 2001-2002 3 * Portions Copyright (C) Christoph Hellwig, 2001-2002
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
@@ -18,10 +18,11 @@
18 */ 18 */
19 19
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/mm.h>
22#include <linux/bio.h>
21#include <linux/init.h> 23#include <linux/init.h>
22#include <linux/buffer_head.h> 24#include <linux/buffer_head.h>
23#include <linux/mempool.h> 25#include <linux/mempool.h>
24#include <linux/delay.h>
25#include "jfs_incore.h" 26#include "jfs_incore.h"
26#include "jfs_superblock.h" 27#include "jfs_superblock.h"
27#include "jfs_filsys.h" 28#include "jfs_filsys.h"
@@ -29,8 +30,6 @@
29#include "jfs_txnmgr.h" 30#include "jfs_txnmgr.h"
30#include "jfs_debug.h" 31#include "jfs_debug.h"
31 32
32static DEFINE_SPINLOCK(meta_lock);
33
34#ifdef CONFIG_JFS_STATISTICS 33#ifdef CONFIG_JFS_STATISTICS
35static struct { 34static struct {
36 uint pagealloc; /* # of page allocations */ 35 uint pagealloc; /* # of page allocations */
@@ -39,22 +38,8 @@ static struct {
39} mpStat; 38} mpStat;
40#endif 39#endif
41 40
42 41#define metapage_locked(mp) test_bit(META_locked, &(mp)->flag)
43#define HASH_BITS 10 /* This makes hash_table 1 4K page */ 42#define trylock_metapage(mp) test_and_set_bit(META_locked, &(mp)->flag)
44#define HASH_SIZE (1 << HASH_BITS)
45static struct metapage **hash_table = NULL;
46static unsigned long hash_order;
47
48
49static inline int metapage_locked(struct metapage *mp)
50{
51 return test_bit(META_locked, &mp->flag);
52}
53
54static inline int trylock_metapage(struct metapage *mp)
55{
56 return test_and_set_bit(META_locked, &mp->flag);
57}
58 43
59static inline void unlock_metapage(struct metapage *mp) 44static inline void unlock_metapage(struct metapage *mp)
60{ 45{
@@ -62,26 +47,26 @@ static inline void unlock_metapage(struct metapage *mp)
62 wake_up(&mp->wait); 47 wake_up(&mp->wait);
63} 48}
64 49
65static void __lock_metapage(struct metapage *mp) 50static inline void __lock_metapage(struct metapage *mp)
66{ 51{
67 DECLARE_WAITQUEUE(wait, current); 52 DECLARE_WAITQUEUE(wait, current);
68
69 INCREMENT(mpStat.lockwait); 53 INCREMENT(mpStat.lockwait);
70
71 add_wait_queue_exclusive(&mp->wait, &wait); 54 add_wait_queue_exclusive(&mp->wait, &wait);
72 do { 55 do {
73 set_current_state(TASK_UNINTERRUPTIBLE); 56 set_current_state(TASK_UNINTERRUPTIBLE);
74 if (metapage_locked(mp)) { 57 if (metapage_locked(mp)) {
75 spin_unlock(&meta_lock); 58 unlock_page(mp->page);
76 schedule(); 59 schedule();
77 spin_lock(&meta_lock); 60 lock_page(mp->page);
78 } 61 }
79 } while (trylock_metapage(mp)); 62 } while (trylock_metapage(mp));
80 __set_current_state(TASK_RUNNING); 63 __set_current_state(TASK_RUNNING);
81 remove_wait_queue(&mp->wait, &wait); 64 remove_wait_queue(&mp->wait, &wait);
82} 65}
83 66
84/* needs meta_lock */ 67/*
68 * Must have mp->page locked
69 */
85static inline void lock_metapage(struct metapage *mp) 70static inline void lock_metapage(struct metapage *mp)
86{ 71{
87 if (trylock_metapage(mp)) 72 if (trylock_metapage(mp))
@@ -92,6 +77,110 @@ static inline void lock_metapage(struct metapage *mp)
92static kmem_cache_t *metapage_cache; 77static kmem_cache_t *metapage_cache;
93static mempool_t *metapage_mempool; 78static mempool_t *metapage_mempool;
94 79
80#define MPS_PER_PAGE (PAGE_CACHE_SIZE >> L2PSIZE)
81
82#if MPS_PER_PAGE > 1
83
84struct meta_anchor {
85 int mp_count;
86 atomic_t io_count;
87 struct metapage *mp[MPS_PER_PAGE];
88};
89#define mp_anchor(page) ((struct meta_anchor *)page->private)
90
91static inline struct metapage *page_to_mp(struct page *page, uint offset)
92{
93 if (!PagePrivate(page))
94 return NULL;
95 return mp_anchor(page)->mp[offset >> L2PSIZE];
96}
97
98static inline int insert_metapage(struct page *page, struct metapage *mp)
99{
100 struct meta_anchor *a;
101 int index;
102 int l2mp_blocks; /* log2 blocks per metapage */
103
104 if (PagePrivate(page))
105 a = mp_anchor(page);
106 else {
107 a = kmalloc(sizeof(struct meta_anchor), GFP_NOFS);
108 if (!a)
109 return -ENOMEM;
110 memset(a, 0, sizeof(struct meta_anchor));
111 page->private = (unsigned long)a;
112 SetPagePrivate(page);
113 kmap(page);
114 }
115
116 if (mp) {
117 l2mp_blocks = L2PSIZE - page->mapping->host->i_blkbits;
118 index = (mp->index >> l2mp_blocks) & (MPS_PER_PAGE - 1);
119 a->mp_count++;
120 a->mp[index] = mp;
121 }
122
123 return 0;
124}
125
126static inline void remove_metapage(struct page *page, struct metapage *mp)
127{
128 struct meta_anchor *a = mp_anchor(page);
129 int l2mp_blocks = L2PSIZE - page->mapping->host->i_blkbits;
130 int index;
131
132 index = (mp->index >> l2mp_blocks) & (MPS_PER_PAGE - 1);
133
134 BUG_ON(a->mp[index] != mp);
135
136 a->mp[index] = NULL;
137 if (--a->mp_count == 0) {
138 kfree(a);
139 page->private = 0;
140 ClearPagePrivate(page);
141 kunmap(page);
142 }
143}
144
145static inline void inc_io(struct page *page)
146{
147 atomic_inc(&mp_anchor(page)->io_count);
148}
149
150static inline void dec_io(struct page *page, void (*handler) (struct page *))
151{
152 if (atomic_dec_and_test(&mp_anchor(page)->io_count))
153 handler(page);
154}
155
156#else
157static inline struct metapage *page_to_mp(struct page *page, uint offset)
158{
159 return PagePrivate(page) ? (struct metapage *)page->private : NULL;
160}
161
162static inline int insert_metapage(struct page *page, struct metapage *mp)
163{
164 if (mp) {
165 page->private = (unsigned long)mp;
166 SetPagePrivate(page);
167 kmap(page);
168 }
169 return 0;
170}
171
172static inline void remove_metapage(struct page *page, struct metapage *mp)
173{
174 page->private = 0;
175 ClearPagePrivate(page);
176 kunmap(page);
177}
178
179#define inc_io(page) do {} while(0)
180#define dec_io(page, handler) handler(page)
181
182#endif
183
95static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags) 184static void init_once(void *foo, kmem_cache_t *cachep, unsigned long flags)
96{ 185{
97 struct metapage *mp = (struct metapage *)foo; 186 struct metapage *mp = (struct metapage *)foo;
@@ -139,16 +228,6 @@ int __init metapage_init(void)
139 kmem_cache_destroy(metapage_cache); 228 kmem_cache_destroy(metapage_cache);
140 return -ENOMEM; 229 return -ENOMEM;
141 } 230 }
142 /*
143 * Now the hash list
144 */
145 for (hash_order = 0;
146 ((PAGE_SIZE << hash_order) / sizeof(void *)) < HASH_SIZE;
147 hash_order++);
148 hash_table =
149 (struct metapage **) __get_free_pages(GFP_KERNEL, hash_order);
150 assert(hash_table);
151 memset(hash_table, 0, PAGE_SIZE << hash_order);
152 231
153 return 0; 232 return 0;
154} 233}
@@ -159,73 +238,388 @@ void metapage_exit(void)
159 kmem_cache_destroy(metapage_cache); 238 kmem_cache_destroy(metapage_cache);
160} 239}
161 240
241static inline void drop_metapage(struct page *page, struct metapage *mp)
242{
243 if (mp->count || mp->nohomeok || test_bit(META_dirty, &mp->flag) ||
244 test_bit(META_io, &mp->flag))
245 return;
246 remove_metapage(page, mp);
247 INCREMENT(mpStat.pagefree);
248 free_metapage(mp);
249}
250
162/* 251/*
163 * Basically same hash as in pagemap.h, but using our hash table 252 * Metapage address space operations
164 */ 253 */
165static struct metapage **meta_hash(struct address_space *mapping, 254
166 unsigned long index) 255static sector_t metapage_get_blocks(struct inode *inode, sector_t lblock,
256 unsigned int *len)
167{ 257{
168#define i (((unsigned long)mapping)/ \ 258 int rc = 0;
169 (sizeof(struct inode) & ~(sizeof(struct inode) -1 ))) 259 int xflag;
170#define s(x) ((x) + ((x) >> HASH_BITS)) 260 s64 xaddr;
171 return hash_table + (s(i + index) & (HASH_SIZE - 1)); 261 sector_t file_blocks = (inode->i_size + inode->i_blksize - 1) >>
172#undef i 262 inode->i_blkbits;
173#undef s 263
264 if (lblock >= file_blocks)
265 return 0;
266 if (lblock + *len > file_blocks)
267 *len = file_blocks - lblock;
268
269 if (inode->i_ino) {
270 rc = xtLookup(inode, (s64)lblock, *len, &xflag, &xaddr, len, 0);
271 if ((rc == 0) && *len)
272 lblock = (sector_t)xaddr;
273 else
274 lblock = 0;
275 } /* else no mapping */
276
277 return lblock;
174} 278}
175 279
176static struct metapage *search_hash(struct metapage ** hash_ptr, 280static void last_read_complete(struct page *page)
177 struct address_space *mapping,
178 unsigned long index)
179{ 281{
180 struct metapage *ptr; 282 if (!PageError(page))
283 SetPageUptodate(page);
284 unlock_page(page);
285}
286
287static int metapage_read_end_io(struct bio *bio, unsigned int bytes_done,
288 int err)
289{
290 struct page *page = bio->bi_private;
291
292 if (bio->bi_size)
293 return 1;
181 294
182 for (ptr = *hash_ptr; ptr; ptr = ptr->hash_next) { 295 if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) {
183 if ((ptr->mapping == mapping) && (ptr->index == index)) 296 printk(KERN_ERR "metapage_read_end_io: I/O error\n");
184 return ptr; 297 SetPageError(page);
185 } 298 }
186 299
187 return NULL; 300 dec_io(page, last_read_complete);
301 bio_put(bio);
302
303 return 0;
188} 304}
189 305
190static void add_to_hash(struct metapage * mp, struct metapage ** hash_ptr) 306static void remove_from_logsync(struct metapage *mp)
191{ 307{
192 if (*hash_ptr) 308 struct jfs_log *log = mp->log;
193 (*hash_ptr)->hash_prev = mp; 309 unsigned long flags;
310/*
311 * This can race. Recheck that log hasn't been set to null, and after
312 * acquiring logsync lock, recheck lsn
313 */
314 if (!log)
315 return;
316
317 LOGSYNC_LOCK(log, flags);
318 if (mp->lsn) {
319 mp->log = NULL;
320 mp->lsn = 0;
321 mp->clsn = 0;
322 log->count--;
323 list_del(&mp->synclist);
324 }
325 LOGSYNC_UNLOCK(log, flags);
326}
194 327
195 mp->hash_prev = NULL; 328static void last_write_complete(struct page *page)
196 mp->hash_next = *hash_ptr; 329{
197 *hash_ptr = mp; 330 struct metapage *mp;
331 unsigned int offset;
332
333 for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) {
334 mp = page_to_mp(page, offset);
335 if (mp && test_bit(META_io, &mp->flag)) {
336 if (mp->lsn)
337 remove_from_logsync(mp);
338 clear_bit(META_io, &mp->flag);
339 }
340 /*
341 * I'd like to call drop_metapage here, but I don't think it's
342 * safe unless I have the page locked
343 */
344 }
345 end_page_writeback(page);
198} 346}
199 347
200static void remove_from_hash(struct metapage * mp, struct metapage ** hash_ptr) 348static int metapage_write_end_io(struct bio *bio, unsigned int bytes_done,
349 int err)
201{ 350{
202 if (mp->hash_prev) 351 struct page *page = bio->bi_private;
203 mp->hash_prev->hash_next = mp->hash_next; 352
204 else { 353 BUG_ON(!PagePrivate(page));
205 assert(*hash_ptr == mp); 354
206 *hash_ptr = mp->hash_next; 355 if (bio->bi_size)
356 return 1;
357
358 if (! test_bit(BIO_UPTODATE, &bio->bi_flags)) {
359 printk(KERN_ERR "metapage_write_end_io: I/O error\n");
360 SetPageError(page);
361 }
362 dec_io(page, last_write_complete);
363 bio_put(bio);
364 return 0;
365}
366
367static int metapage_writepage(struct page *page, struct writeback_control *wbc)
368{
369 struct bio *bio = NULL;
370 unsigned int block_offset; /* block offset of mp within page */
371 struct inode *inode = page->mapping->host;
372 unsigned int blocks_per_mp = JFS_SBI(inode->i_sb)->nbperpage;
373 unsigned int len;
374 unsigned int xlen;
375 struct metapage *mp;
376 int redirty = 0;
377 sector_t lblock;
378 sector_t pblock;
379 sector_t next_block = 0;
380 sector_t page_start;
381 unsigned long bio_bytes = 0;
382 unsigned long bio_offset = 0;
383 unsigned int offset;
384
385 page_start = (sector_t)page->index <<
386 (PAGE_CACHE_SHIFT - inode->i_blkbits);
387 BUG_ON(!PageLocked(page));
388 BUG_ON(PageWriteback(page));
389
390 for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) {
391 mp = page_to_mp(page, offset);
392
393 if (!mp || !test_bit(META_dirty, &mp->flag))
394 continue;
395
396 if (mp->nohomeok && !test_bit(META_forcewrite, &mp->flag)) {
397 redirty = 1;
398 continue;
399 }
400
401 clear_bit(META_dirty, &mp->flag);
402 block_offset = offset >> inode->i_blkbits;
403 lblock = page_start + block_offset;
404 if (bio) {
405 if (xlen && lblock == next_block) {
406 /* Contiguous, in memory & on disk */
407 len = min(xlen, blocks_per_mp);
408 xlen -= len;
409 bio_bytes += len << inode->i_blkbits;
410 set_bit(META_io, &mp->flag);
411 continue;
412 }
413 /* Not contiguous */
414 if (bio_add_page(bio, page, bio_bytes, bio_offset) <
415 bio_bytes)
416 goto add_failed;
417 /*
418 * Increment counter before submitting i/o to keep
419 * count from hitting zero before we're through
420 */
421 inc_io(page);
422 if (!bio->bi_size)
423 goto dump_bio;
424 submit_bio(WRITE, bio);
425 bio = NULL;
426 } else {
427 set_page_writeback(page);
428 inc_io(page);
429 }
430 xlen = (PAGE_CACHE_SIZE - offset) >> inode->i_blkbits;
431 pblock = metapage_get_blocks(inode, lblock, &xlen);
432 if (!pblock) {
433 /* Need better error handling */
434 printk(KERN_ERR "JFS: metapage_get_blocks failed\n");
435 dec_io(page, last_write_complete);
436 continue;
437 }
438 set_bit(META_io, &mp->flag);
439 len = min(xlen, (uint) JFS_SBI(inode->i_sb)->nbperpage);
440
441 bio = bio_alloc(GFP_NOFS, 1);
442 bio->bi_bdev = inode->i_sb->s_bdev;
443 bio->bi_sector = pblock << (inode->i_blkbits - 9);
444 bio->bi_end_io = metapage_write_end_io;
445 bio->bi_private = page;
446
447 /* Don't call bio_add_page yet, we may add to this vec */
448 bio_offset = offset;
449 bio_bytes = len << inode->i_blkbits;
450
451 xlen -= len;
452 next_block = lblock + len;
453 }
454 if (bio) {
455 if (bio_add_page(bio, page, bio_bytes, bio_offset) < bio_bytes)
456 goto add_failed;
457 if (!bio->bi_size)
458 goto dump_bio;
459
460 submit_bio(WRITE, bio);
461 }
462 if (redirty)
463 redirty_page_for_writepage(wbc, page);
464
465 unlock_page(page);
466
467 return 0;
468add_failed:
469 /* We should never reach here, since we're only adding one vec */
470 printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n");
471 goto skip;
472dump_bio:
473 dump_mem("bio", bio, sizeof(*bio));
474skip:
475 bio_put(bio);
476 unlock_page(page);
477 dec_io(page, last_write_complete);
478
479 return -EIO;
480}
481
482static int metapage_readpage(struct file *fp, struct page *page)
483{
484 struct inode *inode = page->mapping->host;
485 struct bio *bio = NULL;
486 unsigned int block_offset;
487 unsigned int blocks_per_page = PAGE_CACHE_SIZE >> inode->i_blkbits;
488 sector_t page_start; /* address of page in fs blocks */
489 sector_t pblock;
490 unsigned int xlen;
491 unsigned int len;
492 unsigned int offset;
493
494 BUG_ON(!PageLocked(page));
495 page_start = (sector_t)page->index <<
496 (PAGE_CACHE_SHIFT - inode->i_blkbits);
497
498 block_offset = 0;
499 while (block_offset < blocks_per_page) {
500 xlen = blocks_per_page - block_offset;
501 pblock = metapage_get_blocks(inode, page_start + block_offset,
502 &xlen);
503 if (pblock) {
504 if (!PagePrivate(page))
505 insert_metapage(page, NULL);
506 inc_io(page);
507 if (bio)
508 submit_bio(READ, bio);
509
510 bio = bio_alloc(GFP_NOFS, 1);
511 bio->bi_bdev = inode->i_sb->s_bdev;
512 bio->bi_sector = pblock << (inode->i_blkbits - 9);
513 bio->bi_end_io = metapage_read_end_io;
514 bio->bi_private = page;
515 len = xlen << inode->i_blkbits;
516 offset = block_offset << inode->i_blkbits;
517 if (bio_add_page(bio, page, len, offset) < len)
518 goto add_failed;
519 block_offset += xlen;
520 } else
521 block_offset++;
207 } 522 }
523 if (bio)
524 submit_bio(READ, bio);
525 else
526 unlock_page(page);
527
528 return 0;
208 529
209 if (mp->hash_next) 530add_failed:
210 mp->hash_next->hash_prev = mp->hash_prev; 531 printk(KERN_ERR "JFS: bio_add_page failed unexpectedly\n");
532 bio_put(bio);
533 dec_io(page, last_read_complete);
534 return -EIO;
211} 535}
212 536
537static int metapage_releasepage(struct page *page, int gfp_mask)
538{
539 struct metapage *mp;
540 int busy = 0;
541 unsigned int offset;
542
543 for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) {
544 mp = page_to_mp(page, offset);
545
546 if (!mp)
547 continue;
548
549 jfs_info("metapage_releasepage: mp = 0x%p", mp);
550 if (mp->count || mp->nohomeok) {
551 jfs_info("count = %ld, nohomeok = %d", mp->count,
552 mp->nohomeok);
553 busy = 1;
554 continue;
555 }
556 wait_on_page_writeback(page);
557 //WARN_ON(test_bit(META_dirty, &mp->flag));
558 if (test_bit(META_dirty, &mp->flag)) {
559 dump_mem("dirty mp in metapage_releasepage", mp,
560 sizeof(struct metapage));
561 dump_mem("page", page, sizeof(struct page));
562 dump_stack();
563 }
564 WARN_ON(mp->lsn);
565 if (mp->lsn)
566 remove_from_logsync(mp);
567 remove_metapage(page, mp);
568 INCREMENT(mpStat.pagefree);
569 free_metapage(mp);
570 }
571 if (busy)
572 return -1;
573
574 return 0;
575}
576
577static int metapage_invalidatepage(struct page *page, unsigned long offset)
578{
579 BUG_ON(offset);
580
581 if (PageWriteback(page))
582 return 0;
583
584 return metapage_releasepage(page, 0);
585}
586
587struct address_space_operations jfs_metapage_aops = {
588 .readpage = metapage_readpage,
589 .writepage = metapage_writepage,
590 .sync_page = block_sync_page,
591 .releasepage = metapage_releasepage,
592 .invalidatepage = metapage_invalidatepage,
593 .set_page_dirty = __set_page_dirty_nobuffers,
594};
595
213struct metapage *__get_metapage(struct inode *inode, unsigned long lblock, 596struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
214 unsigned int size, int absolute, 597 unsigned int size, int absolute,
215 unsigned long new) 598 unsigned long new)
216{ 599{
217 struct metapage **hash_ptr;
218 int l2BlocksPerPage; 600 int l2BlocksPerPage;
219 int l2bsize; 601 int l2bsize;
220 struct address_space *mapping; 602 struct address_space *mapping;
221 struct metapage *mp; 603 struct metapage *mp = NULL;
604 struct page *page;
222 unsigned long page_index; 605 unsigned long page_index;
223 unsigned long page_offset; 606 unsigned long page_offset;
224 607
225 jfs_info("__get_metapage: inode = 0x%p, lblock = 0x%lx", inode, lblock); 608 jfs_info("__get_metapage: ino = %ld, lblock = 0x%lx, abs=%d",
226 609 inode->i_ino, lblock, absolute);
610
611 l2bsize = inode->i_blkbits;
612 l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize;
613 page_index = lblock >> l2BlocksPerPage;
614 page_offset = (lblock - (page_index << l2BlocksPerPage)) << l2bsize;
615 if ((page_offset + size) > PAGE_CACHE_SIZE) {
616 jfs_err("MetaData crosses page boundary!!");
617 jfs_err("lblock = %lx, size = %d", lblock, size);
618 dump_stack();
619 return NULL;
620 }
227 if (absolute) 621 if (absolute)
228 mapping = inode->i_sb->s_bdev->bd_inode->i_mapping; 622 mapping = JFS_SBI(inode->i_sb)->direct_inode->i_mapping;
229 else { 623 else {
230 /* 624 /*
231 * If an nfs client tries to read an inode that is larger 625 * If an nfs client tries to read an inode that is larger
@@ -237,312 +631,212 @@ struct metapage *__get_metapage(struct inode *inode, unsigned long lblock,
237 mapping = inode->i_mapping; 631 mapping = inode->i_mapping;
238 } 632 }
239 633
240 hash_ptr = meta_hash(mapping, lblock); 634 if (new && (PSIZE == PAGE_CACHE_SIZE)) {
241again: 635 page = grab_cache_page(mapping, page_index);
242 spin_lock(&meta_lock); 636 if (!page) {
243 mp = search_hash(hash_ptr, mapping, lblock); 637 jfs_err("grab_cache_page failed!");
638 return NULL;
639 }
640 SetPageUptodate(page);
641 } else {
642 page = read_cache_page(mapping, page_index,
643 (filler_t *)mapping->a_ops->readpage, NULL);
644 if (IS_ERR(page)) {
645 jfs_err("read_cache_page failed!");
646 return NULL;
647 }
648 lock_page(page);
649 }
650
651 mp = page_to_mp(page, page_offset);
244 if (mp) { 652 if (mp) {
245 page_found: 653 if (mp->logical_size != size) {
246 if (test_bit(META_stale, &mp->flag)) { 654 jfs_error(inode->i_sb,
247 spin_unlock(&meta_lock); 655 "__get_metapage: mp->logical_size != size");
248 msleep(1); 656 jfs_err("logical_size = %d, size = %d",
249 goto again; 657 mp->logical_size, size);
658 dump_stack();
659 goto unlock;
250 } 660 }
251 mp->count++; 661 mp->count++;
252 lock_metapage(mp); 662 lock_metapage(mp);
253 spin_unlock(&meta_lock);
254 if (test_bit(META_discard, &mp->flag)) { 663 if (test_bit(META_discard, &mp->flag)) {
255 if (!new) { 664 if (!new) {
256 jfs_error(inode->i_sb, 665 jfs_error(inode->i_sb,
257 "__get_metapage: using a " 666 "__get_metapage: using a "
258 "discarded metapage"); 667 "discarded metapage");
259 release_metapage(mp); 668 discard_metapage(mp);
260 return NULL; 669 goto unlock;
261 } 670 }
262 clear_bit(META_discard, &mp->flag); 671 clear_bit(META_discard, &mp->flag);
263 } 672 }
264 jfs_info("__get_metapage: found 0x%p, in hash", mp);
265 if (mp->logical_size != size) {
266 jfs_error(inode->i_sb,
267 "__get_metapage: mp->logical_size != size");
268 release_metapage(mp);
269 return NULL;
270 }
271 } else { 673 } else {
272 l2bsize = inode->i_blkbits; 674 INCREMENT(mpStat.pagealloc);
273 l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize; 675 mp = alloc_metapage(GFP_NOFS);
274 page_index = lblock >> l2BlocksPerPage; 676 mp->page = page;
275 page_offset = (lblock - (page_index << l2BlocksPerPage)) <<
276 l2bsize;
277 if ((page_offset + size) > PAGE_CACHE_SIZE) {
278 spin_unlock(&meta_lock);
279 jfs_err("MetaData crosses page boundary!!");
280 return NULL;
281 }
282
283 /*
284 * Locks held on aggregate inode pages are usually
285 * not held long, and they are taken in critical code
286 * paths (committing dirty inodes, txCommit thread)
287 *
288 * Attempt to get metapage without blocking, tapping into
289 * reserves if necessary.
290 */
291 mp = NULL;
292 if (JFS_IP(inode)->fileset == AGGREGATE_I) {
293 mp = alloc_metapage(GFP_ATOMIC);
294 if (!mp) {
295 /*
296 * mempool is supposed to protect us from
297 * failing here. We will try a blocking
298 * call, but a deadlock is possible here
299 */
300 printk(KERN_WARNING
301 "__get_metapage: atomic call to mempool_alloc failed.\n");
302 printk(KERN_WARNING
303 "Will attempt blocking call\n");
304 }
305 }
306 if (!mp) {
307 struct metapage *mp2;
308
309 spin_unlock(&meta_lock);
310 mp = alloc_metapage(GFP_NOFS);
311 spin_lock(&meta_lock);
312
313 /* we dropped the meta_lock, we need to search the
314 * hash again.
315 */
316 mp2 = search_hash(hash_ptr, mapping, lblock);
317 if (mp2) {
318 free_metapage(mp);
319 mp = mp2;
320 goto page_found;
321 }
322 }
323 mp->flag = 0; 677 mp->flag = 0;
324 lock_metapage(mp);
325 if (absolute)
326 set_bit(META_absolute, &mp->flag);
327 mp->xflag = COMMIT_PAGE; 678 mp->xflag = COMMIT_PAGE;
328 mp->count = 1; 679 mp->count = 1;
329 atomic_set(&mp->nohomeok,0); 680 mp->nohomeok = 0;
330 mp->mapping = mapping;
331 mp->index = lblock;
332 mp->page = NULL;
333 mp->logical_size = size; 681 mp->logical_size = size;
334 add_to_hash(mp, hash_ptr); 682 mp->data = page_address(page) + page_offset;
335 spin_unlock(&meta_lock); 683 mp->index = lblock;
336 684 if (unlikely(insert_metapage(page, mp))) {
337 if (new) { 685 free_metapage(mp);
338 jfs_info("__get_metapage: Calling grab_cache_page"); 686 goto unlock;
339 mp->page = grab_cache_page(mapping, page_index);
340 if (!mp->page) {
341 jfs_err("grab_cache_page failed!");
342 goto freeit;
343 } else {
344 INCREMENT(mpStat.pagealloc);
345 unlock_page(mp->page);
346 }
347 } else {
348 jfs_info("__get_metapage: Calling read_cache_page");
349 mp->page = read_cache_page(mapping, lblock,
350 (filler_t *)mapping->a_ops->readpage, NULL);
351 if (IS_ERR(mp->page)) {
352 jfs_err("read_cache_page failed!");
353 goto freeit;
354 } else
355 INCREMENT(mpStat.pagealloc);
356 } 687 }
357 mp->data = kmap(mp->page) + page_offset; 688 lock_metapage(mp);
358 } 689 }
359 690
360 if (new) 691 if (new) {
692 jfs_info("zeroing mp = 0x%p", mp);
361 memset(mp->data, 0, PSIZE); 693 memset(mp->data, 0, PSIZE);
694 }
362 695
363 jfs_info("__get_metapage: returning = 0x%p", mp); 696 unlock_page(page);
697 jfs_info("__get_metapage: returning = 0x%p data = 0x%p", mp, mp->data);
364 return mp; 698 return mp;
365 699
366freeit: 700unlock:
367 spin_lock(&meta_lock); 701 unlock_page(page);
368 remove_from_hash(mp, hash_ptr);
369 free_metapage(mp);
370 spin_unlock(&meta_lock);
371 return NULL; 702 return NULL;
372} 703}
373 704
374void hold_metapage(struct metapage * mp, int force) 705void grab_metapage(struct metapage * mp)
375{ 706{
376 spin_lock(&meta_lock); 707 jfs_info("grab_metapage: mp = 0x%p", mp);
377 708 page_cache_get(mp->page);
709 lock_page(mp->page);
378 mp->count++; 710 mp->count++;
379 711 lock_metapage(mp);
380 if (force) { 712 unlock_page(mp->page);
381 ASSERT (!(test_bit(META_forced, &mp->flag)));
382 if (trylock_metapage(mp))
383 set_bit(META_forced, &mp->flag);
384 } else
385 lock_metapage(mp);
386
387 spin_unlock(&meta_lock);
388} 713}
389 714
390static void __write_metapage(struct metapage * mp) 715void force_metapage(struct metapage *mp)
391{ 716{
392 int l2bsize = mp->mapping->host->i_blkbits; 717 struct page *page = mp->page;
393 int l2BlocksPerPage = PAGE_CACHE_SHIFT - l2bsize; 718 jfs_info("force_metapage: mp = 0x%p", mp);
394 unsigned long page_index; 719 set_bit(META_forcewrite, &mp->flag);
395 unsigned long page_offset; 720 clear_bit(META_sync, &mp->flag);
396 int rc; 721 page_cache_get(page);
397 722 lock_page(page);
398 jfs_info("__write_metapage: mp = 0x%p", mp); 723 set_page_dirty(page);
399 724 write_one_page(page, 1);
400 page_index = mp->page->index; 725 clear_bit(META_forcewrite, &mp->flag);
401 page_offset = 726 page_cache_release(page);
402 (mp->index - (page_index << l2BlocksPerPage)) << l2bsize; 727}
403 728
729extern void hold_metapage(struct metapage *mp)
730{
404 lock_page(mp->page); 731 lock_page(mp->page);
405 rc = mp->mapping->a_ops->prepare_write(NULL, mp->page, page_offset, 732}
406 page_offset + 733
407 mp->logical_size); 734extern void put_metapage(struct metapage *mp)
408 if (rc) { 735{
409 jfs_err("prepare_write return %d!", rc); 736 if (mp->count || mp->nohomeok) {
410 ClearPageUptodate(mp->page); 737 /* Someone else will release this */
411 unlock_page(mp->page); 738 unlock_page(mp->page);
412 clear_bit(META_dirty, &mp->flag);
413 return; 739 return;
414 } 740 }
415 rc = mp->mapping->a_ops->commit_write(NULL, mp->page, page_offset, 741 page_cache_get(mp->page);
416 page_offset + 742 mp->count++;
417 mp->logical_size); 743 lock_metapage(mp);
418 if (rc) {
419 jfs_err("commit_write returned %d", rc);
420 }
421
422 unlock_page(mp->page); 744 unlock_page(mp->page);
423 clear_bit(META_dirty, &mp->flag); 745 release_metapage(mp);
424
425 jfs_info("__write_metapage done");
426}
427
428static inline void sync_metapage(struct metapage *mp)
429{
430 struct page *page = mp->page;
431
432 page_cache_get(page);
433 lock_page(page);
434
435 /* we're done with this page - no need to check for errors */
436 if (page_has_buffers(page))
437 write_one_page(page, 1);
438 else
439 unlock_page(page);
440 page_cache_release(page);
441} 746}
442 747
443void release_metapage(struct metapage * mp) 748void release_metapage(struct metapage * mp)
444{ 749{
445 struct jfs_log *log; 750 struct page *page = mp->page;
446
447 jfs_info("release_metapage: mp = 0x%p, flag = 0x%lx", mp, mp->flag); 751 jfs_info("release_metapage: mp = 0x%p, flag = 0x%lx", mp, mp->flag);
448 752
449 spin_lock(&meta_lock); 753 BUG_ON(!page);
450 if (test_bit(META_forced, &mp->flag)) { 754
451 clear_bit(META_forced, &mp->flag); 755 lock_page(page);
452 mp->count--; 756 unlock_metapage(mp);
453 spin_unlock(&meta_lock);
454 return;
455 }
456 757
457 assert(mp->count); 758 assert(mp->count);
458 if (--mp->count || atomic_read(&mp->nohomeok)) { 759 if (--mp->count || mp->nohomeok) {
459 unlock_metapage(mp); 760 unlock_page(page);
460 spin_unlock(&meta_lock); 761 page_cache_release(page);
461 return; 762 return;
462 } 763 }
463 764
464 if (mp->page) { 765 if (test_bit(META_dirty, &mp->flag)) {
465 set_bit(META_stale, &mp->flag); 766 set_page_dirty(page);
466 spin_unlock(&meta_lock);
467 kunmap(mp->page);
468 mp->data = NULL;
469 if (test_bit(META_dirty, &mp->flag))
470 __write_metapage(mp);
471 if (test_bit(META_sync, &mp->flag)) { 767 if (test_bit(META_sync, &mp->flag)) {
472 sync_metapage(mp);
473 clear_bit(META_sync, &mp->flag); 768 clear_bit(META_sync, &mp->flag);
769 write_one_page(page, 1);
770 lock_page(page); /* write_one_page unlocks the page */
474 } 771 }
772 } else if (mp->lsn) /* discard_metapage doesn't remove it */
773 remove_from_logsync(mp);
475 774
476 if (test_bit(META_discard, &mp->flag)) { 775#if MPS_PER_PAGE == 1
477 lock_page(mp->page); 776 /*
478 block_invalidatepage(mp->page, 0); 777 * If we know this is the only thing in the page, we can throw
479 unlock_page(mp->page); 778 * the page out of the page cache. If pages are larger, we
480 } 779 * don't want to do this.
481 780 */
482 page_cache_release(mp->page);
483 mp->page = NULL;
484 INCREMENT(mpStat.pagefree);
485 spin_lock(&meta_lock);
486 }
487 781
488 if (mp->lsn) { 782 /* Retest mp->count since we may have released page lock */
489 /* 783 if (test_bit(META_discard, &mp->flag) && !mp->count) {
490 * Remove metapage from logsynclist. 784 clear_page_dirty(page);
491 */ 785 ClearPageUptodate(page);
492 log = mp->log; 786#ifdef _NOT_YET
493 LOGSYNC_LOCK(log); 787 if (page->mapping) {
494 mp->log = NULL; 788 /* Remove from page cache and page cache reference */
495 mp->lsn = 0; 789 remove_from_page_cache(page);
496 mp->clsn = 0; 790 page_cache_release(page);
497 log->count--; 791 metapage_releasepage(page, 0);
498 list_del(&mp->synclist); 792 }
499 LOGSYNC_UNLOCK(log); 793#endif
500 } 794 }
501 remove_from_hash(mp, meta_hash(mp->mapping, mp->index)); 795#else
502 spin_unlock(&meta_lock); 796 /* Try to keep metapages from using up too much memory */
503 797 drop_metapage(page, mp);
504 free_metapage(mp); 798#endif
799 unlock_page(page);
800 page_cache_release(page);
505} 801}
506 802
507void __invalidate_metapages(struct inode *ip, s64 addr, int len) 803void __invalidate_metapages(struct inode *ip, s64 addr, int len)
508{ 804{
509 struct metapage **hash_ptr; 805 sector_t lblock;
510 unsigned long lblock;
511 int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_blkbits; 806 int l2BlocksPerPage = PAGE_CACHE_SHIFT - ip->i_blkbits;
807 int BlocksPerPage = 1 << l2BlocksPerPage;
512 /* All callers are interested in block device's mapping */ 808 /* All callers are interested in block device's mapping */
513 struct address_space *mapping = ip->i_sb->s_bdev->bd_inode->i_mapping; 809 struct address_space *mapping =
810 JFS_SBI(ip->i_sb)->direct_inode->i_mapping;
514 struct metapage *mp; 811 struct metapage *mp;
515 struct page *page; 812 struct page *page;
813 unsigned int offset;
516 814
517 /* 815 /*
518 * First, mark metapages to discard. They will eventually be 816 * Mark metapages to discard. They will eventually be
519 * released, but should not be written. 817 * released, but should not be written.
520 */ 818 */
521 for (lblock = addr; lblock < addr + len; 819 for (lblock = addr & ~(BlocksPerPage - 1); lblock < addr + len;
522 lblock += 1 << l2BlocksPerPage) { 820 lblock += BlocksPerPage) {
523 hash_ptr = meta_hash(mapping, lblock); 821 page = find_lock_page(mapping, lblock >> l2BlocksPerPage);
524again: 822 if (!page)
525 spin_lock(&meta_lock); 823 continue;
526 mp = search_hash(hash_ptr, mapping, lblock); 824 for (offset = 0; offset < PAGE_CACHE_SIZE; offset += PSIZE) {
527 if (mp) { 825 mp = page_to_mp(page, offset);
528 if (test_bit(META_stale, &mp->flag)) { 826 if (!mp)
529 spin_unlock(&meta_lock); 827 continue;
530 msleep(1); 828 if (mp->index < addr)
531 goto again; 829 continue;
532 } 830 if (mp->index >= addr + len)
831 break;
533 832
534 clear_bit(META_dirty, &mp->flag); 833 clear_bit(META_dirty, &mp->flag);
535 set_bit(META_discard, &mp->flag); 834 set_bit(META_discard, &mp->flag);
536 spin_unlock(&meta_lock); 835 if (mp->lsn)
537 } else { 836 remove_from_logsync(mp);
538 spin_unlock(&meta_lock);
539 page = find_lock_page(mapping, lblock>>l2BlocksPerPage);
540 if (page) {
541 block_invalidatepage(page, 0);
542 unlock_page(page);
543 page_cache_release(page);
544 }
545 } 837 }
838 unlock_page(page);
839 page_cache_release(page);
546 } 840 }
547} 841}
548 842
diff --git a/fs/jfs/jfs_metapage.h b/fs/jfs/jfs_metapage.h
index 0e58aba58c37..991e9fb84c75 100644
--- a/fs/jfs/jfs_metapage.h
+++ b/fs/jfs/jfs_metapage.h
@@ -33,38 +33,27 @@ struct metapage {
33 unsigned long flag; /* See Below */ 33 unsigned long flag; /* See Below */
34 unsigned long count; /* Reference count */ 34 unsigned long count; /* Reference count */
35 void *data; /* Data pointer */ 35 void *data; /* Data pointer */
36 36 sector_t index; /* block address of page */
37 /* list management stuff */
38 struct metapage *hash_prev;
39 struct metapage *hash_next; /* Also used for free list */
40
41 /*
42 * mapping & index become redundant, but we need these here to
43 * add the metapage to the hash before we have the real page
44 */
45 struct address_space *mapping;
46 unsigned long index;
47 wait_queue_head_t wait; 37 wait_queue_head_t wait;
48 38
49 /* implementation */ 39 /* implementation */
50 struct page *page; 40 struct page *page;
51 unsigned long logical_size; 41 unsigned int logical_size;
52 42
53 /* Journal management */ 43 /* Journal management */
54 int clsn; 44 int clsn;
55 atomic_t nohomeok; 45 int nohomeok;
56 struct jfs_log *log; 46 struct jfs_log *log;
57}; 47};
58 48
59/* metapage flag */ 49/* metapage flag */
60#define META_locked 0 50#define META_locked 0
61#define META_absolute 1 51#define META_free 1
62#define META_free 2 52#define META_dirty 2
63#define META_dirty 3 53#define META_sync 3
64#define META_sync 4 54#define META_discard 4
65#define META_discard 5 55#define META_forcewrite 5
66#define META_forced 6 56#define META_io 6
67#define META_stale 7
68 57
69#define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag) 58#define mark_metapage_dirty(mp) set_bit(META_dirty, &(mp)->flag)
70 59
@@ -80,7 +69,16 @@ extern struct metapage *__get_metapage(struct inode *inode,
80 __get_metapage(inode, lblock, size, absolute, TRUE) 69 __get_metapage(inode, lblock, size, absolute, TRUE)
81 70
82extern void release_metapage(struct metapage *); 71extern void release_metapage(struct metapage *);
83extern void hold_metapage(struct metapage *, int); 72extern void grab_metapage(struct metapage *);
73extern void force_metapage(struct metapage *);
74
75/*
76 * hold_metapage and put_metapage are used in conjuction. The page lock
77 * is not dropped between the two, so no other threads can get or release
78 * the metapage
79 */
80extern void hold_metapage(struct metapage *);
81extern void put_metapage(struct metapage *);
84 82
85static inline void write_metapage(struct metapage *mp) 83static inline void write_metapage(struct metapage *mp)
86{ 84{
@@ -101,6 +99,46 @@ static inline void discard_metapage(struct metapage *mp)
101 release_metapage(mp); 99 release_metapage(mp);
102} 100}
103 101
102static inline void metapage_nohomeok(struct metapage *mp)
103{
104 struct page *page = mp->page;
105 lock_page(page);
106 if (!mp->nohomeok++) {
107 mark_metapage_dirty(mp);
108 page_cache_get(page);
109 wait_on_page_writeback(page);
110 }
111 unlock_page(page);
112}
113
114/*
115 * This serializes access to mp->lsn when metapages are added to logsynclist
116 * without setting nohomeok. i.e. updating imap & dmap
117 */
118static inline void metapage_wait_for_io(struct metapage *mp)
119{
120 if (test_bit(META_io, &mp->flag))
121 wait_on_page_writeback(mp->page);
122}
123
124/*
125 * This is called when already holding the metapage
126 */
127static inline void _metapage_homeok(struct metapage *mp)
128{
129 if (!--mp->nohomeok)
130 page_cache_release(mp->page);
131}
132
133static inline void metapage_homeok(struct metapage *mp)
134{
135 hold_metapage(mp);
136 _metapage_homeok(mp);
137 put_metapage(mp);
138}
139
140extern struct address_space_operations jfs_metapage_aops;
141
104/* 142/*
105 * This routines invalidate all pages for an extent. 143 * This routines invalidate all pages for an extent.
106 */ 144 */
diff --git a/fs/jfs/jfs_mount.c b/fs/jfs/jfs_mount.c
index c535ffd638e8..032d111bc330 100644
--- a/fs/jfs/jfs_mount.c
+++ b/fs/jfs/jfs_mount.c
@@ -285,11 +285,6 @@ int jfs_mount_rw(struct super_block *sb, int remount)
285 */ 285 */
286 logMOUNT(sb); 286 logMOUNT(sb);
287 287
288 /*
289 * Set page cache allocation policy
290 */
291 mapping_set_gfp_mask(sb->s_bdev->bd_inode->i_mapping, GFP_NOFS);
292
293 return rc; 288 return rc;
294} 289}
295 290
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index f40301d93f74..e93d01aa12c4 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -227,6 +227,7 @@ static lid_t txLockAlloc(void)
227 227
228static void txLockFree(lid_t lid) 228static void txLockFree(lid_t lid)
229{ 229{
230 TxLock[lid].tid = 0;
230 TxLock[lid].next = TxAnchor.freelock; 231 TxLock[lid].next = TxAnchor.freelock;
231 TxAnchor.freelock = lid; 232 TxAnchor.freelock = lid;
232 TxAnchor.tlocksInUse--; 233 TxAnchor.tlocksInUse--;
@@ -566,9 +567,6 @@ void txEnd(tid_t tid)
566 * synchronize with logsync barrier 567 * synchronize with logsync barrier
567 */ 568 */
568 if (test_bit(log_SYNCBARRIER, &log->flag)) { 569 if (test_bit(log_SYNCBARRIER, &log->flag)) {
569 /* forward log syncpt */
570 /* lmSync(log); */
571
572 jfs_info("log barrier off: 0x%x", log->lsn); 570 jfs_info("log barrier off: 0x%x", log->lsn);
573 571
574 /* enable new transactions start */ 572 /* enable new transactions start */
@@ -576,15 +574,22 @@ void txEnd(tid_t tid)
576 574
577 /* wakeup all waitors for logsync barrier */ 575 /* wakeup all waitors for logsync barrier */
578 TXN_WAKEUP(&log->syncwait); 576 TXN_WAKEUP(&log->syncwait);
577
578 TXN_UNLOCK();
579
580 /* forward log syncpt */
581 jfs_syncpt(log);
582
583 goto wakeup;
579 } 584 }
580 } 585 }
581 586
587 TXN_UNLOCK();
588wakeup:
582 /* 589 /*
583 * wakeup all waitors for a free tblock 590 * wakeup all waitors for a free tblock
584 */ 591 */
585 TXN_WAKEUP(&TxAnchor.freewait); 592 TXN_WAKEUP(&TxAnchor.freewait);
586
587 TXN_UNLOCK();
588} 593}
589 594
590 595
@@ -633,8 +638,10 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
633 638
634 /* is page locked by the requester transaction ? */ 639 /* is page locked by the requester transaction ? */
635 tlck = lid_to_tlock(lid); 640 tlck = lid_to_tlock(lid);
636 if ((xtid = tlck->tid) == tid) 641 if ((xtid = tlck->tid) == tid) {
642 TXN_UNLOCK();
637 goto grantLock; 643 goto grantLock;
644 }
638 645
639 /* 646 /*
640 * is page locked by anonymous transaction/lock ? 647 * is page locked by anonymous transaction/lock ?
@@ -649,6 +656,7 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
649 */ 656 */
650 if (xtid == 0) { 657 if (xtid == 0) {
651 tlck->tid = tid; 658 tlck->tid = tid;
659 TXN_UNLOCK();
652 tblk = tid_to_tblock(tid); 660 tblk = tid_to_tblock(tid);
653 /* 661 /*
654 * The order of the tlocks in the transaction is important 662 * The order of the tlocks in the transaction is important
@@ -706,17 +714,18 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
706 */ 714 */
707 tlck->tid = tid; 715 tlck->tid = tid;
708 716
717 TXN_UNLOCK();
718
709 /* mark tlock for meta-data page */ 719 /* mark tlock for meta-data page */
710 if (mp->xflag & COMMIT_PAGE) { 720 if (mp->xflag & COMMIT_PAGE) {
711 721
712 tlck->flag = tlckPAGELOCK; 722 tlck->flag = tlckPAGELOCK;
713 723
714 /* mark the page dirty and nohomeok */ 724 /* mark the page dirty and nohomeok */
715 mark_metapage_dirty(mp); 725 metapage_nohomeok(mp);
716 atomic_inc(&mp->nohomeok);
717 726
718 jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p", 727 jfs_info("locking mp = 0x%p, nohomeok = %d tid = %d tlck = 0x%p",
719 mp, atomic_read(&mp->nohomeok), tid, tlck); 728 mp, mp->nohomeok, tid, tlck);
720 729
721 /* if anonymous transaction, and buffer is on the group 730 /* if anonymous transaction, and buffer is on the group
722 * commit synclist, mark inode to show this. This will 731 * commit synclist, mark inode to show this. This will
@@ -762,8 +771,10 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
762 if (tlck->next == 0) { 771 if (tlck->next == 0) {
763 /* This inode's first anonymous transaction */ 772 /* This inode's first anonymous transaction */
764 jfs_ip->atltail = lid; 773 jfs_ip->atltail = lid;
774 TXN_LOCK();
765 list_add_tail(&jfs_ip->anon_inode_list, 775 list_add_tail(&jfs_ip->anon_inode_list,
766 &TxAnchor.anon_list); 776 &TxAnchor.anon_list);
777 TXN_UNLOCK();
767 } 778 }
768 } 779 }
769 780
@@ -821,8 +832,6 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
821 grantLock: 832 grantLock:
822 tlck->type |= type; 833 tlck->type |= type;
823 834
824 TXN_UNLOCK();
825
826 return tlck; 835 return tlck;
827 836
828 /* 837 /*
@@ -841,11 +850,19 @@ struct tlock *txLock(tid_t tid, struct inode *ip, struct metapage * mp,
841 BUG(); 850 BUG();
842 } 851 }
843 INCREMENT(stattx.waitlock); /* statistics */ 852 INCREMENT(stattx.waitlock); /* statistics */
853 TXN_UNLOCK();
844 release_metapage(mp); 854 release_metapage(mp);
855 TXN_LOCK();
856 xtid = tlck->tid; /* reaquire after dropping TXN_LOCK */
845 857
846 jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d", 858 jfs_info("txLock: in waitLock, tid = %d, xtid = %d, lid = %d",
847 tid, xtid, lid); 859 tid, xtid, lid);
848 TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor); 860
861 /* Recheck everything since dropping TXN_LOCK */
862 if (xtid && (tlck->mp == mp) && (mp->lid == lid))
863 TXN_SLEEP_DROP_LOCK(&tid_to_tblock(xtid)->waitor);
864 else
865 TXN_UNLOCK();
849 jfs_info("txLock: awakened tid = %d, lid = %d", tid, lid); 866 jfs_info("txLock: awakened tid = %d, lid = %d", tid, lid);
850 867
851 return NULL; 868 return NULL;
@@ -906,6 +923,7 @@ static void txUnlock(struct tblock * tblk)
906 struct metapage *mp; 923 struct metapage *mp;
907 struct jfs_log *log; 924 struct jfs_log *log;
908 int difft, diffp; 925 int difft, diffp;
926 unsigned long flags;
909 927
910 jfs_info("txUnlock: tblk = 0x%p", tblk); 928 jfs_info("txUnlock: tblk = 0x%p", tblk);
911 log = JFS_SBI(tblk->sb)->log; 929 log = JFS_SBI(tblk->sb)->log;
@@ -925,19 +943,14 @@ static void txUnlock(struct tblock * tblk)
925 assert(mp->xflag & COMMIT_PAGE); 943 assert(mp->xflag & COMMIT_PAGE);
926 944
927 /* hold buffer 945 /* hold buffer
928 *
929 * It's possible that someone else has the metapage.
930 * The only things were changing are nohomeok, which
931 * is handled atomically, and clsn which is protected
932 * by the LOGSYNC_LOCK.
933 */ 946 */
934 hold_metapage(mp, 1); 947 hold_metapage(mp);
935 948
936 assert(atomic_read(&mp->nohomeok) > 0); 949 assert(mp->nohomeok > 0);
937 atomic_dec(&mp->nohomeok); 950 _metapage_homeok(mp);
938 951
939 /* inherit younger/larger clsn */ 952 /* inherit younger/larger clsn */
940 LOGSYNC_LOCK(log); 953 LOGSYNC_LOCK(log, flags);
941 if (mp->clsn) { 954 if (mp->clsn) {
942 logdiff(difft, tblk->clsn, log); 955 logdiff(difft, tblk->clsn, log);
943 logdiff(diffp, mp->clsn, log); 956 logdiff(diffp, mp->clsn, log);
@@ -945,16 +958,11 @@ static void txUnlock(struct tblock * tblk)
945 mp->clsn = tblk->clsn; 958 mp->clsn = tblk->clsn;
946 } else 959 } else
947 mp->clsn = tblk->clsn; 960 mp->clsn = tblk->clsn;
948 LOGSYNC_UNLOCK(log); 961 LOGSYNC_UNLOCK(log, flags);
949 962
950 assert(!(tlck->flag & tlckFREEPAGE)); 963 assert(!(tlck->flag & tlckFREEPAGE));
951 964
952 if (tlck->flag & tlckWRITEPAGE) { 965 put_metapage(mp);
953 write_metapage(mp);
954 } else {
955 /* release page which has been forced */
956 release_metapage(mp);
957 }
958 } 966 }
959 967
960 /* insert tlock, and linelock(s) of the tlock if any, 968 /* insert tlock, and linelock(s) of the tlock if any,
@@ -981,10 +989,10 @@ static void txUnlock(struct tblock * tblk)
981 * has been inserted in logsync list at txUpdateMap()) 989 * has been inserted in logsync list at txUpdateMap())
982 */ 990 */
983 if (tblk->lsn) { 991 if (tblk->lsn) {
984 LOGSYNC_LOCK(log); 992 LOGSYNC_LOCK(log, flags);
985 log->count--; 993 log->count--;
986 list_del(&tblk->synclist); 994 list_del(&tblk->synclist);
987 LOGSYNC_UNLOCK(log); 995 LOGSYNC_UNLOCK(log, flags);
988 } 996 }
989} 997}
990 998
@@ -1573,8 +1581,8 @@ static int dataLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1573 * the last entry, so don't bother logging this 1581 * the last entry, so don't bother logging this
1574 */ 1582 */
1575 mp->lid = 0; 1583 mp->lid = 0;
1576 hold_metapage(mp, 0); 1584 grab_metapage(mp);
1577 atomic_dec(&mp->nohomeok); 1585 metapage_homeok(mp);
1578 discard_metapage(mp); 1586 discard_metapage(mp);
1579 tlck->mp = NULL; 1587 tlck->mp = NULL;
1580 return 0; 1588 return 0;
@@ -1712,7 +1720,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1712 struct maplock *maplock; 1720 struct maplock *maplock;
1713 struct xdlistlock *xadlock; 1721 struct xdlistlock *xadlock;
1714 struct pxd_lock *pxdlock; 1722 struct pxd_lock *pxdlock;
1715 pxd_t *pxd; 1723 pxd_t *page_pxd;
1716 int next, lwm, hwm; 1724 int next, lwm, hwm;
1717 1725
1718 ip = tlck->ip; 1726 ip = tlck->ip;
@@ -1722,7 +1730,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1722 lrd->log.redopage.type = cpu_to_le16(LOG_XTREE); 1730 lrd->log.redopage.type = cpu_to_le16(LOG_XTREE);
1723 lrd->log.redopage.l2linesize = cpu_to_le16(L2XTSLOTSIZE); 1731 lrd->log.redopage.l2linesize = cpu_to_le16(L2XTSLOTSIZE);
1724 1732
1725 pxd = &lrd->log.redopage.pxd; 1733 page_pxd = &lrd->log.redopage.pxd;
1726 1734
1727 if (tlck->type & tlckBTROOT) { 1735 if (tlck->type & tlckBTROOT) {
1728 lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT); 1736 lrd->log.redopage.type |= cpu_to_le16(LOG_BTROOT);
@@ -1752,9 +1760,9 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1752 * applying the after-image to the meta-data page. 1760 * applying the after-image to the meta-data page.
1753 */ 1761 */
1754 lrd->type = cpu_to_le16(LOG_REDOPAGE); 1762 lrd->type = cpu_to_le16(LOG_REDOPAGE);
1755// *pxd = mp->cm_pxd; 1763// *page_pxd = mp->cm_pxd;
1756 PXDaddress(pxd, mp->index); 1764 PXDaddress(page_pxd, mp->index);
1757 PXDlength(pxd, 1765 PXDlength(page_pxd,
1758 mp->logical_size >> tblk->sb->s_blocksize_bits); 1766 mp->logical_size >> tblk->sb->s_blocksize_bits);
1759 lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); 1767 lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
1760 1768
@@ -1776,25 +1784,31 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1776 tlck->flag |= tlckUPDATEMAP; 1784 tlck->flag |= tlckUPDATEMAP;
1777 xadlock->flag = mlckALLOCXADLIST; 1785 xadlock->flag = mlckALLOCXADLIST;
1778 xadlock->count = next - lwm; 1786 xadlock->count = next - lwm;
1779 if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) { 1787 if ((xadlock->count <= 4) && (tblk->xflag & COMMIT_LAZY)) {
1780 int i; 1788 int i;
1789 pxd_t *pxd;
1781 /* 1790 /*
1782 * Lazy commit may allow xtree to be modified before 1791 * Lazy commit may allow xtree to be modified before
1783 * txUpdateMap runs. Copy xad into linelock to 1792 * txUpdateMap runs. Copy xad into linelock to
1784 * preserve correct data. 1793 * preserve correct data.
1794 *
1795 * We can fit twice as may pxd's as xads in the lock
1785 */ 1796 */
1786 xadlock->xdlist = &xtlck->pxdlock; 1797 xadlock->flag = mlckALLOCPXDLIST;
1787 memcpy(xadlock->xdlist, &p->xad[lwm], 1798 pxd = xadlock->xdlist = &xtlck->pxdlock;
1788 sizeof(xad_t) * xadlock->count); 1799 for (i = 0; i < xadlock->count; i++) {
1789 1800 PXDaddress(pxd, addressXAD(&p->xad[lwm + i]));
1790 for (i = 0; i < xadlock->count; i++) 1801 PXDlength(pxd, lengthXAD(&p->xad[lwm + i]));
1791 p->xad[lwm + i].flag &= 1802 p->xad[lwm + i].flag &=
1792 ~(XAD_NEW | XAD_EXTENDED); 1803 ~(XAD_NEW | XAD_EXTENDED);
1804 pxd++;
1805 }
1793 } else { 1806 } else {
1794 /* 1807 /*
1795 * xdlist will point to into inode's xtree, ensure 1808 * xdlist will point to into inode's xtree, ensure
1796 * that transaction is not committed lazily. 1809 * that transaction is not committed lazily.
1797 */ 1810 */
1811 xadlock->flag = mlckALLOCXADLIST;
1798 xadlock->xdlist = &p->xad[lwm]; 1812 xadlock->xdlist = &p->xad[lwm];
1799 tblk->xflag &= ~COMMIT_LAZY; 1813 tblk->xflag &= ~COMMIT_LAZY;
1800 } 1814 }
@@ -1836,8 +1850,8 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1836 if (tblk->xflag & COMMIT_TRUNCATE) { 1850 if (tblk->xflag & COMMIT_TRUNCATE) {
1837 /* write NOREDOPAGE for the page */ 1851 /* write NOREDOPAGE for the page */
1838 lrd->type = cpu_to_le16(LOG_NOREDOPAGE); 1852 lrd->type = cpu_to_le16(LOG_NOREDOPAGE);
1839 PXDaddress(pxd, mp->index); 1853 PXDaddress(page_pxd, mp->index);
1840 PXDlength(pxd, 1854 PXDlength(page_pxd,
1841 mp->logical_size >> tblk->sb-> 1855 mp->logical_size >> tblk->sb->
1842 s_blocksize_bits); 1856 s_blocksize_bits);
1843 lrd->backchain = 1857 lrd->backchain =
@@ -1872,22 +1886,32 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1872 * deleted page itself; 1886 * deleted page itself;
1873 */ 1887 */
1874 tlck->flag |= tlckUPDATEMAP; 1888 tlck->flag |= tlckUPDATEMAP;
1875 xadlock->flag = mlckFREEXADLIST;
1876 xadlock->count = hwm - XTENTRYSTART + 1; 1889 xadlock->count = hwm - XTENTRYSTART + 1;
1877 if ((xadlock->count <= 2) && (tblk->xflag & COMMIT_LAZY)) { 1890 if ((xadlock->count <= 4) && (tblk->xflag & COMMIT_LAZY)) {
1891 int i;
1892 pxd_t *pxd;
1878 /* 1893 /*
1879 * Lazy commit may allow xtree to be modified before 1894 * Lazy commit may allow xtree to be modified before
1880 * txUpdateMap runs. Copy xad into linelock to 1895 * txUpdateMap runs. Copy xad into linelock to
1881 * preserve correct data. 1896 * preserve correct data.
1897 *
1898 * We can fit twice as may pxd's as xads in the lock
1882 */ 1899 */
1883 xadlock->xdlist = &xtlck->pxdlock; 1900 xadlock->flag = mlckFREEPXDLIST;
1884 memcpy(xadlock->xdlist, &p->xad[XTENTRYSTART], 1901 pxd = xadlock->xdlist = &xtlck->pxdlock;
1885 sizeof(xad_t) * xadlock->count); 1902 for (i = 0; i < xadlock->count; i++) {
1903 PXDaddress(pxd,
1904 addressXAD(&p->xad[XTENTRYSTART + i]));
1905 PXDlength(pxd,
1906 lengthXAD(&p->xad[XTENTRYSTART + i]));
1907 pxd++;
1908 }
1886 } else { 1909 } else {
1887 /* 1910 /*
1888 * xdlist will point to into inode's xtree, ensure 1911 * xdlist will point to into inode's xtree, ensure
1889 * that transaction is not committed lazily. 1912 * that transaction is not committed lazily.
1890 */ 1913 */
1914 xadlock->flag = mlckFREEXADLIST;
1891 xadlock->xdlist = &p->xad[XTENTRYSTART]; 1915 xadlock->xdlist = &p->xad[XTENTRYSTART];
1892 tblk->xflag &= ~COMMIT_LAZY; 1916 tblk->xflag &= ~COMMIT_LAZY;
1893 } 1917 }
@@ -1918,7 +1942,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1918 * header ? 1942 * header ?
1919 */ 1943 */
1920 if (tlck->type & tlckTRUNCATE) { 1944 if (tlck->type & tlckTRUNCATE) {
1921 pxd_t tpxd; /* truncated extent of xad */ 1945 pxd_t pxd; /* truncated extent of xad */
1922 int twm; 1946 int twm;
1923 1947
1924 /* 1948 /*
@@ -1947,8 +1971,9 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1947 * applying the after-image to the meta-data page. 1971 * applying the after-image to the meta-data page.
1948 */ 1972 */
1949 lrd->type = cpu_to_le16(LOG_REDOPAGE); 1973 lrd->type = cpu_to_le16(LOG_REDOPAGE);
1950 PXDaddress(pxd, mp->index); 1974 PXDaddress(page_pxd, mp->index);
1951 PXDlength(pxd, mp->logical_size >> tblk->sb->s_blocksize_bits); 1975 PXDlength(page_pxd,
1976 mp->logical_size >> tblk->sb->s_blocksize_bits);
1952 lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck)); 1977 lrd->backchain = cpu_to_le32(lmLog(log, tblk, lrd, tlck));
1953 1978
1954 /* 1979 /*
@@ -1966,7 +1991,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
1966 lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD); 1991 lrd->log.updatemap.type = cpu_to_le16(LOG_FREEPXD);
1967 lrd->log.updatemap.nxd = cpu_to_le16(1); 1992 lrd->log.updatemap.nxd = cpu_to_le16(1);
1968 lrd->log.updatemap.pxd = pxdlock->pxd; 1993 lrd->log.updatemap.pxd = pxdlock->pxd;
1969 tpxd = pxdlock->pxd; /* save to format maplock */ 1994 pxd = pxdlock->pxd; /* save to format maplock */
1970 lrd->backchain = 1995 lrd->backchain =
1971 cpu_to_le32(lmLog(log, tblk, lrd, NULL)); 1996 cpu_to_le32(lmLog(log, tblk, lrd, NULL));
1972 } 1997 }
@@ -2035,7 +2060,7 @@ static void xtLog(struct jfs_log * log, struct tblock * tblk, struct lrd * lrd,
2035 pxdlock = (struct pxd_lock *) xadlock; 2060 pxdlock = (struct pxd_lock *) xadlock;
2036 pxdlock->flag = mlckFREEPXD; 2061 pxdlock->flag = mlckFREEPXD;
2037 pxdlock->count = 1; 2062 pxdlock->count = 1;
2038 pxdlock->pxd = tpxd; 2063 pxdlock->pxd = pxd;
2039 2064
2040 jfs_info("xtLog: truncate ip:0x%p mp:0x%p count:%d " 2065 jfs_info("xtLog: truncate ip:0x%p mp:0x%p count:%d "
2041 "hwm:%d", ip, mp, pxdlock->count, hwm); 2066 "hwm:%d", ip, mp, pxdlock->count, hwm);
@@ -2253,7 +2278,8 @@ void txForce(struct tblock * tblk)
2253 tlck->flag &= ~tlckWRITEPAGE; 2278 tlck->flag &= ~tlckWRITEPAGE;
2254 2279
2255 /* do not release page to freelist */ 2280 /* do not release page to freelist */
2256 2281 force_metapage(mp);
2282#if 0
2257 /* 2283 /*
2258 * The "right" thing to do here is to 2284 * The "right" thing to do here is to
2259 * synchronously write the metadata. 2285 * synchronously write the metadata.
@@ -2265,9 +2291,10 @@ void txForce(struct tblock * tblk)
2265 * we can get by with synchronously writing 2291 * we can get by with synchronously writing
2266 * the pages when they are released. 2292 * the pages when they are released.
2267 */ 2293 */
2268 assert(atomic_read(&mp->nohomeok)); 2294 assert(mp->nohomeok);
2269 set_bit(META_dirty, &mp->flag); 2295 set_bit(META_dirty, &mp->flag);
2270 set_bit(META_sync, &mp->flag); 2296 set_bit(META_sync, &mp->flag);
2297#endif
2271 } 2298 }
2272 } 2299 }
2273 } 2300 }
@@ -2327,7 +2354,7 @@ static void txUpdateMap(struct tblock * tblk)
2327 */ 2354 */
2328 mp = tlck->mp; 2355 mp = tlck->mp;
2329 ASSERT(mp->xflag & COMMIT_PAGE); 2356 ASSERT(mp->xflag & COMMIT_PAGE);
2330 hold_metapage(mp, 0); 2357 grab_metapage(mp);
2331 } 2358 }
2332 2359
2333 /* 2360 /*
@@ -2377,8 +2404,8 @@ static void txUpdateMap(struct tblock * tblk)
2377 ASSERT(mp->lid == lid); 2404 ASSERT(mp->lid == lid);
2378 tlck->mp->lid = 0; 2405 tlck->mp->lid = 0;
2379 } 2406 }
2380 assert(atomic_read(&mp->nohomeok) == 1); 2407 assert(mp->nohomeok == 1);
2381 atomic_dec(&mp->nohomeok); 2408 metapage_homeok(mp);
2382 discard_metapage(mp); 2409 discard_metapage(mp);
2383 tlck->mp = NULL; 2410 tlck->mp = NULL;
2384 } 2411 }
@@ -2844,24 +2871,9 @@ static void LogSyncRelease(struct metapage * mp)
2844{ 2871{
2845 struct jfs_log *log = mp->log; 2872 struct jfs_log *log = mp->log;
2846 2873
2847 assert(atomic_read(&mp->nohomeok)); 2874 assert(mp->nohomeok);
2848 assert(log); 2875 assert(log);
2849 atomic_dec(&mp->nohomeok); 2876 metapage_homeok(mp);
2850
2851 if (atomic_read(&mp->nohomeok))
2852 return;
2853
2854 hold_metapage(mp, 0);
2855
2856 LOGSYNC_LOCK(log);
2857 mp->log = NULL;
2858 mp->lsn = 0;
2859 mp->clsn = 0;
2860 log->count--;
2861 list_del_init(&mp->synclist);
2862 LOGSYNC_UNLOCK(log);
2863
2864 release_metapage(mp);
2865} 2877}
2866 2878
2867/* 2879/*
diff --git a/fs/jfs/jfs_umount.c b/fs/jfs/jfs_umount.c
index f31a9e3f3fec..5cf91785b541 100644
--- a/fs/jfs/jfs_umount.c
+++ b/fs/jfs/jfs_umount.c
@@ -49,7 +49,6 @@
49 */ 49 */
50int jfs_umount(struct super_block *sb) 50int jfs_umount(struct super_block *sb)
51{ 51{
52 struct address_space *bdev_mapping = sb->s_bdev->bd_inode->i_mapping;
53 struct jfs_sb_info *sbi = JFS_SBI(sb); 52 struct jfs_sb_info *sbi = JFS_SBI(sb);
54 struct inode *ipbmap = sbi->ipbmap; 53 struct inode *ipbmap = sbi->ipbmap;
55 struct inode *ipimap = sbi->ipimap; 54 struct inode *ipimap = sbi->ipimap;
@@ -109,8 +108,8 @@ int jfs_umount(struct super_block *sb)
109 * Make sure all metadata makes it to disk before we mark 108 * Make sure all metadata makes it to disk before we mark
110 * the superblock as clean 109 * the superblock as clean
111 */ 110 */
112 filemap_fdatawrite(bdev_mapping); 111 filemap_fdatawrite(sbi->direct_inode->i_mapping);
113 filemap_fdatawait(bdev_mapping); 112 filemap_fdatawait(sbi->direct_inode->i_mapping);
114 113
115 /* 114 /*
116 * ensure all file system file pages are propagated to their 115 * ensure all file system file pages are propagated to their
@@ -123,9 +122,6 @@ int jfs_umount(struct super_block *sb)
123 if (log) { /* log = NULL if read-only mount */ 122 if (log) { /* log = NULL if read-only mount */
124 updateSuper(sb, FM_CLEAN); 123 updateSuper(sb, FM_CLEAN);
125 124
126 /* Restore default gfp_mask for bdev */
127 mapping_set_gfp_mask(bdev_mapping, GFP_USER);
128
129 /* 125 /*
130 * close log: 126 * close log:
131 * 127 *
@@ -140,7 +136,6 @@ int jfs_umount(struct super_block *sb)
140 136
141int jfs_umount_rw(struct super_block *sb) 137int jfs_umount_rw(struct super_block *sb)
142{ 138{
143 struct address_space *bdev_mapping = sb->s_bdev->bd_inode->i_mapping;
144 struct jfs_sb_info *sbi = JFS_SBI(sb); 139 struct jfs_sb_info *sbi = JFS_SBI(sb);
145 struct jfs_log *log = sbi->log; 140 struct jfs_log *log = sbi->log;
146 141
@@ -166,13 +161,10 @@ int jfs_umount_rw(struct super_block *sb)
166 * mark the superblock clean before everything is flushed to 161 * mark the superblock clean before everything is flushed to
167 * disk. 162 * disk.
168 */ 163 */
169 filemap_fdatawrite(bdev_mapping); 164 filemap_fdatawrite(sbi->direct_inode->i_mapping);
170 filemap_fdatawait(bdev_mapping); 165 filemap_fdatawait(sbi->direct_inode->i_mapping);
171 166
172 updateSuper(sb, FM_CLEAN); 167 updateSuper(sb, FM_CLEAN);
173 168
174 /* Restore default gfp_mask for bdev */
175 mapping_set_gfp_mask(bdev_mapping, GFP_USER);
176
177 return lmLogClose(sb); 169 return lmLogClose(sb);
178} 170}
diff --git a/fs/jfs/jfs_xtree.c b/fs/jfs/jfs_xtree.c
index 11c58c54b818..2c1f311914a1 100644
--- a/fs/jfs/jfs_xtree.c
+++ b/fs/jfs/jfs_xtree.c
@@ -111,8 +111,8 @@ static struct {
111/* 111/*
112 * forward references 112 * forward references
113 */ 113 */
114static int xtSearch(struct inode *ip, 114static int xtSearch(struct inode *ip, s64 xoff, s64 *next, int *cmpp,
115 s64 xoff, int *cmpp, struct btstack * btstack, int flag); 115 struct btstack * btstack, int flag);
116 116
117static int xtSplitUp(tid_t tid, 117static int xtSplitUp(tid_t tid,
118 struct inode *ip, 118 struct inode *ip,
@@ -159,11 +159,12 @@ int xtLookup(struct inode *ip, s64 lstart,
159 xtpage_t *p; 159 xtpage_t *p;
160 int index; 160 int index;
161 xad_t *xad; 161 xad_t *xad;
162 s64 size, xoff, xend; 162 s64 next, size, xoff, xend;
163 int xlen; 163 int xlen;
164 s64 xaddr; 164 s64 xaddr;
165 165
166 *plen = 0; 166 *paddr = 0;
167 *plen = llen;
167 168
168 if (!no_check) { 169 if (!no_check) {
169 /* is lookup offset beyond eof ? */ 170 /* is lookup offset beyond eof ? */
@@ -180,7 +181,7 @@ int xtLookup(struct inode *ip, s64 lstart,
180 * search for the xad entry covering the logical extent 181 * search for the xad entry covering the logical extent
181 */ 182 */
182//search: 183//search:
183 if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) { 184 if ((rc = xtSearch(ip, lstart, &next, &cmp, &btstack, 0))) {
184 jfs_err("xtLookup: xtSearch returned %d", rc); 185 jfs_err("xtLookup: xtSearch returned %d", rc);
185 return rc; 186 return rc;
186 } 187 }
@@ -198,8 +199,11 @@ int xtLookup(struct inode *ip, s64 lstart,
198 * lstart is a page start address, 199 * lstart is a page start address,
199 * i.e., lstart cannot start in a hole; 200 * i.e., lstart cannot start in a hole;
200 */ 201 */
201 if (cmp) 202 if (cmp) {
203 if (next)
204 *plen = min(next - lstart, llen);
202 goto out; 205 goto out;
206 }
203 207
204 /* 208 /*
205 * lxd covered by xad 209 * lxd covered by xad
@@ -284,7 +288,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
284 if (lstart >= size) 288 if (lstart >= size)
285 return 0; 289 return 0;
286 290
287 if ((rc = xtSearch(ip, lstart, &cmp, &btstack, 0))) 291 if ((rc = xtSearch(ip, lstart, NULL, &cmp, &btstack, 0)))
288 return rc; 292 return rc;
289 293
290 /* 294 /*
@@ -488,6 +492,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
488 * parameters: 492 * parameters:
489 * ip - file object; 493 * ip - file object;
490 * xoff - extent offset; 494 * xoff - extent offset;
495 * nextp - address of next extent (if any) for search miss
491 * cmpp - comparison result: 496 * cmpp - comparison result:
492 * btstack - traverse stack; 497 * btstack - traverse stack;
493 * flag - search process flag (XT_INSERT); 498 * flag - search process flag (XT_INSERT);
@@ -497,7 +502,7 @@ int xtLookupList(struct inode *ip, struct lxdlist * lxdlist,
497 * *cmpp is set to result of comparison with the entry returned. 502 * *cmpp is set to result of comparison with the entry returned.
498 * the page containing the entry is pinned at exit. 503 * the page containing the entry is pinned at exit.
499 */ 504 */
500static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */ 505static int xtSearch(struct inode *ip, s64 xoff, s64 *nextp,
501 int *cmpp, struct btstack * btstack, int flag) 506 int *cmpp, struct btstack * btstack, int flag)
502{ 507{
503 struct jfs_inode_info *jfs_ip = JFS_IP(ip); 508 struct jfs_inode_info *jfs_ip = JFS_IP(ip);
@@ -511,6 +516,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
511 struct btframe *btsp; 516 struct btframe *btsp;
512 int nsplit = 0; /* number of pages to split */ 517 int nsplit = 0; /* number of pages to split */
513 s64 t64; 518 s64 t64;
519 s64 next = 0;
514 520
515 INCREMENT(xtStat.search); 521 INCREMENT(xtStat.search);
516 522
@@ -579,6 +585,7 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
579 * previous and this entry 585 * previous and this entry
580 */ 586 */
581 *cmpp = 1; 587 *cmpp = 1;
588 next = t64;
582 goto out; 589 goto out;
583 } 590 }
584 591
@@ -623,6 +630,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
623 /* update sequential access heuristics */ 630 /* update sequential access heuristics */
624 jfs_ip->btindex = index; 631 jfs_ip->btindex = index;
625 632
633 if (nextp)
634 *nextp = next;
635
626 INCREMENT(xtStat.fastSearch); 636 INCREMENT(xtStat.fastSearch);
627 return 0; 637 return 0;
628 } 638 }
@@ -675,10 +685,11 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
675 685
676 return 0; 686 return 0;
677 } 687 }
678
679 /* search hit - internal page: 688 /* search hit - internal page:
680 * descend/search its child page 689 * descend/search its child page
681 */ 690 */
691 if (index < p->header.nextindex - 1)
692 next = offsetXAD(&p->xad[index + 1]);
682 goto next; 693 goto next;
683 } 694 }
684 695
@@ -694,6 +705,8 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
694 * base is the smallest index with key (Kj) greater than 705 * base is the smallest index with key (Kj) greater than
695 * search key (K) and may be zero or maxentry index. 706 * search key (K) and may be zero or maxentry index.
696 */ 707 */
708 if (base < p->header.nextindex)
709 next = offsetXAD(&p->xad[base]);
697 /* 710 /*
698 * search miss - leaf page: 711 * search miss - leaf page:
699 * 712 *
@@ -727,6 +740,9 @@ static int xtSearch(struct inode *ip, s64 xoff, /* offset of extent */
727 jfs_ip->btorder = BT_RANDOM; 740 jfs_ip->btorder = BT_RANDOM;
728 jfs_ip->btindex = base; 741 jfs_ip->btindex = base;
729 742
743 if (nextp)
744 *nextp = next;
745
730 return 0; 746 return 0;
731 } 747 }
732 748
@@ -793,6 +809,7 @@ int xtInsert(tid_t tid, /* transaction id */
793 struct xtsplit split; /* split information */ 809 struct xtsplit split; /* split information */
794 xad_t *xad; 810 xad_t *xad;
795 int cmp; 811 int cmp;
812 s64 next;
796 struct tlock *tlck; 813 struct tlock *tlck;
797 struct xtlock *xtlck; 814 struct xtlock *xtlck;
798 815
@@ -806,7 +823,7 @@ int xtInsert(tid_t tid, /* transaction id */
806 * n.b. xtSearch() may return index of maxentry of 823 * n.b. xtSearch() may return index of maxentry of
807 * the full page. 824 * the full page.
808 */ 825 */
809 if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) 826 if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
810 return rc; 827 return rc;
811 828
812 /* retrieve search result */ 829 /* retrieve search result */
@@ -814,7 +831,7 @@ int xtInsert(tid_t tid, /* transaction id */
814 831
815 /* This test must follow XT_GETSEARCH since mp must be valid if 832 /* This test must follow XT_GETSEARCH since mp must be valid if
816 * we branch to out: */ 833 * we branch to out: */
817 if (cmp == 0) { 834 if ((cmp == 0) || (next && (xlen > next - xoff))) {
818 rc = -EEXIST; 835 rc = -EEXIST;
819 goto out; 836 goto out;
820 } 837 }
@@ -1626,7 +1643,7 @@ int xtExtend(tid_t tid, /* transaction id */
1626 jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen); 1643 jfs_info("xtExtend: nxoff:0x%lx nxlen:0x%x", (ulong) xoff, xlen);
1627 1644
1628 /* there must exist extent to be extended */ 1645 /* there must exist extent to be extended */
1629 if ((rc = xtSearch(ip, xoff - 1, &cmp, &btstack, XT_INSERT))) 1646 if ((rc = xtSearch(ip, xoff - 1, NULL, &cmp, &btstack, XT_INSERT)))
1630 return rc; 1647 return rc;
1631 1648
1632 /* retrieve search result */ 1649 /* retrieve search result */
@@ -1794,7 +1811,7 @@ printf("xtTailgate: nxoff:0x%lx nxlen:0x%x nxaddr:0x%lx\n",
1794*/ 1811*/
1795 1812
1796 /* there must exist extent to be tailgated */ 1813 /* there must exist extent to be tailgated */
1797 if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) 1814 if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, XT_INSERT)))
1798 return rc; 1815 return rc;
1799 1816
1800 /* retrieve search result */ 1817 /* retrieve search result */
@@ -1977,7 +1994,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
1977 nxlen = lengthXAD(nxad); 1994 nxlen = lengthXAD(nxad);
1978 nxaddr = addressXAD(nxad); 1995 nxaddr = addressXAD(nxad);
1979 1996
1980 if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) 1997 if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
1981 return rc; 1998 return rc;
1982 1999
1983 /* retrieve search result */ 2000 /* retrieve search result */
@@ -2291,7 +2308,7 @@ int xtUpdate(tid_t tid, struct inode *ip, xad_t * nxad)
2291 if (nextindex == le16_to_cpu(p->header.maxentry)) { 2308 if (nextindex == le16_to_cpu(p->header.maxentry)) {
2292 XT_PUTPAGE(mp); 2309 XT_PUTPAGE(mp);
2293 2310
2294 if ((rc = xtSearch(ip, nxoff, &cmp, &btstack, XT_INSERT))) 2311 if ((rc = xtSearch(ip, nxoff, NULL, &cmp, &btstack, XT_INSERT)))
2295 return rc; 2312 return rc;
2296 2313
2297 /* retrieve search result */ 2314 /* retrieve search result */
@@ -2438,6 +2455,7 @@ int xtAppend(tid_t tid, /* transaction id */
2438 int nsplit, nblocks, xlen; 2455 int nsplit, nblocks, xlen;
2439 struct pxdlist pxdlist; 2456 struct pxdlist pxdlist;
2440 pxd_t *pxd; 2457 pxd_t *pxd;
2458 s64 next;
2441 2459
2442 xaddr = *xaddrp; 2460 xaddr = *xaddrp;
2443 xlen = *xlenp; 2461 xlen = *xlenp;
@@ -2452,7 +2470,7 @@ int xtAppend(tid_t tid, /* transaction id */
2452 * n.b. xtSearch() may return index of maxentry of 2470 * n.b. xtSearch() may return index of maxentry of
2453 * the full page. 2471 * the full page.
2454 */ 2472 */
2455 if ((rc = xtSearch(ip, xoff, &cmp, &btstack, XT_INSERT))) 2473 if ((rc = xtSearch(ip, xoff, &next, &cmp, &btstack, XT_INSERT)))
2456 return rc; 2474 return rc;
2457 2475
2458 /* retrieve search result */ 2476 /* retrieve search result */
@@ -2462,6 +2480,9 @@ int xtAppend(tid_t tid, /* transaction id */
2462 rc = -EEXIST; 2480 rc = -EEXIST;
2463 goto out; 2481 goto out;
2464 } 2482 }
2483
2484 if (next)
2485 xlen = min(xlen, (int)(next - xoff));
2465//insert: 2486//insert:
2466 /* 2487 /*
2467 * insert entry for new extent 2488 * insert entry for new extent
@@ -2600,7 +2621,7 @@ int xtDelete(tid_t tid, struct inode *ip, s64 xoff, s32 xlen, int flag)
2600 /* 2621 /*
2601 * find the matching entry; xtSearch() pins the page 2622 * find the matching entry; xtSearch() pins the page
2602 */ 2623 */
2603 if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0))) 2624 if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
2604 return rc; 2625 return rc;
2605 2626
2606 XT_GETSEARCH(ip, btstack.top, bn, mp, p, index); 2627 XT_GETSEARCH(ip, btstack.top, bn, mp, p, index);
@@ -2852,7 +2873,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
2852 */ 2873 */
2853 if (xtype == DATAEXT) { 2874 if (xtype == DATAEXT) {
2854 /* search in leaf entry */ 2875 /* search in leaf entry */
2855 rc = xtSearch(ip, xoff, &cmp, &btstack, 0); 2876 rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
2856 if (rc) 2877 if (rc)
2857 return rc; 2878 return rc;
2858 2879
@@ -2958,7 +2979,7 @@ xtRelocate(tid_t tid, struct inode * ip, xad_t * oxad, /* old XAD */
2958 } 2979 }
2959 2980
2960 /* get back parent page */ 2981 /* get back parent page */
2961 if ((rc = xtSearch(ip, xoff, &cmp, &btstack, 0))) 2982 if ((rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0)))
2962 return rc; 2983 return rc;
2963 2984
2964 XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index); 2985 XT_GETSEARCH(ip, btstack.top, bn, pmp, pp, index);
@@ -3991,7 +4012,7 @@ s64 xtTruncate_pmap(tid_t tid, struct inode *ip, s64 committed_size)
3991 4012
3992 if (committed_size) { 4013 if (committed_size) {
3993 xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1; 4014 xoff = (committed_size >> JFS_SBI(ip->i_sb)->l2bsize) - 1;
3994 rc = xtSearch(ip, xoff, &cmp, &btstack, 0); 4015 rc = xtSearch(ip, xoff, NULL, &cmp, &btstack, 0);
3995 if (rc) 4016 if (rc)
3996 return rc; 4017 return rc;
3997 4018
diff --git a/fs/jfs/resize.c b/fs/jfs/resize.c
index 2eb6869b6e72..c6dc254d3253 100644
--- a/fs/jfs/resize.c
+++ b/fs/jfs/resize.c
@@ -209,6 +209,9 @@ int jfs_extendfs(struct super_block *sb, s64 newLVSize, int newLogSize)
209 */ 209 */
210 txQuiesce(sb); 210 txQuiesce(sb);
211 211
212 /* Reset size of direct inode */
213 sbi->direct_inode->i_size = sb->s_bdev->bd_inode->i_size;
214
212 if (sbi->mntflag & JFS_INLINELOG) { 215 if (sbi->mntflag & JFS_INLINELOG) {
213 /* 216 /*
214 * deactivate old inline log 217 * deactivate old inline log
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 5856866e24fc..5e774ed7fb64 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -210,6 +210,10 @@ static void jfs_put_super(struct super_block *sb)
210 unload_nls(sbi->nls_tab); 210 unload_nls(sbi->nls_tab);
211 sbi->nls_tab = NULL; 211 sbi->nls_tab = NULL;
212 212
213 truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
214 iput(sbi->direct_inode);
215 sbi->direct_inode = NULL;
216
213 kfree(sbi); 217 kfree(sbi);
214} 218}
215 219
@@ -358,6 +362,12 @@ static int jfs_remount(struct super_block *sb, int *flags, char *data)
358 } 362 }
359 363
360 if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) { 364 if ((sb->s_flags & MS_RDONLY) && !(*flags & MS_RDONLY)) {
365 /*
366 * Invalidate any previously read metadata. fsck may have
367 * changed the on-disk data since we mounted r/o
368 */
369 truncate_inode_pages(JFS_SBI(sb)->direct_inode->i_mapping, 0);
370
361 JFS_SBI(sb)->flag = flag; 371 JFS_SBI(sb)->flag = flag;
362 return jfs_mount_rw(sb, 1); 372 return jfs_mount_rw(sb, 1);
363 } 373 }
@@ -428,12 +438,26 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
428 sb->s_op = &jfs_super_operations; 438 sb->s_op = &jfs_super_operations;
429 sb->s_export_op = &jfs_export_operations; 439 sb->s_export_op = &jfs_export_operations;
430 440
441 /*
442 * Initialize direct-mapping inode/address-space
443 */
444 inode = new_inode(sb);
445 if (inode == NULL)
446 goto out_kfree;
447 inode->i_ino = 0;
448 inode->i_nlink = 1;
449 inode->i_size = sb->s_bdev->bd_inode->i_size;
450 inode->i_mapping->a_ops = &jfs_metapage_aops;
451 mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
452
453 sbi->direct_inode = inode;
454
431 rc = jfs_mount(sb); 455 rc = jfs_mount(sb);
432 if (rc) { 456 if (rc) {
433 if (!silent) { 457 if (!silent) {
434 jfs_err("jfs_mount failed w/return code = %d", rc); 458 jfs_err("jfs_mount failed w/return code = %d", rc);
435 } 459 }
436 goto out_kfree; 460 goto out_mount_failed;
437 } 461 }
438 if (sb->s_flags & MS_RDONLY) 462 if (sb->s_flags & MS_RDONLY)
439 sbi->log = NULL; 463 sbi->log = NULL;
@@ -482,6 +506,13 @@ out_no_rw:
482 if (rc) { 506 if (rc) {
483 jfs_err("jfs_umount failed with return code %d", rc); 507 jfs_err("jfs_umount failed with return code %d", rc);
484 } 508 }
509out_mount_failed:
510 filemap_fdatawrite(sbi->direct_inode->i_mapping);
511 filemap_fdatawait(sbi->direct_inode->i_mapping);
512 truncate_inode_pages(sbi->direct_inode->i_mapping, 0);
513 make_bad_inode(sbi->direct_inode);
514 iput(sbi->direct_inode);
515 sbi->direct_inode = NULL;
485out_kfree: 516out_kfree:
486 if (sbi->nls_tab) 517 if (sbi->nls_tab)
487 unload_nls(sbi->nls_tab); 518 unload_nls(sbi->nls_tab);
@@ -527,8 +558,10 @@ static int jfs_sync_fs(struct super_block *sb, int wait)
527 struct jfs_log *log = JFS_SBI(sb)->log; 558 struct jfs_log *log = JFS_SBI(sb)->log;
528 559
529 /* log == NULL indicates read-only mount */ 560 /* log == NULL indicates read-only mount */
530 if (log) 561 if (log) {
531 jfs_flush_journal(log, wait); 562 jfs_flush_journal(log, wait);
563 jfs_syncpt(log);
564 }
532 565
533 return 0; 566 return 0;
534} 567}