android_kernel_xiaomi_sm8450/drivers/md
Mikulas Patocka 751f188dd5 dm raid1: fix crash with mirror recovery and discard
This patch fixes a crash when a discard request is sent during mirror
recovery.

Firstly, some background.  Generally, the following sequence happens during
mirror synchronization:
- function do_recovery is called
- do_recovery calls dm_rh_recovery_prepare
- dm_rh_recovery_prepare uses a semaphore to limit the number
  simultaneously recovered regions (by default the semaphore value is 1,
  so only one region at a time is recovered)
- dm_rh_recovery_prepare calls __rh_recovery_prepare,
  __rh_recovery_prepare asks the log driver for the next region to
  recover. Then, it sets the region state to DM_RH_RECOVERING. If there
  are no pending I/Os on this region, the region is added to
  quiesced_regions list. If there are pending I/Os, the region is not
  added to any list. It is added to the quiesced_regions list later (by
  dm_rh_dec function) when all I/Os finish.
- when the region is on quiesced_regions list, there are no I/Os in
  flight on this region. The region is popped from the list in
  dm_rh_recovery_start function. Then, a kcopyd job is started in the
  recover function.
- when the kcopyd job finishes, recovery_complete is called. It calls
  dm_rh_recovery_end. dm_rh_recovery_end adds the region to
  recovered_regions or failed_recovered_regions list (depending on
  whether the copy operation was successful or not).

The above mechanism assumes that if the region is in DM_RH_RECOVERING
state, no new I/Os are started on this region. When I/O is started,
dm_rh_inc_pending is called, which increases reg->pending count. When
I/O is finished, dm_rh_dec is called. It decreases reg->pending count.
If the count is zero and the region was in DM_RH_RECOVERING state,
dm_rh_dec adds it to the quiesced_regions list.

Consequently, if we call dm_rh_inc_pending/dm_rh_dec while the region is
in DM_RH_RECOVERING state, it could be added to quiesced_regions list
multiple times or it could be added to this list when kcopyd is copying
data (it is assumed that the region is not on any list while kcopyd does
its jobs). This results in memory corruption and crash.

There already exist bypasses for REQ_FLUSH requests: REQ_FLUSH requests
do not belong to any region, so they are always added to the sync list
in do_writes. dm_rh_inc_pending does not increase count for REQ_FLUSH
requests. In mirror_end_io, dm_rh_dec is never called for REQ_FLUSH
requests. These bypasses avoid the crash possibility described above.

These bypasses were improperly implemented for REQ_DISCARD when
the mirror target gained discard support in commit
5fc2ffeabb (dm raid1: support discard).

In do_writes, REQ_DISCARD requests is always added to the sync queue and
immediately dispatched (even if the region is in DM_RH_RECOVERING).  However,
dm_rh_inc and dm_rh_dec is called for REQ_DISCARD resusts.  So it violates the
rule that no I/Os are started on DM_RH_RECOVERING regions, and causes the list
corruption described above.

This patch changes it so that REQ_DISCARD requests follow the same path
as REQ_FLUSH. This avoids the crash.

