diff options
Diffstat (limited to 'mm')
-rw-r--r-- | mm/swapfile.c | 64 |
1 files changed, 39 insertions, 25 deletions
diff --git a/mm/swapfile.c b/mm/swapfile.c index 14590775212d..fc687b234eb5 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c | |||
@@ -1889,6 +1889,43 @@ static struct swap_info_struct *alloc_swap_info(void) | |||
1889 | return p; | 1889 | return p; |
1890 | } | 1890 | } |
1891 | 1891 | ||
1892 | static int claim_swapfile(struct swap_info_struct *p, struct inode *inode) | ||
1893 | { | ||
1894 | int error; | ||
1895 | |||
1896 | if (S_ISBLK(inode->i_mode)) { | ||
1897 | p->bdev = bdgrab(I_BDEV(inode)); | ||
1898 | error = blkdev_get(p->bdev, | ||
1899 | FMODE_READ | FMODE_WRITE | FMODE_EXCL, | ||
1900 | sys_swapon); | ||
1901 | if (error < 0) { | ||
1902 | p->bdev = NULL; | ||
1903 | error = -EINVAL; | ||
1904 | goto bad_swap; | ||
1905 | } | ||
1906 | p->old_block_size = block_size(p->bdev); | ||
1907 | error = set_blocksize(p->bdev, PAGE_SIZE); | ||
1908 | if (error < 0) | ||
1909 | goto bad_swap; | ||
1910 | p->flags |= SWP_BLKDEV; | ||
1911 | } else if (S_ISREG(inode->i_mode)) { | ||
1912 | p->bdev = inode->i_sb->s_bdev; | ||
1913 | mutex_lock(&inode->i_mutex); | ||
1914 | if (IS_SWAPFILE(inode)) { | ||
1915 | error = -EBUSY; | ||
1916 | goto bad_swap; | ||
1917 | } | ||
1918 | } else { | ||
1919 | error = -EINVAL; | ||
1920 | goto bad_swap; | ||
1921 | } | ||
1922 | |||
1923 | return 0; | ||
1924 | |||
1925 | bad_swap: | ||
1926 | return error; | ||
1927 | } | ||
1928 | |||
1892 | SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | 1929 | SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) |
1893 | { | 1930 | { |
1894 | struct swap_info_struct *p; | 1931 | struct swap_info_struct *p; |
@@ -1942,32 +1979,9 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) | |||
1942 | } | 1979 | } |
1943 | } | 1980 | } |
1944 | 1981 | ||
1945 | if (S_ISBLK(inode->i_mode)) { | 1982 | error = claim_swapfile(p, inode); |
1946 | p->bdev = bdgrab(I_BDEV(inode)); | 1983 | if (unlikely(error)) |
1947 | error = blkdev_get(p->bdev, | ||
1948 | FMODE_READ | FMODE_WRITE | FMODE_EXCL, | ||
1949 | sys_swapon); | ||
1950 | if (error < 0) { | ||
1951 | p->bdev = NULL; | ||
1952 | error = -EINVAL; | ||
1953 | goto bad_swap; | ||
1954 | } | ||
1955 | p->old_block_size = block_size(p->bdev); | ||
1956 | error = set_blocksize(p->bdev, PAGE_SIZE); | ||
1957 | if (error < 0) | ||
1958 | goto bad_swap; | ||
1959 | p->flags |= SWP_BLKDEV; | ||
1960 | } else if (S_ISREG(inode->i_mode)) { | ||
1961 | p->bdev = inode->i_sb->s_bdev; | ||
1962 | mutex_lock(&inode->i_mutex); | ||
1963 | if (IS_SWAPFILE(inode)) { | ||
1964 | error = -EBUSY; | ||
1965 | goto bad_swap; | ||
1966 | } | ||
1967 | } else { | ||
1968 | error = -EINVAL; | ||
1969 | goto bad_swap; | 1984 | goto bad_swap; |
1970 | } | ||
1971 | 1985 | ||
1972 | swapfilepages = i_size_read(inode) >> PAGE_SHIFT; | 1986 | swapfilepages = i_size_read(inode) >> PAGE_SHIFT; |
1973 | 1987 | ||