diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-31 15:08:19 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-08-31 15:08:19 -0700 |
commit | b79c4f75e4d3fbfd225660c12f29a7fafcd8e6d9 (patch) | |
tree | 225b9ee9ec351224f3e3afa4a18c293f3e03f877 | |
parent | fd53f7d8eea9cd43c5fb6d316ea1ed128c9b8e45 (diff) | |
parent | 8c0bec2151a47906bf779c6715a10ce04453ab77 (diff) |
Merge tag 'for_linus-20110831' of git://github.com/tytso/ext4
* tag 'for_linus-20110831' of git://github.com/tytso/ext4:
ext4: remove i_mutex lock in ext4_evict_inode to fix lockdep complaining
-rw-r--r-- | fs/ext4/ext4.h | 1 | ||||
-rw-r--r-- | fs/ext4/inode.c | 3 | ||||
-rw-r--r-- | fs/ext4/page-io.c | 18 |
3 files changed, 18 insertions, 4 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index e717dfd2f2b4..b7d7bd0f066e 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -175,6 +175,7 @@ struct mpage_da_data { */ #define EXT4_IO_END_UNWRITTEN 0x0001 #define EXT4_IO_END_ERROR 0x0002 +#define EXT4_IO_END_QUEUED 0x0004 struct ext4_io_page { struct page *p_page; diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index c4da98a959ae..18d2558b7624 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -121,9 +121,6 @@ void ext4_evict_inode(struct inode *inode) trace_ext4_evict_inode(inode); - mutex_lock(&inode->i_mutex); - ext4_flush_completed_IO(inode); - mutex_unlock(&inode->i_mutex); ext4_ioend_wait(inode); if (inode->i_nlink) { diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 78839af7ce29..92f38ee13f8a 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -142,7 +142,23 @@ static void ext4_end_io_work(struct work_struct *work) unsigned long flags; int ret; - mutex_lock(&inode->i_mutex); + if (!mutex_trylock(&inode->i_mutex)) { + /* + * Requeue the work instead of waiting so that the work + * items queued after this can be processed. + */ + queue_work(EXT4_SB(inode->i_sb)->dio_unwritten_wq, &io->work); + /* + * To prevent the ext4-dio-unwritten thread from keeping + * requeueing end_io requests and occupying cpu for too long, + * yield the cpu if it sees an end_io request that has already + * been requeued. + */ + if (io->flag & EXT4_IO_END_QUEUED) + yield(); + io->flag |= EXT4_IO_END_QUEUED; + return; + } ret = ext4_end_io_nolock(io); if (ret < 0) { mutex_unlock(&inode->i_mutex); |