]> git.hungrycats.org Git - linux/commitdiff
[PATCH] remove i_dirty_data_buffers
authorAndrew Morton <akpm@zip.com.au>
Tue, 30 Apr 2002 06:53:20 +0000 (23:53 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Tue, 30 Apr 2002 06:53:20 +0000 (23:53 -0700)
Removes inode.i_dirty_data_buffers.  It's no longer used - all dirty
buffers have their pages marked dirty and filemap_fdatasync() /
filemap_fdatawait() catches it all.

Updates all callers.

This required a change in JFS - it has "metapages" which
are a container around a page which holds metadata.  They
were holding these pages locked and were relying on fsync_inode_data_buffers
for writing them out.  So fdatasync() deadlocked.

I've changed JFS to not lock those pages.  Change was acked
by Dave Kleikamp <shaggy@austin.ibm.com> as the right
thing to do, but may not be complete.  Probably igrab()
against ->host is needed to pin the address_space down.

17 files changed:
fs/buffer.c
fs/ext2/fsync.c
fs/ext3/fsync.c
fs/inode.c
fs/jfs/file.c
fs/jfs/jfs_dmap.c
fs/jfs/jfs_imap.c
fs/jfs/jfs_logmgr.c
fs/jfs/jfs_metapage.c
fs/jfs/jfs_txnmgr.c
fs/jfs/super.c
fs/minix/file.c
fs/reiserfs/file.c
fs/sysv/file.c
fs/udf/fsync.c
include/linux/fs.h
mm/filemap.c

index 88bb9b9f297d4831ceaf8d4e8b4c4952d3888176..fc575fd54f017e81c9ce06353e22f637d092899a 100644 (file)
@@ -428,8 +428,7 @@ int inode_has_buffers(struct inode *inode)
        int ret;
        
        spin_lock(&inode->i_bufferlist_lock);
-       ret = !list_empty(&inode->i_dirty_buffers) ||
-                       !list_empty(&inode->i_dirty_data_buffers);
+       ret = !list_empty(&inode->i_dirty_buffers);
        spin_unlock(&inode->i_bufferlist_lock);
        
        return ret;
@@ -694,9 +693,6 @@ void invalidate_inode_buffers(struct inode *inode)
        while ((entry = inode->i_dirty_buffers.next) !=
                                &inode->i_dirty_buffers)
                __remove_inode_queue(BH_ENTRY(entry));
-       while ((entry = inode->i_dirty_data_buffers.next) !=
-                               &inode->i_dirty_data_buffers)
-               __remove_inode_queue(BH_ENTRY(entry));
        spin_unlock(&inode->i_bufferlist_lock);
 }
 
@@ -954,10 +950,6 @@ __getblk(struct block_device *bdev, sector_t block, int size)
  * block_read_full_page() against that page will discover all the uptodate
  * buffers, will set the page uptodate and will perform no I/O.
  */
-static inline void __mark_dirty(struct buffer_head *bh)
-{
-       __set_page_dirty_nobuffers(bh->b_page);
-}
 
 /**
  * mark_buffer_dirty - mark a buffer_head as needing writeout
@@ -973,7 +965,7 @@ static inline void __mark_dirty(struct buffer_head *bh)
 void mark_buffer_dirty(struct buffer_head *bh)
 {
        if (!atomic_set_buffer_dirty(bh))
-               __mark_dirty(bh);
+               __set_page_dirty_nobuffers(bh->b_page);
 }
 
 /*
@@ -1498,10 +1490,7 @@ static int __block_commit_write(struct inode *inode, struct page *page,
                                partial = 1;
                } else {
                        mark_buffer_uptodate(bh, 1);
-                       if (!atomic_set_buffer_dirty(bh)) {
-                               __mark_dirty(bh);
-                               buffer_insert_inode_data_queue(bh, inode);
-                       }
+                       mark_buffer_dirty(bh);
                }
        }
 
index 17caa2fee0503a058412ce7cbb9a3c683cce3316..71ac1701a3a47e51d50bddde6e1e2c8bf583965c 100644 (file)
@@ -38,7 +38,6 @@ int ext2_sync_file(struct file * file, struct dentry *dentry, int datasync)
        int err;
        
        err  = fsync_inode_buffers(inode);
-       err |= fsync_inode_data_buffers(inode);
        if (!(inode->i_state & I_DIRTY))
                return err;
        if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
index e474547eb3e248aa190bc418adb4b5f99e5a5329..8266f2408664debc108fce94c521303bce3b603e 100644 (file)
@@ -62,8 +62,6 @@ int ext3_sync_file(struct file * file, struct dentry *dentry, int datasync)
         * we'll end up waiting on them in commit.
         */
        ret = fsync_inode_buffers(inode);
