@@ -457,6 +457,33 @@ bool iomap_is_partially_uptodate(struct folio *folio, size_t from, size_t count)
457
457
}
458
458
EXPORT_SYMBOL_GPL (iomap_is_partially_uptodate );
459
459
460
+ /**
461
+ * iomap_get_folio - get a folio reference for writing
462
+ * @iter: iteration structure
463
+ * @pos: start offset of write
464
+ *
465
+ * Returns a locked reference to the folio at @pos, or an error pointer if the
466
+ * folio could not be obtained.
467
+ */
468
+ struct folio * iomap_get_folio (struct iomap_iter * iter , loff_t pos )
469
+ {
470
+ unsigned fgp = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE | FGP_NOFS ;
471
+ struct folio * folio ;
472
+
473
+ if (iter -> flags & IOMAP_NOWAIT )
474
+ fgp |= FGP_NOWAIT ;
475
+
476
+ folio = __filemap_get_folio (iter -> inode -> i_mapping , pos >> PAGE_SHIFT ,
477
+ fgp , mapping_gfp_mask (iter -> inode -> i_mapping ));
478
+ if (folio )
479
+ return folio ;
480
+
481
+ if (iter -> flags & IOMAP_NOWAIT )
482
+ return ERR_PTR (- EAGAIN );
483
+ return ERR_PTR (- ENOMEM );
484
+ }
485
+ EXPORT_SYMBOL_GPL (iomap_get_folio );
486
+
460
487
bool iomap_release_folio (struct folio * folio , gfp_t gfp_flags )
461
488
{
462
489
trace_iomap_release_folio (folio -> mapping -> host , folio_pos (folio ),
@@ -575,6 +602,30 @@ static int __iomap_write_begin(const struct iomap_iter *iter, loff_t pos,
575
602
return 0 ;
576
603
}
577
604
605
+ static struct folio * __iomap_get_folio (struct iomap_iter * iter , loff_t pos ,
606
+ size_t len )
607
+ {
608
+ const struct iomap_folio_ops * folio_ops = iter -> iomap .folio_ops ;
609
+
610
+ if (folio_ops && folio_ops -> get_folio )
611
+ return folio_ops -> get_folio (iter , pos , len );
612
+ else
613
+ return iomap_get_folio (iter , pos );
614
+ }
615
+
616
+ static void __iomap_put_folio (struct iomap_iter * iter , loff_t pos , size_t ret ,
617
+ struct folio * folio )
618
+ {
619
+ const struct iomap_folio_ops * folio_ops = iter -> iomap .folio_ops ;
620
+
621
+ if (folio_ops && folio_ops -> put_folio ) {
622
+ folio_ops -> put_folio (iter -> inode , pos , ret , folio );
623
+ } else {
624
+ folio_unlock (folio );
625
+ folio_put (folio );
626
+ }
627
+ }
628
+
578
629
static int iomap_write_begin_inline (const struct iomap_iter * iter ,
579
630
struct folio * folio )
580
631
{
@@ -587,15 +638,11 @@ static int iomap_write_begin_inline(const struct iomap_iter *iter,
587
638
static int iomap_write_begin (struct iomap_iter * iter , loff_t pos ,
588
639
size_t len , struct folio * * foliop )
589
640
{
590
- const struct iomap_page_ops * page_ops = iter -> iomap .page_ops ;
641
+ const struct iomap_folio_ops * folio_ops = iter -> iomap .folio_ops ;
591
642
const struct iomap * srcmap = iomap_iter_srcmap (iter );
592
643
struct folio * folio ;
593
- unsigned fgp = FGP_LOCK | FGP_WRITE | FGP_CREAT | FGP_STABLE | FGP_NOFS ;
594
644
int status = 0 ;
595
645
596
- if (iter -> flags & IOMAP_NOWAIT )
597
- fgp |= FGP_NOWAIT ;
598
-
599
646
BUG_ON (pos + len > iter -> iomap .offset + iter -> iomap .length );
600
647
if (srcmap != & iter -> iomap )
601
648
BUG_ON (pos + len > srcmap -> offset + srcmap -> length );
@@ -606,18 +653,9 @@ static int iomap_write_begin(struct iomap_iter *iter, loff_t pos,
606
653
if (!mapping_large_folio_support (iter -> inode -> i_mapping ))
607
654
len = min_t (size_t , len , PAGE_SIZE - offset_in_page (pos ));
608
655
609
- if (page_ops && page_ops -> page_prepare ) {
610
- status = page_ops -> page_prepare (iter -> inode , pos , len );
611
- if (status )
612
- return status ;
613
- }
614
-
615
- folio = __filemap_get_folio (iter -> inode -> i_mapping , pos >> PAGE_SHIFT ,
616
- fgp , mapping_gfp_mask (iter -> inode -> i_mapping ));
617
- if (!folio ) {
618
- status = (iter -> flags & IOMAP_NOWAIT ) ? - EAGAIN : - ENOMEM ;
619
- goto out_no_page ;
620
- }
656
+ folio = __iomap_get_folio (iter , pos , len );
657
+ if (IS_ERR (folio ))
658
+ return PTR_ERR (folio );
621
659
622
660
/*
623
661
* Now we have a locked folio, before we do anything with it we need to
@@ -629,9 +667,9 @@ static int iomap_write_begin(struct iomap_iter *iter, loff_t pos,
629
667
* could do the wrong thing here (zero a page range incorrectly or fail
630
668
* to zero) and corrupt data.
631
669
*/
632
- if (page_ops && page_ops -> iomap_valid ) {
633
- bool iomap_valid = page_ops -> iomap_valid (iter -> inode ,
634
- & iter -> iomap );
670
+ if (folio_ops && folio_ops -> iomap_valid ) {
671
+ bool iomap_valid = folio_ops -> iomap_valid (iter -> inode ,
672
+ & iter -> iomap );
635
673
if (!iomap_valid ) {
636
674
iter -> iomap .flags |= IOMAP_F_STALE ;
637
675
status = 0 ;
@@ -656,13 +694,9 @@ static int iomap_write_begin(struct iomap_iter *iter, loff_t pos,
656
694
return 0 ;
657
695
658
696
out_unlock :
659
- folio_unlock (folio );
660
- folio_put (folio );
697
+ __iomap_put_folio (iter , pos , 0 , folio );
661
698
iomap_write_failed (iter -> inode , pos , len );
662
699
663
- out_no_page :
664
- if (page_ops && page_ops -> page_done )
665
- page_ops -> page_done (iter -> inode , pos , 0 , NULL );
666
700
return status ;
667
701
}
668
702
@@ -712,7 +746,6 @@ static size_t iomap_write_end_inline(const struct iomap_iter *iter,
712
746
static size_t iomap_write_end (struct iomap_iter * iter , loff_t pos , size_t len ,
713
747
size_t copied , struct folio * folio )
714
748
{
715
- const struct iomap_page_ops * page_ops = iter -> iomap .page_ops ;
716
749
const struct iomap * srcmap = iomap_iter_srcmap (iter );
717
750
loff_t old_size = iter -> inode -> i_size ;
718
751
size_t ret ;
@@ -735,14 +768,10 @@ static size_t iomap_write_end(struct iomap_iter *iter, loff_t pos, size_t len,
735
768
i_size_write (iter -> inode , pos + ret );
736
769
iter -> iomap .flags |= IOMAP_F_SIZE_CHANGED ;
737
770
}
738
- folio_unlock ( folio );
771
+ __iomap_put_folio ( iter , pos , ret , folio );
739
772
740
773
if (old_size < pos )
741
774
pagecache_isize_extended (iter -> inode , old_size , pos );
742
- if (page_ops && page_ops -> page_done )
743
- page_ops -> page_done (iter -> inode , pos , ret , & folio -> page );
744
- folio_put (folio );
745
-
746
775
if (ret < len )
747
776
iomap_write_failed (iter -> inode , pos + ret , len - ret );
748
777
return ret ;
0 commit comments