static ssize_t read_zero(struct file * file, char * buf, size_t count, loff_t *ppos) { unsigned long left; if (!count) return 0; if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; left = count; #ifndef NO_MM { unsigned long unwritten, written = 0; /* do we want to be clever? Arbitrary cut-off */ if (count >= PAGE_SIZE*4) { unsigned long partial; /* How much left of the page? */ partial = (PAGE_SIZE-1) & -(unsigned long) buf; unwritten = clear_user(buf, partial); written = partial - unwritten; if (unwritten) goto out; left -= partial; buf += partial; unwritten = read_zero_pagealigned(buf, left & PAGE_MASK); written += (left & PAGE_MASK) - unwritten; if (unwritten) goto out; buf += left & PAGE_MASK; left &= ~PAGE_MASK; } unwritten = clear_user(buf, left); written += left - unwritten; out: return written ? written : -EFAULT; } #else for (left = count; left > 0; left--) { put_user(0,buf); buf++; if (current->need_resched) schedule(); } return(count); #endif }
static ssize_t read_zero(struct file * file, char * buf, size_t count, loff_t *ppos) { unsigned long left, unwritten, written = 0; if (!count) return 0; if (!access_ok(VERIFY_WRITE, buf, count)) return -EFAULT; left = count; /* do we want to be clever? Arbitrary cut-off */ if (count >= PAGE_SIZE*4) { unsigned long partial; /* How much left of the page? */ partial = (PAGE_SIZE-1) & -(unsigned long) buf; unwritten = clear_user(buf, partial); written = partial - unwritten; if (unwritten) goto out; left -= partial; buf += partial; unwritten = read_zero_pagealigned(buf, left & PAGE_MASK); written += (left & PAGE_MASK) - unwritten; if (unwritten) goto out; buf += left & PAGE_MASK; left &= ~PAGE_MASK; } unwritten = clear_user(buf, left); written += left - unwritten; out: return written ? written : -EFAULT; }