--- IO-AIO/AIO.xs 2012/04/10 05:01:33 1.213 +++ 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); } @@ -985,6 +992,7 @@ const_eio (SYNC_FILE_RANGE_WAIT_AFTER) const_eio (FALLOC_FL_KEEP_SIZE) + const_eio (FALLOC_FL_PUNCH_HOLE) const_eio (READDIR_DENTS) const_eio (READDIR_DIRS_FIRST) @@ -1217,7 +1225,10 @@ { /* read: check type and grow scalar as necessary */ SvUPGRADE (data, SVt_PV); - svptr = SvGROW (data, len + dataoffset + 1); + if (SvLEN (data) >= SvCUR (data)) + svptr = SvGROW (data, len + dataoffset + 1); + else if (SvCUR (data) < len + dataoffset) + croak ("length + dataoffset outside of scalar, and cannot grow"); } { @@ -1530,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; @@ -1688,7 +1699,7 @@ RETVAL void -mmap (SV *scalar, size_t length, int prot, int flags, SV *fh, off_t offset = 0) +mmap (SV *scalar, size_t length, int prot, int flags, SV *fh = &PL_sv_undef, off_t offset = 0) PPCODE: sv_unmagic (scalar, MMAP_MAGIC); { @@ -1731,7 +1742,7 @@ CODE: { STRLEN svlen; - void *addr = SvPVbyte (scalar, svlen); + void *addr = SvPVbyte (scalar, svlen); size_t len = SvUV (length); if (offset < 0)