diff options
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 28 |
1 files changed, 14 insertions, 14 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 55e04a0734c1..dc25565a61e9 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -71,9 +71,6 @@ | |||
71 | /* Pretend that each entry is of this size in directory's i_size */ | 71 | /* Pretend that each entry is of this size in directory's i_size */ |
72 | #define BOGO_DIRENT_SIZE 20 | 72 | #define BOGO_DIRENT_SIZE 20 |
73 | 73 | ||
74 | /* Keep swapped page count in private field of indirect struct page */ | ||
75 | #define nr_swapped private | ||
76 | |||
77 | /* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */ | 74 | /* Flag allocation requirements to shmem_getpage and shmem_swp_alloc */ |
78 | enum sgp_type { | 75 | enum sgp_type { |
79 | SGP_QUICK, /* don't try more than file page cache lookup */ | 76 | SGP_QUICK, /* don't try more than file page cache lookup */ |
@@ -324,8 +321,10 @@ static void shmem_swp_set(struct shmem_inode_info *info, swp_entry_t *entry, uns | |||
324 | 321 | ||
325 | entry->val = value; | 322 | entry->val = value; |
326 | info->swapped += incdec; | 323 | info->swapped += incdec; |
327 | if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT) | 324 | if ((unsigned long)(entry - info->i_direct) >= SHMEM_NR_DIRECT) { |
328 | kmap_atomic_to_page(entry)->nr_swapped += incdec; | 325 | struct page *page = kmap_atomic_to_page(entry); |
326 | set_page_private(page, page_private(page) + incdec); | ||
327 | } | ||
329 | } | 328 | } |
330 | 329 | ||
331 | /* | 330 | /* |
@@ -368,9 +367,8 @@ static swp_entry_t *shmem_swp_alloc(struct shmem_inode_info *info, unsigned long | |||
368 | 367 | ||
369 | spin_unlock(&info->lock); | 368 | spin_unlock(&info->lock); |
370 | page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping) | __GFP_ZERO); | 369 | page = shmem_dir_alloc(mapping_gfp_mask(inode->i_mapping) | __GFP_ZERO); |
371 | if (page) { | 370 | if (page) |
372 | page->nr_swapped = 0; | 371 | set_page_private(page, 0); |
373 | } | ||
374 | spin_lock(&info->lock); | 372 | spin_lock(&info->lock); |
375 | 373 | ||
376 | if (!page) { | 374 | if (!page) { |
@@ -561,7 +559,7 @@ static void shmem_truncate(struct inode *inode) | |||
561 | diroff = 0; | 559 | diroff = 0; |
562 | } | 560 | } |
563 | subdir = dir[diroff]; | 561 | subdir = dir[diroff]; |
564 | if (subdir && subdir->nr_swapped) { | 562 | if (subdir && page_private(subdir)) { |
565 | size = limit - idx; | 563 | size = limit - idx; |
566 | if (size > ENTRIES_PER_PAGE) | 564 | if (size > ENTRIES_PER_PAGE) |
567 | size = ENTRIES_PER_PAGE; | 565 | size = ENTRIES_PER_PAGE; |
@@ -572,10 +570,10 @@ static void shmem_truncate(struct inode *inode) | |||
572 | nr_swaps_freed += freed; | 570 | nr_swaps_freed += freed; |
573 | if (offset) | 571 | if (offset) |
574 | spin_lock(&info->lock); | 572 | spin_lock(&info->lock); |
575 | subdir->nr_swapped -= freed; | 573 | set_page_private(subdir, page_private(subdir) - freed); |
576 | if (offset) | 574 | if (offset) |
577 | spin_unlock(&info->lock); | 575 | spin_unlock(&info->lock); |
578 | BUG_ON(subdir->nr_swapped > offset); | 576 | BUG_ON(page_private(subdir) > offset); |
579 | } | 577 | } |
580 | if (offset) | 578 | if (offset) |
581 | offset = 0; | 579 | offset = 0; |
@@ -743,7 +741,7 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s | |||
743 | dir = shmem_dir_map(subdir); | 741 | dir = shmem_dir_map(subdir); |
744 | } | 742 | } |
745 | subdir = *dir; | 743 | subdir = *dir; |
746 | if (subdir && subdir->nr_swapped) { | 744 | if (subdir && page_private(subdir)) { |
747 | ptr = shmem_swp_map(subdir); | 745 | ptr = shmem_swp_map(subdir); |
748 | size = limit - idx; | 746 | size = limit - idx; |
749 | if (size > ENTRIES_PER_PAGE) | 747 | if (size > ENTRIES_PER_PAGE) |
@@ -1201,7 +1199,7 @@ static int shmem_populate(struct vm_area_struct *vma, | |||
1201 | page_cache_release(page); | 1199 | page_cache_release(page); |
1202 | return err; | 1200 | return err; |
1203 | } | 1201 | } |
1204 | } else { | 1202 | } else if (vma->vm_flags & VM_NONLINEAR) { |
1205 | /* No page was found just because we can't read it in | 1203 | /* No page was found just because we can't read it in |
1206 | * now (being here implies nonblock != 0), but the page | 1204 | * now (being here implies nonblock != 0), but the page |
1207 | * may exist, so set the PTE to fault it in later. */ | 1205 | * may exist, so set the PTE to fault it in later. */ |
@@ -1506,8 +1504,10 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_ | |||
1506 | */ | 1504 | */ |
1507 | if (!offset) | 1505 | if (!offset) |
1508 | mark_page_accessed(page); | 1506 | mark_page_accessed(page); |
1509 | } else | 1507 | } else { |
1510 | page = ZERO_PAGE(0); | 1508 | page = ZERO_PAGE(0); |
1509 | page_cache_get(page); | ||
1510 | } | ||
1511 | 1511 | ||
1512 | /* | 1512 | /* |
1513 | * Ok, we have the page, and it's up-to-date, so | 1513 | * Ok, we have the page, and it's up-to-date, so |