Hi, I assume this has something to do with using updated btrfs and old btrfs utils, but it''s only the presentation that is wrong. btrfs-show gives: Label: none uuid: 2332476e-ed10-44b4-844b-c85cc7388a61 Total devices 1 FS bytes used 266.53GB devid 1 size 145.00GB used 145.00GB path /dev/mapper/root But df -h gives: /dev/mapper/root 145G -64Z -122G 100% / Also, following your guides i tried to do a rm -rf ext2_saved, which didn''t quite work... rm -rf ext2_saved/ rm: cannot remove directory `ext2_saved'': Directory not empty ls -la ext2_saved/ total 4 drwxr-xr-x 1 root root 0 9 feb 13.41 . drwxr-xr-x 1 root root 170 2 dec 21.54 .. Any clues, ideas, suggestions? (Remember the CC) PS. Beyond that i really like my experiences with btrfs so far (this was my first root filesystem migration though) DS. -- Ian Kumlien <pomac () vapor ! com> -- http://pomac.netswarm.net
Hi, > Hi, I assume this has something to do with using updated btrfs > and old btrfs utils, but it''s only the presentation that is > wrong. Yes, this wouldn''t happen with latest btrfs-progs. > But df -h gives: > /dev/mapper/root 145G -64Z -122G 100% / Here''s a patch to btrfsck from Josef that should fix this: Signed-off-by: Josef Bacik <jbacik@redhat.com> --- btrfsck.c | 30 ++++++++++++++++++++++++++++++ ctree.h | 1 + extent-tree.c | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+), 0 deletions(-) diff --git a/btrfsck.c b/btrfsck.c index 46a6eae..77db11a 100644 --- a/btrfsck.c +++ b/btrfsck.c @@ -2805,6 +2805,34 @@ static int check_extents(struct btrfs_root *root) return ret; } +static void check_space_used(struct btrfs_root *root) +{ + struct btrfs_fs_info *info = root->fs_info; + u64 total; + u64 super_total; + + total = btrfs_total_used(root); + super_total = btrfs_super_bytes_used(&info->super_copy); + + if (total != super_total) { + struct btrfs_trans_handle *trans; + + trans = btrfs_start_transaction(root, 1); + if (!trans) + return; + printf("Super total bytes used (%llu) doesn''t match actual " + "bytes used (%llu). Fixing.\n", + (unsigned long long)super_total, + (unsigned long long)total); + btrfs_set_super_bytes_used(&info->super_copy, total); + btrfs_commit_transaction(trans, root); + } else { + printf("Super total bytes used (%llu) matches actual (%llu)\n", + (unsigned long long)super_total, + (unsigned long long)total); + } +} + static void print_usage(void) { fprintf(stderr, "usage: btrfsck dev\n"); @@ -2836,6 +2864,8 @@ int main(int ac, char **av) goto out; ret = check_root_refs(root, &root_cache); + if (!ret) + check_space_used(root); out: free_root_recs(&root_cache); close_ctree(root); diff --git a/ctree.h b/ctree.h index a9062ea..89eb0b9 100644 --- a/ctree.h +++ b/ctree.h @@ -1699,6 +1699,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytes_used, u64 type, u64 chunk_objectid, u64 chunk_offset, u64 size); +u64 btrfs_total_used(struct btrfs_root *root); int btrfs_make_block_groups(struct btrfs_trans_handle *trans, struct btrfs_root *root); int btrfs_update_block_group(struct btrfs_trans_handle *trans, diff --git a/extent-tree.c b/extent-tree.c index e1d7ffd..478807c 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -3135,6 +3135,38 @@ error: return ret; } +u64 btrfs_total_used(struct btrfs_root *root) +{ + struct btrfs_block_group_cache *cache; + struct extent_io_tree *block_group_cache; + int ret; + u64 ptr; + u64 start; + u64 end; + u64 total = 0; + + block_group_cache = &root->fs_info->block_group_cache; + start = BTRFS_SUPER_INFO_OFFSET + BTRFS_SUPER_INFO_SIZE; + while (1) { + ret = find_first_extent_bit(block_group_cache, + start, &start, &end, + BLOCK_GROUP_DATA | + BLOCK_GROUP_METADATA | + BLOCK_GROUP_SYSTEM); + if (ret) + break; + ret = get_state_private(block_group_cache, start, &ptr); + if (ret) + break; + + cache = (struct btrfs_block_group_cache *)(unsigned long)ptr; + total += btrfs_block_group_used(&cache->item); + start = end + 1; + } + + return total; +} + int btrfs_make_block_group(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytes_used, u64 type, u64 chunk_objectid, u64 chunk_offset, -- 1.5.4.3 -- Chris Ball <cjb@laptop.org> One Laptop Per Child -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Hi, > Here''s a patch to btrfsck from Josef that should fix this: Sorry, that was an older patch. This is the working one: From: Josef Bacik <jbacik@redhat.com> Date: Wed, 14 Oct 2009 14:39:26 -0400 Subject: [PATCH] patch fix-space-accounting.patch Signed-off-by: Josef Bacik <jbacik@redhat.com> --- btrfsck.c | 32 +++++++++++++++++++++++++++++ ctree.h | 2 + disk-io.c | 47 +++++++++++++++++++++++++++++++++++++++++++ disk-io.h | 2 + extent-tree.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 145 insertions(+), 0 deletions(-) diff --git a/btrfsck.c b/btrfsck.c index 46a6eae..1aaf022 100644 --- a/btrfsck.c +++ b/btrfsck.c @@ -2805,6 +2805,36 @@ static int check_extents(struct btrfs_root *root) return ret; } +static void check_space_used(struct btrfs_root *root) +{ + struct btrfs_fs_info *info = root->fs_info; + u64 total; + u64 super_total; + + total = btrfs_total_used(root); + super_total = btrfs_super_bytes_used(&info->super_copy); + + if (total != super_total) { + struct btrfs_trans_handle *trans; + + btrfs_make_readwrite(info); + trans = btrfs_start_transaction(root, 1); + if (!trans) + return; + printf("Super total bytes used (%llu) doesn''t match actual " + "bytes used (%llu). Fixing.\n", + (unsigned long long)super_total, + (unsigned long long)total); + btrfs_set_super_bytes_used(&info->super_copy, total); + btrfs_commit_transaction(trans, root); + btrfs_make_readonly(info); + } else { + printf("Super total bytes used (%llu) matches actual (%llu)\n", + (unsigned long long)super_total, + (unsigned long long)total); + } +} + static void print_usage(void) { fprintf(stderr, "usage: btrfsck dev\n"); @@ -2836,6 +2866,8 @@ int main(int ac, char **av) goto out; ret = check_root_refs(root, &root_cache); + if (!ret) + check_space_used(root); out: free_root_recs(&root_cache); close_ctree(root); diff --git a/ctree.h b/ctree.h index a9062ea..0681017 100644 --- a/ctree.h +++ b/ctree.h @@ -1699,6 +1699,8 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytes_used, u64 type, u64 chunk_objectid, u64 chunk_offset, u64 size); +u64 btrfs_total_used(struct btrfs_root *root); +void btrfs_update_block_groups_readonly(struct btrfs_fs_info *info); int btrfs_make_block_groups(struct btrfs_trans_handle *trans, struct btrfs_root *root); int btrfs_update_block_group(struct btrfs_trans_handle *trans, diff --git a/disk-io.c b/disk-io.c index 4d4e902..ecea152 100644 --- a/disk-io.c +++ b/disk-io.c @@ -946,6 +946,53 @@ static int close_all_devices(struct btrfs_fs_info *fs_info) return 0; } +int btrfs_make_readwrite(struct btrfs_fs_info *fs_info) +{ + struct list_head *list; + struct list_head *next; + struct list_head *tmp; + struct btrfs_device *device; + int fd; + + list = &fs_info->fs_devices->devices; + list_for_each_safe(next, tmp, list) { + device = list_entry(next, struct btrfs_device, dev_list); + close(device->fd); + fd = open(device->name, O_RDWR); + if (fd < 0) + return -errno; + device->fd = fd; + device->writeable = 1; + } + fs_info->readonly = 0; + btrfs_update_block_groups_readonly(fs_info); + return 0; +} + +int btrfs_make_readonly(struct btrfs_fs_info *fs_info) +{ + struct list_head *list; + struct list_head *next; + struct list_head *tmp; + struct btrfs_device *device; + int fd; + + list = &fs_info->fs_devices->devices; + list_for_each_safe(next, tmp, list) { + device = list_entry(next, struct btrfs_device, dev_list); + close(device->fd); + fd = open(device->name, O_RDONLY); + if (fd < 0) + return -errno; + device->fd = fd; + device->writeable = 0; + } + fs_info->readonly = 1; + btrfs_update_block_groups_readonly(fs_info); + return 0; + +} + int close_ctree(struct btrfs_root *root) { int ret; diff --git a/disk-io.h b/disk-io.h index 49e5692..646586e 100644 --- a/disk-io.h +++ b/disk-io.h @@ -75,4 +75,6 @@ int csum_tree_block_size(struct extent_buffer *buf, u16 csum_sectorsize, int csum_tree_block(struct btrfs_root *root, struct extent_buffer *buf, int verify); int btrfs_read_buffer(struct extent_buffer *buf, u64 parent_transid); +int btrfs_make_readwrite(struct btrfs_fs_info *fs_info); +int btrfs_make_readonly(struct btrfs_fs_info *fs_info); #endif diff --git a/extent-tree.c b/extent-tree.c index e1d7ffd..49bffe7 100644 --- a/extent-tree.c +++ b/extent-tree.c @@ -3135,6 +3135,68 @@ error: return ret; } +void btrfs_update_block_groups_readonly(struct btrfs_fs_info *info) +{ + struct btrfs_block_group_cache *cache; + struct extent_io_tree *block_group_cache; + int ret; + u64 ptr; + u64 start; + u64 end; + + block_group_cache = &info->block_group_cache; + start = BTRFS_SUPER_INFO_OFFSET + BTRFS_SUPER_INFO_SIZE; + while (1) { + ret = find_first_extent_bit(block_group_cache, + start, &start, &end, + BLOCK_GROUP_DATA | + BLOCK_GROUP_METADATA | + BLOCK_GROUP_SYSTEM); + if (ret) + break; + ret = get_state_private(block_group_cache, start, &ptr); + if (ret) + break; + + cache = (struct btrfs_block_group_cache *)(unsigned long)ptr; + cache->ro = btrfs_chunk_readonly(info->extent_root, + cache->key.objectid); + start = end + 1; + } +} + +u64 btrfs_total_used(struct btrfs_root *root) +{ + struct btrfs_block_group_cache *cache; + struct extent_io_tree *block_group_cache; + int ret; + u64 ptr; + u64 start; + u64 end; + u64 total = 0; + + block_group_cache = &root->fs_info->block_group_cache; + start = BTRFS_SUPER_INFO_OFFSET + BTRFS_SUPER_INFO_SIZE; + while (1) { + ret = find_first_extent_bit(block_group_cache, + start, &start, &end, + BLOCK_GROUP_DATA | + BLOCK_GROUP_METADATA | + BLOCK_GROUP_SYSTEM); + if (ret) + break; + ret = get_state_private(block_group_cache, start, &ptr); + if (ret) + break; + + cache = (struct btrfs_block_group_cache *)(unsigned long)ptr; + total += btrfs_block_group_used(&cache->item); + start = end + 1; + } + + return total; +} + int btrfs_make_block_group(struct btrfs_trans_handle *trans, struct btrfs_root *root, u64 bytes_used, u64 type, u64 chunk_objectid, u64 chunk_offset, -- 1.5.4.3 -- Chris Ball <cjb@laptop.org> One Laptop Per Child -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On tis, 2010-02-09 at 16:02 -0500, Chris Ball wrote:> Hi, > > > Here''s a patch to btrfsck from Josef that should fix this: > > Sorry, that was an older patch. This is the working one:Will test soon! Will this also fix the directory that i can''t delete? -- Ian Kumlien <pomac () vapor ! com> -- http://pomac.netswarm.net
Hi, > Will this also fix the directory that i can''t delete? No, I think you need "btrfsctl -D" for that. - Chris. -- Chris Ball <cjb@laptop.org> One Laptop Per Child -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On tis, 2010-02-09 at 16:07 -0500, Chris Ball wrote:> Hi, > > > Will this also fix the directory that i can''t delete? > > No, I think you need "btrfsctl -D" for that.btrfsctl -D ext2_saved/ ioctl:: Invalid argument uname -r 2.6.33-rc7 So i assume it''s not merged yet?> - Chris.-- Ian Kumlien <pomac () vapor ! com> -- http://pomac.netswarm.net
Hi, > btrfsctl -D ext2_saved/ > ioctl:: Invalid argument It''s merged (during 2.6.32) -- I think you just have the wrong syntax. See http://btrfs.wiki.kernel.org/index.php/Btrfsctl. - Chris. -- Chris Ball <cjb@laptop.org> One Laptop Per Child -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
On tis, 2010-02-09 at 16:17 -0500, Chris Ball wrote:> Hi, > > > btrfsctl -D ext2_saved/ > > ioctl:: Invalid argument > > It''s merged (during 2.6.32) -- I think you just have the wrong syntax. > See http://btrfs.wiki.kernel.org/index.php/Btrfsctl.Ahh, now i get it, thanks =)> - Chris.-- Ian Kumlien <pomac () vapor ! com> -- http://pomac.netswarm.net
On tis, 2010-02-09 at 16:02 -0500, Chris Ball wrote:> Hi, > > > Here''s a patch to btrfsck from Josef that should fix this: > > Sorry, that was an older patch. This is the working one:It didn''t apply cleanly to latest git, so i remerged the patch... The new output sure looks better in my eyes: /dev/mapper/root 145G 135G 11G 93% / =) Thanks, I do wonder btw, btrfsck always seems to segfault when you check a filesystem in real use - ie loged in users and daemons running - but not on a normal ''single'' user boot. Anything that could be done with this? (It doesn''t inspire confidence ;)) -- Ian Kumlien <pomac () vapor ! com> -- http://pomac.netswarm.net
* [Ian Kumlien]> Thanks, I do wonder btw, btrfsck always seems to segfault when you check > a filesystem in real use - ie loged in users and daemons running - but > not on a normal ''single'' user boot. Anything that could be done with > this? (It doesn''t inspire confidence ;))Online filesystem check isn''t yet implemented. What you''re seeing is btrfsck not actually checking to see if the fs is mounted before running. Make sure to always umount before running btrfsck. (I remember reading something about such a check being added to btrfsck, so it might be better with newer btrfs-tools). Øystein -- Outgoing mail is certified Virus Free. ..of course, the virus would tell you the same thing.. -- To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html