Currently the tree_lock protects mapping->nrpages, this will not be possible much longer. Hence abstract the access to this variable so that it can be easily replaced by an atomic_ulong_t. Signed-off-by: Peter Zijlstra --- arch/sh64/lib/dbg.c | 2 +- fs/block_dev.c | 2 +- fs/buffer.c | 2 +- fs/gfs2/glock.c | 2 +- fs/gfs2/glops.c | 6 +++--- fs/gfs2/meta_io.c | 2 +- fs/hugetlbfs/inode.c | 2 +- fs/inode.c | 10 +++++----- fs/jffs/inode-v23.c | 2 +- fs/jffs2/dir.c | 4 ++-- fs/jffs2/fs.c | 2 +- fs/libfs.c | 2 +- fs/nfs/inode.c | 6 +++--- fs/xfs/linux-2.6/xfs_vnode.h | 2 +- include/linux/fs.h | 22 +++++++++++++++++++++- include/linux/swap.h | 2 +- ipc/shm.c | 4 ++-- mm/filemap.c | 12 ++++++------ mm/shmem.c | 8 ++++---- mm/swap_state.c | 4 ++-- mm/truncate.c | 2 +- 21 files changed, 60 insertions(+), 40 deletions(-) Index: linux-2.6/arch/sh64/lib/dbg.c =================================================================== --- linux-2.6.orig/arch/sh64/lib/dbg.c 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/arch/sh64/lib/dbg.c 2007-01-28 14:02:36.000000000 +0100 @@ -424,6 +424,6 @@ void print_page(struct page *page) printk(" page[%p] -> index 0x%lx, count 0x%x, flags 0x%lx\n", page, page->index, page_count(page), page->flags); printk(" address_space = %p, pages =%ld\n", page->mapping, - page->mapping->nrpages); + mapping_nrpages(page->mapping)); } Index: linux-2.6/fs/block_dev.c =================================================================== --- linux-2.6.orig/fs/block_dev.c 2007-01-27 20:36:02.000000000 +0100 +++ linux-2.6/fs/block_dev.c 2007-01-28 14:02:36.000000000 +0100 @@ -554,7 +554,7 @@ long nr_blockdev_pages(void) list_for_each(p, &all_bdevs) { struct block_device *bdev; bdev = list_entry(p, struct block_device, bd_list); - ret += bdev->bd_inode->i_mapping->nrpages; + ret += mapping_nrpages(bdev->bd_inode->i_mapping); } spin_unlock(&bdev_lock); return ret; Index: linux-2.6/fs/buffer.c =================================================================== --- linux-2.6.orig/fs/buffer.c 2007-01-28 13:59:24.000000000 +0100 +++ linux-2.6/fs/buffer.c 2007-01-28 14:02:36.000000000 +0100 @@ -336,7 +336,7 @@ void invalidate_bdev(struct block_device { struct address_space *mapping = bdev->bd_inode->i_mapping; - if (mapping->nrpages == 0) + if (mapping_nrpages(mapping) == 0) return; invalidate_bh_lrus(); Index: linux-2.6/fs/gfs2/glock.c =================================================================== --- linux-2.6.orig/fs/gfs2/glock.c 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/fs/gfs2/glock.c 2007-01-28 14:02:36.000000000 +0100 @@ -2110,7 +2110,7 @@ static int dump_glock(struct gfs2_glock (list_empty(&gl->gl_reclaim)) ? "no" : "yes"); if (gl->gl_aspace) printk(KERN_INFO " aspace = 0x%p nrpages = %lu\n", gl->gl_aspace, - gl->gl_aspace->i_mapping->nrpages); + mapping_nrpages(gl->gl_aspace->i_mapping)); else printk(KERN_INFO " aspace = no\n"); printk(KERN_INFO " ail = %d\n", atomic_read(&gl->gl_ail_count)); Index: linux-2.6/fs/gfs2/glops.c =================================================================== --- linux-2.6.orig/fs/gfs2/glops.c 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/fs/gfs2/glops.c 2007-01-28 14:02:36.000000000 +0100 @@ -243,7 +243,7 @@ static void inode_go_inval(struct gfs2_g if (ip && S_ISREG(ip->i_inode.i_mode)) { truncate_inode_pages(ip->i_inode.i_mapping, 0); - gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !ip->i_inode.i_mapping->nrpages); + gfs2_assert_withdraw(GFS2_SB(&ip->i_inode), !mapping_nrpages(ip->i_inode.i_mapping)); clear_bit(GIF_PAGED, &ip->i_flags); } } @@ -260,7 +260,7 @@ static int inode_go_demote_ok(struct gfs struct gfs2_sbd *sdp = gl->gl_sbd; int demote = 0; - if (!gl->gl_object && !gl->gl_aspace->i_mapping->nrpages) + if (!gl->gl_object && !mapping_nrpages(gl->gl_aspace->i_mapping)) demote = 1; else if (!sdp->sd_args.ar_localcaching && time_after_eq(jiffies, gl->gl_stamp + @@ -360,7 +360,7 @@ static void inode_greedy(struct gfs2_glo static int rgrp_go_demote_ok(struct gfs2_glock *gl) { - return !gl->gl_aspace->i_mapping->nrpages; + return !mapping_nrpages(gl->gl_aspace->i_mapping); } /** Index: linux-2.6/fs/gfs2/meta_io.c =================================================================== --- linux-2.6.orig/fs/gfs2/meta_io.c 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/fs/gfs2/meta_io.c 2007-01-28 14:02:36.000000000 +0100 @@ -104,7 +104,7 @@ void gfs2_meta_inval(struct gfs2_glock * truncate_inode_pages(mapping, 0); atomic_dec(&aspace->i_writecount); - gfs2_assert_withdraw(sdp, !mapping->nrpages); + gfs2_assert_withdraw(sdp, !mapping_nrpages(mapping)); } /** Index: linux-2.6/fs/hugetlbfs/inode.c =================================================================== --- linux-2.6.orig/fs/hugetlbfs/inode.c 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/fs/hugetlbfs/inode.c 2007-01-28 14:02:36.000000000 +0100 @@ -214,7 +214,7 @@ static void truncate_hugepages(struct in } huge_pagevec_release(&pvec); } - BUG_ON(!lstart && mapping->nrpages); + BUG_ON(!lstart && mapping_nrpages(mapping)); hugetlb_unreserve_pages(inode, start, freed); } Index: linux-2.6/fs/jffs/inode-v23.c =================================================================== --- linux-2.6.orig/fs/jffs/inode-v23.c 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/fs/jffs/inode-v23.c 2007-01-28 14:02:36.000000000 +0100 @@ -1352,7 +1352,7 @@ jffs_create(struct inode *dir, struct de inode->i_op = &jffs_file_inode_operations; inode->i_fop = &jffs_file_operations; inode->i_mapping->a_ops = &jffs_address_operations; - inode->i_mapping->nrpages = 0; + mapping_nrpages_init(inode->i_mapping); d_instantiate(dentry, inode); jffs_create_end: Index: linux-2.6/fs/jffs2/dir.c =================================================================== --- linux-2.6.orig/fs/jffs2/dir.c 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/fs/jffs2/dir.c 2007-01-28 14:02:36.000000000 +0100 @@ -206,7 +206,7 @@ static int jffs2_create(struct inode *di inode->i_op = &jffs2_file_inode_operations; inode->i_fop = &jffs2_file_operations; inode->i_mapping->a_ops = &jffs2_file_address_operations; - inode->i_mapping->nrpages = 0; + mapping_nrpages_init(inode->i_mapping); f = JFFS2_INODE_INFO(inode); dir_f = JFFS2_INODE_INFO(dir_i); @@ -230,7 +230,7 @@ static int jffs2_create(struct inode *di d_instantiate(dentry, inode); D1(printk(KERN_DEBUG "jffs2_create: Created ino #%lu with mode %o, nlink %d(%d). nrpages %ld\n", - inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, inode->i_mapping->nrpages)); + inode->i_ino, inode->i_mode, inode->i_nlink, f->inocache->nlink, mapping_nrpages(inode->i_mapping))); return 0; fail: Index: linux-2.6/fs/jffs2/fs.c =================================================================== --- linux-2.6.orig/fs/jffs2/fs.c 2007-01-27 20:36:02.000000000 +0100 +++ linux-2.6/fs/jffs2/fs.c 2007-01-28 14:02:36.000000000 +0100 @@ -293,7 +293,7 @@ void jffs2_read_inode (struct inode *ino inode->i_op = &jffs2_file_inode_operations; inode->i_fop = &jffs2_file_operations; inode->i_mapping->a_ops = &jffs2_file_address_operations; - inode->i_mapping->nrpages = 0; + mapping_nrpages_init(inode->i_mapping); break; case S_IFBLK: Index: linux-2.6/fs/libfs.c =================================================================== --- linux-2.6.orig/fs/libfs.c 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/fs/libfs.c 2007-01-28 14:02:36.000000000 +0100 @@ -16,7 +16,7 @@ int simple_getattr(struct vfsmount *mnt, { struct inode *inode = dentry->d_inode; generic_fillattr(inode, stat); - stat->blocks = inode->i_mapping->nrpages << (PAGE_CACHE_SHIFT - 9); + stat->blocks = mapping_nrpages(inode->i_mapping) << (PAGE_CACHE_SHIFT - 9); return 0; } Index: linux-2.6/fs/nfs/inode.c =================================================================== --- linux-2.6.orig/fs/nfs/inode.c 2007-01-27 20:36:03.000000000 +0100 +++ linux-2.6/fs/nfs/inode.c 2007-01-28 14:03:13.000000000 +0100 @@ -93,7 +93,7 @@ int nfs_sync_mapping(struct address_spac { int ret; - if (mapping->nrpages == 0) + if (mapping_nrpages(mapping) == 0) return 0; unmap_mapping_range(mapping, 0, 0, 0); ret = filemap_write_and_wait(mapping); @@ -133,7 +133,7 @@ void nfs_zap_caches(struct inode *inode) void nfs_zap_mapping(struct inode *inode, struct address_space *mapping) { - if (mapping->nrpages != 0) { + if (mapping_nrpages(mapping) != 0) { spin_lock(&inode->i_lock); NFS_I(inode)->cache_validity |= NFS_INO_INVALID_DATA; spin_unlock(&inode->i_lock); @@ -669,7 +669,7 @@ static int nfs_invalidate_mapping_nolock { struct nfs_inode *nfsi = NFS_I(inode); - if (mapping->nrpages != 0) { + if (mapping_nrpages(mapping) != 0) { int ret = invalidate_inode_pages2(mapping); if (ret < 0) return ret; Index: linux-2.6/fs/xfs/linux-2.6/xfs_vnode.h =================================================================== --- linux-2.6.orig/fs/xfs/linux-2.6/xfs_vnode.h 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/fs/xfs/linux-2.6/xfs_vnode.h 2007-01-28 14:02:36.000000000 +0100 @@ -548,7 +548,7 @@ static inline void vn_atime_to_time_t(bh * Some useful predicates. */ #define VN_MAPPED(vp) mapping_mapped(vn_to_inode(vp)->i_mapping) -#define VN_CACHED(vp) (vn_to_inode(vp)->i_mapping->nrpages) +#define VN_CACHED(vp) mapping_nrpages(vn_to_inode(vp)->i_mapping) #define VN_DIRTY(vp) mapping_tagged(vn_to_inode(vp)->i_mapping, \ PAGECACHE_TAG_DIRTY) #define VN_TRUNC(vp) ((vp)->v_flag & VTRUNCATED) Index: linux-2.6/include/linux/fs.h =================================================================== --- linux-2.6.orig/include/linux/fs.h 2007-01-28 13:59:24.000000000 +0100 +++ linux-2.6/include/linux/fs.h 2007-01-28 14:02:36.000000000 +0100 @@ -439,7 +439,7 @@ struct address_space { struct list_head i_mmap_nonlinear;/*list VM_NONLINEAR mappings */ spinlock_t i_mmap_lock; /* protect tree, count, list */ unsigned int truncate_count; /* Cover race condition with truncate */ - unsigned long nrpages; /* number of total pages */ + unsigned long __nrpages; /* number of total pages */ pgoff_t writeback_index;/* writeback starts here */ const struct address_space_operations *a_ops; /* methods */ unsigned long flags; /* error bits/gfp mask */ @@ -454,6 +454,26 @@ struct address_space { * of struct page's "mapping" pointer be used for PAGE_MAPPING_ANON. */ +static inline void mapping_nrpages_init(struct address_space *mapping) +{ + mapping->__nrpages = 0; +} + +static inline unsigned long mapping_nrpages(struct address_space *mapping) +{ + return mapping->__nrpages; +} + +static inline void mapping_nrpages_inc(struct address_space *mapping) +{ + mapping->__nrpages++; +} + +static inline void mapping_nrpages_dec(struct address_space *mapping) +{ + mapping->__nrpages--; +} + struct block_device { dev_t bd_dev; /* not a kdev_t - it's a search key */ struct inode * bd_inode; /* will die */ Index: linux-2.6/ipc/shm.c =================================================================== --- linux-2.6.orig/ipc/shm.c 2007-01-27 20:36:03.000000000 +0100 +++ linux-2.6/ipc/shm.c 2007-01-28 14:02:36.000000000 +0100 @@ -499,11 +499,11 @@ static void shm_get_stat(struct ipc_name if (is_file_hugepages(shp->shm_file)) { struct address_space *mapping = inode->i_mapping; - *rss += (HPAGE_SIZE/PAGE_SIZE)*mapping->nrpages; + *rss += (HPAGE_SIZE/PAGE_SIZE)*mapping_nrpages(mapping); } else { struct shmem_inode_info *info = SHMEM_I(inode); spin_lock(&info->lock); - *rss += inode->i_mapping->nrpages; + *rss += mapping_nrpages(inode->i_mapping); *swp += info->swapped; spin_unlock(&info->lock); } Index: linux-2.6/mm/filemap.c =================================================================== --- linux-2.6.orig/mm/filemap.c 2007-01-28 13:59:24.000000000 +0100 +++ linux-2.6/mm/filemap.c 2007-01-28 14:02:36.000000000 +0100 @@ -118,7 +118,7 @@ void __remove_from_page_cache(struct pag radix_tree_delete(&mapping->page_tree, page->index); page->mapping = NULL; - mapping->nrpages--; + mapping_nrpages_dec(mapping); __dec_zone_page_state(page, NR_FILE_PAGES); } @@ -190,7 +190,7 @@ int __filemap_fdatawrite_range(struct ad int ret; struct writeback_control wbc = { .sync_mode = sync_mode, - .nr_to_write = mapping->nrpages * 2, + .nr_to_write = mapping_nrpages(mapping) * 2, .range_start = start, .range_end = end, }; @@ -372,7 +372,7 @@ int filemap_write_and_wait(struct addres { int err = 0; - if (mapping->nrpages) { + if (mapping_nrpages(mapping)) { err = filemap_fdatawrite(mapping); /* * Even if the above returned error, the pages may be @@ -406,7 +406,7 @@ int filemap_write_and_wait_range(struct { int err = 0; - if (mapping->nrpages) { + if (mapping_nrpages(mapping)) { err = __filemap_fdatawrite_range(mapping, lstart, lend, WB_SYNC_ALL); /* See comment of filemap_write_and_wait() */ @@ -448,7 +448,7 @@ int add_to_page_cache(struct page *page, SetPageLocked(page); page->mapping = mapping; page->index = offset; - mapping->nrpages++; + mapping_nrpages_inc(mapping); __inc_zone_page_state(page, NR_FILE_PAGES); } spin_unlock_irq(&mapping->tree_lock); @@ -2477,7 +2477,7 @@ generic_file_direct_IO(int rw, struct ki if (retval == 0) { retval = mapping->a_ops->direct_IO(rw, iocb, iov, offset, nr_segs); - if (rw == WRITE && mapping->nrpages) { + if (rw == WRITE && mapping_nrpages(mapping)) { pgoff_t end = (offset + write_len - 1) >> PAGE_CACHE_SHIFT; int err = invalidate_inode_pages2_range(mapping, Index: linux-2.6/mm/shmem.c =================================================================== --- linux-2.6.orig/mm/shmem.c 2007-01-22 22:43:27.000000000 +0100 +++ linux-2.6/mm/shmem.c 2007-01-28 14:02:36.000000000 +0100 @@ -211,8 +211,8 @@ static void shmem_free_blocks(struct ino * We have to calculate the free blocks since the mm can drop * undirtied hole pages behind our back. * - * But normally info->alloced == inode->i_mapping->nrpages + info->swapped - * So mm freed is info->alloced - (inode->i_mapping->nrpages + info->swapped) + * But normally info->alloced == mapping_nrpages(inode->i_mapping) + info->swapped + * So mm freed is info->alloced - (mapping_nrpages(inode->i_mapping) + info->swapped) * * It has to be called with the spinlock held. */ @@ -221,7 +221,7 @@ static void shmem_recalc_inode(struct in struct shmem_inode_info *info = SHMEM_I(inode); long freed; - freed = info->alloced - info->swapped - inode->i_mapping->nrpages; + freed = info->alloced - info->swapped - mapping_nrpages(inode->i_mapping); if (freed > 0) { info->alloced -= freed; shmem_unacct_blocks(info->flags, freed); @@ -607,7 +607,7 @@ static void shmem_truncate_range(struct done1: shmem_dir_unmap(dir); done2: - if (inode->i_mapping->nrpages && (info->flags & SHMEM_PAGEIN)) { + if (mapping_nrpages(inode->i_mapping) && (info->flags & SHMEM_PAGEIN)) { /* * Call truncate_inode_pages again: racing shmem_unuse_inode * may have swizzled a page in from swap since vmtruncate or Index: linux-2.6/mm/swap_state.c =================================================================== --- linux-2.6.orig/mm/swap_state.c 2007-01-28 13:59:24.000000000 +0100 +++ linux-2.6/mm/swap_state.c 2007-01-28 14:02:36.000000000 +0100 @@ -87,7 +87,7 @@ static int __add_to_swap_cache(struct pa SetPageLocked(page); SetPageSwapCache(page); set_page_private(page, entry.val); - total_swapcache_pages++; + mapping_nrpages_inc(&swapper_space); __inc_zone_page_state(page, NR_FILE_PAGES); } spin_unlock_irq(&swapper_space.tree_lock); @@ -133,7 +133,7 @@ void __delete_from_swap_cache(struct pag radix_tree_delete(&swapper_space.page_tree, page_private(page)); set_page_private(page, 0); ClearPageSwapCache(page); - total_swapcache_pages--; + mapping_nrpages_dec(&swapper_space); __dec_zone_page_state(page, NR_FILE_PAGES); INC_CACHE_INFO(del_total); } Index: linux-2.6/mm/truncate.c =================================================================== --- linux-2.6.orig/mm/truncate.c 2007-01-28 13:59:24.000000000 +0100 +++ linux-2.6/mm/truncate.c 2007-01-28 14:02:36.000000000 +0100 @@ -163,7 +163,7 @@ void truncate_inode_pages_range(struct a pgoff_t next; int i; - if (mapping->nrpages == 0) + if (mapping_nrpages(mapping) == 0) return; BUG_ON((lend & (PAGE_CACHE_SIZE - 1)) != (PAGE_CACHE_SIZE - 1)); Index: linux-2.6/include/linux/swap.h =================================================================== --- linux-2.6.orig/include/linux/swap.h 2007-01-22 22:43:26.000000000 +0100 +++ linux-2.6/include/linux/swap.h 2007-01-28 14:02:36.000000000 +0100 @@ -222,7 +222,7 @@ extern int end_swap_bio_read(struct bio /* linux/mm/swap_state.c */ extern struct address_space swapper_space; -#define total_swapcache_pages swapper_space.nrpages +#define total_swapcache_pages mapping_nrpages(&swapper_space) extern void show_swap_cache_info(void); extern int add_to_swap(struct page *, gfp_t); extern void __delete_from_swap_cache(struct page *); Index: linux-2.6/fs/inode.c =================================================================== --- linux-2.6.orig/fs/inode.c 2007-01-28 13:59:24.000000000 +0100 +++ linux-2.6/fs/inode.c 2007-01-28 14:02:36.000000000 +0100 @@ -246,7 +246,7 @@ void clear_inode(struct inode *inode) might_sleep(); invalidate_inode_buffers(inode); - BUG_ON(inode->i_data.nrpages); + BUG_ON(mapping_nrpages(&inode->i_data)); BUG_ON(!(inode->i_state & I_FREEING)); BUG_ON(inode->i_state & I_CLEAR); wait_on_inode(inode); @@ -279,7 +279,7 @@ static void dispose_list(struct list_hea inode = list_entry(head->next, struct inode, i_list); list_del(&inode->i_list); - if (inode->i_data.nrpages) + if (mapping_nrpages(&inode->i_data)) truncate_inode_pages(&inode->i_data, 0); clear_inode(inode); @@ -371,7 +371,7 @@ static int can_unuse(struct inode *inode return 0; if (atomic_read(&inode->i_count)) return 0; - if (inode->i_data.nrpages) + if (mapping_nrpages(&inode->i_data)) return 0; return 1; } @@ -410,7 +410,7 @@ static void prune_icache(int nr_to_scan) list_move(&inode->i_list, &inode_unused); continue; } - if (inode_has_buffers(inode) || inode->i_data.nrpages) { + if (inode_has_buffers(inode) || mapping_nrpages(&inode->i_data)) { __iget(inode); spin_unlock(&inode_lock); if (remove_inode_buffers(inode)) @@ -1057,7 +1057,7 @@ static void generic_forget_inode(struct inode->i_state |= I_FREEING; inodes_stat.nr_inodes--; spin_unlock(&inode_lock); - if (inode->i_data.nrpages) + if (mapping_nrpages(&inode->i_data)) truncate_inode_pages(&inode->i_data, 0); clear_inode(inode); wake_up_inode(inode); -- - 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/