@@ -679,11 +679,12 @@ static int iomap_read_folio_sync(loff_t block_start, struct folio *folio,
679
679
return submit_bio_wait (& bio );
680
680
}
681
681
682
- static int __iomap_write_begin (const struct iomap_iter * iter , loff_t pos ,
683
- size_t len , struct folio * folio )
682
+ static int __iomap_write_begin (const struct iomap_iter * iter , size_t len ,
683
+ struct folio * folio )
684
684
{
685
685
const struct iomap * srcmap = iomap_iter_srcmap (iter );
686
686
struct iomap_folio_state * ifs ;
687
+ loff_t pos = iter -> pos ;
687
688
loff_t block_size = i_blocksize (iter -> inode );
688
689
loff_t block_start = round_down (pos , block_size );
689
690
loff_t block_end = round_up (pos + len , block_size );
@@ -741,21 +742,25 @@ static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos,
741
742
return 0 ;
742
743
}
743
744
744
- static struct folio * __iomap_get_folio (struct iomap_iter * iter , loff_t pos ,
745
- size_t len )
745
+ static struct folio * __iomap_get_folio (struct iomap_iter * iter , size_t len )
746
746
{
747
747
const struct iomap_folio_ops * folio_ops = iter -> iomap .folio_ops ;
748
+ loff_t pos = iter -> pos ;
749
+
750
+ if (!mapping_large_folio_support (iter -> inode -> i_mapping ))
751
+ len = min_t (size_t , len , PAGE_SIZE - offset_in_page (pos ));
748
752
749
753
if (folio_ops && folio_ops -> get_folio )
750
754
return folio_ops -> get_folio (iter , pos , len );
751
755
else
752
756
return iomap_get_folio (iter , pos , len );
753
757
}
754
758
755
- static void __iomap_put_folio (struct iomap_iter * iter , loff_t pos , size_t ret ,
759
+ static void __iomap_put_folio (struct iomap_iter * iter , size_t ret ,
756
760
struct folio * folio )
757
761
{
758
762
const struct iomap_folio_ops * folio_ops = iter -> iomap .folio_ops ;
763
+ loff_t pos = iter -> pos ;
759
764
760
765
if (folio_ops && folio_ops -> put_folio ) {
761
766
folio_ops -> put_folio (iter -> inode , pos , ret , folio );
@@ -765,6 +770,22 @@ static void __iomap_put_folio(struct iomap_iter *iter, loff_t pos, size_t ret,
765
770
}
766
771
}
767
772
773
+ /* trim pos and bytes to within a given folio */
774
+ static loff_t iomap_trim_folio_range (struct iomap_iter * iter ,
775
+ struct folio * folio , size_t * offset , u64 * bytes )
776
+ {
777
+ loff_t pos = iter -> pos ;
778
+ size_t fsize = folio_size (folio );
779
+
780
+ WARN_ON_ONCE (pos < folio_pos (folio ));
781
+ WARN_ON_ONCE (pos >= folio_pos (folio ) + fsize );
782
+
783
+ * offset = offset_in_folio (folio , pos );
784
+ * bytes = min (* bytes , fsize - * offset );
785
+
786
+ return pos ;
787
+ }
788
+
768
789
static int iomap_write_begin_inline (const struct iomap_iter * iter ,
769
790
struct folio * folio )
770
791
{
@@ -774,25 +795,30 @@ static int iomap_write_begin_inline(const struct iomap_iter *iter,
774
795
return iomap_read_inline_data (iter , folio );
775
796
}
776
797
777
- static int iomap_write_begin (struct iomap_iter * iter , loff_t pos ,
778
- size_t len , struct folio * * foliop )
798
+ /*
799
+ * Grab and prepare a folio for write based on iter state. Returns the folio,
800
+ * offset, and length. Callers can optionally pass a max length *plen,
801
+ * otherwise init to zero.
802
+ */
803
+ static int iomap_write_begin (struct iomap_iter * iter , struct folio * * foliop ,
804
+ size_t * poffset , u64 * plen )
779
805
{
780
806
const struct iomap_folio_ops * folio_ops = iter -> iomap .folio_ops ;
781
807
const struct iomap * srcmap = iomap_iter_srcmap (iter );
808
+ loff_t pos = iter -> pos ;
809
+ u64 len = min_t (u64 , SIZE_MAX , iomap_length (iter ));
782
810
struct folio * folio ;
783
811
int status = 0 ;
784
812
813
+ len = min_not_zero (len , * plen );
785
814
BUG_ON (pos + len > iter -> iomap .offset + iter -> iomap .length );
786
815
if (srcmap != & iter -> iomap )
787
816
BUG_ON (pos + len > srcmap -> offset + srcmap -> length );
788
817
789
818
if (fatal_signal_pending (current ))
790
819
return - EINTR ;
791
820
792
- if (!mapping_large_folio_support (iter -> inode -> i_mapping ))
793
- len = min_t (size_t , len , PAGE_SIZE - offset_in_page (pos ));
794
-
795
- folio = __iomap_get_folio (iter , pos , len );
821
+ folio = __iomap_get_folio (iter , len );
796
822
if (IS_ERR (folio ))
797
823
return PTR_ERR (folio );
798
824
@@ -816,24 +842,24 @@ static int iomap_write_begin(struct iomap_iter *iter, loff_t pos,
816
842
}
817
843
}
818
844
819
- if (pos + len > folio_pos (folio ) + folio_size (folio ))
820
- len = folio_pos (folio ) + folio_size (folio ) - pos ;
845
+ pos = iomap_trim_folio_range (iter , folio , poffset , & len );
821
846
822
847
if (srcmap -> type == IOMAP_INLINE )
823
848
status = iomap_write_begin_inline (iter , folio );
824
849
else if (srcmap -> flags & IOMAP_F_BUFFER_HEAD )
825
850
status = __block_write_begin_int (folio , pos , len , NULL , srcmap );
826
851
else
827
- status = __iomap_write_begin (iter , pos , len , folio );
852
+ status = __iomap_write_begin (iter , len , folio );
828
853
829
854
if (unlikely (status ))
830
855
goto out_unlock ;
831
856
832
857
* foliop = folio ;
858
+ * plen = len ;
833
859
return 0 ;
834
860
835
861
out_unlock :
836
- __iomap_put_folio (iter , pos , 0 , folio );
862
+ __iomap_put_folio (iter , 0 , folio );
837
863
838
864
return status ;
839
865
}
@@ -883,10 +909,11 @@ static void iomap_write_end_inline(const struct iomap_iter *iter,
883
909
* Returns true if all copied bytes have been written to the pagecache,
884
910
* otherwise return false.
885
911
*/
886
- static bool iomap_write_end (struct iomap_iter * iter , loff_t pos , size_t len ,
887
- size_t copied , struct folio * folio )
912
+ static bool iomap_write_end (struct iomap_iter * iter , size_t len , size_t copied ,
913
+ struct folio * folio )
888
914
{
889
915
const struct iomap * srcmap = iomap_iter_srcmap (iter );
916
+ loff_t pos = iter -> pos ;
890
917
891
918
if (srcmap -> type == IOMAP_INLINE ) {
892
919
iomap_write_end_inline (iter , folio , pos , copied );
@@ -917,14 +944,14 @@ static int iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
917
944
struct folio * folio ;
918
945
loff_t old_size ;
919
946
size_t offset ; /* Offset into folio */
920
- size_t bytes ; /* Bytes to write to folio */
947
+ u64 bytes ; /* Bytes to write to folio */
921
948
size_t copied ; /* Bytes copied from user */
922
949
u64 written ; /* Bytes have been written */
923
- loff_t pos = iter -> pos ;
950
+ loff_t pos ;
924
951
925
952
bytes = iov_iter_count (i );
926
953
retry :
927
- offset = pos & (chunk - 1 );
954
+ offset = iter -> pos & (chunk - 1 );
928
955
bytes = min (chunk - offset , bytes );
929
956
status = balance_dirty_pages_ratelimited_flags (mapping ,
930
957
bdp_flags );
@@ -949,23 +976,21 @@ static int iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
949
976
break ;
950
977
}
951
978
952
- status = iomap_write_begin (iter , pos , bytes , & folio );
979
+ status = iomap_write_begin (iter , & folio , & offset , & bytes );
953
980
if (unlikely (status )) {
954
- iomap_write_failed (iter -> inode , pos , bytes );
981
+ iomap_write_failed (iter -> inode , iter -> pos , bytes );
955
982
break ;
956
983
}
957
984
if (iter -> iomap .flags & IOMAP_F_STALE )
958
985
break ;
959
986
960
- offset = offset_in_folio (folio , pos );
961
- if (bytes > folio_size (folio ) - offset )
962
- bytes = folio_size (folio ) - offset ;
987
+ pos = iter -> pos ;
963
988
964
989
if (mapping_writably_mapped (mapping ))
965
990
flush_dcache_folio (folio );
966
991
967
992
copied = copy_folio_from_iter_atomic (folio , offset , bytes , i );
968
- written = iomap_write_end (iter , pos , bytes , copied , folio ) ?
993
+ written = iomap_write_end (iter , bytes , copied , folio ) ?
969
994
copied : 0 ;
970
995
971
996
/*
@@ -980,7 +1005,7 @@ static int iomap_write_iter(struct iomap_iter *iter, struct iov_iter *i)
980
1005
i_size_write (iter -> inode , pos + written );
981
1006
iter -> iomap .flags |= IOMAP_F_SIZE_CHANGED ;
982
1007
}
983
- __iomap_put_folio (iter , pos , written , folio );
1008
+ __iomap_put_folio (iter , written , folio );
984
1009
985
1010
if (old_size < pos )
986
1011
pagecache_isize_extended (iter -> inode , old_size , pos );
@@ -1276,22 +1301,17 @@ static int iomap_unshare_iter(struct iomap_iter *iter)
1276
1301
do {
1277
1302
struct folio * folio ;
1278
1303
size_t offset ;
1279
- loff_t pos = iter -> pos ;
1280
1304
bool ret ;
1281
1305
1282
1306
bytes = min_t (u64 , SIZE_MAX , bytes );
1283
- status = iomap_write_begin (iter , pos , bytes , & folio );
1307
+ status = iomap_write_begin (iter , & folio , & offset , & bytes );
1284
1308
if (unlikely (status ))
1285
1309
return status ;
1286
1310
if (iomap -> flags & IOMAP_F_STALE )
1287
1311
break ;
1288
1312
1289
- offset = offset_in_folio (folio , pos );
1290
- if (bytes > folio_size (folio ) - offset )
1291
- bytes = folio_size (folio ) - offset ;
1292
-
1293
- ret = iomap_write_end (iter , pos , bytes , bytes , folio );
1294
- __iomap_put_folio (iter , pos , bytes , folio );
1313
+ ret = iomap_write_end (iter , bytes , bytes , folio );
1314
+ __iomap_put_folio (iter , bytes , folio );
1295
1315
if (WARN_ON_ONCE (!ret ))
1296
1316
return - EIO ;
1297
1317
@@ -1351,27 +1371,23 @@ static int iomap_zero_iter(struct iomap_iter *iter, bool *did_zero)
1351
1371
do {
1352
1372
struct folio * folio ;
1353
1373
size_t offset ;
1354
- loff_t pos = iter -> pos ;
1355
1374
bool ret ;
1356
1375
1357
1376
bytes = min_t (u64 , SIZE_MAX , bytes );
1358
- status = iomap_write_begin (iter , pos , bytes , & folio );
1377
+ status = iomap_write_begin (iter , & folio , & offset , & bytes );
1359
1378
if (status )
1360
1379
return status ;
1361
1380
if (iter -> iomap .flags & IOMAP_F_STALE )
1362
1381
break ;
1363
1382
1364
1383
/* warn about zeroing folios beyond eof that won't write back */
1365
1384
WARN_ON_ONCE (folio_pos (folio ) > iter -> inode -> i_size );
1366
- offset = offset_in_folio (folio , pos );
1367
- if (bytes > folio_size (folio ) - offset )
1368
- bytes = folio_size (folio ) - offset ;
1369
1385
1370
1386
folio_zero_range (folio , offset , bytes );
1371
1387
folio_mark_accessed (folio );
1372
1388
1373
- ret = iomap_write_end (iter , pos , bytes , bytes , folio );
1374
- __iomap_put_folio (iter , pos , bytes , folio );
1389
+ ret = iomap_write_end (iter , bytes , bytes , folio );
1390
+ __iomap_put_folio (iter , bytes , folio );
1375
1391
if (WARN_ON_ONCE (!ret ))
1376
1392
return - EIO ;
1377
1393
0 commit comments