@@ -3493,6 +3493,63 @@ static void ext4_set_iomap(struct inode *inode, struct iomap *iomap,
3493
3493
}
3494
3494
}
3495
3495
3496
+ static int ext4_iomap_alloc (struct inode * inode , struct ext4_map_blocks * map ,
3497
+ unsigned int flags )
3498
+ {
3499
+ handle_t * handle ;
3500
+ u8 blkbits = inode -> i_blkbits ;
3501
+ int ret , dio_credits , retries = 0 ;
3502
+
3503
+ /*
3504
+ * Trim the mapping request to the maximum value that we can map at
3505
+ * once for direct I/O.
3506
+ */
3507
+ if (map -> m_len > DIO_MAX_BLOCKS )
3508
+ map -> m_len = DIO_MAX_BLOCKS ;
3509
+ dio_credits = ext4_chunk_trans_blocks (inode , map -> m_len );
3510
+
3511
+ retry :
3512
+ /*
3513
+ * Either we allocate blocks and then don't get an unwritten extent, so
3514
+ * in that case we have reserved enough credits. Or, the blocks are
3515
+ * already allocated and unwritten. In that case, the extent conversion
3516
+ * fits into the credits as well.
3517
+ */
3518
+ handle = ext4_journal_start (inode , EXT4_HT_MAP_BLOCKS , dio_credits );
3519
+ if (IS_ERR (handle ))
3520
+ return PTR_ERR (handle );
3521
+
3522
+ ret = ext4_map_blocks (handle , inode , map , EXT4_GET_BLOCKS_CREATE_ZERO );
3523
+ if (ret < 0 )
3524
+ goto journal_stop ;
3525
+
3526
+ /*
3527
+ * If we've allocated blocks beyond EOF, we need to ensure that they're
3528
+ * truncated if we crash before updating the inode size metadata within
3529
+ * ext4_iomap_end(). For faults, we don't need to do that (and cannot
3530
+ * due to orphan list operations needing an inode_lock()). If we happen
3531
+ * to instantiate blocks beyond EOF, it is because we race with a
3532
+ * truncate operation, which already has added the inode onto the
3533
+ * orphan list.
3534
+ */
3535
+ if (!(flags & IOMAP_FAULT ) && map -> m_lblk + map -> m_len >
3536
+ (i_size_read (inode ) + (1 << blkbits ) - 1 ) >> blkbits ) {
3537
+ int err ;
3538
+
3539
+ err = ext4_orphan_add (handle , inode );
3540
+ if (err < 0 )
3541
+ ret = err ;
3542
+ }
3543
+
3544
+ journal_stop :
3545
+ ext4_journal_stop (handle );
3546
+ if (ret == - ENOSPC && ext4_should_retry_alloc (inode -> i_sb , & retries ))
3547
+ goto retry ;
3548
+
3549
+ return ret ;
3550
+ }
3551
+
3552
+
3496
3553
static int ext4_iomap_begin (struct inode * inode , loff_t offset , loff_t length ,
3497
3554
unsigned flags , struct iomap * iomap , struct iomap * srcmap )
3498
3555
{
@@ -3553,62 +3610,14 @@ static int ext4_iomap_begin(struct inode *inode, loff_t offset, loff_t length,
3553
3610
}
3554
3611
}
3555
3612
} else if (flags & IOMAP_WRITE ) {
3556
- int dio_credits ;
3557
- handle_t * handle ;
3558
- int retries = 0 ;
3559
-
3560
- /* Trim mapping request to maximum we can map at once for DIO */
3561
- if (map .m_len > DIO_MAX_BLOCKS )
3562
- map .m_len = DIO_MAX_BLOCKS ;
3563
- dio_credits = ext4_chunk_trans_blocks (inode , map .m_len );
3564
- retry :
3565
- /*
3566
- * Either we allocate blocks and then we don't get unwritten
3567
- * extent so we have reserved enough credits, or the blocks
3568
- * are already allocated and unwritten and in that case
3569
- * extent conversion fits in the credits as well.
3570
- */
3571
- handle = ext4_journal_start (inode , EXT4_HT_MAP_BLOCKS ,
3572
- dio_credits );
3573
- if (IS_ERR (handle ))
3574
- return PTR_ERR (handle );
3575
-
3576
- ret = ext4_map_blocks (handle , inode , & map ,
3577
- EXT4_GET_BLOCKS_CREATE_ZERO );
3578
- if (ret < 0 ) {
3579
- ext4_journal_stop (handle );
3580
- if (ret == - ENOSPC &&
3581
- ext4_should_retry_alloc (inode -> i_sb , & retries ))
3582
- goto retry ;
3583
- return ret ;
3584
- }
3585
-
3586
- /*
3587
- * If we added blocks beyond i_size, we need to make sure they
3588
- * will get truncated if we crash before updating i_size in
3589
- * ext4_iomap_end(). For faults we don't need to do that (and
3590
- * even cannot because for orphan list operations inode_lock is
3591
- * required) - if we happen to instantiate block beyond i_size,
3592
- * it is because we race with truncate which has already added
3593
- * the inode to the orphan list.
3594
- */
3595
- if (!(flags & IOMAP_FAULT ) && first_block + map .m_len >
3596
- (i_size_read (inode ) + (1 << blkbits ) - 1 ) >> blkbits ) {
3597
- int err ;
3598
-
3599
- err = ext4_orphan_add (handle , inode );
3600
- if (err < 0 ) {
3601
- ext4_journal_stop (handle );
3602
- return err ;
3603
- }
3604
- }
3605
- ext4_journal_stop (handle );
3613
+ ret = ext4_iomap_alloc (inode , & map , flags );
3606
3614
} else {
3607
3615
ret = ext4_map_blocks (NULL , inode , & map , 0 );
3608
- if (ret < 0 )
3609
- return ret ;
3610
3616
}
3611
3617
3618
+ if (ret < 0 )
3619
+ return ret ;
3620
+
3612
3621
ext4_set_iomap (inode , iomap , & map , offset , length );
3613
3622
if (delalloc && iomap -> type == IOMAP_HOLE )
3614
3623
iomap -> type = IOMAP_DELALLOC ;
0 commit comments