static ssize_t orangefs_file_write_iter(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; loff_t pos; ssize_t rc; BUG_ON(iocb->private); gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_write_iter\n"); inode_lock(file->f_mapping->host); /* Make sure generic_write_checks sees an up to date inode size. */ if (file->f_flags & O_APPEND) { rc = orangefs_inode_getattr(file->f_mapping->host, 0, 1); if (rc == -ESTALE) rc = -EIO; if (rc) { gossip_err("%s: orangefs_inode_getattr failed, " "rc:%zd:.\n", __func__, rc); goto out; } } if (file->f_pos > i_size_read(file->f_mapping->host)) orangefs_i_size_write(file->f_mapping->host, file->f_pos); rc = generic_write_checks(iocb, iter); if (rc <= 0) { gossip_err("%s: generic_write_checks failed, rc:%zd:.\n", __func__, rc); goto out; } /* * if we are appending, generic_write_checks would have updated * pos to the end of the file, so we will wait till now to set * pos... */ pos = *(&iocb->ki_pos); rc = do_readv_writev(ORANGEFS_IO_WRITE, file, &pos, iter); if (rc < 0) { gossip_err("%s: do_readv_writev failed, rc:%zd:.\n", __func__, rc); goto out; } iocb->ki_pos = pos; g_orangefs_stats.writes++; out: inode_unlock(file->f_mapping->host); return rc; }
ssize_t vfs_writev(struct file *file, const struct iovec __user *vec, unsigned long vlen, loff_t *pos) { if (!(file->f_mode & FMODE_WRITE)) return -EBADF; if (!file->f_op || (!file->f_op->writev && !file->f_op->write)) return -EINVAL; return do_readv_writev(WRITE, file, vec, vlen, pos); }
ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, unsigned long vlen, loff_t *pos) { if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!file->f_op || (!file->f_op->aio_read && !file->f_op->read)) return -EINVAL; return do_readv_writev(READ, file, vec, vlen, pos); }
ssize_t vfs_readv(struct file *file, const struct iovec __user *vec, unsigned long vlen, loff_t *pos, int flags) { if (!(file->f_mode & FMODE_READ)) return -EBADF; if (!(file->f_mode & FMODE_CAN_READ)) return -EINVAL; return do_readv_writev(READ, file, vec, vlen, pos, flags); }
asmlinkage int sys_readv(unsigned long fd, const struct iovec * vector, long count) { struct file * file; struct inode * inode; if (fd >= NR_OPEN || !(file = current->files->fd[fd]) || !(inode = file->f_inode)) return -EBADF; if (!(file->f_mode & 1)) return -EBADF; return do_readv_writev(VERIFY_WRITE, inode, file, vector, count); }
asmlinkage int sys_writev(unsigned long fd, const struct iovec * vector, long count) { int error; struct file * file; struct inode * inode; if (fd >= NR_OPEN || !(file = current->files->fd[fd]) || !(inode = file->f_inode)) return -EBADF; if (!(file->f_mode & 2)) return -EBADF; down(&inode->i_sem); error = do_readv_writev(VERIFY_READ, inode, file, vector, count); up(&inode->i_sem); return error; }
static ssize_t orangefs_file_read_iter(struct kiocb *iocb, struct iov_iter *iter) { struct file *file = iocb->ki_filp; loff_t pos = *(&iocb->ki_pos); ssize_t rc = 0; BUG_ON(iocb->private); gossip_debug(GOSSIP_FILE_DEBUG, "orangefs_file_read_iter\n"); g_orangefs_stats.reads++; rc = do_readv_writev(ORANGEFS_IO_READ, file, &pos, iter); iocb->ki_pos = pos; return rc; }
asmlinkage ssize_t sys_writev(unsigned long fd, const struct iovec * vector, unsigned long count) { struct file * file; ssize_t ret; ret = -EBADF; file = fget(fd); if (!file) goto bad_file; if (file->f_op && (file->f_mode & FMODE_WRITE) && (file->f_op->writev || file->f_op->write)) ret = do_readv_writev(VERIFY_READ, file, vector, count); fput(file); bad_file: return ret; }
asmlinkage ssize_t sys_readv(unsigned long fd, const struct iovec * vector, unsigned long count) { struct file * file; struct vms_fd * vms_fd; ssize_t ret; ret = -EBADF; vms_fd = fget(fd); file = vms_fd->vfd$l_fd_p; if (!file) goto bad_file; if (file->f_op && (file->f_mode & FMODE_READ) && (file->f_op->readv || file->f_op->read)) ret = do_readv_writev(VERIFY_WRITE, file, vector, count); fput(file); bad_file: return ret; }
static ssize_t scribe_do_readv_writev(int type, struct file *file, const struct iovec __user * uvector, unsigned long nr_segs, loff_t *pos) { struct scribe_ps *scribe = current->scribe; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; int force_block = 0; ssize_t ret, len = 0; if (!is_scribed(scribe)) return do_readv_writev(type, file, uvector, nr_segs, 0, pos, force_block); if (is_kernel_copy()) goto out; if (!should_scribe_data(scribe)) goto out; scribe_need_syscall_ret(scribe); if (is_replaying(scribe)) { len = scribe->orig_ret; if (len <= 0) { rw_copy_check_uvector(type, uvector, nr_segs, ARRAY_SIZE(iovstack), iovstack, &iov); ret = len; goto free; } force_block = 1; } if (type == READ) { if (is_deterministic(file)) goto out; scribe_data_non_det(); if (is_recording(scribe)) goto out; rw_copy_check_uvector(type, uvector, nr_segs, ARRAY_SIZE(iovstack), iovstack, &iov); ret = __do_loop_readv_writev(file, iov, nr_segs, len, pos, io_scribe_emul_copy_to_user); goto free; } out: scribe->in_read_write = true; ret = do_readv_writev(type, file, uvector, nr_segs, len, pos, force_block); scribe->in_read_write = false; free: if (iov != iovstack) kfree(iov); return ret; }
static ssize_t scribe_do_readv_writev(int type, struct file *file, const struct iovec __user * uvector, unsigned long nr_segs, loff_t *pos) { return do_readv_writev(type, file, uvector, nr_segs, 0, pos, 0); }