Lines 20-34
Link Here
|
20 |
#include <stdio.h> |
20 |
#include <stdio.h> |
21 |
#include <sys/types.h> |
21 |
#include <sys/types.h> |
22 |
#include <sys/ioctl.h> |
22 |
#include <sys/ioctl.h> |
|
|
23 |
#include <sys/utsname.h> |
23 |
#include <assert.h> |
24 |
#include <assert.h> |
24 |
|
25 |
|
25 |
#include "system.h" |
26 |
#include "system.h" |
26 |
#include "extent-scan.h" |
27 |
#include "extent-scan.h" |
|
|
28 |
#include "xstrtol.h" |
27 |
|
29 |
|
28 |
#ifndef HAVE_FIEMAP |
30 |
#ifndef HAVE_FIEMAP |
29 |
# include "fiemap.h" |
31 |
# include "fiemap.h" |
30 |
#endif |
32 |
#endif |
31 |
|
33 |
|
|
|
34 |
/* Work around Linux kernel issues on BTRFS and EXT4 before 2.6.39. |
35 |
FIXME: remove in 2013, or whenever we're pretty confident |
36 |
that the offending, unpatched kernels are no longer in use. */ |
37 |
static bool |
38 |
extent_need_sync (void) |
39 |
{ |
40 |
static int need_sync = -1; |
41 |
|
42 |
if (need_sync == -1) |
43 |
{ |
44 |
struct utsname name; |
45 |
need_sync = 0; /* No workaround by default. */ |
46 |
|
47 |
#ifdef __linux__ |
48 |
if (uname (&name) != -1 && strncmp (name.release, "2.6.", 4) == 0) |
49 |
{ |
50 |
unsigned long val; |
51 |
if (xstrtoul (name.release + 4, NULL, 10, &val, NULL) == LONGINT_OK) |
52 |
{ |
53 |
if (val < 39) |
54 |
need_sync = 1; |
55 |
} |
56 |
} |
57 |
#endif |
58 |
} |
59 |
|
60 |
return need_sync; |
61 |
} |
62 |
|
32 |
/* Allocate space for struct extent_scan, initialize the entries if |
63 |
/* Allocate space for struct extent_scan, initialize the entries if |
33 |
necessary and return it as the input argument of extent_scan_read(). */ |
64 |
necessary and return it as the input argument of extent_scan_read(). */ |
34 |
extern void |
65 |
extern void |
Lines 39-44
extent_scan_init (int src_fd, struct extent_scan *scan)
Link Here
|
39 |
scan->scan_start = 0; |
70 |
scan->scan_start = 0; |
40 |
scan->initial_scan_failed = false; |
71 |
scan->initial_scan_failed = false; |
41 |
scan->hit_final_extent = false; |
72 |
scan->hit_final_extent = false; |
|
|
73 |
scan->fm_flags = extent_need_sync () ? FIEMAP_FLAG_SYNC : 0; |
42 |
} |
74 |
} |
43 |
|
75 |
|
44 |
#ifdef __linux__ |
76 |
#ifdef __linux__ |
Lines 62-68
extent_scan_read (struct extent_scan *scan)
Link Here
|
62 |
memset (&fiemap_buf, 0, sizeof fiemap_buf); |
94 |
memset (&fiemap_buf, 0, sizeof fiemap_buf); |
63 |
|
95 |
|
64 |
fiemap->fm_start = scan->scan_start; |
96 |
fiemap->fm_start = scan->scan_start; |
65 |
fiemap->fm_flags = FIEMAP_FLAG_SYNC; |
97 |
fiemap->fm_flags = scan->fm_flags; |
66 |
fiemap->fm_extent_count = count; |
98 |
fiemap->fm_extent_count = count; |
67 |
fiemap->fm_length = FIEMAP_MAX_OFFSET - scan->scan_start; |
99 |
fiemap->fm_length = FIEMAP_MAX_OFFSET - scan->scan_start; |
68 |
|
100 |
|