On Fri, 2019-07-12 at 10:46 +0800, Yan, Zheng wrote: > 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 > Good catch. Looks like I left another one too in ceph_aio_complete. I'll remove that one as well. > > - 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 > > -- Jeff Layton <jlayton@xxxxxxxxxx>