@@ -565,10 +565,12 @@ static u64 get_writepages_data_length(struct inode *inode,
565
565
struct page * page , u64 start )
566
566
{
567
567
struct ceph_inode_info * ci = ceph_inode (inode );
568
- struct ceph_snap_context * snapc = page_snap_context ( page ) ;
568
+ struct ceph_snap_context * snapc ;
569
569
struct ceph_cap_snap * capsnap = NULL ;
570
570
u64 end = i_size_read (inode );
571
+ u64 ret ;
571
572
573
+ snapc = page_snap_context (ceph_fscrypt_pagecache_page (page ));
572
574
if (snapc != ci -> i_head_snapc ) {
573
575
bool found = false;
574
576
spin_lock (& ci -> i_ceph_lock );
@@ -583,9 +585,12 @@ static u64 get_writepages_data_length(struct inode *inode,
583
585
spin_unlock (& ci -> i_ceph_lock );
584
586
WARN_ON (!found );
585
587
}
586
- if (end > page_offset (page ) + thp_size (page ))
587
- end = page_offset (page ) + thp_size (page );
588
- return end > start ? end - start : 0 ;
588
+ if (end > ceph_fscrypt_page_offset (page ) + thp_size (page ))
589
+ end = ceph_fscrypt_page_offset (page ) + thp_size (page );
590
+ ret = end > start ? end - start : 0 ;
591
+ if (ret && fscrypt_is_bounce_page (page ))
592
+ ret = round_up (ret , CEPH_FSCRYPT_BLOCK_SIZE );
593
+ return ret ;
589
594
}
590
595
591
596
/*
@@ -604,10 +609,12 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
604
609
loff_t page_off = page_offset (page );
605
610
int err ;
606
611
loff_t len = thp_size (page );
612
+ loff_t wlen ;
607
613
struct ceph_writeback_ctl ceph_wbc ;
608
614
struct ceph_osd_client * osdc = & fsc -> client -> osdc ;
609
615
struct ceph_osd_request * req ;
610
616
bool caching = ceph_is_cache_enabled (inode );
617
+ struct page * bounce_page = NULL ;
611
618
612
619
dout ("writepage %p idx %lu\n" , page , page -> index );
613
620
@@ -643,39 +650,59 @@ static int writepage_nounlock(struct page *page, struct writeback_control *wbc)
643
650
if (ceph_wbc .i_size < page_off + len )
644
651
len = ceph_wbc .i_size - page_off ;
645
652
653
+ wlen = IS_ENCRYPTED (inode ) ? round_up (len , CEPH_FSCRYPT_BLOCK_SIZE ) : len ;
646
654
dout ("writepage %p page %p index %lu on %llu~%llu snapc %p seq %lld\n" ,
647
- inode , page , page -> index , page_off , len , snapc , snapc -> seq );
655
+ inode , page , page -> index , page_off , wlen , snapc , snapc -> seq );
648
656
649
657
if (atomic_long_inc_return (& fsc -> writeback_count ) >
650
658
CONGESTION_ON_THRESH (fsc -> mount_options -> congestion_kb ))
651
659
fsc -> write_congested = true;
652
660
653
- req = ceph_osdc_new_request (osdc , & ci -> i_layout , ceph_vino (inode ), page_off , & len , 0 , 1 ,
654
- CEPH_OSD_OP_WRITE , CEPH_OSD_FLAG_WRITE , snapc ,
655
- ceph_wbc .truncate_seq , ceph_wbc .truncate_size ,
656
- true);
661
+ req = ceph_osdc_new_request (osdc , & ci -> i_layout , ceph_vino (inode ),
662
+ page_off , & wlen , 0 , 1 , CEPH_OSD_OP_WRITE ,
663
+ CEPH_OSD_FLAG_WRITE , snapc ,
664
+ ceph_wbc .truncate_seq ,
665
+ ceph_wbc .truncate_size , true);
657
666
if (IS_ERR (req )) {
658
667
redirty_page_for_writepage (wbc , page );
659
668
return PTR_ERR (req );
660
669
}
661
670
671
+ if (wlen < len )
672
+ len = wlen ;
673
+
662
674
set_page_writeback (page );
663
675
if (caching )
664
676
ceph_set_page_fscache (page );
665
677
ceph_fscache_write_to_cache (inode , page_off , len , caching );
666
678
679
+ if (IS_ENCRYPTED (inode )) {
680
+ bounce_page = fscrypt_encrypt_pagecache_blocks (page ,
681
+ CEPH_FSCRYPT_BLOCK_SIZE , 0 ,
682
+ GFP_NOFS );
683
+ if (IS_ERR (bounce_page )) {
684
+ redirty_page_for_writepage (wbc , page );
685
+ end_page_writeback (page );
686
+ ceph_osdc_put_request (req );
687
+ return PTR_ERR (bounce_page );
688
+ }
689
+ }
690
+
667
691
/* it may be a short write due to an object boundary */
668
692
WARN_ON_ONCE (len > thp_size (page ));
669
- osd_req_op_extent_osd_data_pages (req , 0 , & page , len , 0 , false, false);
670
- dout ("writepage %llu~%llu (%llu bytes)\n" , page_off , len , len );
693
+ osd_req_op_extent_osd_data_pages (req , 0 ,
694
+ bounce_page ? & bounce_page : & page , wlen , 0 ,
695
+ false, false);
696
+ dout ("writepage %llu~%llu (%llu bytes, %sencrypted)\n" ,
697
+ page_off , len , wlen , IS_ENCRYPTED (inode ) ? "" : "not " );
671
698
672
699
req -> r_mtime = inode -> i_mtime ;
673
700
ceph_osdc_start_request (osdc , req );
674
701
err = ceph_osdc_wait_request (osdc , req );
675
702
676
703
ceph_update_write_metrics (& fsc -> mdsc -> metric , req -> r_start_latency ,
677
704
req -> r_end_latency , len , err );
678
-
705
+ fscrypt_free_bounce_page ( bounce_page );
679
706
ceph_osdc_put_request (req );
680
707
if (err == 0 )
681
708
err = len ;
@@ -794,6 +821,11 @@ static void writepages_finish(struct ceph_osd_request *req)
794
821
total_pages += num_pages ;
795
822
for (j = 0 ; j < num_pages ; j ++ ) {
796
823
page = osd_data -> pages [j ];
824
+ if (fscrypt_is_bounce_page (page )) {
825
+ page = fscrypt_pagecache_page (page );
826
+ fscrypt_free_bounce_page (osd_data -> pages [j ]);
827
+ osd_data -> pages [j ] = page ;
828
+ }
797
829
BUG_ON (!page );
798
830
WARN_ON (!PageUptodate (page ));
799
831
@@ -1064,9 +1096,28 @@ static int ceph_writepages_start(struct address_space *mapping,
1064
1096
fsc -> mount_options -> congestion_kb ))
1065
1097
fsc -> write_congested = true;
1066
1098
1067
- pages [locked_pages ++ ] = page ;
1068
- fbatch .folios [i ] = NULL ;
1099
+ if (IS_ENCRYPTED (inode )) {
1100
+ pages [locked_pages ] =
1101
+ fscrypt_encrypt_pagecache_blocks (page ,
1102
+ PAGE_SIZE , 0 ,
1103
+ locked_pages ? GFP_NOWAIT : GFP_NOFS );
1104
+ if (IS_ERR (pages [locked_pages ])) {
1105
+ if (PTR_ERR (pages [locked_pages ]) == - EINVAL )
1106
+ pr_err ("%s: inode->i_blkbits=%hhu\n" ,
1107
+ __func__ , inode -> i_blkbits );
1108
+ /* better not fail on first page! */
1109
+ BUG_ON (locked_pages == 0 );
1110
+ pages [locked_pages ] = NULL ;
1111
+ redirty_page_for_writepage (wbc , page );
1112
+ unlock_page (page );
1113
+ break ;
1114
+ }
1115
+ ++ locked_pages ;
1116
+ } else {
1117
+ pages [locked_pages ++ ] = page ;
1118
+ }
1069
1119
1120
+ fbatch .folios [i ] = NULL ;
1070
1121
len += thp_size (page );
1071
1122
}
1072
1123
@@ -1094,7 +1145,7 @@ static int ceph_writepages_start(struct address_space *mapping,
1094
1145
}
1095
1146
1096
1147
new_request :
1097
- offset = page_offset (pages [0 ]);
1148
+ offset = ceph_fscrypt_page_offset (pages [0 ]);
1098
1149
len = wsize ;
1099
1150
1100
1151
req = ceph_osdc_new_request (& fsc -> client -> osdc ,
@@ -1115,8 +1166,8 @@ static int ceph_writepages_start(struct address_space *mapping,
1115
1166
ceph_wbc .truncate_size , true);
1116
1167
BUG_ON (IS_ERR (req ));
1117
1168
}
1118
- BUG_ON (len < page_offset (pages [locked_pages - 1 ]) +
1119
- thp_size (page ) - offset );
1169
+ BUG_ON (len < ceph_fscrypt_page_offset (pages [locked_pages - 1 ]) +
1170
+ thp_size (pages [ locked_pages - 1 ] ) - offset );
1120
1171
1121
1172
req -> r_callback = writepages_finish ;
1122
1173
req -> r_inode = inode ;
@@ -1126,7 +1177,9 @@ static int ceph_writepages_start(struct address_space *mapping,
1126
1177
data_pages = pages ;
1127
1178
op_idx = 0 ;
1128
1179
for (i = 0 ; i < locked_pages ; i ++ ) {
1129
- u64 cur_offset = page_offset (pages [i ]);
1180
+ struct page * page = ceph_fscrypt_pagecache_page (pages [i ]);
1181
+
1182
+ u64 cur_offset = page_offset (page );
1130
1183
/*
1131
1184
* Discontinuity in page range? Ceph can handle that by just passing
1132
1185
* multiple extents in the write op.
@@ -1155,9 +1208,9 @@ static int ceph_writepages_start(struct address_space *mapping,
1155
1208
op_idx ++ ;
1156
1209
}
1157
1210
1158
- set_page_writeback (pages [ i ] );
1211
+ set_page_writeback (page );
1159
1212
if (caching )
1160
- ceph_set_page_fscache (pages [ i ] );
1213
+ ceph_set_page_fscache (page );
1161
1214
len += thp_size (page );
1162
1215
}
1163
1216
ceph_fscache_write_to_cache (inode , offset , len , caching );
@@ -1173,8 +1226,16 @@ static int ceph_writepages_start(struct address_space *mapping,
1173
1226
offset );
1174
1227
len = max (len , min_len );
1175
1228
}
1229
+ if (IS_ENCRYPTED (inode ))
1230
+ len = round_up (len , CEPH_FSCRYPT_BLOCK_SIZE );
1231
+
1176
1232
dout ("writepages got pages at %llu~%llu\n" , offset , len );
1177
1233
1234
+ if (IS_ENCRYPTED (inode ) &&
1235
+ ((offset | len ) & ~CEPH_FSCRYPT_BLOCK_MASK ))
1236
+ pr_warn ("%s: bad encrypted write offset=%lld len=%llu\n" ,
1237
+ __func__ , offset , len );
1238
+
1178
1239
osd_req_op_extent_osd_data_pages (req , op_idx , data_pages , len ,
1179
1240
0 , from_pool , false);
1180
1241
osd_req_op_extent_update (req , op_idx , len );
0 commit comments