mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-10-03 18:29:36 +00:00
2e93ccc193
In device-mapper I/O is sometimes queued within targets for later processing. For example the multipath target can be configured to store I/O when no paths are available instead of returning it -EIO. This patch allows the device-mapper core to instruct a target to transfer the contents of any such in-target queue back into the core. This frees up the resources used by the target so the core can replace that target with an alternative one and then resend the I/O to it. Without this patch the only way to change the target in such circumstances involves returning the I/O with an error back to the filesystem/application. In the multipath case, this patch will let us add new paths for existing I/O to try after all the existing paths have failed. DMF_NOFLUSH_SUSPENDING ---------------------- If the DM_NOFLUSH_FLAG ioctl option is specified at suspend time, the DMF_NOFLUSH_SUSPENDING flag is set in md->flags during dm_suspend(). It is always cleared before dm_suspend() returns. The flag must be visible while the target is flushing pending I/Os so it is set before presuspend where the flush starts and unset after the wait for md->pending where the flush ends. Target drivers can check this flag by calling dm_noflush_suspending(). DM_MAPIO_REQUEUE / DM_ENDIO_REQUEUE ----------------------------------- A target's map() function can now return DM_MAPIO_REQUEUE to request the device mapper core queue the bio. Similarly, a target's end_io() function can return DM_ENDIO_REQUEUE to request the same. This has been labelled 'pushback'. The __map_bio() and clone_endio() functions in the core treat these return values as errors and call dec_pending() to end the I/O. dec_pending ----------- dec_pending() saves the pushback request in struct dm_io->error. Once all the split clones have ended, dec_pending() will put the original bio on the md->pushback list. Note that this supercedes any I/O errors. It is possible for the suspend with DM_NOFLUSH_FLAG to be aborted while in progress (e.g. by user interrupt). dec_pending() checks for this and returns -EIO if it happened. pushdback list and pushback_lock -------------------------------- The bio is queued on md->pushback temporarily in dec_pending(), and after all pending I/Os return, md->pushback is merged into md->deferred in dm_suspend() for re-issuing at resume time. md->pushback_lock protects md->pushback. The lock should be held with irq disabled because dec_pending() can be called from interrupt context. Queueing bios to md->pushback in dec_pending() must be done atomically with the check for DMF_NOFLUSH_SUSPENDING flag. So md->pushback_lock is held when checking the flag. Otherwise dec_pending() may queue a bio to md->pushback after the interrupted dm_suspend() flushes md->pushback. Then the bio would be left in md->pushback. Flag setting in dm_suspend() can be done without md->pushback_lock because the flag is checked only after presuspend and the set value is already made visible via the target's presuspend function. The flag can be checked without md->pushback_lock (e.g. the first part of the dec_pending() or target drivers), because the flag is checked again with md->pushback_lock held when the bio is really queued to md->pushback as described above. So even if the flag is cleared after the lockless checkings, the bio isn't left in md->pushback but returned to applications with -EIO. Other notes on the current patch -------------------------------- - md->pushback is added to the struct mapped_device instead of using md->deferred directly because md->io_lock which protects md->deferred is rw_semaphore and can't be used in interrupt context like dec_pending(), and md->io_lock protects the DMF_BLOCK_IO flag of md->flags too. - Don't issue lock_fs() in dm_suspend() if the DM_NOFLUSH_FLAG ioctl option is specified, because I/Os generated by lock_fs() would be pushed back and never return if there were no valid devices. - If an error occurs in dm_suspend() after the DMF_NOFLUSH_SUSPENDING flag is set, md->pushback must be flushed because I/Os may be queued to the list already. (flush_and_out label in dm_suspend()) Test results ------------ I have tested using multipath target with the next patch. The following tests are for regression/compatibility: - I/Os succeed when valid paths exist; - I/Os fail when there are no valid paths and queue_if_no_path is not set; - I/Os are queued in the multipath target when there are no valid paths and queue_if_no_path is set; - The queued I/Os above fail when suspend is issued without the DM_NOFLUSH_FLAG ioctl option. I/Os spanning 2 multipath targets also fail. The following tests are for the normal code path of new pushback feature: - Queued I/Os in the multipath target are flushed from the target but don't return when suspend is issued with the DM_NOFLUSH_FLAG ioctl option; - The I/Os above are queued in the multipath target again when resume is issued without path recovery; - The I/Os above succeed when resume is issued after path recovery or table load; - Queued I/Os in the multipath target succeed when resume is issued with the DM_NOFLUSH_FLAG ioctl option after table load. I/Os spanning 2 multipath targets also succeed. The following tests are for the error paths of the new pushback feature: - When the bdget_disk() fails in dm_suspend(), the DMF_NOFLUSH_SUSPENDING flag is cleared and I/Os already queued to the pushback list are flushed properly. - When suspend with the DM_NOFLUSH_FLAG ioctl option is interrupted, o I/Os which had already been queued to the pushback list at the time don't return, and are re-issued at resume time; o I/Os which hadn't been returned at the time return with EIO. Signed-off-by: Kiyoshi Ueda <k-ueda@ct.jp.nec.com> Signed-off-by: Jun'ichi Nomura <j-nomura@ce.jp.nec.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com> Cc: dm-devel@redhat.com Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org> |
||
---|---|---|
.. | ||
amba | ||
byteorder | ||
dvb | ||
hdlc | ||
isdn | ||
lockd | ||
mmc | ||
mtd | ||
netfilter | ||
netfilter_arp | ||
netfilter_bridge | ||
netfilter_ipv4 | ||
netfilter_ipv6 | ||
nfsd | ||
raid | ||
spi | ||
sunrpc | ||
tc_act | ||
tc_ematch | ||
usb | ||
8250_pci.h | ||
a.out.h | ||
ac97_codec.h | ||
acct.h | ||
acpi.h | ||
adb.h | ||
adfs_fs.h | ||
adfs_fs_i.h | ||
adfs_fs_sb.h | ||
aer.h | ||
affs_hardblocks.h | ||
agp_backend.h | ||
agpgart.h | ||
aio.h | ||
aio_abi.h | ||
amifd.h | ||
amifdreg.h | ||
amigaffs.h | ||
apm_bios.h | ||
arcdevice.h | ||
arcfb.h | ||
ata.h | ||
atalk.h | ||
atm.h | ||
atm_eni.h | ||
atm_he.h | ||
atm_idt77105.h | ||
atm_nicstar.h | ||
atm_suni.h | ||
atm_tcp.h | ||
atm_zatm.h | ||
atmapi.h | ||
atmarp.h | ||
atmbr2684.h | ||
atmclip.h | ||
atmdev.h | ||
atmioc.h | ||
atmlec.h | ||
atmmpc.h | ||
atmppp.h | ||
atmsap.h | ||
atmsvc.h | ||
attribute_container.h | ||
audit.h | ||
auto_fs.h | ||
auto_fs4.h | ||
auxvec.h | ||
awe_voice.h | ||
ax25.h | ||
b1lli.h | ||
b1pcmcia.h | ||
backing-dev.h | ||
backlight.h | ||
baycom.h | ||
bcd.h | ||
bfs_fs.h | ||
binfmts.h | ||
bio.h | ||
bit_spinlock.h | ||
bitmap.h | ||
bitops.h | ||
bitrev.h | ||
blkdev.h | ||
blkpg.h | ||
blktrace_api.h | ||
blockgroup_lock.h | ||
bootmem.h | ||
bottom_half.h | ||
bpqether.h | ||
buffer_head.h | ||
bug.h | ||
cache.h | ||
calc64.h | ||
capability.h | ||
capi.h | ||
cciss_ioctl.h | ||
cd1400.h | ||
cdev.h | ||
cdk.h | ||
cdrom.h | ||
chio.h | ||
circ_buf.h | ||
clk.h | ||
clocksource.h | ||
cm4000_cs.h | ||
cn_proc.h | ||
cobalt-nvram.h | ||
coda.h | ||
coda_cache.h | ||
coda_fs_i.h | ||
coda_linux.h | ||
coda_proc.h | ||
coda_psdev.h | ||
coff.h | ||
com20020.h | ||
compat.h | ||
compat_ioctl.h | ||
compiler-gcc.h | ||
compiler-gcc3.h | ||
compiler-gcc4.h | ||
compiler-intel.h | ||
compiler.h | ||
completion.h | ||
comstats.h | ||
concap.h | ||
configfs.h | ||
connector.h | ||
console.h | ||
console_struct.h | ||
consolemap.h | ||
cpu.h | ||
cpufreq.h | ||
cpumask.h | ||
cpuset.h | ||
cramfs_fs.h | ||
cramfs_fs_sb.h | ||
crash_dump.h | ||
crc-ccitt.h | ||
crc16.h | ||
crc32.h | ||
crc32c.h | ||
crypto.h | ||
cryptohash.h | ||
ctype.h | ||
cuda.h | ||
cyclades.h | ||
cyclomx.h | ||
cycx_cfm.h | ||
cycx_drv.h | ||
cycx_x25.h | ||
dcache.h | ||
dccp.h | ||
dcookies.h | ||
debug_locks.h | ||
debugfs.h | ||
delay.h | ||
delayacct.h | ||
device-mapper.h | ||
device.h | ||
devpts_fs.h | ||
dio.h | ||
dirent.h | ||
dlm.h | ||
dlm_device.h | ||
dm-ioctl.h | ||
dm9000.h | ||
dma-mapping.h | ||
dmaengine.h | ||
dmapool.h | ||
dmi.h | ||
dn.h | ||
dnotify.h | ||
dqblk_v1.h | ||
dqblk_v2.h | ||
dqblk_xfs.h | ||
ds1286.h | ||
ds1742rtc.h | ||
ds17287rtc.h | ||
dtlk.h | ||
edd.h | ||
efi.h | ||
efs_dir.h | ||
efs_fs.h | ||
efs_fs_i.h | ||
efs_fs_sb.h | ||
efs_vh.h | ||
eisa.h | ||
elevator.h | ||
elf-em.h | ||
elf-fdpic.h | ||
elf.h | ||
elfcore.h | ||
elfnote.h | ||
err.h | ||
errno.h | ||
errqueue.h | ||
etherdevice.h | ||
ethtool.h | ||
eventpoll.h | ||
ext2_fs.h | ||
ext2_fs_sb.h | ||
ext3_fs.h | ||
ext3_fs_i.h | ||
ext3_fs_sb.h | ||
ext3_jbd.h | ||
ext4_fs.h | ||
ext4_fs_extents.h | ||
ext4_fs_i.h | ||
ext4_fs_sb.h | ||
ext4_jbd2.h | ||
fadvise.h | ||
fault-inject.h | ||
fb.h | ||
fcdevice.h | ||
fcntl.h | ||
fd.h | ||
fd1772.h | ||
fddidevice.h | ||
fdreg.h | ||
fib_rules.h | ||
file.h | ||
filter.h | ||
firmware.h | ||
flat.h | ||
font.h | ||
freezer.h | ||
fs.h | ||
fs_enet_pd.h | ||
fs_stack.h | ||
fs_struct.h | ||
fs_uart_pd.h | ||
fsl_devices.h | ||
fsnotify.h | ||
fuse.h | ||
futex.h | ||
gameport.h | ||
gen_stats.h | ||
genalloc.h | ||
generic_acl.h | ||
generic_serial.h | ||
genetlink.h | ||
genhd.h | ||
getcpu.h | ||
gfp.h | ||
gfs2_ondisk.h | ||
gigaset_dev.h | ||
hardirq.h | ||
harrier_defs.h | ||
hash.h | ||
hayesesp.h | ||
hdlc.h | ||
hdlcdrv.h | ||
hdpu_features.h | ||
hdreg.h | ||
hdsmart.h | ||
hiddev.h | ||
highmem.h | ||
highuid.h | ||
hil.h | ||
hil_mlc.h | ||
hippidevice.h | ||
hp_sdc.h | ||
hpet.h | ||
hrtimer.h | ||
htirq.h | ||
hugetlb.h | ||
hw_random.h | ||
hwmon-sysfs.h | ||
hwmon-vid.h | ||
hwmon.h | ||
hysdn_if.h | ||
i2c-algo-bit.h | ||
i2c-algo-ite.h | ||
i2c-algo-pca.h | ||
i2c-algo-pcf.h | ||
i2c-algo-sgi.h | ||
i2c-dev.h | ||
i2c-id.h | ||
i2c-isa.h | ||
i2c-ocores.h | ||
i2c-pxa.h | ||
i2c.h | ||
i2o-dev.h | ||
i2o.h | ||
i8k.h | ||
ibmtr.h | ||
icmp.h | ||
icmpv6.h | ||
ide.h | ||
idr.h | ||
if.h | ||
if_addr.h | ||
if_arcnet.h | ||
if_arp.h | ||
if_bonding.h | ||
if_bridge.h | ||
if_cablemodem.h | ||
if_ec.h | ||
if_eql.h | ||
if_ether.h | ||
if_fc.h | ||
if_fddi.h | ||
if_frad.h | ||
if_hippi.h | ||
if_infiniband.h | ||
if_link.h | ||
if_ltalk.h | ||
if_packet.h | ||
if_plip.h | ||
if_ppp.h | ||
if_pppox.h | ||
if_shaper.h | ||
if_slip.h | ||
if_strip.h | ||
if_tr.h | ||
if_tun.h | ||
if_tunnel.h | ||
if_vlan.h | ||
if_wanpipe.h | ||
if_wanpipe_common.h | ||
igmp.h | ||
in.h | ||
in6.h | ||
in_route.h | ||
inet.h | ||
inet_diag.h | ||
inetdevice.h | ||
init.h | ||
init_task.h | ||
initrd.h | ||
inotify.h | ||
input.h | ||
interrupt.h | ||
io.h | ||
ioc3.h | ||
ioc4.h | ||
ioctl.h | ||
ioctl32.h | ||
ioport.h | ||
ioprio.h | ||
ip.h | ||
ip6_tunnel.h | ||
ip_mp_alg.h | ||
ipc.h | ||
ipmi.h | ||
ipmi_msgdefs.h | ||
ipmi_smi.h | ||
ipsec.h | ||
ipv6.h | ||
ipv6_route.h | ||
ipx.h | ||
irda.h | ||
irq.h | ||
irq_cpustat.h | ||
irqflags.h | ||
irqreturn.h | ||
isa.h | ||
isapnp.h | ||
isdn.h | ||
isdn_divertif.h | ||
isdn_ppp.h | ||
isdnif.h | ||
isicom.h | ||
iso_fs.h | ||
istallion.h | ||
ixjuser.h | ||
jbd.h | ||
jbd2.h | ||
jffs.h | ||
jffs2.h | ||
jhash.h | ||
jiffies.h | ||
journal-head.h | ||
joystick.h | ||
kallsyms.h | ||
kbd_diacr.h | ||
kbd_kern.h | ||
Kbuild | ||
kd.h | ||
kdev_t.h | ||
kernel.h | ||
kernel_stat.h | ||
kernelcapi.h | ||
kexec.h | ||
key-ui.h | ||
key.h | ||
keyboard.h | ||
keyctl.h | ||
kfifo.h | ||
klist.h | ||
kmalloc_sizes.h | ||
kmod.h | ||
kobj_map.h | ||
kobject.h | ||
kprobes.h | ||
kref.h | ||
kthread.h | ||
ktime.h | ||
lapb.h | ||
latency.h | ||
lcd.h | ||
leds.h | ||
libata.h | ||
libps2.h | ||
license.h | ||
limits.h | ||
linkage.h | ||
linux_logo.h | ||
list.h | ||
llc.h | ||
lm_interface.h | ||
lock_dlm_plock.h | ||
lockdep.h | ||
log2.h | ||
loop.h | ||
lp.h | ||
m41t00.h | ||
m48t86.h | ||
magic.h | ||
major.h | ||
matroxfb.h | ||
mbcache.h | ||
mc6821.h | ||
mc146818rtc.h | ||
mca-legacy.h | ||
mca.h | ||
memory.h | ||
memory_hotplug.h | ||
mempolicy.h | ||
mempool.h | ||
meye.h | ||
migrate.h | ||
mii.h | ||
minix_fs.h | ||
miscdevice.h | ||
mm.h | ||
mm_inline.h | ||
mm_types.h | ||
mman.h | ||
mmtimer.h | ||
mmzone.h | ||
mnt_namespace.h | ||
mod_devicetable.h | ||
module.h | ||
moduleloader.h | ||
moduleparam.h | ||
mount.h | ||
mpage.h | ||
mqueue.h | ||
mroute.h | ||
msdos_fs.h | ||
msg.h | ||
msi.h | ||
mtio.h | ||
mutex-debug.h | ||
mutex.h | ||
mv643xx.h | ||
n_r3964.h | ||
namei.h | ||
nbd.h | ||
ncp.h | ||
ncp_fs.h | ||
ncp_fs_i.h | ||
ncp_fs_sb.h | ||
ncp_mount.h | ||
ncp_no.h | ||
neighbour.h | ||
net.h | ||
netdevice.h | ||
netfilter.h | ||
netfilter_arp.h | ||
netfilter_bridge.h | ||
netfilter_decnet.h | ||
netfilter_ipv4.h | ||
netfilter_ipv6.h | ||
netlink.h | ||
netpoll.h | ||
netrom.h | ||
nfs.h | ||
nfs2.h | ||
nfs3.h | ||
nfs4.h | ||
nfs4_acl.h | ||
nfs4_mount.h | ||
nfs_fs.h | ||
nfs_fs_i.h | ||
nfs_fs_sb.h | ||
nfs_idmap.h | ||
nfs_mount.h | ||
nfs_page.h | ||
nfs_xdr.h | ||
nfsacl.h | ||
nfsd_idmap.h | ||
nls.h | ||
nmi.h | ||
node.h | ||
nodemask.h | ||
notifier.h | ||
nsc_gpio.h | ||
nsproxy.h | ||
nubus.h | ||
numa.h | ||
nvram.h | ||
oom.h | ||
oprofile.h | ||
page-flags.h | ||
pagemap.h | ||
pagevec.h | ||
param.h | ||
parport.h | ||
parport_pc.h | ||
parser.h | ||
pata_platform.h | ||
patchkey.h | ||
pci-acpi.h | ||
pci.h | ||
pci_hotplug.h | ||
pci_ids.h | ||
pci_regs.h | ||
pcieport_if.h | ||
percpu.h | ||
percpu_counter.h | ||
personality.h | ||
pfkeyv2.h | ||
pfn.h | ||
pg.h | ||
phonedev.h | ||
phy.h | ||
pid.h | ||
pid_namespace.h | ||
pipe_fs_i.h | ||
pkt_cls.h | ||
pkt_sched.h | ||
pktcdvd.h | ||
platform_device.h | ||
plist.h | ||
pm.h | ||
pm_legacy.h | ||
pmu.h | ||
pnp.h | ||
pnpbios.h | ||
poison.h | ||
poll.h | ||
posix-timers.h | ||
posix_acl.h | ||
posix_acl_xattr.h | ||
posix_types.h | ||
ppdev.h | ||
ppp-comp.h | ||
ppp_channel.h | ||
ppp_defs.h | ||
prctl.h | ||
preempt.h | ||
prefetch.h | ||
prio_tree.h | ||
proc_fs.h | ||
profile.h | ||
ps2esdi.h | ||
ptrace.h | ||
qic117.h | ||
qnx4_fs.h | ||
qnxtypes.h | ||
quota.h | ||
quotaio_v1.h | ||
quotaio_v2.h | ||
quotaops.h | ||
radeonfb.h | ||
radix-tree.h | ||
raid_class.h | ||
ramfs.h | ||
random.h | ||
raw.h | ||
rbtree.h | ||
rcupdate.h | ||
reboot.h | ||
reboot_fixups.h | ||
reiserfs_acl.h | ||
reiserfs_fs.h | ||
reiserfs_fs_i.h | ||
reiserfs_fs_sb.h | ||
reiserfs_xattr.h | ||
relay.h | ||
resource.h | ||
resume-trace.h | ||
rio.h | ||
rio_drv.h | ||
rio_ids.h | ||
rio_regs.h | ||
rmap.h | ||
romfs_fs.h | ||
root_dev.h | ||
rose.h | ||
route.h | ||
rslib.h | ||
rtc-v3020.h | ||
rtc.h | ||
rtmutex.h | ||
rtnetlink.h | ||
rwsem-spinlock.h | ||
rwsem.h | ||
sc26198.h | ||
scatterlist.h | ||
scc.h | ||
sched.h | ||
screen_info.h | ||
sctp.h | ||
scx200.h | ||
scx200_gpio.h | ||
sdla.h | ||
sdla_fr.h | ||
seccomp.h | ||
securebits.h | ||
security.h | ||
selection.h | ||
selinux.h | ||
selinux_netlink.h | ||
sem.h | ||
seq_file.h | ||
seqlock.h | ||
serial.h | ||
serial167.h | ||
serial_8250.h | ||
serial_core.h | ||
serial_ip3106.h | ||
serial_reg.h | ||
serialP.h | ||
serio.h | ||
shm.h | ||
shmem_fs.h | ||
signal.h | ||
skbuff.h | ||
slab.h | ||
smb.h | ||
smb_fs.h | ||
smb_fs_i.h | ||
smb_fs_sb.h | ||
smb_mount.h | ||
smbno.h | ||
smp.h | ||
smp_lock.h | ||
snmp.h | ||
socket.h | ||
sockios.h | ||
som.h | ||
sonet.h | ||
sonypi.h | ||
sort.h | ||
sound.h | ||
soundcard.h | ||
spinlock.h | ||
spinlock_api_smp.h | ||
spinlock_api_up.h | ||
spinlock_types.h | ||
spinlock_types_up.h | ||
spinlock_up.h | ||
srcu.h | ||
stacktrace.h | ||
stallion.h | ||
start_kernel.h | ||
stat.h | ||
statfs.h | ||
stddef.h | ||
stop_machine.h | ||
string.h | ||
stringify.h | ||
superhyway.h | ||
suspend.h | ||
swap.h | ||
swapops.h | ||
synclink.h | ||
sys.h | ||
syscalls.h | ||
sysctl.h | ||
sysdev.h | ||
sysfs.h | ||
sysrq.h | ||
sysv_fs.h | ||
taskstats.h | ||
taskstats_kern.h | ||
tcp.h | ||
telephony.h | ||
termios.h | ||
textsearch.h | ||
textsearch_fsm.h | ||
tfrc.h | ||
thread_info.h | ||
threads.h | ||
ticable.h | ||
tifm.h | ||
time.h | ||
timer.h | ||
times.h | ||
timex.h | ||
tiocl.h | ||
tipc.h | ||
tipc_config.h | ||
topology.h | ||
toshiba.h | ||
transport_class.h | ||
trdevice.h | ||
tsacct_kern.h | ||
tty.h | ||
tty_driver.h | ||
tty_flip.h | ||
tty_ldisc.h | ||
types.h | ||
uaccess.h | ||
udf_fs.h | ||
udf_fs_i.h | ||
udf_fs_sb.h | ||
udp.h | ||
ufs_fs.h | ||
ufs_fs_i.h | ||
ufs_fs_sb.h | ||
uinput.h | ||
uio.h | ||
ultrasound.h | ||
umem.h | ||
un.h | ||
unistd.h | ||
unwind.h | ||
usb.h | ||
usb_ch9.h | ||
usb_gadget.h | ||
usb_gadgetfs.h | ||
usb_usual.h | ||
usbdevice_fs.h | ||
user.h | ||
utime.h | ||
uts.h | ||
utsname.h | ||
vermagic.h | ||
vfs.h | ||
via.h | ||
video_decoder.h | ||
video_encoder.h | ||
videodev.h | ||
videodev2.h | ||
videotext.h | ||
vmalloc.h | ||
vmstat.h | ||
vt.h | ||
vt_buffer.h | ||
vt_kern.h | ||
wait.h | ||
wanrouter.h | ||
watchdog.h | ||
wireless.h | ||
workqueue.h | ||
writeback.h | ||
x25.h | ||
xattr.h | ||
xfrm.h | ||
yam.h | ||
zconf.h | ||
zlib.h | ||
zorro.h | ||
zorro_ids.h | ||
zutil.h |