@@ -2899,10 +2899,6 @@ static int claim_swapfile(struct swap_info_struct *p, struct inode *inode)
2899
2899
p -> bdev = inode -> i_sb -> s_bdev ;
2900
2900
}
2901
2901
2902
- inode_lock (inode );
2903
- if (IS_SWAPFILE (inode ))
2904
- return - EBUSY ;
2905
-
2906
2902
return 0 ;
2907
2903
}
2908
2904
@@ -3157,36 +3153,41 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
3157
3153
mapping = swap_file -> f_mapping ;
3158
3154
inode = mapping -> host ;
3159
3155
3160
- /* will take i_rwsem; */
3161
3156
error = claim_swapfile (p , inode );
3162
3157
if (unlikely (error ))
3163
3158
goto bad_swap ;
3164
3159
3160
+ inode_lock (inode );
3161
+ if (IS_SWAPFILE (inode )) {
3162
+ error = - EBUSY ;
3163
+ goto bad_swap_unlock_inode ;
3164
+ }
3165
+
3165
3166
/*
3166
3167
* Read the swap header.
3167
3168
*/
3168
3169
if (!mapping -> a_ops -> readpage ) {
3169
3170
error = - EINVAL ;
3170
- goto bad_swap ;
3171
+ goto bad_swap_unlock_inode ;
3171
3172
}
3172
3173
page = read_mapping_page (mapping , 0 , swap_file );
3173
3174
if (IS_ERR (page )) {
3174
3175
error = PTR_ERR (page );
3175
- goto bad_swap ;
3176
+ goto bad_swap_unlock_inode ;
3176
3177
}
3177
3178
swap_header = kmap (page );
3178
3179
3179
3180
maxpages = read_swap_header (p , swap_header , inode );
3180
3181
if (unlikely (!maxpages )) {
3181
3182
error = - EINVAL ;
3182
- goto bad_swap ;
3183
+ goto bad_swap_unlock_inode ;
3183
3184
}
3184
3185
3185
3186
/* OK, set up the swap map and apply the bad block list */
3186
3187
swap_map = vzalloc (maxpages );
3187
3188
if (!swap_map ) {
3188
3189
error = - ENOMEM ;
3189
- goto bad_swap ;
3190
+ goto bad_swap_unlock_inode ;
3190
3191
}
3191
3192
3192
3193
if (bdi_cap_stable_pages_required (inode_to_bdi (inode )))
@@ -3211,7 +3212,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
3211
3212
GFP_KERNEL );
3212
3213
if (!cluster_info ) {
3213
3214
error = - ENOMEM ;
3214
- goto bad_swap ;
3215
+ goto bad_swap_unlock_inode ;
3215
3216
}
3216
3217
3217
3218
for (ci = 0 ; ci < nr_cluster ; ci ++ )
@@ -3220,7 +3221,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
3220
3221
p -> percpu_cluster = alloc_percpu (struct percpu_cluster );
3221
3222
if (!p -> percpu_cluster ) {
3222
3223
error = - ENOMEM ;
3223
- goto bad_swap ;
3224
+ goto bad_swap_unlock_inode ;
3224
3225
}
3225
3226
for_each_possible_cpu (cpu ) {
3226
3227
struct percpu_cluster * cluster ;
@@ -3234,13 +3235,13 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
3234
3235
3235
3236
error = swap_cgroup_swapon (p -> type , maxpages );
3236
3237
if (error )
3237
- goto bad_swap ;
3238
+ goto bad_swap_unlock_inode ;
3238
3239
3239
3240
nr_extents = setup_swap_map_and_extents (p , swap_header , swap_map ,
3240
3241
cluster_info , maxpages , & span );
3241
3242
if (unlikely (nr_extents < 0 )) {
3242
3243
error = nr_extents ;
3243
- goto bad_swap ;
3244
+ goto bad_swap_unlock_inode ;
3244
3245
}
3245
3246
/* frontswap enabled? set up bit-per-page map for frontswap */
3246
3247
if (IS_ENABLED (CONFIG_FRONTSWAP ))
@@ -3280,7 +3281,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
3280
3281
3281
3282
error = init_swap_address_space (p -> type , maxpages );
3282
3283
if (error )
3283
- goto bad_swap ;
3284
+ goto bad_swap_unlock_inode ;
3284
3285
3285
3286
/*
3286
3287
* Flush any pending IO and dirty mappings before we start using this
@@ -3290,7 +3291,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
3290
3291
error = inode_drain_writes (inode );
3291
3292
if (error ) {
3292
3293
inode -> i_flags &= ~S_SWAPFILE ;
3293
- goto bad_swap ;
3294
+ goto bad_swap_unlock_inode ;
3294
3295
}
3295
3296
3296
3297
mutex_lock (& swapon_mutex );
@@ -3315,13 +3316,16 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
3315
3316
3316
3317
error = 0 ;
3317
3318
goto out ;
3319
+ bad_swap_unlock_inode :
3320
+ inode_unlock (inode );
3318
3321
bad_swap :
3319
3322
free_percpu (p -> percpu_cluster );
3320
3323
p -> percpu_cluster = NULL ;
3321
3324
if (inode && S_ISBLK (inode -> i_mode ) && p -> bdev ) {
3322
3325
set_blocksize (p -> bdev , p -> old_block_size );
3323
3326
blkdev_put (p -> bdev , FMODE_READ | FMODE_WRITE | FMODE_EXCL );
3324
3327
}
3328
+ inode = NULL ;
3325
3329
destroy_swap_extents (p );
3326
3330
swap_cgroup_swapoff (p -> type );
3327
3331
spin_lock (& swap_lock );
@@ -3333,13 +3337,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags)
3333
3337
kvfree (frontswap_map );
3334
3338
if (inced_nr_rotate_swap )
3335
3339
atomic_dec (& nr_rotate_swap );
3336
- if (swap_file ) {
3337
- if (inode ) {
3338
- inode_unlock (inode );
3339
- inode = NULL ;
3340
- }
3340
+ if (swap_file )
3341
3341
filp_close (swap_file , NULL );
3342
- }
3343
3342
out :
3344
3343
if (page && !IS_ERR (page )) {
3345
3344
kunmap (page );
0 commit comments