diff options
Diffstat (limited to 'fs/timerfd.c')
-rw-r--r-- | fs/timerfd.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/fs/timerfd.c b/fs/timerfd.c index 053818dd6c18..815e5348f048 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -49,7 +49,8 @@ static DEFINE_SPINLOCK(cancel_lock); static inline bool isalarm(struct timerfd_ctx *ctx) { return ctx->clockid == CLOCK_REALTIME_ALARM || - ctx->clockid == CLOCK_BOOTTIME_ALARM; + ctx->clockid == CLOCK_BOOTTIME_ALARM || + ctx->clockid == CLOCK_POWEROFF_ALARM; } /* @@ -133,7 +134,8 @@ static bool timerfd_canceled(struct timerfd_ctx *ctx) static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) { if ((ctx->clockid == CLOCK_REALTIME || - ctx->clockid == CLOCK_REALTIME_ALARM) && + ctx->clockid == CLOCK_REALTIME_ALARM || + ctx->clockid == CLOCK_POWEROFF_ALARM) && (flags & TFD_TIMER_ABSTIME) && (flags & TFD_TIMER_CANCEL_ON_SET)) { if (!ctx->might_cancel) { ctx->might_cancel = true; @@ -164,6 +166,7 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags, enum hrtimer_mode htmode; ktime_t texp; int clockid = ctx->clockid; + enum alarmtimer_type type; htmode = (flags & TFD_TIMER_ABSTIME) ? HRTIMER_MODE_ABS: HRTIMER_MODE_REL; @@ -174,10 +177,8 @@ static int timerfd_setup(struct timerfd_ctx *ctx, int flags, ctx->tintv = timespec_to_ktime(ktmr->it_interval); if (isalarm(ctx)) { - alarm_init(&ctx->t.alarm, - ctx->clockid == CLOCK_REALTIME_ALARM ? - ALARM_REALTIME : ALARM_BOOTTIME, - timerfd_alarmproc); + type = clock2alarm(ctx->clockid); + alarm_init(&ctx->t.alarm, type, timerfd_alarmproc); } else { hrtimer_init(&ctx->t.tmr, clockid, htmode); hrtimer_set_expires(&ctx->t.tmr, texp); @@ -377,6 +378,7 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) { int ufd; struct timerfd_ctx *ctx; + enum alarmtimer_type type; /* Check the TFD_* constants for consistency. */ BUILD_BUG_ON(TFD_CLOEXEC != O_CLOEXEC); @@ -387,7 +389,8 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) clockid != CLOCK_REALTIME && clockid != CLOCK_REALTIME_ALARM && clockid != CLOCK_BOOTTIME && - clockid != CLOCK_BOOTTIME_ALARM)) + clockid != CLOCK_BOOTTIME_ALARM && + clockid != CLOCK_POWEROFF_ALARM)) return -EINVAL; ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); @@ -397,13 +400,12 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) init_waitqueue_head(&ctx->wqh); ctx->clockid = clockid; - if (isalarm(ctx)) - alarm_init(&ctx->t.alarm, - ctx->clockid == CLOCK_REALTIME_ALARM ? - ALARM_REALTIME : ALARM_BOOTTIME, - timerfd_alarmproc); - else + if (isalarm(ctx)) { + type = clock2alarm(ctx->clockid); + alarm_init(&ctx->t.alarm, type, timerfd_alarmproc); + } else { hrtimer_init(&ctx->t.tmr, clockid, HRTIMER_MODE_ABS); + } ctx->moffs = ktime_mono_to_real((ktime_t){ .tv64 = 0 }); @@ -475,6 +477,10 @@ static int do_timerfd_settime(int ufd, int flags, ret = timerfd_setup(ctx, flags, new); spin_unlock_irq(&ctx->wqh.lock); + + if (ctx->clockid == CLOCK_POWEROFF_ALARM) + set_power_on_alarm(); + fdput(f); return ret; } |