diff options
Diffstat (limited to 'fs/compat.c')
-rw-r--r-- | fs/compat.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/fs/compat.c b/fs/compat.c index f86df85dff61..ca926ad0430c 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -399,12 +399,28 @@ static int put_compat_flock64(struct flock *kfl, struct compat_flock64 __user *u | |||
399 | } | 399 | } |
400 | #endif | 400 | #endif |
401 | 401 | ||
402 | static unsigned int | ||
403 | convert_fcntl_cmd(unsigned int cmd) | ||
404 | { | ||
405 | switch (cmd) { | ||
406 | case F_GETLK64: | ||
407 | return F_GETLK; | ||
408 | case F_SETLK64: | ||
409 | return F_SETLK; | ||
410 | case F_SETLKW64: | ||
411 | return F_SETLKW; | ||
412 | } | ||
413 | |||
414 | return cmd; | ||
415 | } | ||
416 | |||
402 | COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, | 417 | COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, |
403 | compat_ulong_t, arg) | 418 | compat_ulong_t, arg) |
404 | { | 419 | { |
405 | mm_segment_t old_fs; | 420 | mm_segment_t old_fs; |
406 | struct flock f; | 421 | struct flock f; |
407 | long ret; | 422 | long ret; |
423 | unsigned int conv_cmd; | ||
408 | 424 | ||
409 | switch (cmd) { | 425 | switch (cmd) { |
410 | case F_GETLK: | 426 | case F_GETLK: |
@@ -441,16 +457,18 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, | |||
441 | case F_GETLK64: | 457 | case F_GETLK64: |
442 | case F_SETLK64: | 458 | case F_SETLK64: |
443 | case F_SETLKW64: | 459 | case F_SETLKW64: |
460 | case F_GETLKP: | ||
461 | case F_SETLKP: | ||
462 | case F_SETLKPW: | ||
444 | ret = get_compat_flock64(&f, compat_ptr(arg)); | 463 | ret = get_compat_flock64(&f, compat_ptr(arg)); |
445 | if (ret != 0) | 464 | if (ret != 0) |
446 | break; | 465 | break; |
447 | old_fs = get_fs(); | 466 | old_fs = get_fs(); |
448 | set_fs(KERNEL_DS); | 467 | set_fs(KERNEL_DS); |
449 | ret = sys_fcntl(fd, (cmd == F_GETLK64) ? F_GETLK : | 468 | conv_cmd = convert_fcntl_cmd(cmd); |
450 | ((cmd == F_SETLK64) ? F_SETLK : F_SETLKW), | 469 | ret = sys_fcntl(fd, conv_cmd, (unsigned long)&f); |
451 | (unsigned long)&f); | ||
452 | set_fs(old_fs); | 470 | set_fs(old_fs); |
453 | if (cmd == F_GETLK64 && ret == 0) { | 471 | if ((conv_cmd == F_GETLK || conv_cmd == F_GETLKP) && ret == 0) { |
454 | /* need to return lock information - see above for commentary */ | 472 | /* need to return lock information - see above for commentary */ |
455 | if (f.l_start > COMPAT_LOFF_T_MAX) | 473 | if (f.l_start > COMPAT_LOFF_T_MAX) |
456 | ret = -EOVERFLOW; | 474 | ret = -EOVERFLOW; |
@@ -471,8 +489,15 @@ COMPAT_SYSCALL_DEFINE3(fcntl64, unsigned int, fd, unsigned int, cmd, | |||
471 | COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, | 489 | COMPAT_SYSCALL_DEFINE3(fcntl, unsigned int, fd, unsigned int, cmd, |
472 | compat_ulong_t, arg) | 490 | compat_ulong_t, arg) |
473 | { | 491 | { |
474 | if ((cmd == F_GETLK64) || (cmd == F_SETLK64) || (cmd == F_SETLKW64)) | 492 | switch (cmd) { |
493 | case F_GETLK64: | ||
494 | case F_SETLK64: | ||
495 | case F_SETLKW64: | ||
496 | case F_GETLKP: | ||
497 | case F_SETLKP: | ||
498 | case F_SETLKPW: | ||
475 | return -EINVAL; | 499 | return -EINVAL; |
500 | } | ||
476 | return compat_sys_fcntl64(fd, cmd, arg); | 501 | return compat_sys_fcntl64(fd, cmd, arg); |
477 | } | 502 | } |
478 | 503 | ||