@@ -956,10 +956,10 @@ static int fuse_check_folio(struct folio *folio)
956956 * folio that was originally in @pagep will lose a reference and the new
957957 * folio returned in @pagep will carry a reference.
958958 */
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 )
960960{
961961 int err ;
962- struct folio * oldfolio = page_folio ( * pagep ) ;
962+ struct folio * oldfolio = * foliop ;
963963 struct folio * newfolio ;
964964 struct pipe_buffer * buf = cs -> pipebufs ;
965965
@@ -980,7 +980,7 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
980980 cs -> pipebufs ++ ;
981981 cs -> nr_segs -- ;
982982
983- if (cs -> len != PAGE_SIZE )
983+ if (cs -> len != folio_size ( oldfolio ) )
984984 goto out_fallback ;
985985
986986 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)
10261026 if (test_bit (FR_ABORTED , & cs -> req -> flags ))
10271027 err = - ENOENT ;
10281028 else
1029- * pagep = & newfolio -> page ;
1029+ * foliop = newfolio ;
10301030 spin_unlock (& cs -> req -> waitq .lock );
10311031
10321032 if (err ) {
@@ -1059,26 +1059,26 @@ static int fuse_try_move_page(struct fuse_copy_state *cs, struct page **pagep)
10591059 goto out_put_old ;
10601060}
10611061
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 )
10641064{
10651065 struct pipe_buffer * buf ;
10661066 int err ;
10671067
10681068 if (cs -> nr_segs >= cs -> pipe -> max_usage )
10691069 return - EIO ;
10701070
1071- get_page ( page );
1071+ folio_get ( folio );
10721072 err = unlock_request (cs -> req );
10731073 if (err ) {
1074- put_page ( page );
1074+ folio_put ( folio );
10751075 return err ;
10761076 }
10771077
10781078 fuse_copy_finish (cs );
10791079
10801080 buf = cs -> pipebufs ;
1081- buf -> page = page ;
1081+ buf -> page = & folio -> page ;
10821082 buf -> offset = offset ;
10831083 buf -> len = count ;
10841084
@@ -1090,20 +1090,24 @@ static int fuse_ref_page(struct fuse_copy_state *cs, struct page *page,
10901090}
10911091
10921092/*
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
10941094 * done atomically
10951095 */
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 )
10981098{
10991099 int err ;
1100- struct page * page = * pagep ;
1100+ struct folio * folio = * foliop ;
1101+ size_t size ;
11011102
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+ }
11041108
11051109 while (count ) {
1106- if (cs -> write && cs -> pipebufs && page ) {
1110+ if (cs -> write && cs -> pipebufs && folio ) {
11071111 /*
11081112 * Can't control lifetime of pipe buffers, so always
11091113 * copy user pages.
@@ -1113,12 +1117,12 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
11131117 if (err )
11141118 return err ;
11151119 } else {
1116- return fuse_ref_page (cs , page , offset , count );
1120+ return fuse_ref_folio (cs , folio , offset , count );
11171121 }
11181122 } 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 );
11221126 if (err <= 0 )
11231127 return err ;
11241128 } else {
@@ -1127,22 +1131,30 @@ static int fuse_copy_page(struct fuse_copy_state *cs, struct page **pagep,
11271131 return err ;
11281132 }
11291133 }
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 );
11341144 kunmap_local (mapaddr );
1145+ offset += bytes_copied ;
1146+ count -= bytes_copied ;
11351147 } else
11361148 offset += fuse_copy_do (cs , NULL , & count );
11371149 }
1138- if (page && !cs -> write )
1139- flush_dcache_page ( page );
1150+ if (folio && !cs -> write )
1151+ flush_dcache_folio ( folio );
11401152 return 0 ;
11411153}
11421154
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 )
11461158{
11471159 unsigned i ;
11481160 struct fuse_req * req = cs -> req ;
@@ -1152,23 +1164,12 @@ static int fuse_copy_pages(struct fuse_copy_state *cs, unsigned nbytes,
11521164 int err ;
11531165 unsigned int offset = ap -> descs [i ].offset ;
11541166 unsigned int count = min (nbytes , ap -> descs [i ].length );
1155- struct page * orig , * pagep ;
11561167
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 );
11601169 if (err )
11611170 return err ;
11621171
11631172 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 );
11721173 }
11731174 return 0 ;
11741175}
@@ -1198,7 +1199,7 @@ int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs,
11981199 for (i = 0 ; !err && i < numargs ; i ++ ) {
11991200 struct fuse_arg * arg = & args [i ];
12001201 if (i == numargs - 1 && argpages )
1201- err = fuse_copy_pages (cs , arg -> size , zeroing );
1202+ err = fuse_copy_folios (cs , arg -> size , zeroing );
12021203 else
12031204 err = fuse_copy_one (cs , arg -> value , arg -> size );
12041205 }
@@ -1787,17 +1788,15 @@ static int fuse_notify_store(struct fuse_conn *fc, unsigned int size,
17871788 num = outarg .size ;
17881789 while (num ) {
17891790 struct folio * folio ;
1790- struct page * page ;
17911791 unsigned int this_num ;
17921792
17931793 folio = filemap_grab_folio (mapping , index );
17941794 err = PTR_ERR (folio );
17951795 if (IS_ERR (folio ))
17961796 goto out_iput ;
17971797
1798- page = & folio -> page ;
17991798 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 );
18011800 if (!folio_test_uptodate (folio ) && !err && offset == 0 &&
18021801 (this_num == folio_size (folio ) || file_size == end )) {
18031802 folio_zero_segment (folio , this_num , folio_size (folio ));
@@ -2038,8 +2037,8 @@ static int fuse_notify_inc_epoch(struct fuse_conn *fc)
20382037static int fuse_notify (struct fuse_conn * fc , enum fuse_notify_code code ,
20392038 unsigned int size , struct fuse_copy_state * cs )
20402039{
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;
20432042
20442043 switch (code ) {
20452044 case FUSE_NOTIFY_POLL :
@@ -2190,7 +2189,7 @@ static ssize_t fuse_dev_do_write(struct fuse_dev *fud,
21902189 spin_unlock (& fpq -> lock );
21912190 cs -> req = req ;
21922191 if (!req -> args -> page_replace )
2193- cs -> move_pages = false;
2192+ cs -> move_folios = false;
21942193
21952194 if (oh .error )
21962195 err = nbytes != sizeof (oh ) ? - EINVAL : 0 ;
@@ -2308,7 +2307,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe,
23082307 cs .pipe = pipe ;
23092308
23102309 if (flags & SPLICE_F_MOVE )
2311- cs .move_pages = true;
2310+ cs .move_folios = true;
23122311
23132312 ret = fuse_dev_do_write (fud , & cs , len );
23142313
0 commit comments