HomeFreeBSD

Fix dnode allocation race

Description

Fix dnode allocation race

When performing concurrent object allocations using the new
multi-threaded allocator and large dnodes it's possible to
allocate overlapping large dnodes.

This case should have been handled by detecting an error
returned by dnode_hold_impl(). But that logic only checked
the returned dnp was not-NULL, and the dnp variable was not
reset to NULL when retrying. Resolve this issue by properly
checking the return value of dnode_hold_impl().

Additionally, it was possible that dnode_hold_impl() would
misreport a dnode as free when it was in fact in use. This
could occurs for two reasons:

  • The per-slot zrl_lock must be held over the entire critical section which includes the alloc/free until the new dnode is assigned to children_dnodes. Additionally, all of the zrl_lock's in the range must be held to protect moving dnodes.
  • The dn->dn_ot_type cannot be solely relied upon to check the type. When allocating a new dnode its type will be DMU_OT_NONE after dnode_create(). Only latter when dnode_allocate() is called will it transition to the new type. This means there's a window when allocating where it can mistaken for a free dnode.

Reviewed-by: Giuseppe Di Natale <dinatale2@llnl.gov>
Reviewed-by: Ned Bass <bass6@llnl.gov>
Reviewed-by: Tony Hutter <hutter2@llnl.gov>
Reviewed-by: Olaf Faaland <faaland1@llnl.gov>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Closes #6414
Closes #6439

Details

Provenance
Brian Behlendorf <behlendorf1@llnl.gov>Authored on Aug 8 2017, 3:38 PM
GitHub <noreply@github.com>Committed on Aug 8 2017, 3:38 PM
Parents
rGd19a6d5c80fb: dracut: Install commands required for vdev_id
Branches
Unknown
Tags
Unknown

Event Timeline

GitHub <noreply@github.com> committed rG9631681b7533: Fix dnode allocation race (authored by Brian Behlendorf <behlendorf1@llnl.gov>).Aug 8 2017, 3:38 PM