static ssize_t slm_read( struct file *file, char *buf, size_t count, loff_t *ppos ) { struct inode *node = file->f_dentry->d_inode; loff_t pos = *ppos; unsigned long page; int length; int end; if (count < 0) return( -EINVAL ); if (!(page = __get_free_page( GFP_KERNEL ))) return( -ENOMEM ); length = slm_getstats( (char *)page, MINOR(node->i_rdev) ); if (length < 0) { count = length; goto out; } if (pos < 0 || pos >= length) { count = 0; goto out; } if (count > length - pos) count = length - pos; end = count + pos; if (copy_to_user(buf, (char *)page + pos, count)) { count = -EFAULT; goto out; } *ppos = end; out: free_page( page ); return( count ); }
static ssize_t slm_read( struct file *file, char *buf, size_t count, loff_t *ppos ) { struct inode *node = file->f_dentry->d_inode; unsigned long page; int length; int end; if (count < 0) return( -EINVAL ); if (!(page = __get_free_page( GFP_KERNEL ))) return( -ENOMEM ); length = slm_getstats( (char *)page, MINOR(node->i_rdev) ); if (length < 0) { free_page( page ); return( length ); } if (file->f_pos >= length) { free_page( page ); return( 0 ); } if (count + file->f_pos > length) count = length - file->f_pos; end = count + file->f_pos; copy_to_user( buf, (char *)page + file->f_pos, count ); free_page( page ); file->f_pos = end; return( count ); }