Skip to content

Commit 64c3131

Browse files
author
Al Viro
committed
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>
1 parent 2b777c9 commit 64c3131

File tree

1 file changed

+23
-26
lines changed

1 file changed

+23
-26
lines changed

fs/ceph/file.c

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -546,7 +546,6 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
546546
int written = 0;
547547
int flags;
548548
int check_caps = 0;
549-
int page_align;
550549
int ret;
551550
struct timespec mtime = CURRENT_TIME;
552551
loff_t pos = iocb->ki_pos;
@@ -575,10 +574,9 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
575574
iov_iter_init(&i, WRITE, iov, nr_segs, count);
576575

577576
while (iov_iter_count(&i) > 0) {
578-
void __user *data = i.iov->iov_base + i.iov_offset;
579-
u64 len = i.iov->iov_len - i.iov_offset;
580-
581-
page_align = (unsigned long)data & ~PAGE_MASK;
577+
u64 len = iov_iter_single_seg_count(&i);
578+
size_t start;
579+
ssize_t n;
582580

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

597-
num_pages = calc_pages_for(page_align, len);
598-
pages = ceph_get_direct_page_vector(data, num_pages, false);
599-
if (IS_ERR(pages)) {
600-
ret = PTR_ERR(pages);
601-
goto out;
595+
n = iov_iter_get_pages_alloc(&i, &pages, len, &start);
596+
if (unlikely(n < 0)) {
597+
ret = n;
598+
ceph_osdc_put_request(req);
599+
break;
602600
}
603601

602+
num_pages = (n + start + PAGE_SIZE - 1) / PAGE_SIZE;
604603
/*
605604
* throw out any page cache pages in this range. this
606605
* may block.
607606
*/
608607
truncate_inode_pages_range(inode->i_mapping, pos,
609-
(pos+len) | (PAGE_CACHE_SIZE-1));
610-
osd_req_op_extent_osd_data_pages(req, 0, pages, len, page_align,
608+
(pos+n) | (PAGE_CACHE_SIZE-1));
609+
osd_req_op_extent_osd_data_pages(req, 0, pages, n, start,
611610
false, false);
612611

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

620619
ceph_put_page_vector(pages, num_pages, false);
621620

622-
out:
623621
ceph_osdc_put_request(req);
624-
if (ret == 0) {
625-
pos += len;
626-
written += len;
627-
iov_iter_advance(&i, (size_t)len);
628-
629-
if (pos > i_size_read(inode)) {
630-
check_caps = ceph_inode_set_size(inode, pos);
631-
if (check_caps)
632-
ceph_check_caps(ceph_inode(inode),
633-
CHECK_CAPS_AUTHONLY,
634-
NULL);
635-
}
636-
} else
622+
if (ret)
637623
break;
624+
pos += n;
625+
written += n;
626+
iov_iter_advance(&i, n);
627+
628+
if (pos > i_size_read(inode)) {
629+
check_caps = ceph_inode_set_size(inode, pos);
630+
if (check_caps)
631+
ceph_check_caps(ceph_inode(inode),
632+
CHECK_CAPS_AUTHONLY,
633+
NULL);
634+
}
638635
}
639636

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

0 commit comments

Comments
 (0)