diff options
| author | Andrew Morton <akpm@zip.com.au> | 2002-06-02 03:23:54 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-06-02 03:23:54 -0700 |
| commit | c83686ac2cf1277573c673f4ec2ede6b1d47e95e (patch) | |
| tree | fc7107e623f62480cb9e081f6deb8924959a07b8 | |
| parent | 91cb02b7abedb73a14c555f4b86467dbc637528c (diff) | |
[PATCH] fix race between writeback and unlink
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..
| -rw-r--r-- | fs/fs-writeback.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c index c9549228ee97..1d695b939f2f 100644 --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -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; } |
