J Duff
2007-Nov-05 16:04 UTC
[zfs-code] Modifying a Block - When is it returned to the space map?
When a file is edited/modified by the user, how and when are blocks returned to the space map? I have created a small (43 bytes, one 512 block) text file. When I write the text file to a ZFS pool, I see calls to metaslab_alloc and space_map_remove. When I delete the text file, I see calls to metaslab_free, and space_map_add. This makes sense. However, if I write the same file to a ZFS pool, then change a few characters using a text editor and save it, I see calls to metaslab_alloc and space_map_remove for the new contents of the modified block, but I never see calls to metaslab_free and space_map_add to return the original block to the space map. When and where does the free of the original, no longer used block occur? I am also a bit confused about why I see a space_map_remove AND a space_map_add during the metaslab_alloc sequence. I understand the space_map_remove, but why is there also a call to space_map_add? Duff -- This messages posted from opensolaris.org
Bill Moore
2007-Nov-05 18:17 UTC
[zfs-code] Modifying a Block - When is it returned to the space map?
On Mon, Nov 05, 2007 at 08:04:29AM -0800, J Duff wrote:> When a file is edited/modified by the user, how and when are blocks > returned to the space map?They are returned to the space map when they are no longer referenced.> I have created a small (43 bytes, one 512 block) text file. When I > write the text file to a ZFS pool, I see calls to metaslab_alloc and > space_map_remove. When I delete the text file, I see calls to > metaslab_free, and space_map_add. This makes sense. > > However, if I write the same file to a ZFS pool, then change a few > characters using a text editor and save it, I see calls to > metaslab_alloc and space_map_remove for the new contents of the > modified block, but I never see calls to metaslab_free and > space_map_add to return the original block to the space map. When and > where does the free of the original, no longer used block occur?That happens in the callback to the DMU. When the SPA is done writing the new block, it does a callback to the DMU, which will free the block if it''s not part of a snapshot. The callback is killer(): http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/zfs/dmu_objset.c#806 If the block needs to be freed, killer() calls dsl_dataset_block_kill(), which calls arc_free(), which will eventually find its way to metaslab_free(). My guess as to why you aren''t seeing the free during an overwrite is that the old version of the file is part of a previous snapshot that still references your data block. If that''s not the case, then I''m confused as well. Perhaps there is a case I''m overlooking.> I am also a bit confused about why I see a space_map_remove AND a > space_map_add during the metaslab_alloc sequence. I understand the > space_map_remove, but why is there also a call to space_map_add?The call to space_map_add() adds the newly allocated block to the list of blocks that have been allocated during that transaction group. These allocation (and free) records are then added to the appropriate space map during metaslab_sync(). --Bill