Signed-off-by: Peter Zijlstra --- include/linux/pagemap.h | 55 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 10 deletions(-) Index: linux-2.6/include/linux/pagemap.h =================================================================== --- linux-2.6.orig/include/linux/pagemap.h +++ linux-2.6/include/linux/pagemap.h @@ -357,14 +357,44 @@ extern void FASTCALL(unlock_page_nocheck extern struct lockdep_map page_lockdep_map; -static inline void __lock_page_acquire(int try, unsigned long ip) +static inline struct lockdep_map *page_map(struct page *page) { - lock_acquire(&page_lockdep_map, 0, try, 0, 2, ip); + struct address_space *mapping; + struct inode *inode; + struct super_block *sb; + struct file_system_type *type; + struct lockdep_map *map = &page_lockdep_map; + + mapping = page_mapping(page); + if (!mapping) + goto out; + + inode = mapping->host; + if (!inode) + goto out; + + sb = inode->i_sb; + if (!sb) + goto out; + + type = sb->s_type; + if (type) + map = &type->s_mapping_map; + +out: + return map; } -static inline void __unlock_page_release(unsigned long ip) +static inline void __lock_page_acquire(struct page *page, int try, unsigned long ip) { - lock_release(&page_lockdep_map, 1, ip); + struct lockdep_map *map = page_map(page); + lock_acquire(map, 0, try, 0, 2, ip); +} + +static inline void __unlock_page_release(struct page *page, unsigned long ip) +{ + struct lockdep_map *map = page_map(page); + lock_release(map, 1, ip); } /* @@ -373,22 +403,27 @@ static inline void __unlock_page_release static inline void lock_page(struct page *page) { might_sleep(); - __lock_page_acquire(0, _RET_IP_); + __lock_page_acquire(page, 0, _RET_IP_); if (TestSetPageLocked(page)) __lock_page(page); } +static inline void __lock_page_check(struct page *page) +{ + __lock_page_acquire(page, 0, _RET_IP_); +} + static inline int trylock_page(struct page *page) { int ret = !TestSetPageLocked(page); if (ret) - __lock_page_acquire(1, _RET_IP_); + __lock_page_acquire(page, 1, _RET_IP_); return ret; } static inline void __unlock_page_check(struct page *page) { - __unlock_page_release(_RET_IP_); + __unlock_page_release(page, _RET_IP_); } static inline void unlock_page(struct page *page) @@ -404,7 +439,7 @@ static inline void unlock_page(struct pa static inline void lock_page_nosync(struct page *page) { might_sleep(); - __lock_page_acquire(0, _RET_IP_); + __lock_page_acquire(page, 0, _RET_IP_); if (TestSetPageLocked(page)) __lock_page_nosync(page); } @@ -424,10 +459,10 @@ extern void FASTCALL(wait_on_page_bit(st */ static inline void wait_on_page_locked(struct page *page) { - __lock_page_acquire(0, _RET_IP_); + __lock_page_acquire(page, 0, _RET_IP_); if (PageLocked(page)) wait_on_page_bit(page, PG_locked); - __unlock_page_release(_RET_IP_); + __unlock_page_release(page, _RET_IP_); } /* -- - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/