Messages in this thread Patch in this message | | | Subject | Re: [PATCH v2] ceph: invalidate pages when doing DIO in encrypted inodes | From | Xiubo Li <> | Date | Thu, 7 Apr 2022 11:19:09 +0800 |
| |
Hi Luis,
Please try the following patch, to see could it resolve your issue:
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 5d39d8e54273..3507e4066de4 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c @@ -2011,6 +2011,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to) ceph_cap_string(got));
if (ci->i_inline_version == CEPH_INLINE_NONE) { + filemap_invalidate_lock(inode->i_mapping); if (!retry_op && (iocb->ki_flags & IOCB_DIRECT) && !IS_ENCRYPTED(inode)) { @@ -2021,6 +2022,7 @@ static ssize_t ceph_read_iter(struct kiocb *iocb, struct iov_iter *to) } else { ret = ceph_sync_read(iocb, to, &retry_op); } + filemap_invalidate_unlock(inode->i_mapping); } else { retry_op = READ_INLINE; } @@ -2239,11 +2241,13 @@ static ssize_t ceph_write_iter(struct kiocb *iocb, struct iov_iter *from)
/* we might need to revert back to that point */ data = *from; + filemap_invalidate_lock(inode->i_mapping); if ((iocb->ki_flags & IOCB_DIRECT) && !IS_ENCRYPTED(inode)) written = ceph_direct_read_write(iocb, &data, snapc, &prealloc_cf); else written = ceph_sync_write(iocb, &data, pos, snapc); + filemap_invalidate_unlock(inode->i_mapping); if (direct_lock) ceph_end_io_direct(inode); else
On 4/1/22 9:32 PM, Luís Henriques wrote: > When doing DIO on an encrypted node, we need to invalidate the page cache in > the range being written to, otherwise the cache will include invalid data. > > Signed-off-by: Luís Henriques <lhenriques@suse.de> > --- > fs/ceph/file.c | 11 ++++++++++- > 1 file changed, 10 insertions(+), 1 deletion(-) > > Changes since v1: > - Replaced truncate_inode_pages_range() by invalidate_inode_pages2_range > - Call fscache_invalidate with FSCACHE_INVAL_DIO_WRITE if we're doing DIO > > Note: I'm not really sure this last change is required, it doesn't really > affect generic/647 result, but seems to be the most correct. > > diff --git a/fs/ceph/file.c b/fs/ceph/file.c > index 5072570c2203..b2743c342305 100644 > --- a/fs/ceph/file.c > +++ b/fs/ceph/file.c > @@ -1605,7 +1605,7 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos, > if (ret < 0) > return ret; > > - ceph_fscache_invalidate(inode, false); > + ceph_fscache_invalidate(inode, (iocb->ki_flags & IOCB_DIRECT)); > ret = invalidate_inode_pages2_range(inode->i_mapping, > pos >> PAGE_SHIFT, > (pos + count - 1) >> PAGE_SHIFT); > @@ -1895,6 +1895,15 @@ ceph_sync_write(struct kiocb *iocb, struct iov_iter *from, loff_t pos, > req->r_inode = inode; > req->r_mtime = mtime; > > + if (IS_ENCRYPTED(inode) && (iocb->ki_flags & IOCB_DIRECT)) { > + ret = invalidate_inode_pages2_range( > + inode->i_mapping, > + write_pos >> PAGE_SHIFT, > + (write_pos + write_len - 1) >> PAGE_SHIFT); > + if (ret < 0) > + dout("invalidate_inode_pages2_range returned %d\n", ret); > + } > + > /* Set up the assertion */ > if (rmw) { > /* >
| |