Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 83060
b: refs/heads/master
c: d9fe526
h: refs/heads/master
v: v3
  • Loading branch information
Hugh Dickins authored and Linus Torvalds committed Feb 5, 2008
1 parent 3e390ef commit b78d5d2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 26 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 73b1262fa43a778b1e154deea632cdef5009d6a1
refs/heads/master: d9fe526a83b84edc9c5ff217a00c896bfc20b2ce
69 changes: 44 additions & 25 deletions trunk/mm/shmem.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,6 +827,7 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s
struct page *subdir;
swp_entry_t *ptr;
int offset;
int error;

idx = 0;
ptr = info->i_direct;
Expand Down Expand Up @@ -884,7 +885,20 @@ static int shmem_unuse_inode(struct shmem_inode_info *info, swp_entry_t entry, s
found:
idx += offset;
inode = &info->vfs_inode;
if (add_to_page_cache(page, inode->i_mapping, idx, GFP_ATOMIC) == 0) {
error = add_to_page_cache(page, inode->i_mapping, idx, GFP_ATOMIC);
if (error == -EEXIST) {
struct page *filepage = find_get_page(inode->i_mapping, idx);
if (filepage) {
/*
* There might be a more uptodate page coming down
* from a stacked writepage: forget our swappage if so.
*/
if (PageUptodate(filepage))
error = 0;
page_cache_release(filepage);
}
}
if (!error) {
delete_from_swap_cache(page);
set_page_dirty(page);
info->flags |= SHMEM_PAGEIN;
Expand Down Expand Up @@ -937,44 +951,45 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
struct inode *inode;

BUG_ON(!PageLocked(page));
/*
* shmem_backing_dev_info's capabilities prevent regular writeback or
* sync from ever calling shmem_writepage; but a stacking filesystem
* may use the ->writepage of its underlying filesystem, in which case
* we want to do nothing when that underlying filesystem is tmpfs
* (writing out to swap is useful as a response to memory pressure, but
* of no use to stabilize the data) - just redirty the page, unlock it
* and claim success in this case. AOP_WRITEPAGE_ACTIVATE, and the
* page_mapped check below, must be avoided unless we're in reclaim.
*/
if (!wbc->for_reclaim) {
set_page_dirty(page);
unlock_page(page);
return 0;
}
BUG_ON(page_mapped(page));

mapping = page->mapping;
index = page->index;
inode = mapping->host;
info = SHMEM_I(inode);
if (info->flags & VM_LOCKED)
goto redirty;
swap = get_swap_page();
if (!swap.val)
if (!total_swap_pages)
goto redirty;

/*
* shmem_backing_dev_info's capabilities prevent regular writeback or
* sync from ever calling shmem_writepage; but a stacking filesystem
* may use the ->writepage of its underlying filesystem, in which case
* tmpfs should write out to swap only in response to memory pressure,
* and not for pdflush or sync. However, in those cases, we do still
* want to check if there's a redundant swappage to be discarded.
*/
if (wbc->for_reclaim)
swap = get_swap_page();
else
swap.val = 0;

spin_lock(&info->lock);
shmem_recalc_inode(inode);
if (index >= info->next_index) {
BUG_ON(!(info->flags & SHMEM_TRUNCATE));
goto unlock;
}
entry = shmem_swp_entry(info, index, NULL);
BUG_ON(!entry);
BUG_ON(entry->val);
if (entry->val) {
/*
* The more uptodate page coming down from a stacked
* writepage should replace our old swappage.
*/
free_swap_and_cache(*entry);
shmem_swp_set(info, entry, 0);
}
shmem_recalc_inode(inode);

if (add_to_swap_cache(page, swap, GFP_ATOMIC) == 0) {
if (swap.val && add_to_swap_cache(page, swap, GFP_ATOMIC) == 0) {
remove_from_page_cache(page);
shmem_swp_set(info, entry, swap.val);
shmem_swp_unmap(entry);
Expand All @@ -986,6 +1001,7 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
spin_unlock(&shmem_swaplist_lock);
}
swap_duplicate(swap);
BUG_ON(page_mapped(page));
page_cache_release(page); /* pagecache ref */
set_page_dirty(page);
unlock_page(page);
Expand All @@ -998,7 +1014,10 @@ static int shmem_writepage(struct page *page, struct writeback_control *wbc)
swap_free(swap);
redirty:
set_page_dirty(page);
return AOP_WRITEPAGE_ACTIVATE; /* Return with the page locked */
if (wbc->for_reclaim)
return AOP_WRITEPAGE_ACTIVATE; /* Return with page locked */
unlock_page(page);
return 0;
}

#ifdef CONFIG_NUMA
Expand Down

0 comments on commit b78d5d2

Please sign in to comment.