Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9f3d1d1 authored by Darrick J. Wong's avatar Darrick J. Wong Committed by Jaegeuk Kim
Browse files

mm: set S_SWAPFILE on blockdev swap devices



Set S_SWAPFILE on block device inodes so that they have the same
protections as a swap flie.

Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
parent 0fa945de
Loading
Loading
Loading
Loading
+15 −16
Original line number Diff line number Diff line
@@ -2385,9 +2385,8 @@ add_swap_extent(struct swap_info_struct *sis, unsigned long start_page,
 * requirements, they are simply tossed out - we will never use those blocks
 * for swapping.
 *
 * For S_ISREG swapfiles we set S_SWAPFILE across the life of the swapon.  This
 * prevents root from shooting her foot off by ftruncating an in-use swapfile,
 * which will scribble on the fs.
 * For all swap devices we set S_SWAPFILE across the life of the swapon.  This
 * prevents users from writing to the swap device, which will corrupt memory.
 *
 * The amount of disk space which a single swap extent represents varies.
 * Typically it is in the 1-4 megabyte range.  So we can have hundreds of
@@ -2650,13 +2649,14 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
	inode = mapping->host;
	if (S_ISBLK(inode->i_mode)) {
		struct block_device *bdev = I_BDEV(inode);

		set_blocksize(bdev, old_block_size);
		blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL);
	} else {
	}

	inode_lock(inode);
	inode->i_flags &= ~S_SWAPFILE;
	inode_unlock(inode);
	}
	filp_close(swap_file, NULL);

	/*
@@ -2883,11 +2883,11 @@ static int claim_swapfile(struct swap_info_struct *p, struct inode *inode)
		p->flags |= SWP_BLKDEV;
	} else if (S_ISREG(inode->i_mode)) {
		p->bdev = inode->i_sb->s_bdev;
	}

	inode_lock(inode);
	if (IS_SWAPFILE(inode))
		return -EBUSY;
	} else
		return -EINVAL;

	return 0;
}
@@ -3288,7 +3288,6 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
	atomic_inc(&proc_poll_event);
	wake_up_interruptible(&proc_poll_wait);

	if (S_ISREG(inode->i_mode))
	inode->i_flags |= S_SWAPFILE;
	error = 0;
	goto out;
@@ -3311,7 +3310,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
	if (inced_nr_rotate_swap)
		atomic_dec(&nr_rotate_swap);
	if (swap_file) {
		if (inode && S_ISREG(inode->i_mode)) {
		if (inode) {
			inode_unlock(inode);
			inode = NULL;
		}
@@ -3324,7 +3323,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
	}
	if (name)
		putname(name);
	if (inode && S_ISREG(inode->i_mode))
	if (inode)
		inode_unlock(inode);
	if (!error)
		enable_swap_slots_cache();