* [PATCH 1/4] filefrag: exit with error code on failure
@ 2013-12-17 1:05 Andreas Dilger
2013-12-17 1:05 ` [PATCH 2/4] filefrag: improve extent flags printing Andreas Dilger
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Andreas Dilger @ 2013-12-17 1:05 UTC (permalink / raw)
To: tytso; +Cc: linux-ext4, Andreas Dilger
If an error is hit during filefrag operation, it should continue to
run if multiple files are specified on the command-line, but exit
with a non-zero value, so that callers can determine that some error
was hit during file processing, similar to tar and other utilities.
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
---
misc/filefrag.c | 102 ++++++++++++++++++++++++++++++++++++-------------------
1 files changed, 67 insertions(+), 35 deletions(-)
diff --git a/misc/filefrag.c b/misc/filefrag.c
index a050a22..18dc1e5 100644
--- a/misc/filefrag.c
+++ b/misc/filefrag.c
@@ -103,12 +103,8 @@ static int get_bmap(int fd, unsigned long block, unsigned long *phy_blk)
b = block;
ret = ioctl(fd, FIBMAP, &b); /* FIBMAP takes pointer to integer */
- if (ret < 0) {
- if (errno == EPERM) {
- fprintf(stderr, "No permission to use FIBMAP ioctl; "
- "must have root privileges\n");
- }
- }
+ if (ret < 0)
+ return -errno;
*phy_blk = b;
return ret;
@@ -191,7 +187,6 @@ static int filefrag_fiemap(int fd, int blk_shift, int *num_extents,
unsigned long long expected = 0;
unsigned long flags = 0;
unsigned int i;
- static int fiemap_incompat_printed;
int fiemap_header_printed = 0;
int tot_extents = 0, n = 0;
int last = 0;
@@ -211,9 +206,13 @@ static int filefrag_fiemap(int fd, int blk_shift, int *num_extents,
fiemap->fm_extent_count = count;
rc = ioctl(fd, FS_IOC_FIEMAP, (unsigned long) fiemap);
if (rc < 0) {
- if (errno == EBADR && fiemap_incompat_printed == 0) {
- printf("FIEMAP failed with unsupported "
- "flags %x\n", fiemap->fm_flags);
+ static int fiemap_incompat_printed;
+
+ rc = -errno;
+ if (rc == -EBADR && !fiemap_incompat_printed) {
+ fprintf(stderr, "FIEMAP failed with unknown "
+ "flags %x\n",
+ fiemap->fm_flags);
fiemap_incompat_printed = 1;
}
return rc;
@@ -293,8 +292,23 @@ static int filefrag_fibmap(int fd, int blk_shift, int *num_extents,
last_block++;
}
rc = get_bmap(fd, i, &block);
- if (rc < 0)
+ if (rc < 0) {
+ if (rc == -EINVAL || rc == -ENOTTY) {
+ fprintf(stderr, "FIBMAP unsupported\n");
+ } else if (rc == -EPERM) {
+ static int fibmap_perm_printed;
+
+ if (!fibmap_perm_printed) {
+ fprintf(stderr, "FIBMAP requires "
+ "root privileges\n");
+ fibmap_perm_printed = 1;
+ }
+ } else {
+ fprintf(stderr, "FIBMAP error: %s",
+ strerror(errno));
+ }
return rc;
+ }
if (block == 0)
continue;
if (*num_extents == 0) {
@@ -331,7 +345,7 @@ static int filefrag_fibmap(int fd, int blk_shift, int *num_extents,
return count;
}
-static void frag_report(const char *filename)
+static int frag_report(const char *filename)
{
static struct statfs fsinfo;
ext2fs_struct_stat st;
@@ -342,8 +356,8 @@ static void frag_report(const char *filename)
int num_extents = 1, expected = ~0;
int is_ext2 = 0;
static dev_t last_device;
- unsigned int flags;
int width;
+ int rc = 0;
#if defined(HAVE_OPEN64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
fd = open64(filename, O_RDONLY);
@@ -351,8 +365,10 @@ static void frag_report(const char *filename)
fd = open(filename, O_RDONLY);
#endif
if (fd < 0) {
+ rc = -errno;
perror("open");
- return;
+
+ return rc;
}
#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
@@ -360,28 +376,34 @@ static void frag_report(const char *filename)
#else
if (fstat(fd, &st) < 0) {
#endif
+ rc = -errno;
close(fd);
perror("stat");
- return;
+
+ return rc;
}
if (last_device != st.st_dev) {
if (fstatfs(fd, &fsinfo) < 0) {
+ rc = -errno;
close(fd);
perror("fstatfs");
- return;
+
+ return rc;
}
if (verbose)
printf("Filesystem type is: %lx\n",
(unsigned long) fsinfo.f_type);
}
st.st_blksize = fsinfo.f_bsize;
- if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) < 0)
- flags = 0;
- if (!(flags & EXT4_EXTENTS_FL) &&
- ((fsinfo.f_type == 0xef51) || (fsinfo.f_type == 0xef52) ||
- (fsinfo.f_type == 0xef53)))
- is_ext2++;
+ if (fsinfo.f_type == 0xef51 || fsinfo.f_type == 0xef52 ||
+ fsinfo.f_type == 0xef53) {
+ unsigned int flags;
+
+ if (ioctl(fd, EXT3_IOC_GETFLAGS, &flags) == 0 &&
+ !(flags & EXT4_EXTENTS_FL))
+ is_ext2 = 1;
+ }
if (is_ext2) {
long cylgroups = div_ceil(fsinfo.f_blocks, fsinfo.f_bsize * 8);
@@ -414,19 +436,19 @@ static void frag_report(const char *filename)
numblocks * fsinfo.f_bsize >> blk_shift,
numblocks == 1 ? "" : "s", 1 << blk_shift);
- if (force_bmap ||
- filefrag_fiemap(fd, blk_shift, &num_extents, &st) != 0) {
+ if (!force_bmap) {
+ rc = filefrag_fiemap(fd, blk_shift, &num_extents, &st);
+ expected = 0;
+ }
+
+ if (force_bmap || rc < 0) { /* FIEMAP failed, try FIBMAP instead */
expected = filefrag_fibmap(fd, blk_shift, &num_extents,
&st, numblocks, is_ext2);
if (expected < 0) {
- if (errno == EINVAL || errno == ENOTTY) {
- fprintf(stderr, "%s: FIBMAP unsupported\n",
- filename);
- } else if (errno != EPERM) {
- fprintf(stderr, "%s: FIBMAP error: %s",
- filename, strerror(errno));
- }
+ rc = expected;
goto out_close;
+ } else {
+ rc = 0;
}
expected = expected / data_blocks_per_cyl + 1;
}
@@ -443,6 +465,8 @@ static void frag_report(const char *filename)
fputc('\n', stdout);
out_close:
close(fd);
+
+ return rc;
}
static void usage(const char *progname)
@@ -455,9 +479,10 @@ static void usage(const char *progname)
int main(int argc, char**argv)
{
char **cpp;
+ int rc = 0;
int c;
- while ((c = getopt(argc, argv, "Bb::eksvxX")) != EOF)
+ while ((c = getopt(argc, argv, "Bb::eksvxX")) != EOF) {
switch (c) {
case 'B':
force_bmap++;
@@ -516,10 +541,17 @@ int main(int argc, char**argv)
usage(argv[0]);
break;
}
+ }
+
if (optind == argc)
usage(argv[0]);
- for (cpp=argv+optind; *cpp; cpp++)
- frag_report(*cpp);
- return 0;
+
+ for (cpp = argv + optind; *cpp; cpp++) {
+ int rc2 = frag_report(*cpp);
+ if (rc2 < 0 && rc == 0)
+ rc = rc2;
+ }
+
+ return -rc;
}
#endif
--
1.7.3.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/4] filefrag: improve extent flags printing
2013-12-17 1:05 [PATCH 1/4] filefrag: exit with error code on failure Andreas Dilger
@ 2013-12-17 1:05 ` Andreas Dilger
2013-12-17 1:05 ` [PATCH 3/4] filefrag: reserve fields and new extent flags Andreas Dilger
2013-12-17 1:05 ` [PATCH 4/4] filefrag: print out physical extent length if set Andreas Dilger
2 siblings, 0 replies; 4+ messages in thread
From: Andreas Dilger @ 2013-12-17 1:05 UTC (permalink / raw)
To: tytso; +Cc: linux-ext4, Andreas Dilger
Improve the handling of printing extent flags in verbose mode.
For unknown flags, print out the flag value in hexadecimal.
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
---
misc/filefrag.c | 60 +++++++++++++++++++++++++++++++++----------------------
1 files changed, 36 insertions(+), 24 deletions(-)
diff --git a/misc/filefrag.c b/misc/filefrag.c
index 18dc1e5..6289899 100644
--- a/misc/filefrag.c
+++ b/misc/filefrag.c
@@ -120,6 +120,15 @@ static void print_extent_header(void)
"expected:");
}
+static void print_flag(__u32 *flags, __u32 mask, char *buf, const char *name)
+{
+ if ((*flags & mask) == 0)
+ return;
+
+ strcat(buf, name);
+ *flags &= ~mask;
+}
+
static void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex,
unsigned long long expected, int blk_shift,
ext2fs_struct_stat *st)
@@ -128,10 +137,12 @@ static void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex,
unsigned long long logical_blk;
unsigned long long ext_len;
unsigned long long ext_blks;
- char flags[256] = "";
+ __u32 flags, mask;
+ char buf[256] = "";
+ flags = fm_extent->fe_flags;
/* For inline data all offsets should be in bytes, not blocks */
- if (fm_extent->fe_flags & FIEMAP_EXTENT_DATA_INLINE)
+ if (flags & FIEMAP_EXTENT_DATA_INLINE)
blk_shift = 0;
ext_len = fm_extent->fe_length >> blk_shift;
@@ -140,34 +151,35 @@ static void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex,
physical_blk = fm_extent->fe_physical >> blk_shift;
if (expected)
- sprintf(flags, ext_fmt == hex_fmt ? "%*llx: " : "%*llu: ",
+ sprintf(buf, ext_fmt == hex_fmt ? "%*llx: " : "%*llu: ",
physical_width, expected >> blk_shift);
else
- sprintf(flags, "%.*s ", physical_width, " ");
-
- if (fm_extent->fe_flags & FIEMAP_EXTENT_UNKNOWN)
- strcat(flags, "unknown,");
- if (fm_extent->fe_flags & FIEMAP_EXTENT_DELALLOC)
- strcat(flags, "delalloc,");
- if (fm_extent->fe_flags & FIEMAP_EXTENT_DATA_ENCRYPTED)
- strcat(flags, "encrypted,");
- if (fm_extent->fe_flags & FIEMAP_EXTENT_NOT_ALIGNED)
- strcat(flags, "not_aligned,");
- if (fm_extent->fe_flags & FIEMAP_EXTENT_DATA_INLINE)
- strcat(flags, "inline,");
- if (fm_extent->fe_flags & FIEMAP_EXTENT_DATA_TAIL)
- strcat(flags, "tail_packed,");
- if (fm_extent->fe_flags & FIEMAP_EXTENT_UNWRITTEN)
- strcat(flags, "unwritten,");
- if (fm_extent->fe_flags & FIEMAP_EXTENT_MERGED)
- strcat(flags, "merged,");
+ sprintf(buf, "%.*s ", physical_width, " ");
+
+ print_flag(&flags, FIEMAP_EXTENT_UNKNOWN, buf, "unknown,");
+ print_flag(&flags, FIEMAP_EXTENT_DELALLOC, buf, "delalloc,");
+ print_flag(&flags, FIEMAP_EXTENT_DATA_ENCRYPTED, buf, "encrypted,");
+ print_flag(&flags, FIEMAP_EXTENT_NOT_ALIGNED, buf, "not_aligned,");
+ print_flag(&flags, FIEMAP_EXTENT_DATA_INLINE, buf, "inline,");
+ print_flag(&flags, FIEMAP_EXTENT_DATA_TAIL, buf, "tail_packed,");
+ print_flag(&flags, FIEMAP_EXTENT_UNWRITTEN, buf, "unwritten,");
+ print_flag(&flags, FIEMAP_EXTENT_MERGED, buf, "merged,");
+ print_flag(&flags, FIEMAP_EXTENT_LAST, buf, "last,");
+ /* Print unknown flags in hex format. Known flags are already printed
+ * above and will have their bit cleared from "flags". */
+ for (mask = 1; flags != 0 && mask != 0; mask <<= 1) {
+ char hex[6];
+
+ sprintf(hex, "%04x,", mask);
+ print_flag(&flags, mask, buf, hex);
+ }
if (fm_extent->fe_logical + fm_extent->fe_length >= (__u64) st->st_size)
- strcat(flags, "eof,");
+ strcat(buf, "eof,");
/* Remove trailing comma, if any */
- if (flags[0])
- flags[strlen(flags) - 1] = '\0';
+ if (buf[0])
+ buf[strlen(buf) - 1] = '\0';
printf(ext_fmt, cur_ex, logical_width, logical_blk,
logical_width, logical_blk + ext_blks,
--
1.7.3.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 3/4] filefrag: reserve fields and new extent flags
2013-12-17 1:05 [PATCH 1/4] filefrag: exit with error code on failure Andreas Dilger
2013-12-17 1:05 ` [PATCH 2/4] filefrag: improve extent flags printing Andreas Dilger
@ 2013-12-17 1:05 ` Andreas Dilger
2013-12-17 1:05 ` [PATCH 4/4] filefrag: print out physical extent length if set Andreas Dilger
2 siblings, 0 replies; 4+ messages in thread
From: Andreas Dilger @ 2013-12-17 1:05 UTC (permalink / raw)
To: tytso; +Cc: linux-ext4, Andreas Dilger
Reserve the FIEMAP_EXTENT_DATA_COMPRESSED flag to allow reporting
extents with physical length different than logical length. This
also sets the FIEMAP_EXTENT_ENCODED flag to indicate that the data
cannot be accessed directly. This adds a new fe_phys_length field
to struct fiemap_extent which specifies the physical extent length
in bytes when DATA_COMPRESSED is set. Linux 3.14 and later kernels
will fill out the fe_phys_length field, but in older kernels the
contents are undefined (though typically zero).
Reserve the FIEMAP_EXTENT_NET flag, which indicates that the data
is on a network filesystem. This also sets FIEMAP_EXTENT_ENCODED
flag to indicate the data cannot be accessed directly.
Print out these flags in filefrag if detected.
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
---
lib/ext2fs/fiemap.h | 14 ++++++++++----
misc/filefrag.c | 2 ++
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/lib/ext2fs/fiemap.h b/lib/ext2fs/fiemap.h
index 30bf555..df973da 100644
--- a/lib/ext2fs/fiemap.h
+++ b/lib/ext2fs/fiemap.h
@@ -17,15 +17,17 @@ struct fiemap_extent {
__u64 fe_physical; /* physical offset in bytes for the start
* of the extent from the beginning of the disk */
__u64 fe_length; /* length in bytes for this extent */
- __u64 fe_reserved64[2];
+ __u64 fe_phys_length; /* physical length in bytes for this extent,
+ * undefined if DATA_COMPRESSED not set */
+ __u64 fe_reserved64;
__u32 fe_flags; /* FIEMAP_EXTENT_* flags for this extent */
__u32 fe_reserved[3];
};
struct fiemap {
- __u64 fm_start; /* logical offset (inclusive) at
+ __u64 fm_start; /* logical offset in bytes (inclusive) at
* which to start mapping (in) */
- __u64 fm_length; /* logical length of mapping which
+ __u64 fm_length; /* logical length in bytes of mapping which
* userspace wants (in) */
__u32 fm_flags; /* FIEMAP_FLAG_* flags for request (in/out) */
__u32 fm_mapped_extents;/* number of extents that were mapped (out) */
@@ -51,8 +53,10 @@ struct fiemap {
* Sets EXTENT_UNKNOWN. */
#define FIEMAP_EXTENT_ENCODED 0x00000008 /* Data can not be read
* while fs is unmounted */
+#define FIEMAP_EXTENT_DATA_COMPRESSED 0x00000040 /* Data is compressed by fs.
+ * Sets EXTENT_ENCODED. */
#define FIEMAP_EXTENT_DATA_ENCRYPTED 0x00000080 /* Data is encrypted by fs.
- * Sets EXTENT_NO_BYPASS. */
+ * Sets EXTENT_ENCODED. */
#define FIEMAP_EXTENT_NOT_ALIGNED 0x00000100 /* Extent offsets may not be
* block aligned. */
#define FIEMAP_EXTENT_DATA_INLINE 0x00000200 /* Data mixed with metadata.
@@ -64,5 +68,7 @@ struct fiemap {
#define FIEMAP_EXTENT_MERGED 0x00001000 /* File does not natively
* support extents. Result
* merged for efficiency. */
+#define FIEMAP_EXTENT_NET 0x80000000 /* Data stored remotely.
+ * Sets EXTENT_ENCODED. */
#endif /* _LINUX_FIEMAP_H */
diff --git a/misc/filefrag.c b/misc/filefrag.c
index 6289899..7096abb 100644
--- a/misc/filefrag.c
+++ b/misc/filefrag.c
@@ -158,12 +158,14 @@ static void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex,
print_flag(&flags, FIEMAP_EXTENT_UNKNOWN, buf, "unknown,");
print_flag(&flags, FIEMAP_EXTENT_DELALLOC, buf, "delalloc,");
+ print_flag(&flags, FIEMAP_EXTENT_DATA_COMPRESSED, buf, "compressed,");
print_flag(&flags, FIEMAP_EXTENT_DATA_ENCRYPTED, buf, "encrypted,");
print_flag(&flags, FIEMAP_EXTENT_NOT_ALIGNED, buf, "not_aligned,");
print_flag(&flags, FIEMAP_EXTENT_DATA_INLINE, buf, "inline,");
print_flag(&flags, FIEMAP_EXTENT_DATA_TAIL, buf, "tail_packed,");
print_flag(&flags, FIEMAP_EXTENT_UNWRITTEN, buf, "unwritten,");
print_flag(&flags, FIEMAP_EXTENT_MERGED, buf, "merged,");
+ print_flag(&flags, FIEMAP_EXTENT_NET, buf, "net,");
print_flag(&flags, FIEMAP_EXTENT_LAST, buf, "last,");
/* Print unknown flags in hex format. Known flags are already printed
* above and will have their bit cleared from "flags". */
--
1.7.3.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 4/4] filefrag: print out physical extent length if set
2013-12-17 1:05 [PATCH 1/4] filefrag: exit with error code on failure Andreas Dilger
2013-12-17 1:05 ` [PATCH 2/4] filefrag: improve extent flags printing Andreas Dilger
2013-12-17 1:05 ` [PATCH 3/4] filefrag: reserve fields and new extent flags Andreas Dilger
@ 2013-12-17 1:05 ` Andreas Dilger
2 siblings, 0 replies; 4+ messages in thread
From: Andreas Dilger @ 2013-12-17 1:05 UTC (permalink / raw)
To: tytso; +Cc: linux-ext4, Andreas Dilger
Rename fe_length to be fe_logi_length to distinguish it from the
fe_phys_length field.
If the extent's physical length is different from its logical length
(if FIEMAP_EXTENT_DATA_COMPRESSED is set) then use the fe_phys_length
for the physical length. If FIEMAP_EXTENT_DATA_COMPRESSED is unset,
then continue to use fe_logi_length for the extent length, but set
fe_phys_length = fe_logi_length to simplify the rest of the code.
Signed-off-by: Andreas Dilger <adilger@dilger.ca>
---
lib/ext2fs/fiemap.h | 2 +-
misc/filefrag.c | 62 +++++++++++++++++++++++++++++++++++++--------------
2 files changed, 46 insertions(+), 18 deletions(-)
diff --git a/lib/ext2fs/fiemap.h b/lib/ext2fs/fiemap.h
index df973da..3cf32f7 100644
--- a/lib/ext2fs/fiemap.h
+++ b/lib/ext2fs/fiemap.h
@@ -16,7 +16,7 @@ struct fiemap_extent {
* the extent from the beginning of the file */
__u64 fe_physical; /* physical offset in bytes for the start
* of the extent from the beginning of the disk */
- __u64 fe_length; /* length in bytes for this extent */
+ __u64 fe_logi_length; /* logical length in bytes for this extent */
__u64 fe_phys_length; /* physical length in bytes for this extent,
* undefined if DATA_COMPRESSED not set */
__u64 fe_reserved64;
diff --git a/misc/filefrag.c b/misc/filefrag.c
index 7096abb..6cefaf4 100644
--- a/misc/filefrag.c
+++ b/misc/filefrag.c
@@ -133,10 +133,14 @@ static void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex,
unsigned long long expected, int blk_shift,
ext2fs_struct_stat *st)
{
- unsigned long long physical_blk;
- unsigned long long logical_blk;
- unsigned long long ext_len;
- unsigned long long ext_blks;
+ unsigned long long logical_blk; /* logical starting block of file */
+ unsigned long long logical_len; /* logical length of extent in blocks */
+ unsigned long long logical_unit;/* logical length to end of extent, may
+ * not be logical_len-1 if extent isn't
+ * aligned to requested block size */
+ unsigned long long physical_blk;/* physical starting block in LUN */
+ unsigned long long physical_len;/* physical length of extent in blocks*/
+ unsigned long long physical_unit;/* physical length to end of extent */
__u32 flags, mask;
char buf[256] = "";
@@ -145,10 +149,20 @@ static void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex,
if (flags & FIEMAP_EXTENT_DATA_INLINE)
blk_shift = 0;
- ext_len = fm_extent->fe_length >> blk_shift;
- ext_blks = (fm_extent->fe_length - 1) >> blk_shift;
logical_blk = fm_extent->fe_logical >> blk_shift;
- physical_blk = fm_extent->fe_physical >> blk_shift;
+ logical_len = fm_extent->fe_logi_length >> blk_shift;
+ logical_unit = (fm_extent->fe_logi_length - 1) >> blk_shift;
+ if (flags & FIEMAP_EXTENT_UNKNOWN) {
+ physical_blk = 0;
+ physical_len = 0;
+ physical_unit = 0;
+ } else {
+ /* FIEMAP_EXTENT_DATA_COMPRESSED was checked by caller
+ * and fixed up fe_phys_length if unset. */
+ physical_blk = fm_extent->fe_physical >> blk_shift;
+ physical_len = fm_extent->fe_phys_length >> blk_shift;
+ physical_unit = (fm_extent->fe_phys_length - 1) >> blk_shift;
+ }
if (expected)
sprintf(buf, ext_fmt == hex_fmt ? "%*llx: " : "%*llu: ",
@@ -176,7 +190,8 @@ static void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex,
print_flag(&flags, mask, buf, hex);
}
- if (fm_extent->fe_logical + fm_extent->fe_length >= (__u64) st->st_size)
+ if (fm_extent->fe_logical + fm_extent->fe_logi_length >=
+ (__u64)st->st_size)
strcat(buf, "eof,");
/* Remove trailing comma, if any */
@@ -184,10 +199,10 @@ static void print_extent_info(struct fiemap_extent *fm_extent, int cur_ex,
buf[strlen(buf) - 1] = '\0';
printf(ext_fmt, cur_ex, logical_width, logical_blk,
- logical_width, logical_blk + ext_blks,
+ logical_width, logical_blk + logical_unit,
physical_width, physical_blk,
- physical_width, physical_blk + ext_blks,
- ext_len, flags);
+ physical_width, physical_blk + physical_unit,
+ logical_len, buf);
}
static int filefrag_fiemap(int fd, int blk_shift, int *num_extents,
@@ -250,18 +265,29 @@ static int filefrag_fiemap(int fd, int blk_shift, int *num_extents,
if (!tot_extents)
tot_extents = 1;
}
+
+ /* If DATA_COMPRESSED is set, then the logical and
+ * physical extent lengths are different and the
+ * fe_phys_length field is known to be valid.
+ * Kernels older than 3.14 did not set fe_phys_length,
+ * so do that here to simplify the rest of the code. */
+ if (!(fm_ext[i].fe_flags &
+ FIEMAP_EXTENT_DATA_COMPRESSED))
+ fm_ext[i].fe_phys_length =
+ fm_ext[i].fe_logi_length;
+
if (verbose)
print_extent_info(&fm_ext[i], n, expected,
blk_shift, st);
-
- expected = fm_ext[i].fe_physical + fm_ext[i].fe_length;
+ expected = fm_ext[i].fe_physical +
+ fm_ext[i].fe_phys_length;
if (fm_ext[i].fe_flags & FIEMAP_EXTENT_LAST)
last = 1;
n++;
}
fiemap->fm_start = (fm_ext[i - 1].fe_logical +
- fm_ext[i - 1].fe_length);
+ fm_ext[i - 1].fe_logi_length);
} while (last == 0);
*num_extents = tot_extents;
@@ -335,20 +361,22 @@ static int filefrag_fibmap(int fd, int blk_shift, int *num_extents,
count++;
if (force_extent && last_block != 0 &&
(block != last_block + 1 ||
- fm_ext.fe_logical + fm_ext.fe_length != logical)) {
+ fm_ext.fe_logical + fm_ext.fe_logi_length != logical)) {
print_extent_info(&fm_ext, *num_extents - 1,
(last_block + 1) * st->st_blksize,
blk_shift, st);
fm_ext.fe_logical = logical;
fm_ext.fe_physical = block * st->st_blksize;
- fm_ext.fe_length = 0;
+ fm_ext.fe_logi_length = 0;
+ fm_ext.fe_phys_length = 0;
(*num_extents)++;
} else if (verbose && last_block && (block != last_block + 1)) {
printf("Discontinuity: Block %ld is at %lu (was %lu)\n",
i, block, last_block + 1);
(*num_extents)++;
}
- fm_ext.fe_length += st->st_blksize;
+ fm_ext.fe_logi_length += st->st_blksize;
+ fm_ext.fe_phys_length += st->st_blksize;
last_block = block;
}
--
1.7.3.4
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-12-17 1:15 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-17 1:05 [PATCH 1/4] filefrag: exit with error code on failure Andreas Dilger
2013-12-17 1:05 ` [PATCH 2/4] filefrag: improve extent flags printing Andreas Dilger
2013-12-17 1:05 ` [PATCH 3/4] filefrag: reserve fields and new extent flags Andreas Dilger
2013-12-17 1:05 ` [PATCH 4/4] filefrag: print out physical extent length if set Andreas Dilger
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).