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
Merge ../linux-2.6
[safe/jmp/linux-2.6]
/
mm
/
swapfile.c
diff --git
a/mm/swapfile.c
b/mm/swapfile.c
index
957fef4
..
1f9cf0d
100644
(file)
--- a/
mm/swapfile.c
+++ b/
mm/swapfile.c
@@
-25,6
+25,7
@@
#include <linux/rmap.h>
#include <linux/security.h>
#include <linux/backing-dev.h>
#include <linux/rmap.h>
#include <linux/security.h>
#include <linux/backing-dev.h>
+#include <linux/mutex.h>
#include <linux/capability.h>
#include <linux/syscalls.h>
#include <linux/capability.h>
#include <linux/syscalls.h>
@@
-46,12
+47,12
@@
struct swap_list_t swap_list = {-1, -1};
struct swap_info_struct swap_info[MAX_SWAPFILES];
struct swap_info_struct swap_info[MAX_SWAPFILES];
-static DE
CLARE_MUTEX(swapon_sem
);
+static DE
FINE_MUTEX(swapon_mutex
);
/*
* We need this because the bdev->unplug_fn can sleep and we cannot
* hold swap_lock while calling the unplug_fn. And swap_lock
/*
* We need this because the bdev->unplug_fn can sleep and we cannot
* hold swap_lock while calling the unplug_fn. And swap_lock
- * cannot be turned into a
semaphore
.
+ * cannot be turned into a
mutex
.
*/
static DECLARE_RWSEM(swap_unplug_sem);
*/
static DECLARE_RWSEM(swap_unplug_sem);
@@
-553,6
+554,15
@@
static int unuse_mm(struct mm_struct *mm,
return 0;
}
return 0;
}
+#ifdef CONFIG_MIGRATION
+int remove_vma_swap(struct vm_area_struct *vma, struct page *page)
+{
+ swp_entry_t entry = { .val = page_private(page) };
+
+ return unuse_vma(vma, entry, page);
+}
+#endif
+
/*
* Scan swap_map from current position to next entry still in use.
* Recycle to start on reaching the end, returning 0 when empty.
/*
* Scan swap_map from current position to next entry still in use.
* Recycle to start on reaching the end, returning 0 when empty.
@@
-645,6
+655,7
@@
static int try_to_unuse(unsigned int type)
*/
swap_map = &si->swap_map[i];
entry = swp_entry(type, i);
*/
swap_map = &si->swap_map[i];
entry = swp_entry(type, i);
+again:
page = read_swap_cache_async(entry, NULL, 0);
if (!page) {
/*
page = read_swap_cache_async(entry, NULL, 0);
if (!page) {
/*
@@
-679,6
+690,12
@@
static int try_to_unuse(unsigned int type)
wait_on_page_locked(page);
wait_on_page_writeback(page);
lock_page(page);
wait_on_page_locked(page);
wait_on_page_writeback(page);
lock_page(page);
+ if (!PageSwapCache(page)) {
+ /* Page migration has occured */
+ unlock_page(page);
+ page_cache_release(page);
+ goto again;
+ }
wait_on_page_writeback(page);
/*
wait_on_page_writeback(page);
/*
@@
-1161,7
+1178,7
@@
asmlinkage long sys_swapoff(const char __user * specialfile)
up_write(&swap_unplug_sem);
destroy_swap_extents(p);
up_write(&swap_unplug_sem);
destroy_swap_extents(p);
-
down(&swapon_sem
);
+
mutex_lock(&swapon_mutex
);
spin_lock(&swap_lock);
drain_mmlist();
spin_lock(&swap_lock);
drain_mmlist();
@@
-1180,7
+1197,7
@@
asmlinkage long sys_swapoff(const char __user * specialfile)
p->swap_map = NULL;
p->flags = 0;
spin_unlock(&swap_lock);
p->swap_map = NULL;
p->flags = 0;
spin_unlock(&swap_lock);
-
up(&swapon_sem
);
+
mutex_unlock(&swapon_mutex
);
vfree(swap_map);
inode = mapping->host;
if (S_ISBLK(inode->i_mode)) {
vfree(swap_map);
inode = mapping->host;
if (S_ISBLK(inode->i_mode)) {
@@
-1209,7
+1226,7
@@
static void *swap_start(struct seq_file *swap, loff_t *pos)
int i;
loff_t l = *pos;
int i;
loff_t l = *pos;
-
down(&swapon_sem
);
+
mutex_lock(&swapon_mutex
);
for (i = 0; i < nr_swapfiles; i++, ptr++) {
if (!(ptr->flags & SWP_USED) || !ptr->swap_map)
for (i = 0; i < nr_swapfiles; i++, ptr++) {
if (!(ptr->flags & SWP_USED) || !ptr->swap_map)
@@
-1238,7
+1255,7
@@
static void *swap_next(struct seq_file *swap, void *v, loff_t *pos)
static void swap_stop(struct seq_file *swap, void *v)
{
static void swap_stop(struct seq_file *swap, void *v)
{
-
up(&swapon_sem
);
+
mutex_unlock(&swapon_mutex
);
}
static int swap_show(struct seq_file *swap, void *v)
}
static int swap_show(struct seq_file *swap, void *v)
@@
-1540,7
+1557,7
@@
asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
goto bad_swap;
}
goto bad_swap;
}
-
down(&swapon_sem
);
+
mutex_lock(&swapon_mutex
);
spin_lock(&swap_lock);
p->flags = SWP_ACTIVE;
nr_swap_pages += nr_good_pages;
spin_lock(&swap_lock);
p->flags = SWP_ACTIVE;
nr_swap_pages += nr_good_pages;
@@
-1566,7
+1583,7
@@
asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
swap_info[prev].next = p - swap_info;
}
spin_unlock(&swap_lock);
swap_info[prev].next = p - swap_info;
}
spin_unlock(&swap_lock);
-
up(&swapon_sem
);
+
mutex_unlock(&swapon_mutex
);
error = 0;
goto out;
bad_swap:
error = 0;
goto out;
bad_swap: