ceph_sync_direct_write: stop poking into iov_iter guts

all needed primitives are there...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
Al Viro 2014-04-03 22:58:25 -04:00
parent 2b777c9dd9
commit 64c3131161

View File

@ -546,7 +546,6 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
int written = 0; int written = 0;
int flags; int flags;
int check_caps = 0; int check_caps = 0;
int page_align;
int ret; int ret;
struct timespec mtime = CURRENT_TIME; struct timespec mtime = CURRENT_TIME;
loff_t pos = iocb->ki_pos; 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); iov_iter_init(&i, WRITE, iov, nr_segs, count);
while (iov_iter_count(&i) > 0) { while (iov_iter_count(&i) > 0) {
void __user *data = i.iov->iov_base + i.iov_offset; u64 len = iov_iter_single_seg_count(&i);
u64 len = i.iov->iov_len - i.iov_offset; size_t start;
ssize_t n;
page_align = (unsigned long)data & ~PAGE_MASK;
snapc = ci->i_snap_realm->cached_context; snapc = ci->i_snap_realm->cached_context;
vino = ceph_vino(inode); vino = ceph_vino(inode);
@ -594,20 +592,21 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
break; break;
} }
num_pages = calc_pages_for(page_align, len); n = iov_iter_get_pages_alloc(&i, &pages, len, &start);
pages = ceph_get_direct_page_vector(data, num_pages, false); if (unlikely(n < 0)) {
if (IS_ERR(pages)) { ret = n;
ret = PTR_ERR(pages); ceph_osdc_put_request(req);
goto out; break;
} }
num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE;
/* /*
* throw out any page cache pages in this range. this * throw out any page cache pages in this range. this
* may block. * may block.
*/ */
truncate_inode_pages_range(inode->i_mapping, pos, truncate_inode_pages_range(inode->i_mapping, pos,
(pos+len) | (PAGE_CACHE_SIZE-1)); (pos+n) | (PAGE_CACHE_SIZE-1));
osd_req_op_extent_osd_data_pages(req, 0, pages, len, page_align, osd_req_op_extent_osd_data_pages(req, 0, pages, n, start,
false, false); false, false);
/* BUG_ON(vino.snap != CEPH_NOSNAP); */ /* BUG_ON(vino.snap != CEPH_NOSNAP); */
@ -619,22 +618,20 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
ceph_put_page_vector(pages, num_pages, false); ceph_put_page_vector(pages, num_pages, false);
out:
ceph_osdc_put_request(req); ceph_osdc_put_request(req);
if (ret == 0) { if (ret)
pos += len;
written += len;
iov_iter_advance(&i, (size_t)len);
if (pos > i_size_read(inode)) {
check_caps = ceph_inode_set_size(inode, pos);
if (check_caps)
ceph_check_caps(ceph_inode(inode),
CHECK_CAPS_AUTHONLY,
NULL);
}
} else
break; break;
pos += n;
written += n;
iov_iter_advance(&i, n);
if (pos > i_size_read(inode)) {
check_caps = ceph_inode_set_size(inode, pos);
if (check_caps)
ceph_check_caps(ceph_inode(inode),
CHECK_CAPS_AUTHONLY,
NULL);
}
} }
if (ret != -EOLDSNAPC && written > 0) { if (ret != -EOLDSNAPC && written > 0) {