-       ret |= fsync_inode_data_buffers(inode);
-
        ext3_force_commit(inode->i_sb);
 
        return ret;
index 3cc5dd6abbc3a0144b0da11473cdc48b92e7be07..61e3f66787371b85fd37b6305db971b71678f927 100644 (file)
@@ -140,7 +140,6 @@ void inode_init_once(struct inode *inode)
        INIT_LIST_HEAD(&inode->i_data.io_pages);
        INIT_LIST_HEAD(&inode->i_dentry);
        INIT_LIST_HEAD(&inode->i_dirty_buffers);
-       INIT_LIST_HEAD(&inode->i_dirty_data_buffers);
        INIT_LIST_HEAD(&inode->i_devices);
        sema_init(&inode->i_sem, 1);
        INIT_RADIX_TREE(&inode->i_data.page_tree, GFP_ATOMIC);
index 0c0fa3e29bcde7e1bda5bbd2b0317d924b38da6e..b926fb7ffacddecaeec19ed3147401d34ebf6ef3 100644 (file)
@@ -33,8 +33,6 @@ int jfs_fsync(struct file *file, struct dentry *dentry, int datasync)
        struct inode *inode = dentry->d_inode;
        int rc = 0;
 
-       rc = fsync_inode_data_buffers(inode);
-
        if (!(inode->i_state & I_DIRTY))
                return rc;
        if (datasync || !(inode->i_state & I_DIRTY_DATASYNC))
index 49ef167944d8d3973f298759f4da63654ed4de5f..644ec9efb321ebe0c8e226f4564529459e9f1565 100644 (file)
@@ -325,7 +325,8 @@ int dbSync(struct inode *ipbmap)
        /*
         * write out dirty pages of bmap
         */
-       fsync_inode_data_buffers(ipbmap);
+       filemap_fdatasync(ipbmap->i_mapping);
+       filemap_fdatawait(ipbmap->i_mapping);
 
        ipbmap->i_state |= I_DIRTY;
        diWriteSpecial(ipbmap);
index bc5cfd0bfd275b7bfd293e84d41c2ada0893b124..88f8c02513caca68603ffc4ee9e1029251e7713c 100644 (file)
@@ -282,7 +282,8 @@ int diSync(struct inode *ipimap)
        /*
         * write out dirty pages of imap
         */
-       fsync_inode_data_buffers(ipimap);
+       filemap_fdatasync(ipimap->i_mapping);
+       filemap_fdatawait(ipimap->i_mapping);
 
        diWriteSpecial(ipimap);
 
@@ -607,7 +608,8 @@ void diFreeSpecial(struct inode *ip)
                jERROR(1, ("diFreeSpecial called with NULL ip!\n"));
                return;
        }
-       fsync_inode_data_buffers(ip);
+       filemap_fdatasync(ip->i_mapping);
+       filemap_fdatawait(ip->i_mapping);
        truncate_inode_pages(ip->i_mapping, 0);
        iput(ip);
 }
index b774b32760bf057ea4f8b69e2ef1a38c6530ea44..ee3abdc2ffde82ad49afe3ff604ff52e145284a5 100644 (file)
@@ -966,9 +966,12 @@ int lmLogSync(log_t * log, int nosyncwait)
                 * We need to make sure all of the "written" metapages
                 * actually make it to disk
                 */
-               fsync_inode_data_buffers(sbi->ipbmap);
-               fsync_inode_data_buffers(sbi->ipimap);
-               fsync_inode_data_buffers(sbi->direct_inode);
+               filemap_fdatasync(sbi->ipbmap->i_mapping);
+               filemap_fdatasync(sbi->ipimap->i_mapping);
+               filemap_fdatasync(sbi->direct_inode->i_mapping);
+               filemap_fdatawait(sbi->ipbmap->i_mapping);
+               filemap_fdatawait(sbi->ipimap->i_mapping);
+               filemap_fdatawait(sbi->direct_inode->i_mapping);
 
                lrd.logtid = 0;
                lrd.backchain = 0;
