Commit ca8bd38bf6f05481c4155fc444178151884f65d0
Committed by
Linus Torvalds
1 parent
5de771e41f
Exists in
master
and in
20 other branches
sys_swapon: separate parsing of swapfile header
Move the code which parses and checks the swapfile header (except for the bad block list) to a separate function. Only code movement, no functional changes. Signed-off-by: Cesar Eduardo Barros <cesarb@cesarb.net> Tested-by: Eric B Munson <emunson@mgebm.net> Acked-by: Eric B Munson <emunson@mgebm.net> Reviewed-by: KAMEZAWA Hiroyuki <kamezawa.hiroyu@jp.fujitsu.com> Cc: Hugh Dickins <hughd@google.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 1 changed file with 78 additions and 62 deletions Side-by-side Diff
mm/swapfile.c
... | ... | @@ -1918,6 +1918,82 @@ |
1918 | 1918 | return 0; |
1919 | 1919 | } |
1920 | 1920 | |
1921 | +static unsigned long read_swap_header(struct swap_info_struct *p, | |
1922 | + union swap_header *swap_header, | |
1923 | + struct inode *inode) | |
1924 | +{ | |
1925 | + int i; | |
1926 | + unsigned long maxpages; | |
1927 | + unsigned long swapfilepages; | |
1928 | + | |
1929 | + if (memcmp("SWAPSPACE2", swap_header->magic.magic, 10)) { | |
1930 | + printk(KERN_ERR "Unable to find swap-space signature\n"); | |
1931 | + goto bad_swap; | |
1932 | + } | |
1933 | + | |
1934 | + /* swap partition endianess hack... */ | |
1935 | + if (swab32(swap_header->info.version) == 1) { | |
1936 | + swab32s(&swap_header->info.version); | |
1937 | + swab32s(&swap_header->info.last_page); | |
1938 | + swab32s(&swap_header->info.nr_badpages); | |
1939 | + for (i = 0; i < swap_header->info.nr_badpages; i++) | |
1940 | + swab32s(&swap_header->info.badpages[i]); | |
1941 | + } | |
1942 | + /* Check the swap header's sub-version */ | |
1943 | + if (swap_header->info.version != 1) { | |
1944 | + printk(KERN_WARNING | |
1945 | + "Unable to handle swap header version %d\n", | |
1946 | + swap_header->info.version); | |
1947 | + goto bad_swap; | |
1948 | + } | |
1949 | + | |
1950 | + p->lowest_bit = 1; | |
1951 | + p->cluster_next = 1; | |
1952 | + p->cluster_nr = 0; | |
1953 | + | |
1954 | + /* | |
1955 | + * Find out how many pages are allowed for a single swap | |
1956 | + * device. There are two limiting factors: 1) the number of | |
1957 | + * bits for the swap offset in the swp_entry_t type and | |
1958 | + * 2) the number of bits in the a swap pte as defined by | |
1959 | + * the different architectures. In order to find the | |
1960 | + * largest possible bit mask a swap entry with swap type 0 | |
1961 | + * and swap offset ~0UL is created, encoded to a swap pte, | |
1962 | + * decoded to a swp_entry_t again and finally the swap | |
1963 | + * offset is extracted. This will mask all the bits from | |
1964 | + * the initial ~0UL mask that can't be encoded in either | |
1965 | + * the swp_entry_t or the architecture definition of a | |
1966 | + * swap pte. | |
1967 | + */ | |
1968 | + maxpages = swp_offset(pte_to_swp_entry( | |
1969 | + swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1; | |
1970 | + if (maxpages > swap_header->info.last_page) { | |
1971 | + maxpages = swap_header->info.last_page + 1; | |
1972 | + /* p->max is an unsigned int: don't overflow it */ | |
1973 | + if ((unsigned int)maxpages == 0) | |
1974 | + maxpages = UINT_MAX; | |
1975 | + } | |
1976 | + p->highest_bit = maxpages - 1; | |
1977 | + | |
1978 | + if (!maxpages) | |
1979 | + goto bad_swap; | |
1980 | + swapfilepages = i_size_read(inode) >> PAGE_SHIFT; | |
1981 | + if (swapfilepages && maxpages > swapfilepages) { | |
1982 | + printk(KERN_WARNING | |
1983 | + "Swap area shorter than signature indicates\n"); | |
1984 | + goto bad_swap; | |
1985 | + } | |
1986 | + if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode)) | |
1987 | + goto bad_swap; | |
1988 | + if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) | |
1989 | + goto bad_swap; | |
1990 | + | |
1991 | + return maxpages; | |
1992 | + | |
1993 | +bad_swap: | |
1994 | + return 0; | |
1995 | +} | |
1996 | + | |
1921 | 1997 | SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) |
1922 | 1998 | { |
1923 | 1999 | struct swap_info_struct *p; |
... | ... | @@ -1931,7 +2007,6 @@ |
1931 | 2007 | int nr_extents = 0; |
1932 | 2008 | sector_t span; |
1933 | 2009 | unsigned long maxpages; |
1934 | - unsigned long swapfilepages; | |
1935 | 2010 | unsigned char *swap_map = NULL; |
1936 | 2011 | struct page *page = NULL; |
1937 | 2012 | struct inode *inode = NULL; |
1938 | 2013 | |
... | ... | @@ -1989,70 +2064,11 @@ |
1989 | 2064 | } |
1990 | 2065 | swap_header = kmap(page); |
1991 | 2066 | |
1992 | - if (memcmp("SWAPSPACE2", swap_header->magic.magic, 10)) { | |
1993 | - printk(KERN_ERR "Unable to find swap-space signature\n"); | |
2067 | + maxpages = read_swap_header(p, swap_header, inode); | |
2068 | + if (unlikely(!maxpages)) { | |
1994 | 2069 | error = -EINVAL; |
1995 | 2070 | goto bad_swap; |
1996 | 2071 | } |
1997 | - | |
1998 | - /* swap partition endianess hack... */ | |
1999 | - if (swab32(swap_header->info.version) == 1) { | |
2000 | - swab32s(&swap_header->info.version); | |
2001 | - swab32s(&swap_header->info.last_page); | |
2002 | - swab32s(&swap_header->info.nr_badpages); | |
2003 | - for (i = 0; i < swap_header->info.nr_badpages; i++) | |
2004 | - swab32s(&swap_header->info.badpages[i]); | |
2005 | - } | |
2006 | - /* Check the swap header's sub-version */ | |
2007 | - if (swap_header->info.version != 1) { | |
2008 | - printk(KERN_WARNING | |
2009 | - "Unable to handle swap header version %d\n", | |
2010 | - swap_header->info.version); | |
2011 | - error = -EINVAL; | |
2012 | - goto bad_swap; | |
2013 | - } | |
2014 | - | |
2015 | - p->lowest_bit = 1; | |
2016 | - p->cluster_next = 1; | |
2017 | - p->cluster_nr = 0; | |
2018 | - | |
2019 | - /* | |
2020 | - * Find out how many pages are allowed for a single swap | |
2021 | - * device. There are two limiting factors: 1) the number of | |
2022 | - * bits for the swap offset in the swp_entry_t type and | |
2023 | - * 2) the number of bits in the a swap pte as defined by | |
2024 | - * the different architectures. In order to find the | |
2025 | - * largest possible bit mask a swap entry with swap type 0 | |
2026 | - * and swap offset ~0UL is created, encoded to a swap pte, | |
2027 | - * decoded to a swp_entry_t again and finally the swap | |
2028 | - * offset is extracted. This will mask all the bits from | |
2029 | - * the initial ~0UL mask that can't be encoded in either | |
2030 | - * the swp_entry_t or the architecture definition of a | |
2031 | - * swap pte. | |
2032 | - */ | |
2033 | - maxpages = swp_offset(pte_to_swp_entry( | |
2034 | - swp_entry_to_pte(swp_entry(0, ~0UL)))) + 1; | |
2035 | - if (maxpages > swap_header->info.last_page) { | |
2036 | - maxpages = swap_header->info.last_page + 1; | |
2037 | - /* p->max is an unsigned int: don't overflow it */ | |
2038 | - if ((unsigned int)maxpages == 0) | |
2039 | - maxpages = UINT_MAX; | |
2040 | - } | |
2041 | - p->highest_bit = maxpages - 1; | |
2042 | - | |
2043 | - error = -EINVAL; | |
2044 | - if (!maxpages) | |
2045 | - goto bad_swap; | |
2046 | - swapfilepages = i_size_read(inode) >> PAGE_SHIFT; | |
2047 | - if (swapfilepages && maxpages > swapfilepages) { | |
2048 | - printk(KERN_WARNING | |
2049 | - "Swap area shorter than signature indicates\n"); | |
2050 | - goto bad_swap; | |
2051 | - } | |
2052 | - if (swap_header->info.nr_badpages && S_ISREG(inode->i_mode)) | |
2053 | - goto bad_swap; | |
2054 | - if (swap_header->info.nr_badpages > MAX_SWAP_BADPAGES) | |
2055 | - goto bad_swap; | |
2056 | 2072 | |
2057 | 2073 | /* OK, set up the swap map and apply the bad block list */ |
2058 | 2074 | swap_map = vzalloc(maxpages); |