Commit 4908b822 authored by Al Viro's avatar Al Viro

ceph: switch to ->write_iter()

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 64c31311
...@@ -531,8 +531,7 @@ static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe) ...@@ -531,8 +531,7 @@ static void ceph_sync_write_unsafe(struct ceph_osd_request *req, bool unsafe)
* objects, rollback on failure, etc.) * objects, rollback on failure, etc.)
*/ */
static ssize_t static ssize_t
ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, ceph_sync_direct_write(struct kiocb *iocb, struct iov_iter *from)
unsigned long nr_segs, size_t count)
{ {
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
...@@ -549,7 +548,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -549,7 +548,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
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;
struct iov_iter i; size_t count = iov_iter_count(from);
if (ceph_snap(file_inode(file)) != CEPH_NOSNAP) if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
return -EROFS; return -EROFS;
...@@ -571,10 +570,8 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -571,10 +570,8 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
CEPH_OSD_FLAG_ONDISK | CEPH_OSD_FLAG_ONDISK |
CEPH_OSD_FLAG_WRITE; CEPH_OSD_FLAG_WRITE;
iov_iter_init(&i, WRITE, iov, nr_segs, count); while (iov_iter_count(from) > 0) {
u64 len = iov_iter_single_seg_count(from);
while (iov_iter_count(&i) > 0) {
u64 len = iov_iter_single_seg_count(&i);
size_t start; size_t start;
ssize_t n; ssize_t n;
...@@ -592,7 +589,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -592,7 +589,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
break; break;
} }
n = iov_iter_get_pages_alloc(&i, &pages, len, &start); n = iov_iter_get_pages_alloc(from, &pages, len, &start);
if (unlikely(n < 0)) { if (unlikely(n < 0)) {
ret = n; ret = n;
ceph_osdc_put_request(req); ceph_osdc_put_request(req);
...@@ -623,7 +620,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -623,7 +620,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
break; break;
pos += n; pos += n;
written += n; written += n;
iov_iter_advance(&i, n); iov_iter_advance(from, n);
if (pos > i_size_read(inode)) { if (pos > i_size_read(inode)) {
check_caps = ceph_inode_set_size(inode, pos); check_caps = ceph_inode_set_size(inode, pos);
...@@ -649,8 +646,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -649,8 +646,7 @@ ceph_sync_direct_write(struct kiocb *iocb, const struct iovec *iov,
* correct atomic write, we should e.g. take write locks on all * correct atomic write, we should e.g. take write locks on all
* objects, rollback on failure, etc.) * objects, rollback on failure, etc.)
*/ */
static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, static ssize_t ceph_sync_write(struct kiocb *iocb, struct iov_iter *from)
unsigned long nr_segs, size_t count)
{ {
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
...@@ -668,7 +664,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -668,7 +664,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov,
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;
struct iov_iter i; size_t count = iov_iter_count(from);
if (ceph_snap(file_inode(file)) != CEPH_NOSNAP) if (ceph_snap(file_inode(file)) != CEPH_NOSNAP)
return -EROFS; return -EROFS;
...@@ -690,9 +686,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -690,9 +686,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov,
CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_WRITE |
CEPH_OSD_FLAG_ACK; CEPH_OSD_FLAG_ACK;
iov_iter_init(&i, WRITE, iov, nr_segs, count); while ((len = iov_iter_count(from)) > 0) {
while ((len = iov_iter_count(&i)) > 0) {
size_t left; size_t left;
int n; int n;
...@@ -724,7 +718,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -724,7 +718,7 @@ static ssize_t ceph_sync_write(struct kiocb *iocb, const struct iovec *iov,
left = len; left = len;
for (n = 0; n < num_pages; n++) { for (n = 0; n < num_pages; n++) {
size_t plen = min_t(size_t, left, PAGE_SIZE); size_t plen = min_t(size_t, left, PAGE_SIZE);
ret = copy_page_from_iter(pages[n], 0, plen, &i); ret = copy_page_from_iter(pages[n], 0, plen, from);
if (ret != plen) { if (ret != plen) {
ret = -EFAULT; ret = -EFAULT;
break; break;
...@@ -861,8 +855,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to) ...@@ -861,8 +855,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to)
* *
* If we are near ENOSPC, write synchronously. * If we are near ENOSPC, write synchronously.
*/ */
static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
unsigned long nr_segs, loff_t pos)
{ {
struct file *file = iocb->ki_filp; struct file *file = iocb->ki_filp;
struct ceph_file_info *fi = file->private_data; struct ceph_file_info *fi = file->private_data;
...@@ -870,16 +863,15 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -870,16 +863,15 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
struct ceph_inode_info *ci = ceph_inode(inode); struct ceph_inode_info *ci = ceph_inode(inode);
struct ceph_osd_client *osdc = struct ceph_osd_client *osdc =
&ceph_sb_to_client(inode->i_sb)->client->osdc; &ceph_sb_to_client(inode->i_sb)->client->osdc;
ssize_t count, written = 0; ssize_t count = iov_iter_count(from), written = 0;
int err, want, got; int err, want, got;
loff_t pos = iocb->ki_pos;
if (ceph_snap(inode) != CEPH_NOSNAP) if (ceph_snap(inode) != CEPH_NOSNAP)
return -EROFS; return -EROFS;
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
count = iov_length(iov, nr_segs);
/* We can write back this queue in page reclaim */ /* We can write back this queue in page reclaim */
current->backing_dev_info = file->f_mapping->backing_dev_info; current->backing_dev_info = file->f_mapping->backing_dev_info;
...@@ -889,6 +881,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -889,6 +881,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
if (count == 0) if (count == 0)
goto out; goto out;
iov_iter_truncate(from, count);
err = file_remove_suid(file); err = file_remove_suid(file);
if (err) if (err)
...@@ -920,23 +913,26 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -920,23 +913,26 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 || if ((got & (CEPH_CAP_FILE_BUFFER|CEPH_CAP_FILE_LAZYIO)) == 0 ||
(file->f_flags & O_DIRECT) || (fi->flags & CEPH_F_SYNC)) { (file->f_flags & O_DIRECT) || (fi->flags & CEPH_F_SYNC)) {
struct iov_iter data;
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
/* we might need to revert back to that point */
data = *from;
if (file->f_flags & O_DIRECT) if (file->f_flags & O_DIRECT)
written = ceph_sync_direct_write(iocb, iov, written = ceph_sync_direct_write(iocb, &data);
nr_segs, count);
else else
written = ceph_sync_write(iocb, iov, nr_segs, count); written = ceph_sync_write(iocb, &data);
if (written == -EOLDSNAPC) { if (written == -EOLDSNAPC) {
dout("aio_write %p %llx.%llx %llu~%u" dout("aio_write %p %llx.%llx %llu~%u"
"got EOLDSNAPC, retrying\n", "got EOLDSNAPC, retrying\n",
inode, ceph_vinop(inode), inode, ceph_vinop(inode),
pos, (unsigned)iov->iov_len); pos, (unsigned)count);
mutex_lock(&inode->i_mutex); mutex_lock(&inode->i_mutex);
goto retry_snap; goto retry_snap;
} }
if (written > 0)
iov_iter_advance(from, written);
} else { } else {
loff_t old_size = inode->i_size; loff_t old_size = inode->i_size;
struct iov_iter from;
/* /*
* No need to acquire the i_truncate_mutex. Because * No need to acquire the i_truncate_mutex. Because
* the MDS revokes Fwb caps before sending truncate * the MDS revokes Fwb caps before sending truncate
...@@ -944,8 +940,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -944,8 +940,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
* are pending vmtruncate. So write and vmtruncate * are pending vmtruncate. So write and vmtruncate
* can not run at the same time * can not run at the same time
*/ */
iov_iter_init(&from, WRITE, iov, nr_segs, count); written = generic_perform_write(file, from, pos);
written = generic_perform_write(file, &from, pos);
if (likely(written >= 0)) if (likely(written >= 0))
iocb->ki_pos = pos + written; iocb->ki_pos = pos + written;
if (inode->i_size > old_size) if (inode->i_size > old_size)
...@@ -963,7 +958,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov, ...@@ -963,7 +958,7 @@ static ssize_t ceph_aio_write(struct kiocb *iocb, const struct iovec *iov,
} }
dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n", dout("aio_write %p %llx.%llx %llu~%u dropping cap refs on %s\n",
inode, ceph_vinop(inode), pos, (unsigned)iov->iov_len, inode, ceph_vinop(inode), pos, (unsigned)count,
ceph_cap_string(got)); ceph_cap_string(got));
ceph_put_cap_refs(ci, got); ceph_put_cap_refs(ci, got);
...@@ -1241,9 +1236,9 @@ const struct file_operations ceph_file_fops = { ...@@ -1241,9 +1236,9 @@ const struct file_operations ceph_file_fops = {
.release = ceph_release, .release = ceph_release,
.llseek = ceph_llseek, .llseek = ceph_llseek,
.read = new_sync_read, .read = new_sync_read,
.write = do_sync_write, .write = new_sync_write,
.read_iter = ceph_read_iter, .read_iter = ceph_read_iter,
.aio_write = ceph_aio_write, .write_iter = ceph_write_iter,
.mmap = ceph_mmap, .mmap = ceph_mmap,
.fsync = ceph_fsync, .fsync = ceph_fsync,
.lock = ceph_lock, .lock = ceph_lock,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment