Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64c31311 authored by Al Viro's avatar Al Viro
Browse files

ceph_sync_direct_write: stop poking into iov_iter guts



all needed primitives are there...

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 2b777c9d
Loading
Loading
Loading
Loading
+23 −26
Original line number Diff line number Diff line
@@ -546,7 +546,6 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
	int written = 0;
	int flags;
	int check_caps = 0;
	int page_align;
	int ret;
	struct timespec mtime = CURRENT_TIME;
	loff_t pos = iocb->ki_pos;
@@ -575,10 +574,9 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
	iov_iter_init(&i, WRITE, iov, nr_segs, count);

	while (iov_iter_count(&i) > 0) {
		void __user *data = i.iov->iov_base + i.iov_offset;
		u64 len = i.iov->iov_len - i.iov_offset;

		page_align = (unsigned long)data & ~PAGE_MASK;
		u64 len = iov_iter_single_seg_count(&i);
		size_t start;
		ssize_t n;

		snapc = ci->i_snap_realm->cached_context;
		vino = ceph_vino(inode);
@@ -594,20 +592,21 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
			break;
		}

		num_pages = calc_pages_for(page_align, len);
		pages = ceph_get_direct_page_vector(data, num_pages, false);
		if (IS_ERR(pages)) {
			ret = PTR_ERR(pages);
			goto out;
		n = iov_iter_get_pages_alloc(&i, &pages, len, &start);
		if (unlikely(n < 0)) {
			ret = n;
			ceph_osdc_put_request(req);
			break;
		}

		num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE;
		/*
		 * throw out any page cache pages in this range. this
		 * may block.
		 */
		truncate_inode_pages_range(inode->i_mapping, pos,
				   (pos+len) | (PAGE_CACHE_SIZE-1));
		osd_req_op_extent_osd_data_pages(req, 0, pages, len, page_align,
				   (pos+n) | (PAGE_CACHE_SIZE-1));
		osd_req_op_extent_osd_data_pages(req, 0, pages, n, start,
						false, false);

		/* BUG_ON(vino.snap != CEPH_NOSNAP); */
@@ -619,12 +618,12 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,

		ceph_put_page_vector(pages, num_pages, false);

out:
		ceph_osdc_put_request(req);
		if (ret == 0) {
			pos += len;
			written += len;
			iov_iter_advance(&i, (size_t)len);
		if (ret)
			break;
		pos += n;
		written += n;
		iov_iter_advance(&i, n);

		if (pos > i_size_read(inode)) {
			check_caps = ceph_inode_set_size(inode, pos);
@@ -633,8 +632,6 @@ out:
						CHECK_CAPS_AUTHONLY,
						NULL);
		}
		} else
			break;
	}

	if (ret != -EOLDSNAPC && written > 0) {