… | |
… | |
167 | req->result = -1; |
167 | req->result = -1; |
168 | |
168 | |
169 | #if HAVE_FIEMAP |
169 | #if HAVE_FIEMAP |
170 | int count = req->int3; |
170 | int count = req->int3; |
171 | |
171 | |
172 | /* heuristic: first try with 64 extents if we don't know how many, */ |
172 | /* heuristic: first try with 72 extents if we don't know how many, */ |
173 | /* as most files have (hopefully) fewer than this many extents */ |
173 | /* as most files have (hopefully) fewer than this many extents */ |
174 | /* in fact, most should have <= 2, so maybe the 72 below is probably overkill */ |
174 | /* in fact, most should have <= 2, so the 72 below is probably overkill */ |
175 | if (count < 0) |
175 | if (count < 0) |
176 | count = 72; /* for what it's worth, 72 extents fit nicely into 4kb */ |
176 | count = 72; /* for what it's worth, 72 extents fit nicely into 4kb */ |
177 | |
177 | |
178 | for (;;) |
178 | for (;;) |
179 | { |
179 | { |
… | |
… | |
194 | return; |
194 | return; |
195 | |
195 | |
196 | if (req->int3 >= 0) |
196 | if (req->int3 >= 0) |
197 | break; /* when not autosizing we are done */ |
197 | break; /* when not autosizing we are done */ |
198 | |
198 | |
199 | if (fiemap->fm_extents [fiemap->fm_mapped_extents - 1].fe_flags & FIEMAP_EXTENT_LAST) |
199 | if (fiemap->fm_mapped_extents < count) |
200 | break; /* autosizing successful, we are done */ |
200 | /* either autosizing succeeded, |
|
|
201 | * or the file had no extents |
|
|
202 | * or we luckily had enough space */ |
|
|
203 | break; |
201 | |
204 | |
|
|
205 | /* some kernels overwrite fm_length, so just reset everything */ |
|
|
206 | fiemap->fm_start = req->offs; |
|
|
207 | fiemap->fm_length = req->size; |
202 | fiemap->fm_flags = req->int2; |
208 | fiemap->fm_flags = req->int2; |
203 | fiemap->fm_extent_count = 0; |
209 | fiemap->fm_extent_count = 0; |
204 | |
210 | |
205 | if (ioctl (req->int1, FS_IOC_FIEMAP, fiemap)) |
211 | if (ioctl (req->int1, FS_IOC_FIEMAP, fiemap)) |
206 | return; |
212 | return; |
207 | |
213 | |
|
|
214 | /* to work around a kernel bug, we allocate one more */ |
208 | count = fiemap->fm_mapped_extents; |
215 | count = fiemap->fm_mapped_extents + 1; |
209 | |
216 | |
210 | free (fiemap); |
217 | free (fiemap); |
211 | } |
218 | } |
212 | |
219 | |
213 | req->result = 0; |
220 | req->result = 0; |