28
28
#include <linux/uaccess.h>
29
29
#include <linux/fiemap.h>
30
30
#include <linux/backing-dev.h>
31
+ #include <linux/iomap.h>
31
32
#include "ext4_jbd2.h"
32
33
#include "ext4_extents.h"
33
34
#include "xattr.h"
@@ -90,9 +91,6 @@ static int ext4_split_extent_at(handle_t *handle,
90
91
int split_flag ,
91
92
int flags );
92
93
93
- static int ext4_find_delayed_extent (struct inode * inode ,
94
- struct extent_status * newes );
95
-
96
94
static int ext4_ext_trunc_restart_fn (struct inode * inode , int * dropped )
97
95
{
98
96
/*
@@ -2130,155 +2128,6 @@ int ext4_ext_insert_extent(handle_t *handle, struct inode *inode,
2130
2128
return err ;
2131
2129
}
2132
2130
2133
- static int ext4_fill_fiemap_extents (struct inode * inode ,
2134
- ext4_lblk_t block , ext4_lblk_t num ,
2135
- struct fiemap_extent_info * fieinfo )
2136
- {
2137
- struct ext4_ext_path * path = NULL ;
2138
- struct ext4_extent * ex ;
2139
- struct extent_status es ;
2140
- ext4_lblk_t next , next_del , start = 0 , end = 0 ;
2141
- ext4_lblk_t last = block + num ;
2142
- int exists , depth = 0 , err = 0 ;
2143
- unsigned int flags = 0 ;
2144
- unsigned char blksize_bits = inode -> i_sb -> s_blocksize_bits ;
2145
-
2146
- while (block < last && block != EXT_MAX_BLOCKS ) {
2147
- num = last - block ;
2148
- /* find extent for this block */
2149
- down_read (& EXT4_I (inode )-> i_data_sem );
2150
-
2151
- path = ext4_find_extent (inode , block , & path , 0 );
2152
- if (IS_ERR (path )) {
2153
- up_read (& EXT4_I (inode )-> i_data_sem );
2154
- err = PTR_ERR (path );
2155
- path = NULL ;
2156
- break ;
2157
- }
2158
-
2159
- depth = ext_depth (inode );
2160
- if (unlikely (path [depth ].p_hdr == NULL )) {
2161
- up_read (& EXT4_I (inode )-> i_data_sem );
2162
- EXT4_ERROR_INODE (inode , "path[%d].p_hdr == NULL" , depth );
2163
- err = - EFSCORRUPTED ;
2164
- break ;
2165
- }
2166
- ex = path [depth ].p_ext ;
2167
- next = ext4_ext_next_allocated_block (path );
2168
-
2169
- flags = 0 ;
2170
- exists = 0 ;
2171
- if (!ex ) {
2172
- /* there is no extent yet, so try to allocate
2173
- * all requested space */
2174
- start = block ;
2175
- end = block + num ;
2176
- } else if (le32_to_cpu (ex -> ee_block ) > block ) {
2177
- /* need to allocate space before found extent */
2178
- start = block ;
2179
- end = le32_to_cpu (ex -> ee_block );
2180
- if (block + num < end )
2181
- end = block + num ;
2182
- } else if (block >= le32_to_cpu (ex -> ee_block )
2183
- + ext4_ext_get_actual_len (ex )) {
2184
- /* need to allocate space after found extent */
2185
- start = block ;
2186
- end = block + num ;
2187
- if (end >= next )
2188
- end = next ;
2189
- } else if (block >= le32_to_cpu (ex -> ee_block )) {
2190
- /*
2191
- * some part of requested space is covered
2192
- * by found extent
2193
- */
2194
- start = block ;
2195
- end = le32_to_cpu (ex -> ee_block )
2196
- + ext4_ext_get_actual_len (ex );
2197
- if (block + num < end )
2198
- end = block + num ;
2199
- exists = 1 ;
2200
- } else {
2201
- BUG ();
2202
- }
2203
- BUG_ON (end <= start );
2204
-
2205
- if (!exists ) {
2206
- es .es_lblk = start ;
2207
- es .es_len = end - start ;
2208
- es .es_pblk = 0 ;
2209
- } else {
2210
- es .es_lblk = le32_to_cpu (ex -> ee_block );
2211
- es .es_len = ext4_ext_get_actual_len (ex );
2212
- es .es_pblk = ext4_ext_pblock (ex );
2213
- if (ext4_ext_is_unwritten (ex ))
2214
- flags |= FIEMAP_EXTENT_UNWRITTEN ;
2215
- }
2216
-
2217
- /*
2218
- * Find delayed extent and update es accordingly. We call
2219
- * it even in !exists case to find out whether es is the
2220
- * last existing extent or not.
2221
- */
2222
- next_del = ext4_find_delayed_extent (inode , & es );
2223
- if (!exists && next_del ) {
2224
- exists = 1 ;
2225
- flags |= (FIEMAP_EXTENT_DELALLOC |
2226
- FIEMAP_EXTENT_UNKNOWN );
2227
- }
2228
- up_read (& EXT4_I (inode )-> i_data_sem );
2229
-
2230
- if (unlikely (es .es_len == 0 )) {
2231
- EXT4_ERROR_INODE (inode , "es.es_len == 0" );
2232
- err = - EFSCORRUPTED ;
2233
- break ;
2234
- }
2235
-
2236
- /*
2237
- * This is possible iff next == next_del == EXT_MAX_BLOCKS.
2238
- * we need to check next == EXT_MAX_BLOCKS because it is
2239
- * possible that an extent is with unwritten and delayed
2240
- * status due to when an extent is delayed allocated and
2241
- * is allocated by fallocate status tree will track both of
2242
- * them in a extent.
2243
- *
2244
- * So we could return a unwritten and delayed extent, and
2245
- * its block is equal to 'next'.
2246
- */
2247
- if (next == next_del && next == EXT_MAX_BLOCKS ) {
2248
- flags |= FIEMAP_EXTENT_LAST ;
2249
- if (unlikely (next_del != EXT_MAX_BLOCKS ||
2250
- next != EXT_MAX_BLOCKS )) {
2251
- EXT4_ERROR_INODE (inode ,
2252
- "next extent == %u, next "
2253
- "delalloc extent = %u" ,
2254
- next , next_del );
2255
- err = - EFSCORRUPTED ;
2256
- break ;
2257
- }
2258
- }
2259
-
2260
- if (exists ) {
2261
- err = fiemap_fill_next_extent (fieinfo ,
2262
- (__u64 )es .es_lblk << blksize_bits ,
2263
- (__u64 )es .es_pblk << blksize_bits ,
2264
- (__u64 )es .es_len << blksize_bits ,
2265
- flags );
2266
- if (err < 0 )
2267
- break ;
2268
- if (err == 1 ) {
2269
- err = 0 ;
2270
- break ;
2271
- }
2272
- }
2273
-
2274
- block = es .es_lblk + es .es_len ;
2275
- }
2276
-
2277
- ext4_ext_drop_refs (path );
2278
- kfree (path );
2279
- return err ;
2280
- }
2281
-
2282
2131
static int ext4_fill_es_cache_info (struct inode * inode ,
2283
2132
ext4_lblk_t block , ext4_lblk_t num ,
2284
2133
struct fiemap_extent_info * fieinfo )
@@ -4927,64 +4776,13 @@ int ext4_convert_unwritten_io_end_vec(handle_t *handle, ext4_io_end_t *io_end)
4927
4776
return ret < 0 ? ret : err ;
4928
4777
}
4929
4778
4930
- /*
4931
- * If newes is not existing extent (newes->ec_pblk equals zero) find
4932
- * delayed extent at start of newes and update newes accordingly and
4933
- * return start of the next delayed extent.
4934
- *
4935
- * If newes is existing extent (newes->ec_pblk is not equal zero)
4936
- * return start of next delayed extent or EXT_MAX_BLOCKS if no delayed
4937
- * extent found. Leave newes unmodified.
4938
- */
4939
- static int ext4_find_delayed_extent (struct inode * inode ,
4940
- struct extent_status * newes )
4941
- {
4942
- struct extent_status es ;
4943
- ext4_lblk_t block , next_del ;
4944
-
4945
- if (newes -> es_pblk == 0 ) {
4946
- ext4_es_find_extent_range (inode , & ext4_es_is_delayed ,
4947
- newes -> es_lblk ,
4948
- newes -> es_lblk + newes -> es_len - 1 ,
4949
- & es );
4950
-
4951
- /*
4952
- * No extent in extent-tree contains block @newes->es_pblk,
4953
- * then the block may stay in 1)a hole or 2)delayed-extent.
4954
- */
4955
- if (es .es_len == 0 )
4956
- /* A hole found. */
4957
- return 0 ;
4958
-
4959
- if (es .es_lblk > newes -> es_lblk ) {
4960
- /* A hole found. */
4961
- newes -> es_len = min (es .es_lblk - newes -> es_lblk ,
4962
- newes -> es_len );
4963
- return 0 ;
4964
- }
4965
-
4966
- newes -> es_len = es .es_lblk + es .es_len - newes -> es_lblk ;
4967
- }
4968
-
4969
- block = newes -> es_lblk + newes -> es_len ;
4970
- ext4_es_find_extent_range (inode , & ext4_es_is_delayed , block ,
4971
- EXT_MAX_BLOCKS , & es );
4972
- if (es .es_len == 0 )
4973
- next_del = EXT_MAX_BLOCKS ;
4974
- else
4975
- next_del = es .es_lblk ;
4976
-
4977
- return next_del ;
4978
- }
4979
-
4980
- static int ext4_xattr_fiemap (struct inode * inode ,
4981
- struct fiemap_extent_info * fieinfo )
4779
+ static int ext4_iomap_xattr_fiemap (struct inode * inode , struct iomap * iomap )
4982
4780
{
4983
4781
__u64 physical = 0 ;
4984
- __u64 length ;
4985
- __u32 flags = FIEMAP_EXTENT_LAST ;
4782
+ __u64 length = 0 ;
4986
4783
int blockbits = inode -> i_sb -> s_blocksize_bits ;
4987
4784
int error = 0 ;
4785
+ u16 iomap_type ;
4988
4786
4989
4787
/* in-inode? */
4990
4788
if (ext4_test_inode_state (inode , EXT4_STATE_XATTR )) {
@@ -4999,40 +4797,49 @@ static int ext4_xattr_fiemap(struct inode *inode,
4999
4797
EXT4_I (inode )-> i_extra_isize ;
5000
4798
physical += offset ;
5001
4799
length = EXT4_SB (inode -> i_sb )-> s_inode_size - offset ;
5002
- flags |= FIEMAP_EXTENT_DATA_INLINE ;
5003
4800
brelse (iloc .bh );
5004
- } else { /* external block */
4801
+ iomap_type = IOMAP_INLINE ;
4802
+ } else if (EXT4_I (inode )-> i_file_acl ) { /* external block */
5005
4803
physical = (__u64 )EXT4_I (inode )-> i_file_acl << blockbits ;
5006
4804
length = inode -> i_sb -> s_blocksize ;
4805
+ iomap_type = IOMAP_MAPPED ;
4806
+ } else {
4807
+ /* no in-inode or external block for xattr, so return -ENOENT */
4808
+ error = - ENOENT ;
4809
+ goto out ;
5007
4810
}
5008
4811
5009
- if (physical )
5010
- error = fiemap_fill_next_extent (fieinfo , 0 , physical ,
5011
- length , flags );
5012
- return (error < 0 ? error : 0 );
4812
+ iomap -> addr = physical ;
4813
+ iomap -> offset = 0 ;
4814
+ iomap -> length = length ;
4815
+ iomap -> type = iomap_type ;
4816
+ iomap -> flags = 0 ;
4817
+ out :
4818
+ return error ;
5013
4819
}
5014
4820
5015
- static int _ext4_fiemap (struct inode * inode ,
5016
- struct fiemap_extent_info * fieinfo ,
5017
- __u64 start , __u64 len ,
5018
- int (* fill )(struct inode * , ext4_lblk_t ,
5019
- ext4_lblk_t ,
5020
- struct fiemap_extent_info * ))
4821
+ static int ext4_iomap_xattr_begin (struct inode * inode , loff_t offset ,
4822
+ loff_t length , unsigned flags ,
4823
+ struct iomap * iomap , struct iomap * srcmap )
5021
4824
{
5022
- ext4_lblk_t start_blk ;
5023
- u32 ext4_fiemap_flags = FIEMAP_FLAG_SYNC |FIEMAP_FLAG_XATTR ;
4825
+ int error ;
5024
4826
5025
- int error = 0 ;
5026
-
5027
- if (ext4_has_inline_data (inode )) {
5028
- int has_inline = 1 ;
4827
+ error = ext4_iomap_xattr_fiemap (inode , iomap );
4828
+ if (error == 0 && (offset >= iomap -> length ))
4829
+ error = - ENOENT ;
4830
+ return error ;
4831
+ }
5029
4832
5030
- error = ext4_inline_data_fiemap (inode , fieinfo , & has_inline ,
5031
- start , len );
4833
+ static const struct iomap_ops ext4_iomap_xattr_ops = {
4834
+ .iomap_begin = ext4_iomap_xattr_begin ,
4835
+ };
5032
4836
5033
- if (has_inline )
5034
- return error ;
5035
- }
4837
+ static int _ext4_fiemap (struct inode * inode , struct fiemap_extent_info * fieinfo ,
4838
+ __u64 start , __u64 len , bool from_es_cache )
4839
+ {
4840
+ ext4_lblk_t start_blk ;
4841
+ u32 ext4_fiemap_flags = FIEMAP_FLAG_SYNC | FIEMAP_FLAG_XATTR ;
4842
+ int error = 0 ;
5036
4843
5037
4844
if (fieinfo -> fi_flags & FIEMAP_FLAG_CACHE ) {
5038
4845
error = ext4_ext_precache (inode );
@@ -5041,19 +4848,19 @@ static int _ext4_fiemap(struct inode *inode,
5041
4848
fieinfo -> fi_flags &= ~FIEMAP_FLAG_CACHE ;
5042
4849
}
5043
4850
5044
- /* fallback to generic here if not in extents fmt */
5045
- if (!(ext4_test_inode_flag (inode , EXT4_INODE_EXTENTS )) & &
5046
- fill == ext4_fill_fiemap_extents )
5047
- return generic_block_fiemap (inode , fieinfo , start , len ,
5048
- ext4_get_block );
5049
-
5050
- if (fill == ext4_fill_es_cache_info )
4851
+ if (from_es_cache )
5051
4852
ext4_fiemap_flags &= FIEMAP_FLAG_XATTR ;
4853
+
5052
4854
if (fiemap_check_flags (fieinfo , ext4_fiemap_flags ))
5053
4855
return - EBADR ;
5054
4856
5055
4857
if (fieinfo -> fi_flags & FIEMAP_FLAG_XATTR ) {
5056
- error = ext4_xattr_fiemap (inode , fieinfo );
4858
+ fieinfo -> fi_flags &= ~FIEMAP_FLAG_XATTR ;
4859
+ error = iomap_fiemap (inode , fieinfo , start , len ,
4860
+ & ext4_iomap_xattr_ops );
4861
+ } else if (!from_es_cache ) {
4862
+ error = iomap_fiemap (inode , fieinfo , start , len ,
4863
+ & ext4_iomap_report_ops );
5057
4864
} else {
5058
4865
ext4_lblk_t len_blks ;
5059
4866
__u64 last_blk ;
@@ -5068,16 +4875,16 @@ static int _ext4_fiemap(struct inode *inode,
5068
4875
* Walk the extent tree gathering extent information
5069
4876
* and pushing extents back to the user.
5070
4877
*/
5071
- error = fill (inode , start_blk , len_blks , fieinfo );
4878
+ error = ext4_fill_es_cache_info (inode , start_blk , len_blks ,
4879
+ fieinfo );
5072
4880
}
5073
4881
return error ;
5074
4882
}
5075
4883
5076
4884
int ext4_fiemap (struct inode * inode , struct fiemap_extent_info * fieinfo ,
5077
4885
__u64 start , __u64 len )
5078
4886
{
5079
- return _ext4_fiemap (inode , fieinfo , start , len ,
5080
- ext4_fill_fiemap_extents );
4887
+ return _ext4_fiemap (inode , fieinfo , start , len , false);
5081
4888
}
5082
4889
5083
4890
int ext4_get_es_cache (struct inode * inode , struct fiemap_extent_info * fieinfo ,
@@ -5093,8 +4900,7 @@ int ext4_get_es_cache(struct inode *inode, struct fiemap_extent_info *fieinfo,
5093
4900
return 0 ;
5094
4901
}
5095
4902
5096
- return _ext4_fiemap (inode , fieinfo , start , len ,
5097
- ext4_fill_es_cache_info );
4903
+ return _ext4_fiemap (inode , fieinfo , start , len , true);
5098
4904
}
5099
4905
5100
4906
0 commit comments