index 2ed5a1e3f86a18676da0d3c0ea5b014f19156242..131f9e4c14fda7628dd4d6344d636ddfba51378e 100644 (file)
@@ -349,7 +349,7 @@ metapage_t *__get_metapage(struct inode *inode,
                page_index = lblock >> l2BlocksPerPage;
                page_offset = (lblock - (page_index << l2BlocksPerPage)) <<
                    l2bsize;
-               if ((page_offset + size) > PAGE_SIZE) {
+               if ((page_offset + size) > PAGE_CACHE_SIZE) {
                        spin_unlock(&meta_lock);
                        jERROR(1, ("MetaData crosses page boundary!!\n"));
                        return NULL;
@@ -394,8 +394,10 @@ metapage_t *__get_metapage(struct inode *inode,
                                __free_metapage(mp);
                                spin_unlock(&meta_lock);
                                return NULL;
-                       } else
+                       } else {
                                INCREMENT(mpStat.pagealloc);
+                               unlock_page(mp->page);
+                       }
                } else {
                        jFYI(1,
                             ("__get_metapage: Calling read_cache_page\n"));
@@ -412,7 +414,6 @@ metapage_t *__get_metapage(struct inode *inode,
                                return NULL;
                        } else
                                INCREMENT(mpStat.pagealloc);
-                       lock_page(mp->page);
                }
                mp->data = (void *) (kmap(mp->page) + page_offset);
        }
@@ -459,6 +460,7 @@ static void __write_metapage(metapage_t * mp)
        page_offset =
            (mp->index - (page_index << l2BlocksPerPage)) << l2bsize;
 
+       lock_page(mp->page);
        rc = mp->mapping->a_ops->prepare_write(NULL, mp->page, page_offset,
                                               page_offset +
                                               mp->logical_size);
@@ -466,6 +468,7 @@ static void __write_metapage(metapage_t * mp)
                jERROR(1, ("prepare_write return %d!\n", rc));
                ClearPageUptodate(mp->page);
                kunmap(mp->page);
+               unlock_page(mp->page);
                clear_bit(META_dirty, &mp->flag);
                return;
        }
@@ -476,6 +479,7 @@ static void __write_metapage(metapage_t * mp)
                jERROR(1, ("commit_write returned %d\n", rc));
        }
 
+       unlock_page(mp->page);
        clear_bit(META_dirty, &mp->flag);
 
        jFYI(1, ("__write_metapage done\n"));
@@ -525,7 +529,6 @@ void release_metapage(metapage_t * mp)
                        mp->data = 0;
                        if (test_bit(META_dirty, &mp->flag))
                                __write_metapage(mp);
