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>
This commit is contained in:
Goffredo Baroncelli 2017-08-18 09:04:21 +02:00 committed by David Sterba
parent 02d04d8b23
commit b5665d66e8
2 changed files with 18 additions and 9 deletions

View File

@ -433,7 +433,6 @@ static int du_add_file(const char *filename, int dirfd,
u64 file_total = 0; u64 file_total = 0;
u64 file_shared = 0; u64 file_shared = 0;
u64 dir_set_shared = 0; u64 dir_set_shared = 0;
u64 subvol;
int fd; int fd;
DIR *dirstream = NULL; DIR *dirstream = NULL;
@ -462,6 +461,13 @@ static int du_add_file(const char *filename, int dirfd,
goto out; goto out;
} }
/*
* 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;
ret = lookup_path_rootid(fd, &subvol); ret = lookup_path_rootid(fd, &subvol);
if (ret) if (ret)
goto out_close; goto out_close;
@ -472,6 +478,7 @@ static int du_add_file(const char *filename, int dirfd,
ret = mark_inode_seen(st.st_ino, subvol); ret = mark_inode_seen(st.st_ino, subvol);
if (ret) if (ret)
goto out_close; goto out_close;
}
if (S_ISREG(st.st_mode)) { if (S_ISREG(st.st_mode)) {
ret = du_calc_file_space(fd, shared_extents, &file_total, ret = du_calc_file_space(fd, shared_extents, &file_total,

View File

@ -138,6 +138,8 @@ struct btrfs_free_space_ctl;
*/ */
#define BTRFS_DEV_ITEMS_OBJECTID 1ULL #define BTRFS_DEV_ITEMS_OBJECTID 1ULL
#define BTRFS_EMPTY_SUBVOL_DIR_OBJECTID 2ULL
/* /*
* the max metadata block size. This limit is somewhat artificial, * the max metadata block size. This limit is somewhat artificial,
* but the memmove costs go through the roof for larger blocks. * but the memmove costs go through the roof for larger blocks.