diff options
author | Vitaly Mayatskikh <v.mayatskih@gmail.com> | 2008-09-28 19:24:33 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2008-10-06 23:26:21 -0400 |
commit | 76c31f239ea221a6c84bd26141262a43bfe8b7f4 (patch) | |
tree | e93025a86c4c935d14a996b17aae572b9ded49dd /arch | |
parent | 3396c72b92efd16bca16490a72277b3a494e0f0e (diff) |
powerpc: Honor O_NONBLOCK flag when reading RTAS log
rtas_log_read() doesn't check file flags for O_NONBLOCK and blocks
non-blocking readers of /proc/ppc64/rtas/error_log when there is
no data available. This fixes it.
Also rtas_log_read() returns now with ENODATA to prevent suspending of
process in wait_event_interruptible() when logging facility was
switched off and log is already empty.
Signed-off-by: Vitaly Mayatskikh <v.mayatskih@gmail.com>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/pseries/rtasd.c | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index c9ffd8c225f1..f4e55be2eea9 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c | |||
@@ -295,19 +295,29 @@ static ssize_t rtas_log_read(struct file * file, char __user * buf, | |||
295 | if (!tmp) | 295 | if (!tmp) |
296 | return -ENOMEM; | 296 | return -ENOMEM; |
297 | 297 | ||
298 | |||
299 | spin_lock_irqsave(&rtasd_log_lock, s); | 298 | spin_lock_irqsave(&rtasd_log_lock, s); |
300 | /* if it's 0, then we know we got the last one (the one in NVRAM) */ | 299 | /* if it's 0, then we know we got the last one (the one in NVRAM) */ |
301 | if (rtas_log_size == 0 && logging_enabled) | 300 | while (rtas_log_size == 0) { |
302 | nvram_clear_error_log(); | 301 | if (file->f_flags & O_NONBLOCK) { |
303 | spin_unlock_irqrestore(&rtasd_log_lock, s); | 302 | spin_unlock_irqrestore(&rtasd_log_lock, s); |
303 | error = -EAGAIN; | ||
304 | goto out; | ||
305 | } | ||
304 | 306 | ||
307 | if (!logging_enabled) { | ||
308 | spin_unlock_irqrestore(&rtasd_log_lock, s); | ||
309 | error = -ENODATA; | ||
310 | goto out; | ||
311 | } | ||
312 | nvram_clear_error_log(); | ||
305 | 313 | ||
306 | error = wait_event_interruptible(rtas_log_wait, rtas_log_size); | 314 | spin_unlock_irqrestore(&rtasd_log_lock, s); |
307 | if (error) | 315 | error = wait_event_interruptible(rtas_log_wait, rtas_log_size); |
308 | goto out; | 316 | if (error) |
317 | goto out; | ||
318 | spin_lock_irqsave(&rtasd_log_lock, s); | ||
319 | } | ||
309 | 320 | ||
310 | spin_lock_irqsave(&rtasd_log_lock, s); | ||
311 | offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); | 321 | offset = rtas_error_log_buffer_max * (rtas_log_start & LOG_NUMBER_MASK); |
312 | memcpy(tmp, &rtas_log_buf[offset], count); | 322 | memcpy(tmp, &rtas_log_buf[offset], count); |
313 | 323 | ||