-                       unlock_page(mp->page);
                        if (test_bit(META_sync, &mp->flag)) {
                                sync_metapage(mp);
                                clear_bit(META_sync, &mp->flag);
@@ -585,7 +588,9 @@ void invalidate_metapages(struct inode *ip, unsigned long addr,
                        /*
                         * If in the metapage cache, we've got the page locked
                         */
+                       lock_page(mp->page);
                        block_flushpage(mp->page, 0);
+                       unlock_page(mp->page);
                } else {
                        spin_unlock(&meta_lock);
                        page = find_lock_page(mapping, lblock>>l2BlocksPerPage);
@@ -608,7 +613,6 @@ void invalidate_inode_metapages(struct inode *inode)
                clear_bit(META_dirty, &mp->flag);
                set_bit(META_discard, &mp->flag);
                kunmap(mp->page);
-               unlock_page(mp->page);
                page_cache_release(mp->page);
                INCREMENT(mpStat.pagefree);
                mp->data = 0;
index 8c475afc414aaa0f94363c7a33d63e30dfe161ce..fafc77ba1c7d4c7a9338589e1dad1a8687179b57 100644 (file)
@@ -1163,8 +1163,10 @@ int txCommit(tid_t tid,          /* transaction identifier */
                 * committing transactions and use i_sem instead.
                 */
                if ((!S_ISDIR(ip->i_mode))
-                   && (tblk->flag & COMMIT_DELETE) == 0)
-                       fsync_inode_data_buffers(ip);
+                   && (tblk->flag & COMMIT_DELETE) == 0) {
+                       filemap_fdatasync(ip->i_mapping);
+                       filemap_fdatawait(ip->i_mapping);
+               }
 
                /*
                 * Mark inode as not dirty.  It will still be on the dirty
index a03e9aba5752ee5a903cc2e0102102aee19cc129..eeda6fc33d6ccca63edc023f68d4afe7ecb45251 100644 (file)
@@ -151,7 +151,8 @@ static void jfs_put_super(struct super_block *sb)
         * We need to clean out the direct_inode pages since this inode
         * is not in the inode hash.
         */
-       fsync_inode_data_buffers(sbi->direct_inode);
+       filemap_fdatasync(sbi->direct_inode->i_mapping);
+       filemap_fdatawait(sbi->direct_inode->i_mapping);
        truncate_inode_pages(sbi->direct_mapping, 0);
        iput(sbi->direct_inode);
        sbi->direct_inode = NULL;
@@ -337,7 +338,8 @@ out_no_rw:
                jERROR(1, ("jfs_umount failed with return code %d\n", rc));
        }
 out_mount_failed:
-       fsync_inode_data_buffers(sbi->direct_inode);
+       filemap_fdatasync(sbi->direct_inode->i_mapping);
+       filemap_fdatawait(sbi->direct_inode->i_mapping);
        truncate_inode_pages(sbi->direct_mapping, 0);
        make_bad_inode(sbi->direct_inode);
        iput(sbi->direct_inode);
index 63352bb8cc3e084ca32ba45c4dacce426e4ee83c..870b602d0c39bacb53646f7e3b26d518262e06e5 100644 (file)
@@ -32,7 +32,6 @@ int minix_sync_file(struct file * file, struct dentry *dentry, int datasync)
        int err;
 
        err = fsync_inode_buffers(inode);
-       err |= fsync_inode_data_buffers(inode);
        if (!(inode->i_state & I_DIRTY))
                return err;
        if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
index 75d41a57c53829b9d746d087a15bf461438ba296..f6aa41b82360f28b4cbba27a610051b149347be9 100644 (file)
@@ -86,7 +86,6 @@ static int reiserfs_sync_file(
       BUG ();
 
   n_err = fsync_inode_buffers(p_s_inode) ;
-  n_err |= fsync_inode_data_buffers(p_s_inode);
   reiserfs_commit_for_inode(p_s_inode) ;
   unlock_kernel() ;
   return ( n_err < 0 ) ? -EIO : 0;
index ee1ec8bf62e398414c370a2425ab99d5fded85b1..20ebed3770404f3d64fb1d3286e392ce8e4dd1d7 100644 (file)
@@ -38,7 +38,6 @@ int sysv_sync_file(struct file * file, struct dentry *dentry, int datasync)
        int err;
 
        err = fsync_inode_buffers(inode);
-       err |= fsync_inode_data_buffers(inode);
        if (!(inode->i_state & I_DIRTY))
                return err;
        if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
index 00d4c207f4fe8d96871935236dad61ec3051fdd6..c48ddf0d0408892346f4057e819610261e2136c5 100644 (file)
@@ -45,7 +45,6 @@ int udf_fsync_inode(struct inode *inode, int datasync)
        int err;
 
        err = fsync_inode_buffers(inode);
-       err |= fsync_inode_data_buffers(inode);
        if (!(inode->i_state & I_DIRTY))
                return err;
        if (datasync && !(inode->i_state & I_DIRTY_DATASYNC))
index 16c8dc3de35b7ec4a79cab5703a4d9c82cfe92b7..4027b4573cd70372e4bb9ed313a55132bbdea2ac 100644 (file)
@@ -435,7 +435,6 @@ struct inode {
        struct list_head        i_dentry;
 
        struct list_head        i_dirty_buffers;   /* uses i_bufferlist_lock */
-       struct list_head        i_dirty_data_buffers;
        spinlock_t              i_bufferlist_lock;
 
        unsigned long           i_ino;
@@ -1266,13 +1265,6 @@ buffer_insert_inode_queue(struct buffer_head *bh, struct inode *inode)
                        bh, &inode->i_dirty_buffers);
 }
 
-static inline void
-buffer_insert_inode_data_queue(struct buffer_head *bh, struct inode *inode)
-{
-       buffer_insert_list(&inode->i_bufferlist_lock,
-                       bh, &inode->i_dirty_data_buffers);
-}
-
 #define atomic_set_buffer_dirty(bh) test_and_set_bit(BH_Dirty, &(bh)->b_state)
 
 static inline void mark_buffer_async(struct buffer_head * bh, int on)
@@ -1341,11 +1333,6 @@ static inline int fsync_inode_buffers(struct inode *inode)
        return fsync_buffers_list(&inode->i_bufferlist_lock,
                                &inode->i_dirty_buffers);
 }
-static inline int fsync_inode_data_buffers(struct inode *inode)
-{
-       return fsync_buffers_list(&inode->i_bufferlist_lock,
-                               &inode->i_dirty_data_buffers);
-}
 extern int inode_has_buffers(struct inode *);
 extern int filemap_fdatasync(struct address_space *);
 extern int filemap_fdatawait(struct address_space *);
index 9e2c70f075af59a1e6ca701ac9ba27c56e745d2c..795993c00699311b370741e1eff6f792135c1f03 100644 (file)
@@ -1083,8 +1083,6 @@ static ssize_t generic_file_direct_IO(int rw, struct file * filp, char * buf, si
         * completly asynchronous or performance will go to /dev/null.
         */
        retval = filemap_fdatasync(mapping);
-       if (retval == 0)
-               retval = fsync_inode_data_buffers(inode);
        if (retval == 0)
                retval = filemap_fdatawait(mapping);
        if (retval < 0)