@@ -196,6 +196,50 @@ static ssize_t snapshot_write(struct file *filp, const char __user *buf,
196
196
return res ;
197
197
}
198
198
199
+ struct compat_resume_swap_area {
200
+ compat_loff_t offset ;
201
+ u32 dev ;
202
+ } __packed ;
203
+
204
+ static int snapshot_set_swap_area (struct snapshot_data * data ,
205
+ void __user * argp )
206
+ {
207
+ sector_t offset ;
208
+ dev_t swdev ;
209
+
210
+ if (swsusp_swap_in_use ())
211
+ return - EPERM ;
212
+
213
+ if (in_compat_syscall ()) {
214
+ struct compat_resume_swap_area swap_area ;
215
+
216
+ if (copy_from_user (& swap_area , argp , sizeof (swap_area )))
217
+ return - EFAULT ;
218
+ swdev = new_decode_dev (swap_area .dev );
219
+ offset = swap_area .offset ;
220
+ } else {
221
+ struct resume_swap_area swap_area ;
222
+
223
+ if (copy_from_user (& swap_area , argp , sizeof (swap_area )))
224
+ return - EFAULT ;
225
+ swdev = new_decode_dev (swap_area .dev );
226
+ offset = swap_area .offset ;
227
+ }
228
+
229
+ /*
230
+ * User space encodes device types as two-byte values,
231
+ * so we need to recode them
232
+ */
233
+ if (!swdev ) {
234
+ data -> swap = -1 ;
235
+ return - EINVAL ;
236
+ }
237
+ data -> swap = swap_type_of (swdev , offset , NULL );
238
+ if (data -> swap < 0 )
239
+ return - ENODEV ;
240
+ return 0 ;
241
+ }
242
+
199
243
static long snapshot_ioctl (struct file * filp , unsigned int cmd ,
200
244
unsigned long arg )
201
245
{
@@ -351,34 +395,7 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
351
395
break ;
352
396
353
397
case SNAPSHOT_SET_SWAP_AREA :
354
- if (swsusp_swap_in_use ()) {
355
- error = - EPERM ;
356
- } else {
357
- struct resume_swap_area swap_area ;
358
- dev_t swdev ;
359
-
360
- error = copy_from_user (& swap_area , (void __user * )arg ,
361
- sizeof (struct resume_swap_area ));
362
- if (error ) {
363
- error = - EFAULT ;
364
- break ;
365
- }
366
-
367
- /*
368
- * User space encodes device types as two-byte values,
369
- * so we need to recode them
370
- */
371
- swdev = new_decode_dev (swap_area .dev );
372
- if (swdev ) {
373
- offset = swap_area .offset ;
374
- data -> swap = swap_type_of (swdev , offset , NULL );
375
- if (data -> swap < 0 )
376
- error = - ENODEV ;
377
- } else {
378
- data -> swap = -1 ;
379
- error = - EINVAL ;
380
- }
381
- }
398
+ error = snapshot_set_swap_area (data , (void __user * )arg );
382
399
break ;
383
400
384
401
default :
@@ -393,12 +410,6 @@ static long snapshot_ioctl(struct file *filp, unsigned int cmd,
393
410
}
394
411
395
412
#ifdef CONFIG_COMPAT
396
-
397
- struct compat_resume_swap_area {
398
- compat_loff_t offset ;
399
- u32 dev ;
400
- } __packed ;
401
-
402
413
static long
403
414
snapshot_compat_ioctl (struct file * file , unsigned int cmd , unsigned long arg )
404
415
{
@@ -409,33 +420,13 @@ snapshot_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
409
420
case SNAPSHOT_AVAIL_SWAP_SIZE :
410
421
case SNAPSHOT_ALLOC_SWAP_PAGE :
411
422
case SNAPSHOT_CREATE_IMAGE :
423
+ case SNAPSHOT_SET_SWAP_AREA :
412
424
return snapshot_ioctl (file , cmd ,
413
425
(unsigned long ) compat_ptr (arg ));
414
-
415
- case SNAPSHOT_SET_SWAP_AREA : {
416
- struct compat_resume_swap_area __user * u_swap_area =
417
- compat_ptr (arg );
418
- struct resume_swap_area swap_area ;
419
- mm_segment_t old_fs ;
420
- int err ;
421
-
422
- err = get_user (swap_area .offset , & u_swap_area -> offset );
423
- err |= get_user (swap_area .dev , & u_swap_area -> dev );
424
- if (err )
425
- return - EFAULT ;
426
- old_fs = get_fs ();
427
- set_fs (KERNEL_DS );
428
- err = snapshot_ioctl (file , SNAPSHOT_SET_SWAP_AREA ,
429
- (unsigned long ) & swap_area );
430
- set_fs (old_fs );
431
- return err ;
432
- }
433
-
434
426
default :
435
427
return snapshot_ioctl (file , cmd , arg );
436
428
}
437
429
}
438
-
439
430
#endif /* CONFIG_COMPAT */
440
431
441
432
static const struct file_operations snapshot_fops = {
0 commit comments