git://ftp.safe.ca
/
safe
/
jmp
/
linux-2.6
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
mm: close page_mkwrite races
[safe/jmp/linux-2.6]
/
mm
/
swapfile.c
diff --git
a/mm/swapfile.c
b/mm/swapfile.c
index
1e7a715
..
312fafe
100644
(file)
--- a/
mm/swapfile.c
+++ b/
mm/swapfile.c
@@
-471,8
+471,9
@@
out:
return NULL;
}
return NULL;
}
-static int swap_entry_free(struct swap_info_struct *p,
unsigned long offse
t)
+static int swap_entry_free(struct swap_info_struct *p,
swp_entry_t en
t)
{
{
+ unsigned long offset = swp_offset(ent);
int count = p->swap_map[offset];
if (count < SWAP_MAP_MAX) {
int count = p->swap_map[offset];
if (count < SWAP_MAP_MAX) {
@@
-487,6
+488,7
@@
static int swap_entry_free(struct swap_info_struct *p, unsigned long offset)
swap_list.next = p - swap_info;
nr_swap_pages++;
p->inuse_pages--;
swap_list.next = p - swap_info;
nr_swap_pages++;
p->inuse_pages--;
+ mem_cgroup_uncharge_swap(ent);
}
}
return count;
}
}
return count;
@@
-502,7
+504,7
@@
void swap_free(swp_entry_t entry)
p = swap_info_get(entry);
if (p) {
p = swap_info_get(entry);
if (p) {
- swap_entry_free(p,
swp_offset(entry)
);
+ swap_entry_free(p,
entry
);
spin_unlock(&swap_lock);
}
}
spin_unlock(&swap_lock);
}
}
@@
-582,7
+584,7
@@
int free_swap_and_cache(swp_entry_t entry)
p = swap_info_get(entry);
if (p) {
p = swap_info_get(entry);
if (p) {
- if (swap_entry_free(p,
swp_offset(entry)
) == 1) {
+ if (swap_entry_free(p,
entry
) == 1) {
page = find_get_page(&swapper_space, entry.val);
if (page && !trylock_page(page)) {
page_cache_release(page);
page = find_get_page(&swapper_space, entry.val);
if (page && !trylock_page(page)) {
page_cache_release(page);
@@
-633,7
+635,7
@@
int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
if (!bdev) {
if (bdev_p)
if (!bdev) {
if (bdev_p)
- *bdev_p =
sis->bdev
;
+ *bdev_p =
bdget(sis->bdev->bd_dev)
;
spin_unlock(&swap_lock);
return i;
spin_unlock(&swap_lock);
return i;
@@
-645,7
+647,7
@@
int swap_type_of(dev_t device, sector_t offset, struct block_device **bdev_p)
struct swap_extent, list);
if (se->start_block == offset) {
if (bdev_p)
struct swap_extent, list);
if (se->start_block == offset) {
if (bdev_p)
- *bdev_p =
sis->bdev
;
+ *bdev_p =
bdget(sis->bdev->bd_dev)
;
spin_unlock(&swap_lock);
bdput(bdev);
spin_unlock(&swap_lock);
bdput(bdev);
@@
-696,8
+698,10
@@
static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
pte_t *pte;
int ret = 1;
pte_t *pte;
int ret = 1;
- if (mem_cgroup_try_charge
(vma->vm_mm, GFP_HIGHUSER_MOVABLE, &ptr))
+ if (mem_cgroup_try_charge
_swapin(vma->vm_mm, page, GFP_KERNEL, &ptr)) {
ret = -ENOMEM;
ret = -ENOMEM;
+ goto out_nolock;
+ }
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
if (unlikely(!pte_same(*pte, swp_entry_to_pte(entry)))) {
pte = pte_offset_map_lock(vma->vm_mm, pmd, addr, &ptl);
if (unlikely(!pte_same(*pte, swp_entry_to_pte(entry)))) {
@@
-721,6
+725,7
@@
static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd,
activate_page(page);
out:
pte_unmap_unlock(pte, ptl);
activate_page(page);
out:
pte_unmap_unlock(pte, ptl);
+out_nolock:
return ret;
}
return ret;
}
@@
-1375,7
+1380,7
@@
out:
return ret;
}
return ret;
}
-
asmlinkage long sys_swapoff(const char __user *
specialfile)
+
SYSCALL_DEFINE1(swapoff, const char __user *,
specialfile)
{
struct swap_info_struct * p = NULL;
unsigned short *swap_map;
{
struct swap_info_struct * p = NULL;
unsigned short *swap_map;
@@
-1631,7
+1636,7
@@
late_initcall(max_swapfiles_check);
*
* The swapon system call
*/
*
* The swapon system call
*/
-
asmlinkage long sys_swapon(const char __user * specialfile, int
swap_flags)
+
SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int,
swap_flags)
{
struct swap_info_struct * p;
char *name = NULL;
{
struct swap_info_struct * p;
char *name = NULL;