On Fri, Jul 12, 2019 at 3:17 AM Jeff Layton <jlayton@xxxxxxxxxx> wrote: > > If the src is inlined, then just bail out. Have it attempt to uninline > the dst file however. > > Signed-off-by: Jeff Layton <jlayton@xxxxxxxxxx> > --- > fs/ceph/file.c | 13 ++++++++++++- > 1 file changed, 12 insertions(+), 1 deletion(-) > > diff --git a/fs/ceph/file.c b/fs/ceph/file.c > index 252aac44b8ce..774f51b0b63d 100644 > --- a/fs/ceph/file.c > +++ b/fs/ceph/file.c > @@ -1934,6 +1934,10 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, > if (len < src_ci->i_layout.object_size) > return -EOPNOTSUPP; /* no remote copy will be done */ > > + /* Fall back if src file is inlined */ > + if (READ_ONCE(src_ci->i_inline_version) != CEPH_INLINE_NONE) > + return -EOPNOTSUPP; > + > prealloc_cf = ceph_alloc_cap_flush(); > if (!prealloc_cf) > return -ENOMEM; > @@ -1967,6 +1971,13 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, > if (ret < 0) > goto out_caps; > > + /* uninline the dst inode */ > + dirty = ceph_uninline_data(dst_inode, NULL); > + if (dirty < 0) { > + ret = dirty; > + goto out_caps; > + } > + > size = i_size_read(dst_inode); > endoff = dst_off + len; > > @@ -2080,7 +2091,7 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, > /* Mark Fw dirty */ > spin_lock(&dst_ci->i_ceph_lock); > dst_ci->i_inline_version = CEPH_INLINE_NONE; remove this line > - dirty = __ceph_mark_dirty_caps(dst_ci, CEPH_CAP_FILE_WR, &prealloc_cf); > + dirty |= __ceph_mark_dirty_caps(dst_ci, CEPH_CAP_FILE_WR, &prealloc_cf); > spin_unlock(&dst_ci->i_ceph_lock); > if (dirty) > __mark_inode_dirty(dst_inode, dirty); > -- > 2.21.0 >