summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Kleikamp <shaggy@austin.ibm.com>2005-10-04 00:32:11 +0400
committerDave Kleikamp <shaggy@austin.ibm.com>2005-10-04 00:32:11 +0400
commitac17b8b57013a3e38d1958f66a218f15659e5752 (patch)
treef7a28ccd5bd5496f6a2284f3d77a5019dc75c820
parentddea7be0ec8d1374f0b483a81566ed56ec9f3905 (diff)
downloadlinux-ac17b8b57013a3e38d1958f66a218f15659e5752.tar.xz
JFS: make special inodes play nicely with page balancing
This patch fixes up a few problems with jfs's reserved inodes. 1. There is no need for the jfs code setting the I_DIRTY bits in i_state. I am ashamed that the code ever did this, and surprised it hasn't been noticed until now. 2. Make sure special inodes are on an inode hash list. If the inodes are unhashed, __mark_inode_dirty will fail to put the inode on the superblock's dirty list, and the data will not be flushed under memory pressure. 3. Force writing journal data to disk when metapage_writepage is unable to write a metadata page due to pending journal I/O. Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
-rw-r--r--fs/jfs/jfs_dmap.c1
-rw-r--r--fs/jfs/jfs_imap.c10
-rw-r--r--fs/jfs/jfs_metapage.c6
-rw-r--r--fs/jfs/jfs_txnmgr.c2
-rw-r--r--fs/jfs/super.c1
5 files changed, 15 insertions, 5 deletions
diff --git a/fs/jfs/jfs_dmap.c b/fs/jfs/jfs_dmap.c
index eadf319bee22..51c02bf07878 100644
--- a/fs/jfs/jfs_dmap.c
+++ b/fs/jfs/jfs_dmap.c
@@ -305,7 +305,6 @@ int dbSync(struct inode *ipbmap)
filemap_fdatawrite(ipbmap->i_mapping);
filemap_fdatawait(ipbmap->i_mapping);
- ipbmap->i_state |= I_DIRTY;
diWriteSpecial(ipbmap, 0);
return (0);
diff --git a/fs/jfs/jfs_imap.c b/fs/jfs/jfs_imap.c
index 4021d46da7e3..28201b194f53 100644
--- a/fs/jfs/jfs_imap.c
+++ b/fs/jfs/jfs_imap.c
@@ -57,6 +57,12 @@
#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
*/
/* iag free list lock */
@@ -491,6 +497,8 @@ struct inode *diReadSpecial(struct super_block *sb, ino_t inum, int secondary)
/* release the page */
release_metapage(mp);
+ hlist_add_head(&ip->i_hash, &aggregate_hash);
+
return (ip);
}
@@ -514,8 +522,6 @@ void diWriteSpecial(struct inode *ip, int secondary)
ino_t inum = ip->i_ino;
struct metapage *mp;
- ip->i_state &= ~I_DIRTY;
-
if (secondary)
address = addressPXD(&sbi->ait2) >> sbi->l2nbperpage;
else
diff --git a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
index 13d7e3f1feb4..c81c6438fce5 100644
--- a/fs/jfs/jfs_metapage.c
+++ b/fs/jfs/jfs_metapage.c
@@ -395,6 +395,12 @@ static int metapage_writepage(struct page *page, struct writeback_control *wbc)
if (mp->nohomeok && !test_bit(META_forcewrite, &mp->flag)) {
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;
}
diff --git a/fs/jfs/jfs_txnmgr.c b/fs/jfs/jfs_txnmgr.c
index 9b71ed2674fe..b660c93c92de 100644
--- a/fs/jfs/jfs_txnmgr.c
+++ b/fs/jfs/jfs_txnmgr.c
@@ -2396,7 +2396,6 @@ static void txUpdateMap(struct tblock * tblk)
*/
if (tblk->xflag & COMMIT_CREATE) {
diUpdatePMap(ipimap, tblk->ino, FALSE, tblk);
- ipimap->i_state |= I_DIRTY;
/* update persistent block allocation map
* for the allocation of inode extent;
*/
@@ -2407,7 +2406,6 @@ static void txUpdateMap(struct tblock * tblk)
} else if (tblk->xflag & COMMIT_DELETE) {
ip = tblk->u.ip;
diUpdatePMap(ipimap, ip->i_ino, TRUE, tblk);
- ipimap->i_state |= I_DIRTY;
iput(ip);
}
}
diff --git a/fs/jfs/super.c b/fs/jfs/super.c
index 71bc34b96b2b..4226af3ea91b 100644
--- a/fs/jfs/super.c
+++ b/fs/jfs/super.c
@@ -442,6 +442,7 @@ static int jfs_fill_super(struct super_block *sb, void *data, int silent)
inode->i_nlink = 1;
inode->i_size = sb->s_bdev->bd_inode->i_size;
inode->i_mapping->a_ops = &jfs_metapage_aops;
+ insert_inode_hash(inode);
mapping_set_gfp_mask(inode->i_mapping, GFP_NOFS);
sbi->direct_inode = inode;