JFS: make special inodes play nicely with page balancing
authorDave Kleikamp <shaggy@austin.ibm.com>
Mon, 3 Oct 2005 20:32:11 +0000 (15:32 -0500)
committerDave Kleikamp <shaggy@austin.ibm.com>
Mon, 3 Oct 2005 20:32:11 +0000 (15:32 -0500)
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>
fs/jfs/jfs_dmap.c
fs/jfs/jfs_imap.c
fs/jfs/jfs_metapage.c
fs/jfs/jfs_txnmgr.c
fs/jfs/super.c

index eadf319bee22a67eca765ba30c0fac74ca46d020..51c02bf07878bf7e1e4862e929e6027687dfa0d3 100644 (file)
@@ -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);
index 4021d46da7e3f0e2dc86dab69282e80650873fd9..28201b194f531ba10aa819abccb030bc7ea88cd0 100644 (file)
 #include "jfs_superblock.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
  */
@@ -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
index 13d7e3f1feb4e0c8a0d18462fd5cfb657702da1f..c81c6438fce5c495fbc2930dcd3a1d302c364683 100644 (file)
@@ -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;
                }
 
index 9b71ed2674fea963399f615bf8b9e478b86b1e4f..b660c93c92deaf112c7b7955743c41e6a39c929a 100644 (file)
@@ -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);
        }
 }
index 71bc34b96b2b89d81a0086265aacba9be8b509d6..4226af3ea91bc18dbdf414f63738101babca9cf8 100644 (file)
@@ -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;