From: William Lee Irwin III start_jiffies was not respected by set_timeout(), which reread jiffies instead of respecting what read_events() passed it. This difference can be significant, particularly if the calling process slept during the copy_to_user() operation in read_events(). To correct this, this patch teaches it to respect its argument, with the additional bonus of converting it to use timespec_to_jiffies() instead of open-coding it. Signed-off-by: Andrew Morton --- 25-akpm/fs/aio.c | 16 ++++------------ 1 files changed, 4 insertions(+), 12 deletions(-) diff -puN fs/aio.c~fix-io_getevents-timer-expiry-setting fs/aio.c --- 25/fs/aio.c~fix-io_getevents-timer-expiry-setting 2004-06-01 21:49:06.218935032 -0700 +++ 25-akpm/fs/aio.c 2004-06-01 21:49:06.222934424 -0700 @@ -777,19 +777,11 @@ static inline void init_timeout(struct t static inline void set_timeout(long start_jiffies, struct timeout *to, const struct timespec *ts) { - unsigned long how_long; - - if (ts->tv_sec < 0 || (!ts->tv_sec && !ts->tv_nsec)) { + to->timer.expires = start_jiffies + timespec_to_jiffies(ts); + if (time_after(to->timer.expires, jiffies)) + add_timer(&to->timer); + else to->timed_out = 1; - return; - } - - how_long = ts->tv_sec * HZ; -#define HZ_NS (1000000000 / HZ) - how_long += (ts->tv_nsec + HZ_NS - 1) / HZ_NS; - - to->timer.expires = jiffies + how_long; - add_timer(&to->timer); } static inline void clear_timeout(struct timeout *to) _