]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - mm/swapfile.c
h63xx: tsc2101 alsa sound support
[linux-2.6-omap-h63xx.git] / mm / swapfile.c
index 80f948a2028bdc2f850741a802e81b4d207f8f6f..1f9cf0d073b84caad71234ddfb091618906d3047 100644 (file)
@@ -25,6 +25,8 @@
 #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 <asm/pgtable.h>
@@ -45,12 +47,12 @@ struct swap_list_t swap_list = {-1, -1};
 
 struct swap_info_struct swap_info[MAX_SWAPFILES];
 
-static DECLARE_MUTEX(swapon_sem);
+static DEFINE_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
- * cannot be turned into a semaphore.
+ * cannot be turned into a mutex.
  */
 static DECLARE_RWSEM(swap_unplug_sem);
 
@@ -552,6 +554,15 @@ static int unuse_mm(struct mm_struct *mm,
        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.
@@ -644,6 +655,7 @@ static int try_to_unuse(unsigned int type)
                 */
                swap_map = &si->swap_map[i];
                entry = swp_entry(type, i);
+again:
                page = read_swap_cache_async(entry, NULL, 0);
                if (!page) {
                        /*
@@ -678,6 +690,12 @@ static int try_to_unuse(unsigned int type)
                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);
 
                /*
@@ -1160,7 +1178,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
        up_write(&swap_unplug_sem);
 
        destroy_swap_extents(p);
-       down(&swapon_sem);
+       mutex_lock(&swapon_mutex);
        spin_lock(&swap_lock);
        drain_mmlist();
 
@@ -1179,7 +1197,7 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
        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)) {
@@ -1187,9 +1205,9 @@ asmlinkage long sys_swapoff(const char __user * specialfile)
                set_blocksize(bdev, p->old_block_size);
                bd_release(bdev);
        } else {
-               down(&inode->i_sem);
+               mutex_lock(&inode->i_mutex);
                inode->i_flags &= ~S_SWAPFILE;
-               up(&inode->i_sem);
+               mutex_unlock(&inode->i_mutex);
        }
        filp_close(swap_file, NULL);
        err = 0;
@@ -1208,7 +1226,7 @@ static void *swap_start(struct seq_file *swap, loff_t *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)
@@ -1237,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)
 {
-       up(&swapon_sem);
+       mutex_unlock(&swapon_mutex);
 }
 
 static int swap_show(struct seq_file *swap, void *v)
@@ -1406,7 +1424,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
                p->bdev = bdev;
        } else if (S_ISREG(inode->i_mode)) {
                p->bdev = inode->i_sb->s_bdev;
-               down(&inode->i_sem);
+               mutex_lock(&inode->i_mutex);
                did_down = 1;
                if (IS_SWAPFILE(inode)) {
                        error = -EBUSY;
@@ -1442,7 +1460,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
        else if (!memcmp("SWAPSPACE2",swap_header->magic.magic,10))
                swap_header_version = 2;
        else {
-               printk("Unable to find swap-space signature\n");
+               printk(KERN_ERR "Unable to find swap-space signature\n");
                error = -EINVAL;
                goto bad_swap;
        }
@@ -1539,7 +1557,7 @@ asmlinkage long sys_swapon(const char __user * specialfile, int swap_flags)
                goto bad_swap;
        }
 
-       down(&swapon_sem);
+       mutex_lock(&swapon_mutex);
        spin_lock(&swap_lock);
        p->flags = SWP_ACTIVE;
        nr_swap_pages += nr_good_pages;
@@ -1565,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);
-       up(&swapon_sem);
+       mutex_unlock(&swapon_mutex);
        error = 0;
        goto out;
 bad_swap:
@@ -1596,7 +1614,7 @@ out:
        if (did_down) {
                if (!error)
                        inode->i_flags |= S_SWAPFILE;
-               up(&inode->i_sem);
+               mutex_unlock(&inode->i_mutex);
        }
        return error;
 }