diff options
| author | Deepa Dinamani <deepa.kernel@gmail.com> | 2017-06-24 14:45:07 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2017-06-30 04:14:38 -0400 |
| commit | bff412036f457d8160eebada43199b8d987152d8 (patch) | |
| tree | 0df0e87f95c9682a82a1b67c53d9af30e92895a0 | |
| parent | c0edd7c9acd0eaee149ab6cb4441cc71a1af87f0 (diff) | |
timerfd: Use get_itimerspec64() and put_itimerspec64()
Usage of these apis and their compat versions makes
the syscalls: timerfd_settime and timerfd_gettime and
their compat implementations simpler.
This patch also serves as a preparatory patch for changing
syscalls to use new time_t data types to support the
y2038 effort by isolating the processing of user pointers
through these apis.
Signed-off-by: Deepa Dinamani <deepa.kernel@gmail.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/timerfd.c | 43 |
1 files changed, 21 insertions, 22 deletions
diff --git a/fs/timerfd.c b/fs/timerfd.c index c543cdb5f8ed..ece0c02d7e63 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c | |||
| @@ -169,7 +169,7 @@ static ktime_t timerfd_get_remaining(struct timerfd_ctx *ctx) | |||
| 169 | } | 169 | } |
| 170 | 170 | ||
| 171 | static int timerfd_setup(struct timerfd_ctx *ctx, int flags, | 171 | static int timerfd_setup(struct timerfd_ctx *ctx, int flags, |
| 172 | const struct itimerspec *ktmr) | 172 | const struct itimerspec64 *ktmr) |
| 173 | { | 173 | { |
| 174 | enum hrtimer_mode htmode; | 174 | enum hrtimer_mode htmode; |
| 175 | ktime_t texp; | 175 | ktime_t texp; |
| @@ -178,10 +178,10 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags, | |||
| 178 | htmode = (flags & TFD_TIMER_ABSTIME) ? | 178 | htmode = (flags & TFD_TIMER_ABSTIME) ? |
| 179 | HRTIMER_MODE_ABS: HRTIMER_MODE_REL; | 179 | HRTIMER_MODE_ABS: HRTIMER_MODE_REL; |
| 180 | 180 | ||
| 181 | texp = timespec_to_ktime(ktmr->it_value); | 181 | texp = timespec64_to_ktime(ktmr->it_value); |
| 182 | ctx->expired = 0; | 182 | ctx->expired = 0; |
| 183 | ctx->ticks = 0; | 183 | ctx->ticks = 0; |
| 184 | ctx->tintv = timespec_to_ktime(ktmr->it_interval); | 184 | ctx->tintv = timespec64_to_ktime(ktmr->it_interval); |
| 185 | 185 | ||
| 186 | if (isalarm(ctx)) { | 186 | if (isalarm(ctx)) { |
| 187 | alarm_init(&ctx->t.alarm, | 187 | alarm_init(&ctx->t.alarm, |
| @@ -432,16 +432,15 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) | |||
| 432 | } | 432 | } |
| 433 | 433 | ||
| 434 | static int do_timerfd_settime(int ufd, int flags, | 434 | static int do_timerfd_settime(int ufd, int flags, |
| 435 | const struct itimerspec *new, | 435 | const struct itimerspec64 *new, |
| 436 | struct itimerspec *old) | 436 | struct itimerspec64 *old) |
| 437 | { | 437 | { |
| 438 | struct fd f; | 438 | struct fd f; |
| 439 | struct timerfd_ctx *ctx; | 439 | struct timerfd_ctx *ctx; |
| 440 | int ret; | 440 | int ret; |
| 441 | 441 | ||
| 442 | if ((flags & ~TFD_SETTIME_FLAGS) || | 442 | if ((flags & ~TFD_SETTIME_FLAGS) || |
| 443 | !timespec_valid(&new->it_value) || | 443 | !itimerspec64_valid(new)) |
| 444 | !timespec_valid(&new->it_interval)) | ||
| 445 | return -EINVAL; | 444 | return -EINVAL; |
| 446 | 445 | ||
| 447 | ret = timerfd_fget(ufd, &f); | 446 | ret = timerfd_fget(ufd, &f); |
| @@ -487,8 +486,8 @@ static int do_timerfd_settime(int ufd, int flags, | |||
| 487 | hrtimer_forward_now(&ctx->t.tmr, ctx->tintv); | 486 | hrtimer_forward_now(&ctx->t.tmr, ctx->tintv); |
| 488 | } | 487 | } |
| 489 | 488 | ||
| 490 | old->it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | 489 | old->it_value = ktime_to_timespec64(timerfd_get_remaining(ctx)); |
| 491 | old->it_interval = ktime_to_timespec(ctx->tintv); | 490 | old->it_interval = ktime_to_timespec64(ctx->tintv); |
| 492 | 491 | ||
| 493 | /* | 492 | /* |
| 494 | * Re-program the timer to the new value ... | 493 | * Re-program the timer to the new value ... |
| @@ -500,7 +499,7 @@ static int do_timerfd_settime(int ufd, int flags, | |||
| 500 | return ret; | 499 | return ret; |
| 501 | } | 500 | } |
| 502 | 501 | ||
| 503 | static int do_timerfd_gettime(int ufd, struct itimerspec *t) | 502 | static int do_timerfd_gettime(int ufd, struct itimerspec64 *t) |
| 504 | { | 503 | { |
| 505 | struct fd f; | 504 | struct fd f; |
| 506 | struct timerfd_ctx *ctx; | 505 | struct timerfd_ctx *ctx; |
| @@ -525,8 +524,8 @@ static int do_timerfd_gettime(int ufd, struct itimerspec *t) | |||
| 525 | hrtimer_restart(&ctx->t.tmr); | 524 | hrtimer_restart(&ctx->t.tmr); |
| 526 | } | 525 | } |
| 527 | } | 526 | } |
| 528 | t->it_value = ktime_to_timespec(timerfd_get_remaining(ctx)); | 527 | t->it_value = ktime_to_timespec64(timerfd_get_remaining(ctx)); |
| 529 | t->it_interval = ktime_to_timespec(ctx->tintv); | 528 | t->it_interval = ktime_to_timespec64(ctx->tintv); |
| 530 | spin_unlock_irq(&ctx->wqh.lock); | 529 | spin_unlock_irq(&ctx->wqh.lock); |
| 531 | fdput(f); | 530 | fdput(f); |
| 532 | return 0; | 531 | return 0; |
| @@ -536,15 +535,15 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 536 | const struct itimerspec __user *, utmr, | 535 | const struct itimerspec __user *, utmr, |
| 537 | struct itimerspec __user *, otmr) | 536 | struct itimerspec __user *, otmr) |
| 538 | { | 537 | { |
| 539 | struct itimerspec new, old; | 538 | struct itimerspec64 new, old; |
| 540 | int ret; | 539 | int ret; |
| 541 | 540 | ||
| 542 | if (copy_from_user(&new, utmr, sizeof(new))) | 541 | if (get_itimerspec64(&new, utmr)) |
| 543 | return -EFAULT; | 542 | return -EFAULT; |
| 544 | ret = do_timerfd_settime(ufd, flags, &new, &old); | 543 | ret = do_timerfd_settime(ufd, flags, &new, &old); |
| 545 | if (ret) | 544 | if (ret) |
| 546 | return ret; | 545 | return ret; |
| 547 | if (otmr && copy_to_user(otmr, &old, sizeof(old))) | 546 | if (otmr && put_itimerspec64(&old, otmr)) |
| 548 | return -EFAULT; | 547 | return -EFAULT; |
| 549 | 548 | ||
| 550 | return ret; | 549 | return ret; |
| @@ -552,11 +551,11 @@ SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 552 | 551 | ||
| 553 | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) | 552 | SYSCALL_DEFINE2(timerfd_gettime, int, ufd, struct itimerspec __user *, otmr) |
| 554 | { | 553 | { |
| 555 | struct itimerspec kotmr; | 554 | struct itimerspec64 kotmr; |
| 556 | int ret = do_timerfd_gettime(ufd, &kotmr); | 555 | int ret = do_timerfd_gettime(ufd, &kotmr); |
| 557 | if (ret) | 556 | if (ret) |
| 558 | return ret; | 557 | return ret; |
| 559 | return copy_to_user(otmr, &kotmr, sizeof(kotmr)) ? -EFAULT: 0; | 558 | return put_itimerspec64(&kotmr, otmr) ? -EFAULT : 0; |
| 560 | } | 559 | } |
| 561 | 560 | ||
| 562 | #ifdef CONFIG_COMPAT | 561 | #ifdef CONFIG_COMPAT |
| @@ -564,15 +563,15 @@ COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 564 | const struct compat_itimerspec __user *, utmr, | 563 | const struct compat_itimerspec __user *, utmr, |
| 565 | struct compat_itimerspec __user *, otmr) | 564 | struct compat_itimerspec __user *, otmr) |
| 566 | { | 565 | { |
| 567 | struct itimerspec new, old; | 566 | struct itimerspec64 new, old; |
| 568 | int ret; | 567 | int ret; |
| 569 | 568 | ||
| 570 | if (get_compat_itimerspec(&new, utmr)) | 569 | if (get_compat_itimerspec64(&new, utmr)) |
| 571 | return -EFAULT; | 570 | return -EFAULT; |
| 572 | ret = do_timerfd_settime(ufd, flags, &new, &old); | 571 | ret = do_timerfd_settime(ufd, flags, &new, &old); |
| 573 | if (ret) | 572 | if (ret) |
| 574 | return ret; | 573 | return ret; |
| 575 | if (otmr && put_compat_itimerspec(otmr, &old)) | 574 | if (otmr && put_compat_itimerspec64(&old, otmr)) |
| 576 | return -EFAULT; | 575 | return -EFAULT; |
| 577 | return ret; | 576 | return ret; |
| 578 | } | 577 | } |
| @@ -580,10 +579,10 @@ COMPAT_SYSCALL_DEFINE4(timerfd_settime, int, ufd, int, flags, | |||
| 580 | COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd, | 579 | COMPAT_SYSCALL_DEFINE2(timerfd_gettime, int, ufd, |
| 581 | struct compat_itimerspec __user *, otmr) | 580 | struct compat_itimerspec __user *, otmr) |
| 582 | { | 581 | { |
| 583 | struct itimerspec kotmr; | 582 | struct itimerspec64 kotmr; |
| 584 | int ret = do_timerfd_gettime(ufd, &kotmr); | 583 | int ret = do_timerfd_gettime(ufd, &kotmr); |
| 585 | if (ret) | 584 | if (ret) |
| 586 | return ret; | 585 | return ret; |
| 587 | return put_compat_itimerspec(otmr, &kotmr) ? -EFAULT: 0; | 586 | return put_compat_itimerspec64(&kotmr, otmr) ? -EFAULT : 0; |
| 588 | } | 587 | } |
| 589 | #endif | 588 | #endif |
