summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoffredo Baroncelli <kreijack@inwind.it>2017-08-18 09:04:21 +0200
committerDavid Sterba <dsterba@suse.com>2017-09-08 16:15:05 +0200
commitb5665d66e8662e66b964cb894e21632d64034b4b (patch)
treed98deca455446c7f09bf66a5028a4a48dabed067
parent02d04d8b2393c1760a845699fae96c15589c7613 (diff)
btrfs-progs: fi du: don't call lookup_path_rootid for BTRFS_EMPTY_SUBVOL_DIR_OBJECTID
When ino is BTRFS_EMPTY_SUBVOL_DIR_OBJECTID, the item is not referred to any file-tree. So lookup_path_rootid() doesn't return any meaningful value. As was reported, this can be triggered by $ btrfs sub create test1 $ btrfs sub create test1/test2 $ btrfs sub snap test1 test1.snap $ btrfs fi du -s test1 Total Exclusive Set shared Filename 0.00B 0.00B 0.00B test1 $ btrfs fi du -s test1.snap Total Exclusive Set shared Filename ERROR: cannot check space of 'test1.snap': Inappropriate ioctl for device Signed-off-by: Goffredo Baroncelli <kreijack@inwind.it> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--cmds-fi-du.c25
-rw-r--r--ctree.h2
2 files changed, 18 insertions, 9 deletions
diff --git a/cmds-fi-du.c b/cmds-fi-du.c
index 4bf6af3e..8a44665c 100644
--- a/cmds-fi-du.c
+++ b/cmds-fi-du.c
@@ -433,7 +433,6 @@ static int du_add_file(const char *filename, int dirfd,
u64 file_total = 0;
u64 file_shared = 0;
u64 dir_set_shared = 0;
- u64 subvol;
int fd;
DIR *dirstream = NULL;
@@ -462,16 +461,24 @@ static int du_add_file(const char *filename, int dirfd,
goto out;
}
- ret = lookup_path_rootid(fd, &subvol);
- if (ret)
- goto out_close;
+ /*
+ * If st.st_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID ==2, there is no any
+ * related tree
+ */
+ if (st.st_ino != BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) {
+ u64 subvol;
- if (inode_seen(st.st_ino, subvol))
- goto out_close;
+ ret = lookup_path_rootid(fd, &subvol);
+ if (ret)
+ goto out_close;
- ret = mark_inode_seen(st.st_ino, subvol);
- if (ret)
- goto out_close;
+ if (inode_seen(st.st_ino, subvol))
+ goto out_close;
+
+ ret = mark_inode_seen(st.st_ino, subvol);
+ if (ret)
+ goto out_close;
+ }
if (S_ISREG(st.st_mode)) {
ret = du_calc_file_space(fd, shared_extents, &file_total,
diff --git a/ctree.h b/ctree.h
index 2818441f..81c193f1 100644
--- a/ctree.h
+++ b/ctree.h
@@ -138,6 +138,8 @@ struct btrfs_free_space_ctl;
*/
#define BTRFS_DEV_ITEMS_OBJECTID 1ULL
+#define BTRFS_EMPTY_SUBVOL_DIR_OBJECTID 2ULL
+
/*
* the max metadata block size. This limit is somewhat artificial,
* but the memmove costs go through the roof for larger blocks.