uint64_t last_ext_len = 0;
uint64_t last_read_size = 0;
- open_extent_scan (src_fd, &scan);
+ extent_scan_init (src_fd, &scan);
do
{
- bool ok = get_extents_info (&scan);
+ bool ok = extent_scan_read (&scan);
if (! ok)
{
if (scan.hit_final_extent)
if (scan.initial_scan_failed)
{
- close_extent_scan (&scan);
*require_normal_copy = true;
return false;
}
}
/* Release the space allocated to scan->ext_info. */
- free_extents_info (&scan);
- } while (! scan.hit_final_extent);
+ extent_scan_free (&scan);
- /* Do nothing now. */
- close_extent_scan (&scan);
+ }
+ while (! scan.hit_final_extent);
/* If a file ends up with holes, the sum of the last extent logical offset
and the read-returned size or the last extent length will be shorter than
#endif
/* Allocate space for struct extent_scan, initialize the entries if
- necessary and return it as the input argument of get_extents_info(). */
+ necessary and return it as the input argument of extent_scan_read(). */
extern void
-open_extent_scan (int src_fd, struct extent_scan *scan)
+extent_scan_init (int src_fd, struct extent_scan *scan)
{
scan->fd = src_fd;
scan->ei_count = 0;
/* Call ioctl(2) with FS_IOC_FIEMAP (available in linux 2.6.27) to
obtain a map of file extents excluding holes. */
extern bool
-get_extents_info (struct extent_scan *scan)
+extent_scan_read (struct extent_scan *scan)
{
union { struct fiemap f; char c[4096]; } fiemap_buf;
struct fiemap *fiemap = &fiemap_buf.f;
struct fiemap_extent *fm_extents = &fiemap->fm_extents[0];
enum { count = (sizeof fiemap_buf - sizeof *fiemap) / sizeof *fm_extents };
verify (count != 0);
- unsigned int i;
/* This is required at least to initialize fiemap->fm_start,
but also serves (in mid 2010) to appease valgrind, which
scan->ei_count = fiemap->fm_mapped_extents;
scan->ext_info = xnmalloc (scan->ei_count, sizeof (struct extent_info));
+ unsigned int i;
for (i = 0; i < scan->ei_count; i++)
{
assert (fm_extents[i].fe_logical <= OFF_T_MAX);
return true;
}
#else
-extern bool get_extents_info (ignored) { errno = ENOTSUP; return false; }
+extern bool extent_scan_read (ignored) { errno = ENOTSUP; return false; }
#endif
#ifndef EXTENT_SCAN_H
# define EXTENT_SCAN_H
-/* Structure used to reserve information of each extent. */
+/* Structure used to store information of each extent. */
struct extent_info
{
/* Logical offset of an extent. */
/* How many extent info returned for a scan. */
uint32_t ei_count;
- /* If true, fall back to a normal copy, either
- set by the failure of ioctl(2) for FIEMAP or
- lseek(2) with SEEK_DATA. */
+ /* If true, fall back to a normal copy, either set by the
+ failure of ioctl(2) for FIEMAP or lseek(2) with SEEK_DATA. */
bool initial_scan_failed;
- /* If ture, the total extent scan per file has been finished. */
+ /* If true, the total extent scan per file has been finished. */
bool hit_final_extent;
- /* Extent information. */
+ /* Extent information: a malloc'd array of ei_count structs. */
struct extent_info *ext_info;
};
void
-open_extent_scan (int src_fd, struct extent_scan *scan);
+extent_scan_init (int src_fd, struct extent_scan *scan);
bool
-get_extents_info (struct extent_scan *scan);
+extent_scan_read (struct extent_scan *scan);
-#define free_extents_info(ext_scan) free ((ext_scan)->ext_info)
-#define close_extent_scan(ext_scan) /* empty */
+static inline void
+extent_scan_free (struct extent_scan *scan)
+{
+ free (scan->ext_info);
+}
#endif /* EXTENT_SCAN_H */