Skip to content

Commit 295fc4a

Browse files
lxbszidryomov
authored andcommitted
ceph: fix updating i_truncate_pagecache_size for fscrypt
When fscrypt is enabled we will align the truncate size up to the CEPH_FSCRYPT_BLOCK_SIZE always, so if we truncate the size in the same block more than once, the latter ones will be skipped being invalidated from the page caches. This will force invalidating the page caches by using the smaller size than the real file size. At the same time add more debug log and fix the debug log for truncate code. Link: https://tracker.ceph.com/issues/58834 Signed-off-by: Xiubo Li <[email protected]> Reviewed-and-tested-by: Luís Henriques <[email protected]> Reviewed-by: Milind Changire <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]>
1 parent 1464de9 commit 295fc4a

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

fs/ceph/caps.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3950,8 +3950,8 @@ static bool handle_cap_trunc(struct inode *inode,
39503950
if (IS_ENCRYPTED(inode) && size)
39513951
size = extra_info->fscrypt_file_size;
39523952

3953-
dout("handle_cap_trunc inode %p mds%d seq %d to %lld seq %d\n",
3954-
inode, mds, seq, truncate_size, truncate_seq);
3953+
dout("%s inode %p mds%d seq %d to %lld truncate seq %d\n",
3954+
__func__, inode, mds, seq, truncate_size, truncate_seq);
39553955
queue_trunc = ceph_fill_file_size(inode, issued,
39563956
truncate_seq, truncate_size, size);
39573957
return queue_trunc;

fs/ceph/inode.c

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -764,7 +764,7 @@ int ceph_fill_file_size(struct inode *inode, int issued,
764764
ceph_fscache_update(inode);
765765
ci->i_reported_size = size;
766766
if (truncate_seq != ci->i_truncate_seq) {
767-
dout("truncate_seq %u -> %u\n",
767+
dout("%s truncate_seq %u -> %u\n", __func__,
768768
ci->i_truncate_seq, truncate_seq);
769769
ci->i_truncate_seq = truncate_seq;
770770

@@ -788,15 +788,26 @@ int ceph_fill_file_size(struct inode *inode, int issued,
788788
}
789789
}
790790
}
791-
if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) >= 0 &&
792-
ci->i_truncate_size != truncate_size) {
793-
dout("truncate_size %lld -> %llu\n", ci->i_truncate_size,
794-
truncate_size);
791+
792+
/*
793+
* It's possible that the new sizes of the two consecutive
794+
* size truncations will be in the same fscrypt last block,
795+
* and we need to truncate the corresponding page caches
796+
* anyway.
797+
*/
798+
if (ceph_seq_cmp(truncate_seq, ci->i_truncate_seq) >= 0) {
799+
dout("%s truncate_size %lld -> %llu, encrypted %d\n", __func__,
800+
ci->i_truncate_size, truncate_size, !!IS_ENCRYPTED(inode));
801+
795802
ci->i_truncate_size = truncate_size;
796-
if (IS_ENCRYPTED(inode))
803+
804+
if (IS_ENCRYPTED(inode)) {
805+
dout("%s truncate_pagecache_size %lld -> %llu\n",
806+
__func__, ci->i_truncate_pagecache_size, size);
797807
ci->i_truncate_pagecache_size = size;
798-
else
808+
} else {
799809
ci->i_truncate_pagecache_size = truncate_size;
810+
}
800811
}
801812
return queue_trunc;
802813
}
@@ -2155,7 +2166,7 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
21552166
retry:
21562167
spin_lock(&ci->i_ceph_lock);
21572168
if (ci->i_truncate_pending == 0) {
2158-
dout("__do_pending_vmtruncate %p none pending\n", inode);
2169+
dout("%s %p none pending\n", __func__, inode);
21592170
spin_unlock(&ci->i_ceph_lock);
21602171
mutex_unlock(&ci->i_truncate_mutex);
21612172
return;
@@ -2167,8 +2178,7 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
21672178
*/
21682179
if (ci->i_wrbuffer_ref_head < ci->i_wrbuffer_ref) {
21692180
spin_unlock(&ci->i_ceph_lock);
2170-
dout("__do_pending_vmtruncate %p flushing snaps first\n",
2171-
inode);
2181+
dout("%s %p flushing snaps first\n", __func__, inode);
21722182
filemap_write_and_wait_range(&inode->i_data, 0,
21732183
inode->i_sb->s_maxbytes);
21742184
goto retry;
@@ -2179,7 +2189,7 @@ void __ceph_do_pending_vmtruncate(struct inode *inode)
21792189

21802190
to = ci->i_truncate_pagecache_size;
21812191
wrbuffer_refs = ci->i_wrbuffer_ref;
2182-
dout("__do_pending_vmtruncate %p (%d) to %lld\n", inode,
2192+
dout("%s %p (%d) to %lld\n", __func__, inode,
21832193
ci->i_truncate_pending, to);
21842194
spin_unlock(&ci->i_ceph_lock);
21852195

@@ -2371,6 +2381,9 @@ static int fill_fscrypt_truncate(struct inode *inode,
23712381
header.data_len = cpu_to_le32(8 + 8 + 4 + CEPH_FSCRYPT_BLOCK_SIZE);
23722382
header.file_offset = cpu_to_le64(orig_pos);
23732383

2384+
dout("%s encrypt block boff/bsize %d/%lu\n", __func__,
2385+
boff, CEPH_FSCRYPT_BLOCK_SIZE);
2386+
23742387
/* truncate and zero out the extra contents for the last block */
23752388
memset(iov.iov_base + boff, 0, PAGE_SIZE - boff);
23762389

0 commit comments

Comments
 (0)