diff options
author | Dimitri John Ledkov <xnox@ubuntu.com> | 2017-02-13 11:24:33 +0000 |
---|---|---|
committer | Dimitri John Ledkov <xnox@ubuntu.com> | 2017-02-13 11:24:33 +0000 |
commit | 4305d024938113df5d73021a09eb2a991f54ca2f (patch) | |
tree | d9e7ecc9db14bcc1394607a9e6c644a8b93e9bea /cmds-fi-du.c | |
parent | e693f0e4ffb1776a05b78264ee3d93d5f07efede (diff) |
New upstream release Closes: #849353, #817806, #854915, #845473
Diffstat (limited to 'cmds-fi-du.c')
-rw-r--r-- | cmds-fi-du.c | 34 |
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"); |