@@ -2054,34 +2054,49 @@ bool ext4_is_pending(struct inode *inode, ext4_lblk_t lblk)
2054
2054
}
2055
2055
2056
2056
/*
2057
- * ext4_es_insert_delayed_block - adds a delayed block to the extents status
2058
- * tree, adding a pending reservation where
2059
- * needed
2057
+ * ext4_es_insert_delayed_extent - adds some delayed blocks to the extents
2058
+ * status tree, adding a pending reservation
2059
+ * where needed
2060
2060
*
2061
2061
* @inode - file containing the newly added block
2062
- * @lblk - logical block to be added
2063
- * @allocated - indicates whether a physical cluster has been allocated for
2064
- * the logical cluster that contains the block
2062
+ * @lblk - start logical block to be added
2063
+ * @len - length of blocks to be added
2064
+ * @lclu_allocated/end_allocated - indicates whether a physical cluster has
2065
+ * been allocated for the logical cluster
2066
+ * that contains the start/end block. Note that
2067
+ * end_allocated should always be set to false
2068
+ * if the start and the end block are in the
2069
+ * same cluster
2065
2070
*/
2066
- void ext4_es_insert_delayed_block (struct inode * inode , ext4_lblk_t lblk ,
2067
- bool allocated )
2071
+ void ext4_es_insert_delayed_extent (struct inode * inode , ext4_lblk_t lblk ,
2072
+ ext4_lblk_t len , bool lclu_allocated ,
2073
+ bool end_allocated )
2068
2074
{
2075
+ struct ext4_sb_info * sbi = EXT4_SB (inode -> i_sb );
2069
2076
struct extent_status newes ;
2077
+ ext4_lblk_t end = lblk + len - 1 ;
2070
2078
int err1 = 0 , err2 = 0 , err3 = 0 ;
2071
2079
struct extent_status * es1 = NULL ;
2072
2080
struct extent_status * es2 = NULL ;
2073
- struct pending_reservation * pr = NULL ;
2081
+ struct pending_reservation * pr1 = NULL ;
2082
+ struct pending_reservation * pr2 = NULL ;
2074
2083
2075
2084
if (EXT4_SB (inode -> i_sb )-> s_mount_state & EXT4_FC_REPLAY )
2076
2085
return ;
2077
2086
2078
- es_debug ("add [%u/1) delayed to extent status tree of inode %lu\n" ,
2079
- lblk , inode -> i_ino );
2087
+ es_debug ("add [%u/%u) delayed to extent status tree of inode %lu\n" ,
2088
+ lblk , len , inode -> i_ino );
2089
+ if (!len )
2090
+ return ;
2091
+
2092
+ WARN_ON_ONCE ((EXT4_B2C (sbi , lblk ) == EXT4_B2C (sbi , end )) &&
2093
+ end_allocated );
2080
2094
2081
2095
newes .es_lblk = lblk ;
2082
- newes .es_len = 1 ;
2096
+ newes .es_len = len ;
2083
2097
ext4_es_store_pblock_status (& newes , ~0 , EXTENT_STATUS_DELAYED );
2084
- trace_ext4_es_insert_delayed_block (inode , & newes , allocated );
2098
+ trace_ext4_es_insert_delayed_extent (inode , & newes , lclu_allocated ,
2099
+ end_allocated );
2085
2100
2086
2101
ext4_es_insert_extent_check (inode , & newes );
2087
2102
@@ -2090,11 +2105,15 @@ void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
2090
2105
es1 = __es_alloc_extent (true);
2091
2106
if ((err1 || err2 ) && !es2 )
2092
2107
es2 = __es_alloc_extent (true);
2093
- if ((err1 || err2 || err3 ) && allocated && !pr )
2094
- pr = __alloc_pending (true);
2108
+ if (err1 || err2 || err3 ) {
2109
+ if (lclu_allocated && !pr1 )
2110
+ pr1 = __alloc_pending (true);
2111
+ if (end_allocated && !pr2 )
2112
+ pr2 = __alloc_pending (true);
2113
+ }
2095
2114
write_lock (& EXT4_I (inode )-> i_es_lock );
2096
2115
2097
- err1 = __es_remove_extent (inode , lblk , lblk , NULL , es1 );
2116
+ err1 = __es_remove_extent (inode , lblk , end , NULL , es1 );
2098
2117
if (err1 != 0 )
2099
2118
goto error ;
2100
2119
/* Free preallocated extent if it didn't get used. */
@@ -2114,13 +2133,22 @@ void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk,
2114
2133
es2 = NULL ;
2115
2134
}
2116
2135
2117
- if (allocated ) {
2118
- err3 = __insert_pending (inode , lblk , & pr );
2136
+ if (lclu_allocated ) {
2137
+ err3 = __insert_pending (inode , lblk , & pr1 );
2119
2138
if (err3 != 0 )
2120
2139
goto error ;
2121
- if (pr ) {
2122
- __free_pending (pr );
2123
- pr = NULL ;
2140
+ if (pr1 ) {
2141
+ __free_pending (pr1 );
2142
+ pr1 = NULL ;
2143
+ }
2144
+ }
2145
+ if (end_allocated ) {
2146
+ err3 = __insert_pending (inode , end , & pr2 );
2147
+ if (err3 != 0 )
2148
+ goto error ;
2149
+ if (pr2 ) {
2150
+ __free_pending (pr2 );
2151
+ pr2 = NULL ;
2124
2152
}
2125
2153
}
2126
2154
error :
0 commit comments