--- IO-AIO/AIO.xs 2012/07/25 16:12:28 1.216 +++ IO-AIO/AIO.xs 2012/07/27 18:43:25 1.219 @@ -169,9 +169,9 @@ #if HAVE_FIEMAP int count = req->int3; - /* heuristic: first try with 64 extents if we don't know how many, */ + /* heuristic: first try with 72 extents if we don't know how many, */ /* as most files have (hopefully) fewer than this many extents */ - /* in fact, most should have <= 2, so maybe the 72 below is probably overkill */ + /* in fact, most should have <= 2, so the 72 below is probably overkill */ if (count < 0) count = 72; /* for what it's worth, 72 extents fit nicely into 4kb */ @@ -196,16 +196,23 @@ if (req->int3 >= 0) break; /* when not autosizing we are done */ - if (fiemap->fm_extents [fiemap->fm_mapped_extents - 1].fe_flags & FIEMAP_EXTENT_LAST) - break; /* autosizing successful, we are done */ + if (fiemap->fm_mapped_extents < count) + /* either autosizing succeeded, + * or the file had no extents + * or we luckily had enough space */ + break; + /* some kernels overwrite fm_length, so just reset everything */ + fiemap->fm_start = req->offs; + fiemap->fm_length = req->size; fiemap->fm_flags = req->int2; fiemap->fm_extent_count = 0; if (ioctl (req->int1, FS_IOC_FIEMAP, fiemap)) return; - count = fiemap->fm_mapped_extents; + /* to work around a kernel bug, we allocate one more */ + count = fiemap->fm_mapped_extents + 1; free (fiemap); } @@ -1534,7 +1541,7 @@ aio_fiemap (SV *fh, off_t start, SV *length, U32 flags, SV *count, SV *callback=&PL_sv_undef) PPCODE: { - int fd = s_fileno_croak (fh, 0); + int fd = s_fileno_croak (fh, 0); dREQ; req->type = EIO_CUSTOM;