On Thu, Jul 23, 2015 at 04:13:30PM -0400, Brian Foster wrote: > Freeing an extent in XFS involves logging an EFI (extent free > intention), freeing the actual extent, and logging an EFD (extent free > done). The EFI object is created with a reference count of 2: one for > the current transaction and one for the subsequently created EFD. Under > normal circumstances, the first reference is dropped when the EFI is > unpinned and the second reference is dropped when the EFD is committed > to the on-disk log. > > In event of errors or filesystem shutdown, there are various potential > cleanup scenarios depending on the state of the EFI/EFD. The cleanup > scenarios are confusing and racy, as demonstrated by the following test > sequence: > > # mount $dev $mnt > # fsstress -d $mnt -n 99999 -p 16 -z -f fallocate=1 \ > -f punch=1 -f creat=1 -f unlink=1 & > # sleep 5 > # killall -9 fsstress; wait > # godown -f $mnt > # umount > > ... in which the final umount can hang due to the AIL being pinned > indefinitely by one or more EFI items. This can occur due to several > conditions. For example, if the shutdown occurs after the EFI is > committed to the on-disk log and the EFD committed to the CIL, but > before the EFD committed to the log, the EFD iop_committed() abort > handler does not drop its reference to the EFI. Alternatively, manual > error injection in the xfs_bmap_finish() codepath shows that if an error > occurs after the EFI transaction is committed but before the EFD is > constructed and logged, the EFI is never released from the AIL. > > Update the EFI/EFD item handling code to use a more straightforward and > reliable approach to error handling. If the EFI transaction is > cancelled, the EFI is freed when the log item is unlocked. If the EFI > transaction is committed successfully, from that point forward it is the > responsibility of the EFD to drop its EFI reference. This means that the > EFI unpin callback only ever drops the log reference to the EFI. It does > not free the EFI in the event of log I/O error. This also means that the > EFD item must drop its EFI reference either if the EFD transaction is > cancelled, committed or itself aborted due to log I/O error. Finally, > update xfs_bmap_finish() to ensure that once an EFI transaction is > committed, we are guaranteed to construct and log the associated EFD. > This ensures that the EFD is aborted and drops the reference to the EFI. > > Signed-off-by: Brian Foster <bfoster@xxxxxxxxxx> FWIW, we have the same hang problems in log recovery when xfs_free_extent fails - the efd is not logged and the filesystem is not shut down, so the EFI being processed is not released or removed from the AIL. We also abort the processing of EFIs on the first error, leaving the AIL full of EFIs that will never be removed and so the unmount will hang trying to empty the AIL... Cheers, Dave. -- Dave Chinner david@xxxxxxxxxxxxx _______________________________________________ xfs mailing list xfs@xxxxxxxxxxx http://oss.sgi.com/mailman/listinfo/xfs