Commit 8caf8915 authored by Linus Torvalds's avatar Linus Torvalds
parents f12baeab 7038f1cb
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno, static void dbAllocBits(struct bmap * bmp, struct dmap * dp, s64 blkno,
int nblocks); int nblocks);
static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval); static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval);
static void dbBackSplit(dmtree_t * tp, int leafno); static int dbBackSplit(dmtree_t * tp, int leafno);
static int dbJoin(dmtree_t * tp, int leafno, int newval); static int dbJoin(dmtree_t * tp, int leafno, int newval);
static void dbAdjTree(dmtree_t * tp, int leafno, int newval); static void dbAdjTree(dmtree_t * tp, int leafno, int newval);
static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, static int dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc,
...@@ -305,7 +305,6 @@ int dbSync(struct inode *ipbmap) ...@@ -305,7 +305,6 @@ int dbSync(struct inode *ipbmap)
filemap_fdatawrite(ipbmap->i_mapping); filemap_fdatawrite(ipbmap->i_mapping);
filemap_fdatawait(ipbmap->i_mapping); filemap_fdatawait(ipbmap->i_mapping);
ipbmap->i_state |= I_DIRTY;
diWriteSpecial(ipbmap, 0); diWriteSpecial(ipbmap, 0);
return (0); return (0);
...@@ -2467,7 +2466,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level) ...@@ -2467,7 +2466,9 @@ dbAdjCtl(struct bmap * bmp, s64 blkno, int newval, int alloc, int level)
* that it is at the front of a binary buddy system. * that it is at the front of a binary buddy system.
*/ */
if (oldval == NOFREE) { if (oldval == NOFREE) {
dbBackSplit((dmtree_t *) dcp, leafno); rc = dbBackSplit((dmtree_t *) dcp, leafno);
if (rc)
return rc;
oldval = dcp->stree[ti]; oldval = dcp->stree[ti];
} }
dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval); dbSplit((dmtree_t *) dcp, leafno, dcp->budmin, newval);
...@@ -2627,7 +2628,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval) ...@@ -2627,7 +2628,7 @@ static void dbSplit(dmtree_t * tp, int leafno, int splitsz, int newval)
* *
* serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit; * serialization: IREAD_LOCK(ipbmap) or IWRITE_LOCK(ipbmap) held on entry/exit;
*/ */
static void dbBackSplit(dmtree_t * tp, int leafno) static int dbBackSplit(dmtree_t * tp, int leafno)
{ {
int budsz, bud, w, bsz, size; int budsz, bud, w, bsz, size;
int cursz; int cursz;
...@@ -2662,7 +2663,10 @@ static void dbBackSplit(dmtree_t * tp, int leafno) ...@@ -2662,7 +2663,10 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
*/ */
for (w = leafno, bsz = budsz;; bsz <<= 1, for (w = leafno, bsz = budsz;; bsz <<= 1,
w = (w < bud) ? w : bud) { w = (w < bud) ? w : bud) {
assert(bsz < le32_to_cpu(tp->dmt_nleafs)); if (bsz >= le32_to_cpu(tp->dmt_nleafs)) {
jfs_err("JFS: block map error in dbBackSplit");
return -EIO;
}
/* determine the buddy. /* determine the buddy.
*/ */
...@@ -2681,7 +2685,11 @@ static void dbBackSplit(dmtree_t * tp, int leafno) ...@@ -2681,7 +2685,11 @@ static void dbBackSplit(dmtree_t * tp, int leafno)
} }
} }
assert(leaf[leafno] == size); if (leaf[leafno] != size) {
jfs_err("JFS: wrong leaf value in dbBackSplit");
return -EIO;
}
return 0;
} }
......
...@@ -56,6 +56,12 @@ ...@@ -56,6 +56,12 @@
#include "jfs_superblock.h" #include "jfs_superblock.h"
#include "jfs_debug.h" #include "jfs_debug.h"
/*
* __mark_inode_dirty expects inodes to be hashed. Since we don't want
* special inodes in the fileset inode space, we hash them to a dummy head
*/
static HLIST_HEAD(aggregate_hash);
/* /*
* imap locks * imap locks
*/ */
...@@ -491,6 +497,8 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary) ...@@ -491,6 +497,8 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
/* release the page */ /* release the page */
release_metapage(mp); release_metapage(mp);
hlist_add_head(&ip->i_hash, &aggregate_hash);
return (ip); return (ip);
} }
...@@ -514,8 +522,6 @@ void diWriteSpecial(struct inode *ip, int secondary) ...@@ -514,8 +522,6 @@ void diWriteSpecial(struct inode *ip, int secondary)
ino_t inum = ip->i_ino; ino_t inum = ip->i_ino;
struct metapage *mp; struct metapage *mp;
ip->i_state &= ~I_DIRTY;
if (secondary) if (secondary)
address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage; address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
else else
......
...@@ -395,6 +395,12 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc) ...@@ -395,6 +395,12 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc)
if (mp->nohomeok && !test_bit(META_forcewrite, &mp->flag)) { if (mp->nohomeok && !test_bit(META_forcewrite, &mp->flag)) {
redirty = 1; redirty = 1;
/*
* Make sure this page isn't blocked indefinitely.
* If the journal isn't undergoing I/O, push it
*/
if (mp->log && !(mp->log->cflag & logGC_PAGEOUT))
jfs_flush_journal(mp->log, 0);
continue; continue;
} }
......
...@@ -2396,7 +2396,6 @@ static void txUpdateMap(struct tblock * tblk) ...@@ -2396,7 +2396,6 @@ static void txUpdateMap(struct tblock * tblk)
*/ */
if (tblk->xflag & COMMIT_CREATE) { if (tblk->xflag & COMMIT_CREATE) {
diUpdatePMap(ipimap, tblk->ino, FALSE, tblk); diUpdatePMap(ipimap, tblk->ino, FALSE, tblk);
ipimap->i_state |= I_DIRTY;
/* update persistent block allocation map /* update persistent block allocation map
* for the allocation of inode extent; * for the allocation of inode extent;
*/ */
...@@ -2407,7 +2406,6 @@ static void txUpdateMap(struct tblock * tblk) ...@@ -2407,7 +2406,6 @@ static void txUpdateMap(struct tblock * tblk)
} else if (tblk->xflag & COMMIT_DELETE) { } else if (tblk->xflag & COMMIT_DELETE) {
ip = tblk->u.ip; ip = tblk->u.ip;
diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk); diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
ipimap->i_state |= I_DIRTY;
iput(ip); iput(ip);
} }
} }
......
...@@ -3516,16 +3516,10 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) ...@@ -3516,16 +3516,10 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
/* process entries backward from last index */ /* process entries backward from last index */
index = le16_to_cpu(p->header.nextindex) - 1; index = le16_to_cpu(p->header.nextindex) - 1;
if (p->header.flag & BT_INTERNAL)
goto getChild;
/*
* leaf page
*/
/* Since this is the rightmost leaf, and we may have already freed /* Since this is the rightmost page at this level, and we may have
* a page that was formerly to the right, let's make sure that the * already freed a page that was formerly to the right, let's make
* next pointer is zero. * sure that the next pointer is zero.
*/ */
if (p->header.next) { if (p->header.next) {
if (log) if (log)
...@@ -3539,6 +3533,12 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag) ...@@ -3539,6 +3533,12 @@ s64 xtTruncate(tid_t tid, struct inode *ip, s64 newsize, int flag)
p->header.next = 0; p->header.next = 0;
} }
if (p->header.flag & BT_INTERNAL)
goto getChild;
/*
* leaf page
*/
freed = 0; freed = 0;
/* does region covered by leaf page precede Teof ? */ /* does region covered by leaf page precede Teof ? */
......
...@@ -442,6 +442,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent) ...@@ -442,6 +442,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
inode->i_nlink = 1; inode->i_nlink = 1;
inode->i_size = sb->s_bdev->bd_inode->i_size; inode->i_size = sb->s_bdev->bd_inode->i_size;
inode->i_mapping->a_ops = &jfs_metapage_aops; inode->i_mapping->a_ops = &jfs_metapage_aops;
insert_inode_hash(inode);
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS); mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
sbi->direct_inode = inode; sbi->direct_inode = inode;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment