]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] fix race between writeback and unlink
authorAndrew Morton <akpm@zip.com.au>
Sun, 2 Jun 2002 10:23:54 +0000 (03:23 -0700)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sun, 2 Jun 2002 10:23:54 +0000 (03:23 -0700)
Fixes a race between unlink and writeback: on the sys_sync() and
pdflush paths the caller does not have a reference against the inode.

So run __iget prior to dropping inode_lock.

Oleg Drokin reported this and seems to believe that it fixes the
crashes he was observing.  But I was never able to reproduce them..

fs/fs-writeback.c

index c9549228ee97e0b99b16db182ffa72777d821706..1d695b939f2fc327c43f448f72ac5eab32650651 100644 (file)
@@ -245,17 +245,19 @@ static void sync_sb_inodes(struct super_block *sb, int sync_mode,
                if ((sync_mode == WB_SYNC_LAST) && (head->prev == head))
                        really_sync = 1;
 
+               BUG_ON(inode->i_state & I_FREEING);
+               __iget(inode);
                __writeback_single_inode(inode, really_sync, nr_to_write);
-
                if (sync_mode == WB_SYNC_HOLD) {
                        mapping->dirtied_when = jiffies;
                        list_del(&inode->i_list);
                        list_add(&inode->i_list, &inode->i_sb->s_dirty);
                }
-
                if (current_is_pdflush())
                        writeback_release(bdi);
-
+               spin_unlock(&inode_lock);
+               iput(inode);
+               spin_lock(&inode_lock);
                if (nr_to_write && *nr_to_write <= 0)
                        break;
        }