@@ -956,10 +956,10 @@ static int fuse_check_folio(struct folio *folio)
956
956
* folio that was originally in @pagep will lose a reference and the new
957
957
* folio returned in @pagep will carry a reference.
958
958
*/
959
- static int fuse_try_move_page (struct fuse_copy_state * cs , struct page * * pagep )
959
+ static int fuse_try_move_folio (struct fuse_copy_state * cs , struct folio * * foliop )
960
960
{
961
961
int err ;
962
- struct folio * oldfolio = page_folio ( * pagep ) ;
962
+ struct folio * oldfolio = * foliop ;
963
963
struct folio * newfolio ;
964
964
struct pipe_buffer * buf = cs -> pipebufs ;
965
965
@@ -980,7 +980,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
980
980
cs -> pipebufs ++ ;
981
981
cs -> nr_segs -- ;
982
982
983
- if (cs -> len != PAGE_SIZE )
983
+ if (cs -> len != folio_size ( oldfolio ) )
984
984
goto out_fallback ;
985
985
986
986
if (!pipe_buf_try_steal (cs -> pipe , buf ))
@@ -1026,7 +1026,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
1026
1026
if (test_bit (FR_ABORTED , & cs -> req -> flags ))
1027
1027
err = - ENOENT ;
1028
1028
else
1029
- * pagep = & newfolio -> page ;
1029
+ * foliop = newfolio ;
1030
1030
spin_unlock (& cs -> req -> waitq .lock );
1031
1031
1032
1032
if (err ) {
@@ -1059,26 +1059,26 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
1059
1059
goto out_put_old ;
1060
1060
}
1061
1061
1062
- static int fuse_ref_page (struct fuse_copy_state * cs , struct page * page ,
1063
- unsigned offset , unsigned count )
1062
+ static int fuse_ref_folio (struct fuse_copy_state * cs , struct folio * folio ,
1063
+ unsigned offset , unsigned count )
1064
1064
{
1065
1065
struct pipe_buffer * buf ;
1066
1066
int err ;
1067
1067
1068
1068
if (cs -> nr_segs >= cs -> pipe -> max_usage )
1069
1069
return - EIO ;
1070
1070
1071
- get_page ( page );
1071
+ folio_get ( folio );
1072
1072
err = unlock_request (cs -> req );
1073
1073
if (err ) {
1074
- put_page ( page );
1074
+ folio_put ( folio );
1075
1075
return err ;
1076
1076
}
1077
1077
1078
1078
fuse_copy_finish (cs );
1079
1079
1080
1080
buf = cs -> pipebufs ;
1081
- buf -> page = page ;
1081
+ buf -> page = & folio -> page ;
1082
1082
buf -> offset = offset ;
1083
1083
buf -> len = count ;
1084
1084
@@ -1090,20 +1090,24 @@ static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
1090
1090
}
1091
1091
1092
1092
/*
1093
- * Copy a page in the request to/from the userspace buffer. Must be
1093
+ * Copy a folio in the request to/from the userspace buffer. Must be
1094
1094
* done atomically
1095
1095
*/
1096
- static int fuse_copy_page (struct fuse_copy_state * cs , struct page * * pagep ,
1097
- unsigned offset , unsigned count , int zeroing )
1096
+ static int fuse_copy_folio (struct fuse_copy_state * cs , struct folio * * foliop ,
1097
+ unsigned offset , unsigned count , int zeroing )
1098
1098
{
1099
1099
int err ;
1100
- struct page * page = * pagep ;
1100
+ struct folio * folio = * foliop ;
1101
+ size_t size ;
1101
1102
1102
- if (page && zeroing && count < PAGE_SIZE )
1103
- clear_highpage (page );
1103
+ if (folio ) {
1104
+ size = folio_size (folio );
1105
+ if (zeroing && count < size )
1106
+ folio_zero_range (folio , 0 , size );
1107
+ }
1104
1108
1105
1109
while (count ) {
1106
- if (cs -> write && cs -> pipebufs && page ) {
1110
+ if (cs -> write && cs -> pipebufs && folio ) {
1107
1111
/*
1108
1112
* Can't control lifetime of pipe buffers, so always
1109
1113
* copy user pages.
@@ -1113,12 +1117,12 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
1113
1117
if (err )
1114
1118
return err ;
1115
1119
} else {
1116
- return fuse_ref_page (cs , page , offset , count );
1120
+ return fuse_ref_folio (cs , folio , offset , count );
1117
1121
}
1118
1122
} else if (!cs -> len ) {
1119
- if (cs -> move_pages && page &&
1120
- offset == 0 && count == PAGE_SIZE ) {
1121
- err = fuse_try_move_page (cs , pagep );
1123
+ if (cs -> move_folios && folio &&
1124
+ offset == 0 && count == size ) {
1125
+ err = fuse_try_move_folio (cs , foliop );
1122
1126
if (err <= 0 )
1123
1127
return err ;
1124
1128
} else {
@@ -1127,22 +1131,30 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
1127
1131
return err ;
1128
1132
}
1129
1133
}
1130
- if (page ) {
1131
- void * mapaddr = kmap_local_page (page );
1132
- void * buf = mapaddr + offset ;
1133
- offset += fuse_copy_do (cs , & buf , & count );
1134
+ if (folio ) {
1135
+ void * mapaddr = kmap_local_folio (folio , offset );
1136
+ void * buf = mapaddr ;
1137
+ unsigned int copy = count ;
1138
+ unsigned int bytes_copied ;
1139
+
1140
+ if (folio_test_highmem (folio ) && count > PAGE_SIZE - offset_in_page (offset ))
1141
+ copy = PAGE_SIZE - offset_in_page (offset );
1142
+
1143
+ bytes_copied = fuse_copy_do (cs , & buf , & copy );
1134
1144
kunmap_local (mapaddr );
1145
+ offset += bytes_copied ;
1146
+ count -= bytes_copied ;
1135
1147
} else
1136
1148
offset += fuse_copy_do (cs , NULL , & count );
1137
1149
}
1138
- if (page && !cs -> write )
1139
- flush_dcache_page ( page );
1150
+ if (folio && !cs -> write )
1151
+ flush_dcache_folio ( folio );
1140
1152
return 0 ;
1141
1153
}
1142
1154
1143
- /* Copy pages in the request to/from userspace buffer */
1144
- static int fuse_copy_pages (struct fuse_copy_state * cs , unsigned nbytes ,
1145
- int zeroing )
1155
+ /* Copy folios in the request to/from userspace buffer */
1156
+ static int fuse_copy_folios (struct fuse_copy_state * cs , unsigned nbytes ,
1157
+ int zeroing )
1146
1158
{
1147
1159
unsigned i ;
1148
1160
struct fuse_req * req = cs -> req ;
@@ -1152,23 +1164,12 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
1152
1164
int err ;
1153
1165
unsigned int offset = ap -> descs [i ].offset ;
1154
1166
unsigned int count = min (nbytes , ap -> descs [i ].length );
1155
- struct page * orig , * pagep ;
1156
1167
1157
- orig = pagep = & ap -> folios [i ]-> page ;
1158
-
1159
- err = fuse_copy_page (cs , & pagep , offset , count , zeroing );
1168
+ err = fuse_copy_folio (cs , & ap -> folios [i ], offset , count , zeroing );
1160
1169
if (err )
1161
1170
return err ;
1162
1171
1163
1172
nbytes -= count ;
1164
-
1165
- /*
1166
- * fuse_copy_page may have moved a page from a pipe instead of
1167
- * copying into our given page, so update the folios if it was
1168
- * replaced.
1169
- */
1170
- if (pagep != orig )
1171
- ap -> folios [i ] = page_folio (pagep );
1172
1173
}
1173
1174
return 0 ;
1174
1175
}
@@ -1198,7 +1199,7 @@ int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
1198
1199
for (i = 0 ; !err && i < numargs ; i ++ ) {
1199
1200
struct fuse_arg * arg = & args [i ];
1200
1201
if (i == numargs - 1 && argpages )
1201
- err = fuse_copy_pages (cs , arg -> size , zeroing );
1202
+ err = fuse_copy_folios (cs , arg -> size , zeroing );
1202
1203
else
1203
1204
err = fuse_copy_one (cs , arg -> value , arg -> size );
1204
1205
}
@@ -1787,17 +1788,15 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
1787
1788
num = outarg .size ;
1788
1789
while (num ) {
1789
1790
struct folio * folio ;
1790
- struct page * page ;
1791
1791
unsigned int this_num ;
1792
1792
1793
1793
folio = filemap_grab_folio (mapping , index );
1794
1794
err = PTR_ERR (folio );
1795
1795
if (IS_ERR (folio ))
1796
1796
goto out_iput ;
1797
1797
1798
- page = & folio -> page ;
1799
1798
this_num = min_t (unsigned , num , folio_size (folio ) - offset );
1800
- err = fuse_copy_page (cs , & page , offset , this_num , 0 );
1799
+ err = fuse_copy_folio (cs , & folio , offset , this_num , 0 );
1801
1800
if (!folio_test_uptodate (folio ) && !err && offset == 0 &&
1802
1801
(this_num == folio_size (folio ) || file_size == end )) {
1803
1802
folio_zero_segment (folio , this_num , folio_size (folio ));
@@ -2038,8 +2037,8 @@ static int fuse_notify_inc_epoch(struct fuse_conn *fc)
2038
2037
static int fuse_notify (struct fuse_conn * fc , enum fuse_notify_code code ,
2039
2038
unsigned int size , struct fuse_copy_state * cs )
2040
2039
{
2041
- /* Don't try to move pages (yet) */
2042
- cs -> move_pages = false;
2040
+ /* Don't try to move folios (yet) */
2041
+ cs -> move_folios = false;
2043
2042
2044
2043
switch (code ) {
2045
2044
case FUSE_NOTIFY_POLL :
@@ -2190,7 +2189,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
2190
2189
spin_unlock (& fpq -> lock );
2191
2190
cs -> req = req ;
2192
2191
if (!req -> args -> page_replace )
2193
- cs -> move_pages = false;
2192
+ cs -> move_folios = false;
2194
2193
2195
2194
if (oh .error )
2196
2195
err = nbytes != sizeof (oh ) ? - EINVAL : 0 ;
@@ -2308,7 +2307,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
2308
2307
cs .pipe = pipe ;
2309
2308
2310
2309
if (flags & SPLICE_F_MOVE )
2311
- cs .move_pages = true;
2310
+ cs .move_folios = true;
2312
2311
2313
2312
ret = fuse_dev_do_write (fud , & cs , len );
2314
2313
0 commit comments