Reference: https://bugzilla.redhat.com/837607

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Cc: stable@kernel.org
Signed-off-by: Alasdair G Kergon <agk@redhat.com>
2012-07-20 14:25:03 +01:00
..
persistent-data dm persistent data: fix allocation failure in space map checker init 2012-07-03 12:55:37 +01:00
bitmap.c md/bitmap: record the space available for the bitmap in the superblock. 2012-05-22 13:55:34 +10:00
bitmap.h md/bitmap: record the space available for the bitmap in the superblock. 2012-05-22 13:55:34 +10:00
dm-bio-record.h dm: preserve bi_io_vec when resubmitting bios 2009-04-02 19:55:23 +01:00
dm-bufio.c dm bufio: prefetch 2012-03-28 18:41:29 +01:00
dm-bufio.h dm bufio: prefetch 2012-03-28 18:41:29 +01:00
dm-crypt.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-delay.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-exception-store.c dm exception store: fix init error path 2012-03-28 18:41:22 +01:00
dm-exception-store.h dm snapshot: test chunk size against both origin and snapshot 2010-08-12 04:13:51 +01:00
dm-flakey.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-io.c dm io: fix discard support 2012-03-07 19:09:37 +00:00
dm-ioctl.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-kcopyd.c dm kcopyd: add dm_kcopyd_zero to zero an area 2011-10-31 20:18:58 +00:00
dm-linear.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-log-userspace-base.c Merge branch 'modsplit-Oct31_2011' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg/linux 2011-11-06 19:44:47 -08:00
dm-log-userspace-transfer.c connector/userns: replace netlink uses of cap_raised() with capable() 2012-05-10 23:21:39 -04:00
dm-log-userspace-transfer.h dm log: userspace add luid to distinguish between concurrent log instances 2009-09-04 20:40:34 +01:00
dm-log.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-mpath.c dm mpath: allow ioctls to trigger pg init 2012-06-03 00:29:58 +01:00
dm-mpath.h dm mpath: remove is_active from struct dm_path 2008-10-10 13:36:58 +01:00
dm-path-selector.c md: Add module.h to all files using it implicitly 2011-10-31 19:31:18 -04:00
dm-path-selector.h dm mpath: add start_io and nr_bytes to path selectors 2009-06-22 10:12:27 +01:00
dm-queue-length.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-raid1.c dm raid1: fix crash with mirror recovery and discard 2012-07-20 14:25:03 +01:00
dm-raid.c DM RAID: Use md_error() in place of simply setting Faulty bit 2012-05-22 13:55:31 +10:00
dm-region-hash.c dm raid1: fix crash with mirror recovery and discard 2012-07-20 14:25:03 +01:00
dm-round-robin.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-service-time.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-snap-persistent.c md: Add in export.h for files using EXPORT_SYMBOL 2011-10-31 19:31:19 -04:00
dm-snap-transient.c md: Add in export.h for files using EXPORT_SYMBOL 2011-10-31 19:31:19 -04:00
dm-snap.c dm snapshot: skip reading origin when overwriting complete chunk 2011-08-02 12:32:04 +01:00
dm-stripe.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-sysfs.c Driver core: Constify struct sysfs_ops in struct kobj_type 2010-03-07 17:04:49 -08:00
dm-table.c dm: reject trailing characters in sccanf input 2012-03-28 18:41:26 +01:00
dm-target.c dm: error return error for discards 2010-08-12 04:14:14 +01:00
dm-thin-metadata.c dm thin: provide userspace access to pool metadata 2012-06-03 00:30:01 +01:00
dm-thin-metadata.h dm thin: provide userspace access to pool metadata 2012-06-03 00:30:01 +01:00
dm-thin.c dm thin: commit metadata before creating metadata snapshot 2012-07-03 12:55:31 +01:00
dm-uevent.c md: Add in export.h for files using EXPORT_SYMBOL 2011-10-31 19:31:19 -04:00
dm-uevent.h dm: uevent generate events 2007-10-20 02:01:26 +01:00
dm-verity.c dm: add verity target 2012-03-28 18:43:38 +01:00
dm-zero.c dm: zero silently drop discards 2010-08-12 04:14:12 +01:00
dm.c dm: clear bi_end_io on remapping failure 2012-03-28 18:41:25 +01:00
dm.h dm table: add immutable feature 2011-10-31 20:19:04 +00:00
faulty.c md: tidy up rdev_for_each usage. 2012-03-19 12:46:39 +11:00
Kconfig dm: add verity target 2012-03-28 18:43:38 +01:00
linear.c md/linear: If md_integrity_register() fails, linear_run() must free the mem. 2012-04-02 09:48:37 +10:00
linear.h md/linear: typedef removal: linear_conf_t -> struct linear_conf 2011-10-11 16:48:54 +11:00
Makefile dm: add verity target 2012-03-28 18:43:38 +01:00
md.c md: support re-add of recovering devices. 2012-07-03 15:59:06 +10:00
md.h md/bitmap: add new 'space' attribute for bitmaps. 2012-05-22 13:55:07 +10:00
multipath.c md: make 'name' arg to md_register_thread non-optional. 2012-07-03 15:56:52 +10:00
multipath.h md/multipath: typedef removal: multipath_conf_t -> struct mpconf 2011-10-11 16:48:57 +11:00
raid0.c md: Avoid OOPS when reshaping raid1 to raid0 2012-04-03 15:37:26 +10:00
raid0.h md: add proper merge_bvec handling to RAID0 and Linear. 2012-03-19 12:46:39 +11:00
raid1.c md/raid1: fix use-after-free bug in RAID1 data-check code. 2012-07-09 11:34:13 +10:00
raid1.h md/raid1: Allocate spare to store replacement devices and their bios. 2011-12-23 10:17:56 +11:00
raid5.c md: fix up plugging (again). 2012-07-03 17:45:31 +10:00
raid5.h raid5: support sync request 2012-05-22 13:55:05 +10:00
raid10.c md/raid10: fix careless build error 2012-07-04 09:35:35 +10:00
raid10.h md/raid10: add reshape support 2012-05-22 13:53:47 +10:00