Hello, I've got this merged locally (the completion handler version) and the sysfs bits seem to be working fine.
The only problem is the accounting doesn't record blocks that are deleted in the root items. This is because of the somewhat strange path things take to being freed. So, lets pretend we've got a 1GB file named foo and we rm it. 1) start a transaction 2) remove 'foo' from dir (this cows dir blocks) 3) remove extent pointers from foo (this cows all blocks w/extent pointers) 4) remove the foo's inode 5) (eventually) commit At this point, we have two tree roots. There's the most recent root, where all traces of foo are gone, and there's the old root which has all the tree blocks from before the cow. The extents from foo are not free on disk yet, because they are still referenced by the old root. btrfs_drop_snapshot comes in and starts dropping reference counts on blocks in the old root. It will find the extent pointers for foo and drop references on those too, and finally those extents will really freed on disk. So, this is a very long way of saying that last place actually calling btrfs_free_extent is actually btrfs_drop_snapshot, and it does this with a copy of the root item. So, when we make changes to root->root_item, they never actually get sent down to the disk. What we want to do is update the block count in the most recent root with the number of blocks that were freed by btrfs_drop_snapshot. So, before calling btrfs_drop_snapshot, we need to record the number of blocks allocated, and the compare it with the number still there after calling drop_snapshot. Then update the most recent root to reflect the changes on disk. Does that make any sense? -chris _______________________________________________ Btrfs-devel mailing list [email protected] http://oss.oracle.com/mailman/listinfo/btrfs-devel
