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 1327a02ec778..0548c572839c 100644 --- a/fs/timerfd.c +++ b/fs/timerfd.c @@ -50,7 +50,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; } /* @@ -142,7 +143,8 @@ static void timerfd_setup_cancel(struct timerfd_ctx *ctx, int flags) { spin_lock(&ctx->cancel_lock); 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; @@ -174,6 +176,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; @@ -184,10 +187,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); @@ -387,6 +388,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); @@ -397,7 +399,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); @@ -408,13 +411,12 @@ SYSCALL_DEFINE2(timerfd_create, int, clockid, int, flags) spin_lock_init(&ctx->cancel_lock); 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 }); @@ -486,6 +488,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; } |