예제 #1
0
파일: file.c 프로젝트: 513855417/linux
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;
}
예제 #2
0
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);
}
예제 #3
0
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);
}
예제 #4
0
파일: read_write.c 프로젝트: 020gzh/linux
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);
}
예제 #5
0
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);
}
예제 #6
0
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;
}
예제 #7
0
파일: file.c 프로젝트: 513855417/linux
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;
}
예제 #8
0
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;
}
예제 #9
0
파일: read_write.c 프로젝트: Rick33/freevms
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;
}
예제 #10
0
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;
}
예제 #11
0
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);
}