btrfs-progs: move btrfs_extref_hash() to hash.h
[platform/upstream/btrfs-progs.git] / cmds-fi-du.c
index 6d5bf35..895c242 100644 (file)
 
 #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)
@@ -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;
@@ -540,10 +551,10 @@ 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);
 
-       optind = 1;
        while (1) {
                static const struct option long_options[] = {
                        { "summarize", no_argument, NULL, 's'},
@@ -565,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");