diff options
Diffstat (limited to 'mm/swapfile.c')
-rw-r--r-- | mm/swapfile.c | 411 |
1 files changed, 207 insertions, 204 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index 0341c5700e34..8c6b3ce38f09 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -95,39 +95,6 @@ __try_to_reclaim_swap(struct swap_info_struct *si, unsigned long offset) | |||
95 | } | 95 | } |
96 | 96 | ||
97 | /* | 97 | /* |
98 | * We need this because the bdev->unplug_fn can sleep and we cannot | ||
99 | * hold swap_lock while calling the unplug_fn. And swap_lock | ||
100 | * cannot be turned into a mutex. | ||
101 | */ | ||
102 | static DECLARE_RWSEM(swap_unplug_sem); | ||
103 | |||
104 | void swap_unplug_io_fn(struct backing_dev_info *unused_bdi, struct page *page) | ||
105 | { | ||
106 | swp_entry_t entry; | ||
107 | |||
108 | down_read(&swap_unplug_sem); | ||
109 | entry.val = page_private(page); | ||
110 | if (PageSwapCache(page)) { | ||
111 | struct block_device *bdev = swap_info[swp_type(entry)]->bdev; | ||
112 | struct backing_dev_info *bdi; | ||
113 | |||
114 | /* | ||
115 | * If the page is removed from swapcache from under us (with a | ||
116 | * racy try_to_unuse/swapoff) we need an additional reference | ||
117 | * count to avoid reading garbage from page_private(page) above. | ||
118 | * If the WARN_ON triggers during a swapoff it maybe the race | ||
119 | * condition and it's harmless. However if it triggers without | ||
120 | * swapoff it signals a problem. | ||
121 | */ | ||
122 | WARN_ON(page_count(page) <= 1); | ||
123 | |||
124 | bdi = bdev->bd_inode->i_mapping->backing_dev_info; | ||
125 | blk_run_backing_dev(bdi, page); | ||
126 | } | ||
127 | up_read(&swap_unplug_sem); | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * swapon tell device that all the old swap contents can be discarded, | 98 | * swapon tell device that all the old swap contents can be discarded, |
132 | * to allow the swap device to optimize its wear-levelling. | 99 | * to allow the swap device to optimize its wear-levelling. |
133 | */ | 100 | */ |
@@ -212,8 +179,8 @@ static int wait_for_discard(void *word) | |||
212 | #define SWAPFILE_CLUSTER 256 | 179 | #define SWAPFILE_CLUSTER 256 |
213 | #define LATENCY_LIMIT 256 | 180 | #define LATENCY_LIMIT 256 |
214 | 181 | ||
215 | static inline unsigned long scan_swap_map(struct swap_info_struct *si, | 182 | static unsigned long scan_swap_map(struct swap_info_struct *si, |
216 | unsigned char usage) | 183 | unsigned char usage) |
217 | { | 184 | { |
218 | unsigned long offset; | 185 | unsigned long offset; |
219 | unsigned long scan_base; | 186 | unsigned long scan_base; |
@@ -880,7 +847,7 @@ unsigned int count_swap_pages(int type, int free) | |||
880 | static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd, | 847 | static int unuse_pte(struct vm_area_struct *vma, pmd_t *pmd, |
881 | unsigned long addr, swp_entry_t entry, struct page *page) | 848 | unsigned long addr, swp_entry_t entry, struct page *page) |
882 | { | 849 | { |
883 | struct mem_cgroup *ptr = NULL; | 850 | struct mem_cgroup *ptr; |
884 | spinlock_t *ptl; | 851 | spinlock_t *ptl; |
885 | pte_t *pte; | 852 | pte_t *pte; |
886 | int ret = 1; | 853 | int ret = 1; |
@@ -1550,6 +1517,36 @@ bad_bmap: | |||
1550 | goto out; | 1517 | goto out; |
1551 | } | 1518 | } |
1552 | 1519 | ||
1520 | static void enable_swap_info(struct swap_info_struct *p, int prio, | ||
1521 | unsigned char *swap_map) | ||
1522 | { | ||
1523 | int i, prev; | ||
1524 | |||
1525 | spin_lock(&swap_lock); | ||
1526 | if (prio >= 0) | ||
1527 | p->prio = prio; | ||
1528 | else | ||
1529 | p->prio = --least_priority; | ||
1530 | p->swap_map = swap_map; | ||
1531 | p->flags |= SWP_WRITEOK; | ||
1532 | nr_swap_pages += p->pages; | ||
1533 | total_swap_pages += p->pages; | ||
1534 | |||
1535 | /* insert swap space into swap_list: */ | ||
1536 | prev = -1; | ||
1537 | for (i = swap_list.head; i >= 0; i = swap_info[i]->next) { | ||
1538 | if (p->prio >= swap_info[i]->prio) | ||
1539 | break; | ||
1540 | prev = i; | ||
1541 | } | ||
1542 | p->next = i; | ||
1543 | if (prev < 0) | ||
1544 | swap_list.head = swap_list.next = p->type; | ||
1545 | else | ||
1546 | swap_info[prev]->next = p->type; | ||
1547 | spin_unlock(&swap_lock); | ||
1548 | } | ||
1549 | |||
1553 | SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) | 1550 | SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) |
1554 | { | 1551 | { |
1555 | struct swap_info_struct *p = NULL; | 1552 | struct swap_info_struct *p = NULL; |
@@ -1621,32 +1618,17 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) | |||
1621 | current->flags &= ~PF_OOM_ORIGIN; | 1618 | current->flags &= ~PF_OOM_ORIGIN; |
1622 | 1619 | ||
1623 | if (err) { | 1620 | if (err) { |
1621 | /* | ||
1622 | * reading p->prio and p->swap_map outside the lock is | ||
1623 | * safe here because only sys_swapon and sys_swapoff | ||
1624 | * change them, and there can be no other sys_swapon or | ||
1625 | * sys_swapoff for this swap_info_struct at this point. | ||
1626 | */ | ||
1624 | /* re-insert swap space back into swap_list */ | 1627 | /* re-insert swap space back into swap_list */ |
1625 | spin_lock(&swap_lock); | 1628 | enable_swap_info(p, p->prio, p->swap_map); |
1626 | if (p->prio < 0) | ||
1627 | p->prio = --least_priority; | ||
1628 | prev = -1; | ||
1629 | for (i = swap_list.head; i >= 0; i = swap_info[i]->next) { | ||
1630 | if (p->prio >= swap_info[i]->prio) | ||
1631 | break; | ||
1632 | prev = i; | ||
1633 | } | ||
1634 | p->next = i; | ||
1635 | if (prev < 0) | ||
1636 | swap_list.head = swap_list.next = type; | ||
1637 | else | ||
1638 | swap_info[prev]->next = type; | ||
1639 | nr_swap_pages += p->pages; | ||
1640 | total_swap_pages += p->pages; | ||
1641 | p->flags |= SWP_WRITEOK; | ||
1642 | spin_unlock(&swap_lock); | ||
1643 | goto out_dput; | 1629 | goto out_dput; |
1644 | } | 1630 | } |
1645 | 1631 | ||
1646 | /* wait for any unplug function to finish */ | ||
1647 | down_write(&swap_unplug_sem); | ||
1648 | up_write(&swap_unplug_sem); | ||
1649 | |||
1650 | destroy_swap_extents(p); | 1632 | destroy_swap_extents(p); |
1651 | if (p->flags & SWP_CONTINUED) | 1633 | if (p->flags & SWP_CONTINUED) |
1652 | free_swap_count_continuations(p); | 1634 | free_swap_count_continuations(p); |
@@ -1844,49 +1826,24 @@ static int __init max_swapfiles_check(void) | |||
1844 | late_initcall(max_swapfiles_check); | 1826 | late_initcall(max_swapfiles_check); |
1845 | #endif | 1827 | #endif |
1846 | 1828 | ||
1847 | /* | 1829 | static struct swap_info_struct *alloc_swap_info(void) |
1848 | * Written 01/25/92 by Simmule Turner, heavily changed by Linus. | ||
1849 | * | ||
1850 | * The swapon system call | ||
1851 | */ | ||
1852 | SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | ||
1853 | { | 1830 | { |
1854 | struct swap_info_struct *p; | 1831 | struct swap_info_struct *p; |
1855 | char *name = NULL; | ||
1856 | struct block_device *bdev = NULL; | ||
1857 | struct file *swap_file = NULL; | ||
1858 | struct address_space *mapping; | ||
1859 | unsigned int type; | 1832 | unsigned int type; |
1860 | int i, prev; | ||
1861 | int error; | ||
1862 | union swap_header *swap_header; | ||
1863 | unsigned int nr_good_pages; | ||
1864 | int nr_extents = 0; | ||
1865 | sector_t span; | ||
1866 | unsigned long maxpages; | ||
1867 | unsigned long swapfilepages; | ||
1868 | unsigned char *swap_map = NULL; | ||
1869 | struct page *page = NULL; | ||
1870 | struct inode *inode = NULL; | ||
1871 | int did_down = 0; | ||
1872 | |||
1873 | if (!capable(CAP_SYS_ADMIN)) | ||
1874 | return -EPERM; | ||
1875 | 1833 | ||
1876 | p = kzalloc(sizeof(*p), GFP_KERNEL); | 1834 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
1877 | if (!p) | 1835 | if (!p) |
1878 | return -ENOMEM; | 1836 | return ERR_PTR(-ENOMEM); |
1879 | 1837 | ||
1880 | spin_lock(&swap_lock); | 1838 | spin_lock(&swap_lock); |
1881 | for (type = 0; type < nr_swapfiles; type++) { | 1839 | for (type = 0; type < nr_swapfiles; type++) { |
1882 | if (!(swap_info[type]->flags & SWP_USED)) | 1840 | if (!(swap_info[type]->flags & SWP_USED)) |
1883 | break; | 1841 | break; |
1884 | } | 1842 | } |
1885 | error = -EPERM; | ||
1886 | if (type >= MAX_SWAPFILES) { | 1843 | if (type >= MAX_SWAPFILES) { |
1887 | spin_unlock(&swap_lock); | 1844 | spin_unlock(&swap_lock); |
1888 | kfree(p); | 1845 | kfree(p); |
1889 | goto out; | 1846 | return ERR_PTR(-EPERM); |
1890 | } | 1847 | } |
1891 | if (type >= nr_swapfiles) { | 1848 | if (type >= nr_swapfiles) { |
1892 | p->type = type; | 1849 | p->type = type; |
@@ -1911,81 +1868,49 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
1911 | p->next = -1; | 1868 | p->next = -1; |
1912 | spin_unlock(&swap_lock); | 1869 | spin_unlock(&swap_lock); |
1913 | 1870 | ||
1914 | name = getname(specialfile); | 1871 | return p; |
1915 | error = PTR_ERR(name); | 1872 | } |
1916 | if (IS_ERR(name)) { | ||
1917 | name = NULL; | ||
1918 | goto bad_swap_2; | ||
1919 | } | ||
1920 | swap_file = filp_open(name, O_RDWR|O_LARGEFILE, 0); | ||
1921 | error = PTR_ERR(swap_file); | ||
1922 | if (IS_ERR(swap_file)) { | ||
1923 | swap_file = NULL; | ||
1924 | goto bad_swap_2; | ||
1925 | } | ||
1926 | |||
1927 | p->swap_file = swap_file; | ||
1928 | mapping = swap_file->f_mapping; | ||
1929 | inode = mapping->host; | ||
1930 | |||
1931 | error = -EBUSY; | ||
1932 | for (i = 0; i < nr_swapfiles; i++) { | ||
1933 | struct swap_info_struct *q = swap_info[i]; | ||
1934 | 1873 | ||
1935 | if (i == type || !q->swap_file) | 1874 | static int claim_swapfile(struct swap_info_struct *p, struct inode *inode) |
1936 | continue; | 1875 | { |
1937 | if (mapping == q->swap_file->f_mapping) | 1876 | int error; |
1938 | goto bad_swap; | ||
1939 | } | ||
1940 | 1877 | ||
1941 | error = -EINVAL; | ||
1942 | if (S_ISBLK(inode->i_mode)) { | 1878 | if (S_ISBLK(inode->i_mode)) { |
1943 | bdev = bdgrab(I_BDEV(inode)); | 1879 | p->bdev = bdgrab(I_BDEV(inode)); |
1944 | error = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, | 1880 | error = blkdev_get(p->bdev, |
1881 | FMODE_READ | FMODE_WRITE | FMODE_EXCL, | ||
1945 | sys_swapon); | 1882 | sys_swapon); |
1946 | if (error < 0) { | 1883 | if (error < 0) { |
1947 | bdev = NULL; | 1884 | p->bdev = NULL; |
1948 | error = -EINVAL; | 1885 | return -EINVAL; |
1949 | goto bad_swap; | ||
1950 | } | 1886 | } |
1951 | p->old_block_size = block_size(bdev); | 1887 | p->old_block_size = block_size(p->bdev); |
1952 | error = set_blocksize(bdev, PAGE_SIZE); | 1888 | error = set_blocksize(p->bdev, PAGE_SIZE); |
1953 | if (error < 0) | 1889 | if (error < 0) |
1954 | goto bad_swap; | 1890 | return error; |
1955 | p->bdev = bdev; | ||
1956 | p->flags |= SWP_BLKDEV; | 1891 | p->flags |= SWP_BLKDEV; |
1957 | } else if (S_ISREG(inode->i_mode)) { | 1892 | } else if (S_ISREG(inode->i_mode)) { |
1958 | p->bdev = inode->i_sb->s_bdev; | 1893 | p->bdev = inode->i_sb->s_bdev; |
1959 | mutex_lock(&inode->i_mutex); | 1894 | mutex_lock(&inode->i_mutex); |
1960 | did_down = 1; | 1895 | if (IS_SWAPFILE(inode)) |
1961 | if (IS_SWAPFILE(inode)) { | 1896 | return -EBUSY; |
1962 | error = -EBUSY; | 1897 | } else |
1963 | goto bad_swap; | 1898 | return -EINVAL; |
1964 | } | ||
1965 | } else { | ||
1966 | goto bad_swap; | ||
1967 | } | ||
1968 | 1899 | ||
1969 | swapfilepages = i_size_read(inode) >> PAGE_SHIFT; | 1900 | return 0; |
1901 | } | ||
1970 | 1902 | ||
1971 | /* | 1903 | static unsigned long read_swap_header(struct swap_info_struct *p, |
1972 | * Read the swap header. | 1904 | union swap_header *swap_header, |
1973 | */ | 1905 | struct inode *inode) |
1974 | if (!mapping->a_ops->readpage) { | 1906 | { |
1975 | error = -EINVAL; | 1907 | int i; |
1976 | goto bad_swap; | 1908 | unsigned long maxpages; |
1977 | } | 1909 | unsigned long swapfilepages; |
1978 | page = read_mapping_page(mapping, 0, swap_file); | ||
1979 | if (IS_ERR(page)) { | ||
1980 | error = PTR_ERR(page); | ||
1981 | goto bad_swap; | ||
1982 | } | ||
1983 | swap_header = kmap(page); | ||
1984 | 1910 | ||
1985 | if (memcmp("SWAPSPACE2", swap_header->magic.magic, 10)) { | 1911 | if (memcmp("SWAPSPACE2", swap_header->magic.magic, 10)) { |
1986 | printk(KERN_ERR "Unable to find swap-space signature\n"); | 1912 | printk(KERN_ERR "Unable to find swap-space signature\n"); |
1987 | error = -EINVAL; | 1913 | return 0; |
1988 | goto bad_swap; | ||
1989 | } | 1914 | } |
1990 | 1915 | ||
1991 | /* swap partition endianess hack... */ | 1916 | /* swap partition endianess hack... */ |
@@ -2001,8 +1926,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
2001 | printk(KERN_WARNING | 1926 | printk(KERN_WARNING |
2002 | "Unable to handle swap header version %d\n", | 1927 | "Unable to handle swap header version %d\n", |
2003 | swap_header->info.version); | 1928 | swap_header->info.version); |
2004 | error = -EINVAL; | 1929 | return 0; |
2005 | goto bad_swap; | ||
2006 | } | 1930 | } |
2007 | 1931 | ||
2008 | p->lowest_bit = 1; | 1932 | p->lowest_bit = 1; |
@@ -2033,61 +1957,155 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
2033 | } | 1957 | } |
2034 | p->highest_bit = maxpages - 1; | 1958 | p->highest_bit = maxpages - 1; |
2035 | 1959 | ||
2036 | error = -EINVAL; | ||
2037 | if (!maxpages) | 1960 | if (!maxpages) |
2038 | goto bad_swap; | 1961 | return 0; |
1962 | swapfilepages = i_size_read(inode) >> PAGE_SHIFT; | ||
2039 | if (swapfilepages && maxpages > swapfilepages) { | 1963 | if (swapfilepages && maxpages > swapfilepages) { |
2040 | printk(KERN_WARNING | 1964 | printk(KERN_WARNING |
2041 | "Swap area shorter than signature indicates\n"); | 1965 | "Swap area shorter than signature indicates\n"); |
2042 | goto bad_swap; | 1966 | return 0; |
2043 | } | 1967 | } |
2044 | if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode)) | 1968 | if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode)) |
2045 | goto bad_swap; | 1969 | return 0; |
2046 | if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) | 1970 | if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) |
2047 | goto bad_swap; | 1971 | return 0; |
2048 | 1972 | ||
2049 | /* OK, set up the swap map and apply the bad block list */ | 1973 | return maxpages; |
2050 | swap_map = vmalloc(maxpages); | 1974 | } |
2051 | if (!swap_map) { | 1975 | |
2052 | error = -ENOMEM; | 1976 | static int setup_swap_map_and_extents(struct swap_info_struct *p, |
2053 | goto bad_swap; | 1977 | union swap_header *swap_header, |
2054 | } | 1978 | unsigned char *swap_map, |
1979 | unsigned long maxpages, | ||
1980 | sector_t *span) | ||
1981 | { | ||
1982 | int i; | ||
1983 | unsigned int nr_good_pages; | ||
1984 | int nr_extents; | ||
2055 | 1985 | ||
2056 | memset(swap_map, 0, maxpages); | ||
2057 | nr_good_pages = maxpages - 1; /* omit header page */ | 1986 | nr_good_pages = maxpages - 1; /* omit header page */ |
2058 | 1987 | ||
2059 | for (i = 0; i < swap_header->info.nr_badpages; i++) { | 1988 | for (i = 0; i < swap_header->info.nr_badpages; i++) { |
2060 | unsigned int page_nr = swap_header->info.badpages[i]; | 1989 | unsigned int page_nr = swap_header->info.badpages[i]; |
2061 | if (page_nr == 0 || page_nr > swap_header->info.last_page) { | 1990 | if (page_nr == 0 || page_nr > swap_header->info.last_page) |
2062 | error = -EINVAL; | 1991 | return -EINVAL; |
2063 | goto bad_swap; | ||
2064 | } | ||
2065 | if (page_nr < maxpages) { | 1992 | if (page_nr < maxpages) { |
2066 | swap_map[page_nr] = SWAP_MAP_BAD; | 1993 | swap_map[page_nr] = SWAP_MAP_BAD; |
2067 | nr_good_pages--; | 1994 | nr_good_pages--; |
2068 | } | 1995 | } |
2069 | } | 1996 | } |
2070 | 1997 | ||
2071 | error = swap_cgroup_swapon(type, maxpages); | ||
2072 | if (error) | ||
2073 | goto bad_swap; | ||
2074 | |||
2075 | if (nr_good_pages) { | 1998 | if (nr_good_pages) { |
2076 | swap_map[0] = SWAP_MAP_BAD; | 1999 | swap_map[0] = SWAP_MAP_BAD; |
2077 | p->max = maxpages; | 2000 | p->max = maxpages; |
2078 | p->pages = nr_good_pages; | 2001 | p->pages = nr_good_pages; |
2079 | nr_extents = setup_swap_extents(p, &span); | 2002 | nr_extents = setup_swap_extents(p, span); |
2080 | if (nr_extents < 0) { | 2003 | if (nr_extents < 0) |
2081 | error = nr_extents; | 2004 | return nr_extents; |
2082 | goto bad_swap; | ||
2083 | } | ||
2084 | nr_good_pages = p->pages; | 2005 | nr_good_pages = p->pages; |
2085 | } | 2006 | } |
2086 | if (!nr_good_pages) { | 2007 | if (!nr_good_pages) { |
2087 | printk(KERN_WARNING "Empty swap-file\n"); | 2008 | printk(KERN_WARNING "Empty swap-file\n"); |
2009 | return -EINVAL; | ||
2010 | } | ||
2011 | |||
2012 | return nr_extents; | ||
2013 | } | ||
2014 | |||
2015 | SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | ||
2016 | { | ||
2017 | struct swap_info_struct *p; | ||
2018 | char *name; | ||
2019 | struct file *swap_file = NULL; | ||
2020 | struct address_space *mapping; | ||
2021 | int i; | ||
2022 | int prio; | ||
2023 | int error; | ||
2024 | union swap_header *swap_header; | ||
2025 | int nr_extents; | ||
2026 | sector_t span; | ||
2027 | unsigned long maxpages; | ||
2028 | unsigned char *swap_map = NULL; | ||
2029 | struct page *page = NULL; | ||
2030 | struct inode *inode = NULL; | ||
2031 | |||
2032 | if (!capable(CAP_SYS_ADMIN)) | ||
2033 | return -EPERM; | ||
2034 | |||
2035 | p = alloc_swap_info(); | ||
2036 | if (IS_ERR(p)) | ||
2037 | return PTR_ERR(p); | ||
2038 | |||
2039 | name = getname(specialfile); | ||
2040 | if (IS_ERR(name)) { | ||
2041 | error = PTR_ERR(name); | ||
2042 | name = NULL; | ||
2043 | goto bad_swap; | ||
2044 | } | ||
2045 | swap_file = filp_open(name, O_RDWR|O_LARGEFILE, 0); | ||
2046 | if (IS_ERR(swap_file)) { | ||
2047 | error = PTR_ERR(swap_file); | ||
2048 | swap_file = NULL; | ||
2049 | goto bad_swap; | ||
2050 | } | ||
2051 | |||
2052 | p->swap_file = swap_file; | ||
2053 | mapping = swap_file->f_mapping; | ||
2054 | |||
2055 | for (i = 0; i < nr_swapfiles; i++) { | ||
2056 | struct swap_info_struct *q = swap_info[i]; | ||
2057 | |||
2058 | if (q == p || !q->swap_file) | ||
2059 | continue; | ||
2060 | if (mapping == q->swap_file->f_mapping) { | ||
2061 | error = -EBUSY; | ||
2062 | goto bad_swap; | ||
2063 | } | ||
2064 | } | ||
2065 | |||
2066 | inode = mapping->host; | ||
2067 | /* If S_ISREG(inode->i_mode) will do mutex_lock(&inode->i_mutex); */ | ||
2068 | error = claim_swapfile(p, inode); | ||
2069 | if (unlikely(error)) | ||
2070 | goto bad_swap; | ||
2071 | |||
2072 | /* | ||
2073 | * Read the swap header. | ||
2074 | */ | ||
2075 | if (!mapping->a_ops->readpage) { | ||
2088 | error = -EINVAL; | 2076 | error = -EINVAL; |
2089 | goto bad_swap; | 2077 | goto bad_swap; |
2090 | } | 2078 | } |
2079 | page = read_mapping_page(mapping, 0, swap_file); | ||
2080 | if (IS_ERR(page)) { | ||
2081 | error = PTR_ERR(page); | ||
2082 | goto bad_swap; | ||
2083 | } | ||
2084 | swap_header = kmap(page); | ||
2085 | |||
2086 | maxpages = read_swap_header(p, swap_header, inode); | ||
2087 | if (unlikely(!maxpages)) { | ||
2088 | error = -EINVAL; | ||
2089 | goto bad_swap; | ||
2090 | } | ||
2091 | |||
2092 | /* OK, set up the swap map and apply the bad block list */ | ||
2093 | swap_map = vzalloc(maxpages); | ||
2094 | if (!swap_map) { | ||
2095 | error = -ENOMEM; | ||
2096 | goto bad_swap; | ||
2097 | } | ||
2098 | |||
2099 | error = swap_cgroup_swapon(p->type, maxpages); | ||
2100 | if (error) | ||
2101 | goto bad_swap; | ||
2102 | |||
2103 | nr_extents = setup_swap_map_and_extents(p, swap_header, swap_map, | ||
2104 | maxpages, &span); | ||
2105 | if (unlikely(nr_extents < 0)) { | ||
2106 | error = nr_extents; | ||
2107 | goto bad_swap; | ||
2108 | } | ||
2091 | 2109 | ||
2092 | if (p->bdev) { | 2110 | if (p->bdev) { |
2093 | if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { | 2111 | if (blk_queue_nonrot(bdev_get_queue(p->bdev))) { |
@@ -2099,58 +2117,46 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
2099 | } | 2117 | } |
2100 | 2118 | ||
2101 | mutex_lock(&swapon_mutex); | 2119 | mutex_lock(&swapon_mutex); |
2102 | spin_lock(&swap_lock); | 2120 | prio = -1; |
2103 | if (swap_flags & SWAP_FLAG_PREFER) | 2121 | if (swap_flags & SWAP_FLAG_PREFER) |
2104 | p->prio = | 2122 | prio = |
2105 | (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT; | 2123 | (swap_flags & SWAP_FLAG_PRIO_MASK) >> SWAP_FLAG_PRIO_SHIFT; |
2106 | else | 2124 | enable_swap_info(p, prio, swap_map); |
2107 | p->prio = --least_priority; | ||
2108 | p->swap_map = swap_map; | ||
2109 | p->flags |= SWP_WRITEOK; | ||
2110 | nr_swap_pages += nr_good_pages; | ||
2111 | total_swap_pages += nr_good_pages; | ||
2112 | 2125 | ||
2113 | printk(KERN_INFO "Adding %uk swap on %s. " | 2126 | printk(KERN_INFO "Adding %uk swap on %s. " |
2114 | "Priority:%d extents:%d across:%lluk %s%s\n", | 2127 | "Priority:%d extents:%d across:%lluk %s%s\n", |
2115 | nr_good_pages<<(PAGE_SHIFT-10), name, p->prio, | 2128 | p->pages<<(PAGE_SHIFT-10), name, p->prio, |
2116 | nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10), | 2129 | nr_extents, (unsigned long long)span<<(PAGE_SHIFT-10), |
2117 | (p->flags & SWP_SOLIDSTATE) ? "SS" : "", | 2130 | (p->flags & SWP_SOLIDSTATE) ? "SS" : "", |
2118 | (p->flags & SWP_DISCARDABLE) ? "D" : ""); | 2131 | (p->flags & SWP_DISCARDABLE) ? "D" : ""); |
2119 | 2132 | ||
2120 | /* insert swap space into swap_list: */ | ||
2121 | prev = -1; | ||
2122 | for (i = swap_list.head; i >= 0; i = swap_info[i]->next) { | ||
2123 | if (p->prio >= swap_info[i]->prio) | ||
2124 | break; | ||
2125 | prev = i; | ||
2126 | } | ||
2127 | p->next = i; | ||
2128 | if (prev < 0) | ||
2129 | swap_list.head = swap_list.next = type; | ||
2130 | else | ||
2131 | swap_info[prev]->next = type; | ||
2132 | spin_unlock(&swap_lock); | ||
2133 | mutex_unlock(&swapon_mutex); | 2133 | mutex_unlock(&swapon_mutex); |
2134 | atomic_inc(&proc_poll_event); | 2134 | atomic_inc(&proc_poll_event); |
2135 | wake_up_interruptible(&proc_poll_wait); | 2135 | wake_up_interruptible(&proc_poll_wait); |
2136 | 2136 | ||
2137 | if (S_ISREG(inode->i_mode)) | ||
2138 | inode->i_flags |= S_SWAPFILE; | ||
2137 | error = 0; | 2139 | error = 0; |
2138 | goto out; | 2140 | goto out; |
2139 | bad_swap: | 2141 | bad_swap: |
2140 | if (bdev) { | 2142 | if (inode && S_ISBLK(inode->i_mode) && p->bdev) { |
2141 | set_blocksize(bdev, p->old_block_size); | 2143 | set_blocksize(p->bdev, p->old_block_size); |
2142 | blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); | 2144 | blkdev_put(p->bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); |
2143 | } | 2145 | } |
2144 | destroy_swap_extents(p); | 2146 | destroy_swap_extents(p); |
2145 | swap_cgroup_swapoff(type); | 2147 | swap_cgroup_swapoff(p->type); |
2146 | bad_swap_2: | ||
2147 | spin_lock(&swap_lock); | 2148 | spin_lock(&swap_lock); |
2148 | p->swap_file = NULL; | 2149 | p->swap_file = NULL; |
2149 | p->flags = 0; | 2150 | p->flags = 0; |
2150 | spin_unlock(&swap_lock); | 2151 | spin_unlock(&swap_lock); |
2151 | vfree(swap_map); | 2152 | vfree(swap_map); |
2152 | if (swap_file) | 2153 | if (swap_file) { |
2154 | if (inode && S_ISREG(inode->i_mode)) { | ||
2155 | mutex_unlock(&inode->i_mutex); | ||
2156 | inode = NULL; | ||
2157 | } | ||
2153 | filp_close(swap_file, NULL); | 2158 | filp_close(swap_file, NULL); |
2159 | } | ||
2154 | out: | 2160 | out: |
2155 | if (page && !IS_ERR(page)) { | 2161 | if (page && !IS_ERR(page)) { |
2156 | kunmap(page); | 2162 | kunmap(page); |
@@ -2158,11 +2164,8 @@ out: | |||
2158 | } | 2164 | } |
2159 | if (name) | 2165 | if (name) |
2160 | putname(name); | 2166 | putname(name); |
2161 | if (did_down) { | 2167 | if (inode && S_ISREG(inode->i_mode)) |
2162 | if (!error) | ||
2163 | inode->i_flags |= S_SWAPFILE; | ||
2164 | mutex_unlock(&inode->i_mutex); | 2168 | mutex_unlock(&inode->i_mutex); |
2165 | } | ||
2166 | return error; | 2169 | return error; |
2167 | } | 2170 | } |
2168 | 2171 | ||