swapon(2): open swap with O_EXCL
authorAl Viro <viro@zeniv.linux.org.uk>
Wed, 17 Apr 2024 22:33:34 +0000 (18:33 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Thu, 2 May 2024 21:23:30 +0000 (17:23 -0400)
... eliminating the need to reopen block devices so they could be
exclusively held.

Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
include/linux/swap.h
mm/swapfile.c

index a5b640cca459975351ba25afd36ee847563c5c12..7e61a4aef2fc3b45071e913cc4bd66dfedcb2318 100644 (file)
@@ -298,7 +298,6 @@ struct swap_info_struct {
        unsigned int __percpu *cluster_next_cpu; /*percpu index for next allocation */
        struct percpu_cluster __percpu *percpu_cluster; /* per cpu's swap location */
        struct rb_root swap_extent_root;/* root of the swap extent rbtree */
-       struct file *bdev_file;         /* open handle of the bdev */
        struct block_device *bdev;      /* swap device or bdev of swap file */
        struct file *swap_file;         /* seldom referenced */
        struct completion comp;         /* seldom referenced */
index 304f74d039f3ecbe521d27ef4ebfb20f2348dd8a..7bba0b0d49242926cc9b8e886ad5c6781a802ed8 100644 (file)
@@ -2550,10 +2550,6 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile)
        exit_swap_address_space(p->type);
 
        inode = mapping->host;
-       if (p->bdev_file) {
-               fput(p->bdev_file);
-               p->bdev_file = NULL;
-       }
 
        inode_lock(inode);
        inode->i_flags &= ~S_SWAPFILE;
@@ -2780,14 +2776,7 @@ static struct swap_info_struct *alloc_swap_info(void)
 static int claim_swapfile(struct swap_info_struct *p, struct inode *inode)
 {
        if (S_ISBLK(inode->i_mode)) {
-               p->bdev_file = bdev_file_open_by_dev(inode->i_rdev,
-                               BLK_OPEN_READ | BLK_OPEN_WRITE, p, NULL);
-               if (IS_ERR(p->bdev_file)) {
-                       int error = PTR_ERR(p->bdev_file);
-                       p->bdev_file = NULL;
-                       return error;
-               }
-               p->bdev = file_bdev(p->bdev_file);
+               p->bdev = I_BDEV(inode);
                /*
                 * Zoned block devices contain zones that have a sequential
                 * write only restriction.  Hence zoned block devices are not
@@ -3028,7 +3017,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
                name = NULL;
                goto bad_swap;
        }
-       swap_file = file_open_name(name, O_RDWR|O_LARGEFILE, 0);
+       swap_file = file_open_name(name, O_RDWR | O_LARGEFILE | O_EXCL, 0);
        if (IS_ERR(swap_file)) {
                error = PTR_ERR(swap_file);
                swap_file = NULL;
@@ -3225,10 +3214,6 @@ bad_swap:
        p->percpu_cluster = NULL;
        free_percpu(p->cluster_next_cpu);
        p->cluster_next_cpu = NULL;
-       if (p->bdev_file) {
-               fput(p->bdev_file);
-               p->bdev_file = NULL;
-       }
        inode = NULL;
        destroy_swap_extents(p);
        swap_cgroup_swapoff(p->type);