static ssize_t ncp_file_read(struct file *file, char *buf, size_t count, loff_t *ppos) { struct dentry *dentry = file->f_dentry; struct inode *inode = dentry->d_inode; size_t already_read = 0; off_t pos; size_t bufsize; int error; void* freepage; size_t freelen; DPRINTK("ncp_file_read: enter %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); error = -EIO; if (!ncp_conn_valid(NCP_SERVER(inode))) goto out; error = -EINVAL; if (!S_ISREG(inode->i_mode)) { DPRINTK("ncp_file_read: read from non-file, mode %07o\n", inode->i_mode); goto out; } pos = *ppos; /* leave it out on server ... if (pos + count > inode->i_size) { count = inode->i_size - pos; } */ error = 0; if (!count) /* size_t is never < 0 */ goto out; error = ncp_make_open(inode, O_RDONLY); if (error) { DPRINTK(KERN_ERR "ncp_file_read: open failed, error=%d\n", error); goto out; } bufsize = NCP_SERVER(inode)->buffer_size; error = -EIO; freelen = ncp_read_bounce_size(bufsize); freepage = vmalloc(freelen); if (!freepage) goto outrel; error = 0; /* First read in as much as possible for each bufsize. */ while (already_read < count) { int read_this_time; size_t to_read = min_t(unsigned int, bufsize - (pos % bufsize), count - already_read); error = ncp_read_bounce(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, pos, to_read, buf, &read_this_time, freepage, freelen); if (error) { error = -EIO; /* NW errno -> Linux errno */ break; } pos += read_this_time; buf += read_this_time; already_read += read_this_time; if (read_this_time != to_read) { break; } } vfree(freepage); *ppos = pos; if (!IS_RDONLY(inode)) { inode->i_atime = CURRENT_TIME; } DPRINTK("ncp_file_read: exit %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); outrel: ncp_inode_close(inode); out: return already_read ? already_read : error; }
static ssize_t ncp_file_read_iter(struct kiocb *iocb, struct iov_iter *to) { struct file *file = iocb->ki_filp; struct inode *inode = file_inode(file); size_t already_read = 0; off_t pos = iocb->ki_pos; size_t bufsize; int error; void *freepage; size_t freelen; ncp_dbg(1, "enter %pD2\n", file); if (!iov_iter_count(to)) return 0; if (pos > inode->i_sb->s_maxbytes) return 0; iov_iter_truncate(to, inode->i_sb->s_maxbytes - pos); error = ncp_make_open(inode, O_RDONLY); if (error) { ncp_dbg(1, "open failed, error=%d\n", error); return error; } bufsize = NCP_SERVER(inode)->buffer_size; error = -EIO; freelen = ncp_read_bounce_size(bufsize); freepage = vmalloc(freelen); if (!freepage) goto outrel; error = 0; /* First read in as much as possible for each bufsize. */ while (iov_iter_count(to)) { int read_this_time; size_t to_read = min_t(size_t, bufsize - (pos % bufsize), iov_iter_count(to)); error = ncp_read_bounce(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, pos, to_read, to, &read_this_time, freepage, freelen); if (error) { error = -EIO; /* NW errno -> Linux errno */ break; } pos += read_this_time; already_read += read_this_time; if (read_this_time != to_read) break; } vfree(freepage); iocb->ki_pos = pos; file_accessed(file); ncp_dbg(1, "exit %pD2\n", file); outrel: ncp_inode_close(inode); return already_read ? already_read : error; }
static ssize_t ncp_file_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { struct dentry *dentry = file->f_path.dentry; struct inode *inode = dentry->d_inode; size_t already_read = 0; off_t pos; size_t bufsize; int error; void* freepage; size_t freelen; DPRINTK("ncp_file_read: enter %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); pos = *ppos; if ((ssize_t) count < 0) { return -EINVAL; } if (!count) return 0; if (pos > inode->i_sb->s_maxbytes) return 0; if (pos + count > inode->i_sb->s_maxbytes) { count = inode->i_sb->s_maxbytes - pos; } error = ncp_make_open(inode, O_RDONLY); if (error) { DPRINTK(KERN_ERR "ncp_file_read: open failed, error=%d\n", error); return error; } bufsize = NCP_SERVER(inode)->buffer_size; error = -EIO; freelen = ncp_read_bounce_size(bufsize); freepage = vmalloc(freelen); if (!freepage) goto outrel; error = 0; /* First read in as much as possible for each bufsize. */ while (already_read < count) { int read_this_time; size_t to_read = min_t(unsigned int, bufsize - (pos % bufsize), count - already_read); error = ncp_read_bounce(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle, pos, to_read, buf, &read_this_time, freepage, freelen); if (error) { error = -EIO; /* NW errno -> Linux errno */ break; } pos += read_this_time; buf += read_this_time; already_read += read_this_time; if (read_this_time != to_read) { break; } } vfree(freepage); *ppos = pos; file_accessed(file); DPRINTK("ncp_file_read: exit %s/%s\n", dentry->d_parent->d_name.name, dentry->d_name.name); outrel: ncp_inode_close(inode); return already_read ? already_read : error; }