summaryrefslogtreecommitdiff
path: root/cmds-fi-du.c
diff options
context:
space:
mode:
Diffstat (limited to 'cmds-fi-du.c')
-rw-r--r--cmds-fi-du.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/cmds-fi-du.c b/cmds-fi-du.c
index ec8e550f..2fc11945 100644
--- a/cmds-fi-du.c
+++ b/cmds-fi-du.c
@@ -27,8 +27,13 @@
#include <sys/ioctl.h>
#include <linux/fs.h>
+#include <linux/version.h>
#include <linux/fiemap.h>
+#if !defined(FIEMAP_EXTENT_SHARED) && (HAVE_OWN_FIEMAP_EXTENT_SHARED_DEFINE == 1)
+#define FIEMAP_EXTENT_SHARED 0x00002000
+#endif
+
#include "utils.h"
#include "commands.h"
#include "kerncompat.h"
@@ -79,7 +84,7 @@ static int add_shared_extent(u64 start, u64 len, struct rb_root *root)
{
struct shared_extent *sh;
- BUG_ON(len == 0);
+ ASSERT(len != 0);
sh = calloc(1, sizeof(*sh));
if (!sh)
@@ -111,7 +116,7 @@ static void cleanup_shared_extents(struct rb_root *root)
}
}
-#define dprintf(...)
+#define dbgprintf(...)
/*
* Find all extents which overlap 'n', calculate the space
@@ -123,7 +128,7 @@ static u64 count_unique_bytes(struct rb_root *root, struct shared_extent *n)
u64 wstart = n->start;
u64 wlast = n->last;
- dprintf("Count overlaps:");
+ dbgprintf("Count overlaps:");
do {
/*
@@ -136,7 +141,7 @@ static u64 count_unique_bytes(struct rb_root *root, struct shared_extent *n)
if (wlast < n->last)
wlast = n->last;
- dprintf(" (%llu, %llu)", n->start, n->last);
+ dbgprintf(" (%llu, %llu)", n->start, n->last);
tmp = n;
n = extent_tree_iter_next(n, wstart, wlast);
@@ -145,7 +150,7 @@ static u64 count_unique_bytes(struct rb_root *root, struct shared_extent *n)
free(tmp);
} while (n);
- dprintf("; wstart: %llu wlast: %llu total: %llu\n", wstart,
+ dbgprintf("; wstart: %llu wlast: %llu total: %llu\n", wstart,
wlast, wlast - wstart + 1);
return wlast - wstart + 1;
@@ -228,7 +233,7 @@ static int mark_inode_seen(u64 ino, u64 subvol)
else if (cmp > 0)
p = &(*p)->rb_right;
else
- BUG();
+ return -EEXIST;
}
si = calloc(1, sizeof(*si));
@@ -326,6 +331,12 @@ static int du_calc_file_space(int fd, struct rb_root *shared_extents,
if (flags & SKIP_FLAGS)
continue;
+ if (ext_len == 0) {
+ warning("extent %llu has length 0, skipping",
+ (unsigned long long)fm_ext[i].fe_physical);
+ continue;
+ }
+
file_total += ext_len;
if (flags & FIEMAP_EXTENT_SHARED) {
file_shared += ext_len;
@@ -448,7 +459,7 @@ static int du_add_file(const char *filename, int dirfd,
goto out;
}
- ret = lookup_ino_rootid(fd, &subvol);
+ ret = lookup_path_rootid(fd, &subvol);
if (ret)
goto out_close;
@@ -540,6 +551,7 @@ int cmd_filesystem_du(int argc, char **argv)
{
int ret = 0, err = 0;
int i;
+ u32 kernel_version;
unit_mode = get_unit_mode_from_arg(&argc, argv, 1);
@@ -564,6 +576,14 @@ int cmd_filesystem_du(int argc, char **argv)
if (check_argc_min(argc - optind, 1))
usage(cmd_filesystem_du_usage);
+ kernel_version = get_running_kernel_version();
+
+ if (kernel_version < KERNEL_VERSION(2,6,33)) {
+ warning(
+"old kernel version detected, shared space will be reported as exclusive\n"
+"due to missing support for FIEMAP_EXTENT_SHARED flag");
+ }
+
printf("%10s %10s %10s %s\n", "Total", "Exclusive", "Set shared",
"Filename");