libata: retry failed FLUSH if device didn't fail it
authorTejun Heo <tj@kernel.org>
Thu, 19 Nov 2009 06:36:45 +0000 (15:36 +0900)
committerJeff Garzik <jgarzik@redhat.com>
Thu, 3 Dec 2009 07:46:35 +0000 (02:46 -0500)
commit6013efd8860bf15c1f86f365332642cfe557152f
tree9d7fe6d92ed9e067cda3b2e62d69f50175450e97
parentfd6c29e3dec9e44ecbcba3c57efa08af70a10f1e
libata: retry failed FLUSH if device didn't fail it

If ATA device failed FLUSH, it means that the device failed to write
out some amount of data and the error needs to be reported to upper
layers. As retries can't recover the lost data, FLUSH failures need to
be reported immediately in general.

However, if FLUSH fails due to transmission errors, the FLUSH needs to
be retried; otherwise, filesystems may switch to RO mode and/or raid
array may drop a drive for a random transmission glitch.

This condition can be rather easily reproduced on certain ahci
controllers which go through a PHY event after powersave mode switch +
ext4 combination.  Powersave mode switch is often closely followed by
flush from the filesystem failing the FLUSH with ATA bus error which
makes the filesystem code believe that data is lost and drop to RO
mode.  This was reported in the following bugzilla bug.

  http://bugzilla.kernel.org/show_bug.cgi?id=14543

This patch makes libata EH retry FLUSH if it wasn't failed by the
device.

Signed-off-by: Tejun Heo <tj@kernel.org>
Reported-by: Andrey Vihrov <andrey.vihrov@gmail.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
drivers/ata/libata-eh.c
include/linux/libata.h