summaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/random.c57
1 files changed, 18 insertions, 39 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index fcda7d3937e0..fcc2bff8f887 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -1285,53 +1285,32 @@ void rand_initialize_disk(struct gendisk *disk)
static ssize_t
random_read(struct file *file, char __user *buf, size_t nbytes, loff_t *ppos)
{
- ssize_t n, retval = 0, count = 0;
+ ssize_t n;
if (nbytes == 0)
return 0;
- while (nbytes > 0) {
- n = nbytes;
- if (n > SEC_XFER_SIZE)
- n = SEC_XFER_SIZE;
-
- n = extract_entropy_user(&blocking_pool, buf, n);
-
- if (n < 0) {
- retval = n;
- break;
- }
-
+ nbytes = min_t(size_t, nbytes, SEC_XFER_SIZE);
+ while (1) {
+ n = extract_entropy_user(&blocking_pool, buf, nbytes);
+ if (n < 0)
+ return n;
trace_random_read(n*8, (nbytes-n)*8,
ENTROPY_BITS(&blocking_pool),
ENTROPY_BITS(&input_pool));
-
- if (n == 0) {
- if (file->f_flags & O_NONBLOCK) {
- retval = -EAGAIN;
- break;
- }
-
- wait_event_interruptible(random_read_wait,
- ENTROPY_BITS(&input_pool) >=
- random_read_wakeup_thresh);
-
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
-
- continue;
- }
-
- count += n;
- buf += n;
- nbytes -= n;
- break; /* This break makes the device work */
- /* like a named pipe */
+ if (n > 0)
+ return n;
+ /* Pool is (near) empty. Maybe wait and retry. */
+
+ if (file->f_flags & O_NONBLOCK)
+ return -EAGAIN;
+
+ wait_event_interruptible(random_read_wait,
+ ENTROPY_BITS(&input_pool) >=
+ random_read_wakeup_thresh);
+ if (signal_pending(current))
+ return -ERESTARTSYS;
}
-
- return (count ? count : retval);
}
static ssize_t