Linux block layer
 help / color / mirror / Atom feed
* Re: [PATCH 0/6] RFC add blkdev tests v2
From: Jens Axboe @ 2017-04-06 14:33 UTC (permalink / raw)
  To: Christoph Hellwig, Dmitry Monakhov; +Cc: fstests, linux-fsdevel, linux-block
In-Reply-To: <20170406135524.GA12230@infradead.org>

On 04/06/2017 07:55 AM, Christoph Hellwig wrote:
> I still disagree with using xfstests for this.  Even if we were going
> to treat the block devices nodes as yet another file system that's not
> what the patches do - they create specific virtual devices to test
> for each test.
> 
> I think the right way is to keep your patches as-is and copy the few
> bits you use from xfstests into a new repository.

That is exactly what my recommendation was at lsfmm as well - fork
xfstest, prune bits we don't need, and off we go. I'll get around to
it soonish.

-- 
Jens Axboe

^ permalink raw reply

* Re: [PATCH v2 4/6] mlx5: support ->get_vector_affinity
From: Leon Romanovsky @ 2017-04-06 14:30 UTC (permalink / raw)
  To: Sagi Grimberg
  Cc: Jens Axboe, linux-nvme, linux-block, linux-rdma, Saeed Mahameed,
	Or Gerlitz, Christoph Hellwig
In-Reply-To: <1491474998-16423-5-git-send-email-sagi@grimberg.me>

[-- Attachment #1: Type: text/plain, Size: 276 bytes --]

On Thu, Apr 06, 2017 at 01:36:36PM +0300, Sagi Grimberg wrote:
> Simply refer to the generic affinity mask helper.
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
> ---

Thanks,
Acked-by: Leon Romanovsky <leonro@mellanox.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 2/6] mlx5: move affinity hints assignments to generic code
From: Leon Romanovsky @ 2017-04-06 14:27 UTC (permalink / raw)
  To: Sagi Grimberg
  Cc: Jens Axboe, linux-nvme, linux-block, linux-rdma, Saeed Mahameed,
	Or Gerlitz, Christoph Hellwig
In-Reply-To: <1491474998-16423-3-git-send-email-sagi@grimberg.me>

[-- Attachment #1: Type: text/plain, Size: 818 bytes --]

On Thu, Apr 06, 2017 at 01:36:34PM +0300, Sagi Grimberg wrote:
> generic api takes care of spreading affinity similar to
> what mlx5 open coded (and even handles better asymmetric
> configurations). Ask the generic API to spread affinity
> for us, and feed him pre_vectors that do not participate
> in affinity settings (which is an improvement to what we
> had before).
>
> The affinity assignments should match what mlx5 tried to
> do earlier but now we do not set affinity to async, cmd
> and pages dedicated vectors.
>
> Also, remove mlx5e_get_cpu routine as we have generic helpers
> to get cpumask and node given a irq vector, so use them
> directly.
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
> ---

Thanks,
Acked-by: Leon Romanovsky <leonro@mellanox.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH v2 1/6] mlx5: convert to generic pci_alloc_irq_vectors
From: Leon Romanovsky @ 2017-04-06 14:24 UTC (permalink / raw)
  To: Sagi Grimberg
  Cc: Jens Axboe, linux-nvme, linux-block, linux-rdma, Saeed Mahameed,
	Or Gerlitz, Christoph Hellwig
In-Reply-To: <1491474998-16423-2-git-send-email-sagi@grimberg.me>

[-- Attachment #1: Type: text/plain, Size: 419 bytes --]

On Thu, Apr 06, 2017 at 01:36:33PM +0300, Sagi Grimberg wrote:
> Now that we have a generic code to allocate an array
> of irq vectors and even correctly spread their affinity,
> correctly handle cpu hotplug events and more, were much
> better off using it.
>
> Reviewed-by: Christoph Hellwig <hch@lst.de>
> Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
> ---

Thanks,
Acked-by: Leon Romanovsky <leonro@mellanox.com>

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]

^ permalink raw reply

* Re: [PATCH 0/6] RFC add blkdev tests v2
From: Christoph Hellwig @ 2017-04-06 13:55 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: fstests, linux-fsdevel, linux-block
In-Reply-To: <1491484750-9164-1-git-send-email-dmonakhov@openvz.org>

I still disagree with using xfstests for this.  Even if we were going
to treat the block devices nodes as yet another file system that's not
what the patches do - they create specific virtual devices to test
for each test.

I think the right way is to keep your patches as-is and copy the few
bits you use from xfstests into a new repository.

^ permalink raw reply

* [PATCH 6/6] new: blockdev/005 Check that busy fs survives blkdev page truncation
From: Dmitry Monakhov @ 2017-04-06 13:19 UTC (permalink / raw)
  To: fstests; +Cc: linux-fsdevel, linux-block, Dmitry Monakhov
In-Reply-To: <1491484750-9164-1-git-send-email-dmonakhov@openvz.org>

same as blockdev/004 but with add more stress on corrupted fs.

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 tests/blockdev/005     | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/blockdev/005.out |  2 ++
 tests/blockdev/group   |  1 +
 tests/generic/390      |  1 +
 4 files changed, 96 insertions(+)
 create mode 100755 tests/blockdev/005
 create mode 100644 tests/blockdev/005.out

diff --git a/tests/blockdev/005 b/tests/blockdev/005
new file mode 100755
index 0000000..fa3eadc
--- /dev/null
+++ b/tests/blockdev/005
@@ -0,0 +1,92 @@
+#! /bin/bash
+# FS QA Test 005
+#
+# Check that busy filesystem survives blockdev pagecache truncation.
+# blkdev page cache can be truncated due to various reasons
+# 1)ioctl: BLKDISCARD
+# 2)blkdev: falloc{ FALLOC_FL_ZERO_RANGE, FALLOC_FL_PUNCH_HOLE }
+# 3)nbd: NBD_CLEAR_SOCK
+# test is similar blockdev/004 but push more stress on filesystem.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2017 Dmitry Monakhov <dmonakhov@openvz.org>
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#-----------------------------------------------------------------------
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+	$UMOUNT_PROG $fs_mnt
+	_destroy_loop_device $loop_dev
+	cd /
+	rm -rf $TEST_DIR/$$
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+rm -f $seqres.full
+
+# real QA test starts here
+_supported_fs generic
+_supported_os Linux
+_require_loop
+#_require_xfs_io_command "fzero"
+
+# create the fs image and mount point
+
+mkdir -p $TEST_DIR/$$ || _fail "Can not make test dir"
+fs_img=$TEST_DIR/$$/fs.img
+fs_mnt=$TEST_DIR/$$/mnt
+$XFS_IO_PROG -fc "truncate 1g" $fs_img >>$seqres.full 2>&1
+mkdir -p $fs_mnt
+loop_dev=$(_create_loop_device $fs_img)
+_mkfs_dev $loop_dev
+_mount $loop_dev $fs_mnt
+
+stress_dir="$fs_mnt/stress"
+mkdir "$stress_dir"
+# Disable all sync operations to get higher load
+FSSTRESS_AVOID="$FSSTRESS_AVOID -ffsync=0 -fsync=0 -ffdatasync=0"
+fsstress_args=`_scale_fsstress_args -d $stress_dir -p4 -n9999999 $FSSTRESS_AVOID`
+$FSSTRESS_PROG $fsstress_args > /dev/null 2>&1 &
+fsstress_pid=$!
+# Warm-up
+sleep 3
+
+# Issue zeroout on block device, this act just a giant hammer for fs,
+# A lot of complains are expected, bug_on/panic is not.
+$XFS_IO_PROG -c "fzero -k 0 1G" -f $loop_dev >>$seqres.full 2>&1
+# Force sync operation in order to flush data to screwed disk.
+$XFS_IO_PROG -c "pwrite 0 4k" -c "syncfs" -f $fs_mnt/check_ro >>$seqres.full 2>&1
+sleep 3
+$KILLALL_PROG -q $FSSTRESS_PROG
+wait $pid
+# success, all done
+echo "Silence is golden"
+status=0
+exit
diff --git a/tests/blockdev/005.out b/tests/blockdev/005.out
new file mode 100644
index 0000000..a5027f1
--- /dev/null
+++ b/tests/blockdev/005.out
@@ -0,0 +1,2 @@
+QA output created by 005
+Silence is golden
diff --git a/tests/blockdev/group b/tests/blockdev/group
index d100c85..445b97c 100644
--- a/tests/blockdev/group
+++ b/tests/blockdev/group
@@ -7,3 +7,4 @@
 002 rw blockdev liotarget
 003 rw blockdev liotarget integrity dangerous
 004 rw blockdev dangerous zero
+005 rw blockdev dangerous zero
diff --git a/tests/generic/390 b/tests/generic/390
index 473015a..a717888 100755
--- a/tests/generic/390
+++ b/tests/generic/390
@@ -55,6 +55,7 @@ _supported_os Linux
 _require_scratch
 _require_freeze
 _require_test_program "feature"
+_require_command "$KILLALL_PROG" killall
 
 _scratch_mkfs >>$seqres.full 2>&1
 # We don't want to freeze/unfreeze root fs if mount scratch dev failed
-- 
2.9.3

^ permalink raw reply related

* [PATCH 5/6] new: blockdev/004 Check that live fs survives blkdev page truncation
From: Dmitry Monakhov @ 2017-04-06 13:19 UTC (permalink / raw)
  To: fstests; +Cc: linux-fsdevel, linux-block, Dmitry Monakhov
In-Reply-To: <1491484750-9164-1-git-send-email-dmonakhov@openvz.org>

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 tests/blockdev/004     | 81 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/blockdev/004.out |  2 ++
 tests/blockdev/group   |  1 +
 3 files changed, 84 insertions(+)
 create mode 100755 tests/blockdev/004
 create mode 100644 tests/blockdev/004.out

diff --git a/tests/blockdev/004 b/tests/blockdev/004
new file mode 100755
index 0000000..decb4ad
--- /dev/null
+++ b/tests/blockdev/004
@@ -0,0 +1,81 @@
+#! /bin/bash
+# FS QA Test 004
+#
+# Check that live filesystem survives blockdev pagecache truncation.
+# blkdev page cache can be truncated due to various reasons
+# 1)ioctl: BLKDISCARD
+# 2)blkdev: falloc{ FALLOC_FL_ZERO_RANGE, FALLOC_FL_PUNCH_HOLE }
+# 3)nbd: NBD_CLEAR_SOCK
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2017 Dmitry Monakhov <dmonakhov@openvz.org>
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#-----------------------------------------------------------------------
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+_cleanup()
+{
+	$UMOUNT_PROG $fs_mnt
+	_destroy_loop_device $loop_dev
+	cd /
+	rm -rf $TEST_DIR/$$
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+
+rm -f $seqres.full
+
+# real QA test starts here
+_supported_fs generic
+_supported_os Linux
+_require_loop
+
+# create the fs image and mount point
+
+mkdir -p $TEST_DIR/$$ || _fail "Can not make test dir"
+fs_img=$TEST_DIR/$$/fs.img
+fs_mnt=$TEST_DIR/$$/mnt
+$XFS_IO_PROG -fc "truncate 1g" $fs_img >>$seqres.full 2>&1
+mkdir -p $fs_mnt
+loop_dev=$(_create_loop_device $fs_img)
+_mkfs_dev $loop_dev
+_mount $loop_dev $fs_mnt
+
+# Issue zeroout on block device, this act just a giant hammer for fs,
+# A lot of complains are expected, bug_on/panic is not.
+$XFS_IO_PROG -c "fzero -k 0 1G" -f $loop_dev >>$seqres.full 2>&1
+# Try IO on corrupted fs
+for ((i=0;i<1000;i++));do
+	$XFS_IO_PROG -fc "pwrite -S $i 0 16k" $fs_mnt/test-$i >>$seqres.full 2>&1
+done
+$XFS_IO_PROG -fc "fsync" $fs_mnt/test-0 >>$seqres.full 2>&1
+
+# success, all done
+echo "Silence is golden"
+status=0
+exit
diff --git a/tests/blockdev/004.out b/tests/blockdev/004.out
new file mode 100644
index 0000000..af8614a
--- /dev/null
+++ b/tests/blockdev/004.out
@@ -0,0 +1,2 @@
+QA output created by 004
+Silence is golden
diff --git a/tests/blockdev/group b/tests/blockdev/group
index e5ce864..d100c85 100644
--- a/tests/blockdev/group
+++ b/tests/blockdev/group
@@ -6,3 +6,4 @@
 001 rw blockdev
 002 rw blockdev liotarget
 003 rw blockdev liotarget integrity dangerous
+004 rw blockdev dangerous zero
-- 
2.9.3

^ permalink raw reply related

* [PATCH 3/6] new: blockdev/002 check information leak for lio-fileio
From: Dmitry Monakhov @ 2017-04-06 13:19 UTC (permalink / raw)
  To: fstests; +Cc: linux-fsdevel, linux-block, Dmitry Monakhov
In-Reply-To: <1491484750-9164-1-git-send-email-dmonakhov@openvz.org>

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 tests/blockdev/002     | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/blockdev/002.out | 12 ++++++++
 tests/blockdev/group   |  1 +
 3 files changed, 90 insertions(+)
 create mode 100755 tests/blockdev/002
 create mode 100644 tests/blockdev/002.out

diff --git a/tests/blockdev/002 b/tests/blockdev/002
new file mode 100755
index 0000000..71867d1
--- /dev/null
+++ b/tests/blockdev/002
@@ -0,0 +1,77 @@
+#! /bin/bash
+# FS QA Test 002
+#
+# Regression test for  information leak for lio-fileio target
+# BUG: If image  file is less than virtual blockdev then read() may return
+#      unitilized data.
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2017 Dmitry Monakhov <dmonakhov@openvz.org>
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#-----------------------------------------------------------------------
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+
+_cleanup()
+{
+	cd /
+	rm -f $tmp.*
+	_liotgt_cleanup
+	rm -rf $TEST_DIR/$$
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/liotarget
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_supported_os Linux
+_require_test
+_require_liotarget
+
+mkdir -p $TEST_DIR/$$ || _fail "Can not make test dir"
+
+cfg_path=$(_liotgt_create_fileio  002-test.img $TEST_DIR/$$/002-test.img 128M)
+dev=$(_liotgt_attach_target /backstores/fileio/002-test.img)
+
+$XFS_IO_PROG -f -c "truncate 1M" $TEST_DIR/$$/002-test.img >> $seqres.full
+
+$XFS_IO_PROG -c "pwrite -S 0xa0 -b 512 512 1k" -d $dev >>$seqres.full 2>&1 || \
+    _fail "pwrite failed"
+
+$XFS_IO_PROG -c "pwrite -S 0xab -b 512 2M 1k" -d $dev >>$seqres.full 2>&1 || \
+    _fail "pwrite failed"
+
+dd if=$dev bs=4k  2>>$seqres.full | hexdump
+# success, all done
+status=0
+exit
diff --git a/tests/blockdev/002.out b/tests/blockdev/002.out
new file mode 100644
index 0000000..e761c06
--- /dev/null
+++ b/tests/blockdev/002.out
@@ -0,0 +1,12 @@
+QA output created by 002
+0000000 0000 0000 0000 0000 0000 0000 0000 0000
+*
+0000200 a0a0 a0a0 a0a0 a0a0 a0a0 a0a0 a0a0 a0a0
+*
+0000600 0000 0000 0000 0000 0000 0000 0000 0000
+*
+0200000 abab abab abab abab abab abab abab abab
+*
+0200400 0000 0000 0000 0000 0000 0000 0000 0000
+*
+8000000
diff --git a/tests/blockdev/group b/tests/blockdev/group
index bdfdcb9..0b511f3 100644
--- a/tests/blockdev/group
+++ b/tests/blockdev/group
@@ -4,3 +4,4 @@
 # - comment line before each group is "new" description
 #
 001 rw blockdev
+002 rw blockdev liotarget
-- 
2.9.3

^ permalink raw reply related

* [PATCH 4/6] new: blockdev/003 basic blockdev T10-DIF-TYPE1 integrity checks
From: Dmitry Monakhov @ 2017-04-06 13:19 UTC (permalink / raw)
  To: fstests; +Cc: linux-fsdevel, linux-block, Dmitry Monakhov
In-Reply-To: <1491484750-9164-1-git-send-email-dmonakhov@openvz.org>

Test create virtual block device via lio-targed infastructure and
perform basic IO operations with data corruption detection.

Temprorally mark is as dangerous, because currently it trigger BUG_ON
inside blkdev_issue_flush

BTW: I use 'dd' to test read from corrupted image instead of xfs_io
because even if pread failed, xfs_io still exit with success, BUG?

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 tests/blockdev/003     | 164 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/blockdev/003.out |  39 ++++++++++++
 tests/blockdev/group   |   1 +
 3 files changed, 204 insertions(+)
 create mode 100755 tests/blockdev/003
 create mode 100644 tests/blockdev/003.out

diff --git a/tests/blockdev/003 b/tests/blockdev/003
new file mode 100755
index 0000000..8f31f0d
--- /dev/null
+++ b/tests/blockdev/003
@@ -0,0 +1,164 @@
+#! /bin/bash
+# FS QA Test 003
+#
+# Check basic T10-DIF integrity features for a block device
+#
+# DIF/DIX TYPE: T10-DIF-TYPE1-CRC
+# Kernel docs: Documentation/blockdev/data-integrity.txt
+#-----------------------------------------------------------------------
+# Copyright (c) 2017 Dmitry Monakhov <dmonakhov@openvz.org>
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#-----------------------------------------------------------------------
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+
+_cleanup()
+{
+	cd /
+	rm -f $tmp.*
+	_liotgt_cleanup
+	rm -rf $TEST_DIR/$$
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/liotarget
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# real QA test starts here
+
+# Modify as appropriate.
+_supported_fs generic
+_supported_os Linux
+_require_test
+_require_liotarget
+
+mkdir -p $TEST_DIR/$$ || _fail "Can not make test dir"
+
+# One full test suite
+_run_one()
+{
+	local img_name=$1
+
+	echo "Run: $img_name"
+	echo "T0: Test basic IO"
+	$XFS_IO_PROG -c "pwrite -S 0xa0 -b 4M 0 16M" -d $dev >>$seqres.full 2>&1 || \
+	    _fail "pwrite failed"
+
+	$XFS_IO_PROG -c "pwrite -S 0xa3 -b 1k -V8  20M 32k" -d $dev >>$seqres.full 2>&1 || \
+	    _fail "pwrite failed"
+
+	$XFS_IO_PROG -c "pwrite -S 0xa2 -b 1k -V8  2M 32k" -f $dev >>$seqres.full 2>&1 || \
+	    _fail "pwrite failed"
+
+	$XFS_IO_PROG -c "pwrite -S 0xa1 -b 4k  1536000 8k" -f $dev >>$seqres.full 2>&1 || \
+	    _fail "pwrite failed"
+
+	$XFS_IO_PROG -c "fsync" -d $dev >>$seqres.full 2>&1 || _fail "fsync failed"
+
+	echo "Check that buffered IO"
+	dd if=$dev bs=4k  2>>$seqres.full | md5sum
+	echo "Check that direct IO"
+	# Small requests will not being splitted
+	dd if=$dev bs=64k iflag=direct 2>>$seqres.full | md5sum
+	# Big requests may be splitted on flight, but result MUST be the same.
+	dd if=$dev bs=4M iflag=direct 2>>$seqres.full | md5sum
+
+	echo "Check csum corruption detection"
+	# LIO-fileio store t10 DIF data in separate file ${IMG}.protection
+	# struct t10_pi_tuple {
+	#	__be16 guard_tag;       /* Checksum */
+	#       __be16 app_tag;         /* Opaque storage */
+	#       __be32 ref_tag;         /* Target LBA or indirect LBA */
+	#}
+	# Play with 3000'th sector -> t10_pi_tuple offset == 3000 * 8 == 24000
+	#
+	echo "T1: Corrupt guard_tag, next read should fail"
+	$XFS_IO_PROG -c "pwrite -S 0xde -b2 24000 2 -w" \
+		     -f $TEST_DIR/$$/$img_name.protection >>$seqres.full 2>&1
+	dd if=$dev of=/dev/null bs=1M count=2 iflag=direct >>$seqres.full 2>&1 &&
+	    _fail "read should fail on 3000'th sector"
+
+	echo "T2: Check that unaffected blocks are still readable"
+	dd if=$dev of=/dev/null bs=1M count=1 iflag=direct >>$seqres.full 2>&1 || _fail "read failed"
+
+	echo "T3: Rewrite corrupted sector and check that read works"
+	$XFS_IO_PROG -c "pwrite -S 0xa1 -b 4k 1536000 4k" -d $dev >>$seqres.full 2>&1 || \
+	    _fail "pwrite failed"
+	dd if=$dev bs=2M count=1 iflag=direct >>$seqres.full 2>&1 || _fail "read failed"
+
+	echo "T4: Corrupt app_tag, should not affect read"
+	$XFS_IO_PROG -c "pwrite -S 0xde -b2 24002 2 -w" \
+		     -f $TEST_DIR/$$/$img_name.protection >>$seqres.full 2>&1
+	dd if=$dev bs=2M count=1 iflag=direct >>$seqres.full 2>&1 || _fail "read failed"
+
+	echo "T5: Corrupt ref_tag, next read should fail"
+	$XFS_IO_PROG -c "pwrite -S 0xde -b4 24004 4 -w"  \
+		     $TEST_DIR/$$/$img_name.protection  >>$seqres.full 2>&1
+	dd if=$dev of=/dev/null bs=1M count=2 iflag=direct >>$seqres.full 2>&1 &&
+	    _fail "read should fail on 3000'th sector"
+
+	echo "T6: Check that unaffected blocks are still readable"
+	dd if=$dev of=/dev/null bs=1M count=1 iflag=direct >>$seqres.full 2>&1 || _fail "read failed"
+
+	echo "T7: Rewrite corrupted sector and check that read works"
+	$XFS_IO_PROG -c "pwrite -S 0xa1 -b 4k 1536000 4k" -d $dev >>$seqres.full 2>&1 || \
+	    _fail "pwrite failed"
+
+	echo "Check that buffered and direct read works"
+	dd if=$dev bs=4k  2>>$seqres.full | md5sum
+	# Small requests will not being splitted
+	dd if=$dev bs=64k iflag=direct 2>>$seqres.full | md5sum
+	# Big requests may be splitted on flight, but result MUST be the same.
+	dd if=$dev bs=4M iflag=direct 2>>$seqres.full | md5sum
+}
+
+# Create virtual scsi target with internal csum verification
+name=dif-type1-w
+cfg_path=$(_liotgt_create_fileio $name $TEST_DIR/$$/$name 32M)
+
+_liotgt_set_attribute $cfg_path  pi_prot_type 1
+_liotgt_set_attribute $cfg_path  pi_prot_format 1
+_liotgt_set_attribute $cfg_path  pi_prot_verify 1
+dev=$(_liotgt_attach_target /backstores/fileio/$name)
+_run_one $name
+
+# Create virtual scsi target w/o internal csum verification,
+# check that core blk_integrity_profile->verify_fn works
+#
+name=dif-type1-wo
+cfg_path=$(_liotgt_create_fileio $name $TEST_DIR/$$/$name 32M)
+
+_liotgt_set_attribute $cfg_path  pi_prot_type 1
+_liotgt_set_attribute $cfg_path  pi_prot_format 1
+_liotgt_set_attribute $cfg_path  pi_prot_verify 0
+dev=$(_liotgt_attach_target /backstores/fileio/$name)
+_run_one $name
+
+status=0
+exit
diff --git a/tests/blockdev/003.out b/tests/blockdev/003.out
new file mode 100644
index 0000000..be2efbb
--- /dev/null
+++ b/tests/blockdev/003.out
@@ -0,0 +1,39 @@
+QA output created by 003
+Run: dif-type1-w
+T0: Test basic IO
+Check that buffered IO
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+Check that direct IO
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+Check csum corruption detection
+T1: Corrupt guard_tag, next read should fail
+T2: Check that unaffected blocks are still readable
+T3: Rewrite corrupted sector and check that read works
+T4: Corrupt app_tag, should not affect read
+T5: Corrupt ref_tag, next read should fail
+T6: Check that unaffected blocks are still readable
+T7: Rewrite corrupted sector and check that read works
+Check that buffered and direct read works
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+Run: dif-type1-wo
+T0: Test basic IO
+Check that buffered IO
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+Check that direct IO
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+Check csum corruption detection
+T1: Corrupt guard_tag, next read should fail
+T2: Check that unaffected blocks are still readable
+T3: Rewrite corrupted sector and check that read works
+T4: Corrupt app_tag, should not affect read
+T5: Corrupt ref_tag, next read should fail
+T6: Check that unaffected blocks are still readable
+T7: Rewrite corrupted sector and check that read works
+Check that buffered and direct read works
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+f18a6c9b9d69ff8ed61daa62dfab4341  -
+f18a6c9b9d69ff8ed61daa62dfab4341  -
diff --git a/tests/blockdev/group b/tests/blockdev/group
index 0b511f3..e5ce864 100644
--- a/tests/blockdev/group
+++ b/tests/blockdev/group
@@ -5,3 +5,4 @@
 #
 001 rw blockdev
 002 rw blockdev liotarget
+003 rw blockdev liotarget integrity dangerous
-- 
2.9.3

^ permalink raw reply related

* [PATCH 2/6] add: blockdev/001 check page-cache coherency after BLKDISCARD
From: Dmitry Monakhov @ 2017-04-06 13:19 UTC (permalink / raw)
  To: fstests; +Cc: linux-fsdevel, linux-block, Dmitry Monakhov
In-Reply-To: <1491484750-9164-1-git-send-email-dmonakhov@openvz.org>

Regression test for fix https://lkml.org/lkml/2017/3/22/789
Page cache should be dropped after successful discard

Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 common/config          |  1 +
 tests/blockdev/001     | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++
 tests/blockdev/001.out |  7 +++++
 tests/blockdev/group   |  6 ++++
 4 files changed, 88 insertions(+)
 create mode 100755 tests/blockdev/001
 create mode 100644 tests/blockdev/001.out
 create mode 100644 tests/blockdev/group

diff --git a/common/config b/common/config
index cfe7913..aef842c 100644
--- a/common/config
+++ b/common/config
@@ -199,6 +199,7 @@ export LOGGER_PROG="`set_prog_path logger`"
 export DBENCH_PROG="`set_prog_path dbench`"
 export DMSETUP_PROG="`set_prog_path dmsetup`"
 export WIPEFS_PROG="`set_prog_path wipefs`"
+export BLKDISCARD_PROG="`set_prog_path blkdiscard`"
 export DUMP_PROG="`set_prog_path dump`"
 export RESTORE_PROG="`set_prog_path restore`"
 export LVM_PROG="`set_prog_path lvm`"
diff --git a/tests/blockdev/001 b/tests/blockdev/001
new file mode 100755
index 0000000..53b0664
--- /dev/null
+++ b/tests/blockdev/001
@@ -0,0 +1,74 @@
+#! /bin/bash
+# FS QA Test 001
+#
+# Regression test for fix https://lkml.org/lkml/2017/3/22/789
+# Page cache should be dropped after successful discard
+#
+#-----------------------------------------------------------------------
+# Copyright (c) 2017 Dmitry Monakhov <dmonakhov@openvz.org>
+# All Rights Reserved.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#-----------------------------------------------------------------------
+#
+
+seq=`basename $0`
+seqres=$RESULT_DIR/$seq
+echo "QA output created by $seq"
+
+here=`pwd`
+tmp=/tmp/$$
+status=1	# failure is the default!
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+
+_cleanup()
+{
+	cd /
+	rm -f $tmp.*
+}
+
+# get standard environment, filters and checks
+. ./common/rc
+. ./common/filter
+. ./common/scsi_debug
+
+# remove previous $seqres.full before test
+rm -f $seqres.full
+
+# real QA test starts here
+_supported_fs generic
+_supported_os Linux
+_require_scsi_debug
+_require_command $BLKDISCARD_PROG blkdiscard
+
+
+# Create virtual device with unmap_zeroes_data support
+dev=$(_get_scsi_debug_dev 512 512 0 32 "lbpws=1 lbpws10=1")
+
+# Initialize data with known pattern
+$XFS_IO_PROG -c "pwrite -S 0xaa -b 2M 0 32M -w" -d $dev >>$seqres.full 2>&1 || \
+    _fail "pwrite failed"
+
+# Fill page cache with dirty data
+$XFS_IO_PROG -c "pwrite -S 0xbb -b 2M 2M 10M" -f $dev >>$seqres.full 2>&1 || \
+    _fail "pwrite failed"
+
+$BLKDISCARD_PROG $dev
+# After device was fully discarded, read sould return all zeroes
+dd if=$dev bs=4k  2>>$seqres.full | hexdump
+dd if=$dev bs=4M iflag=direct 2>>$seqres.full | hexdump
+# success, all done
+status=0
+exit
diff --git a/tests/blockdev/001.out b/tests/blockdev/001.out
new file mode 100644
index 0000000..0f81a92
--- /dev/null
+++ b/tests/blockdev/001.out
@@ -0,0 +1,7 @@
+QA output created by 001
+0000000 0000 0000 0000 0000 0000 0000 0000 0000
+*
+2000000
+0000000 0000 0000 0000 0000 0000 0000 0000 0000
+*
+2000000
diff --git a/tests/blockdev/group b/tests/blockdev/group
new file mode 100644
index 0000000..bdfdcb9
--- /dev/null
+++ b/tests/blockdev/group
@@ -0,0 +1,6 @@
+# QA groups control file
+# Defines test groups and nominal group owners
+# - do not start group names with a digit
+# - comment line before each group is "new" description
+#
+001 rw blockdev
-- 
2.9.3

^ permalink raw reply related

* [PATCH 1/6] add lio-target helpers
From: Dmitry Monakhov @ 2017-04-06 13:19 UTC (permalink / raw)
  To: fstests; +Cc: linux-fsdevel, linux-block, Dmitry Monakhov
In-Reply-To: <1491484750-9164-1-git-send-email-dmonakhov@openvz.org>

Linux-IO Target is very good framework for testing block backend.
It is more flexible than scsi_debug.

http://linux-iscsi.org/wiki/LIO
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
---
 common/config    |   2 +
 common/liotarget | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 113 insertions(+)
 create mode 100644 common/liotarget

diff --git a/common/config b/common/config
index 59041a3..cfe7913 100644
--- a/common/config
+++ b/common/config
@@ -212,6 +212,8 @@ export XZ_PROG="`set_prog_path xz`"
 export FLOCK_PROG="`set_prog_path flock`"
 export LDD_PROG="`set_prog_path ldd`"
 export TIMEOUT_PROG="`set_prog_path timeout`"
+export TARGETCLI_PROG="`set_prog_path targetcli`"
+export TARGETCTL_PROG="`set_prog_path targetctl`"
 
 # use 'udevadm settle' or 'udevsettle' to wait for lv to be settled.
 # newer systems have udevadm command but older systems like RHEL5 don't.
diff --git a/common/liotarget b/common/liotarget
new file mode 100644
index 0000000..f821692
--- /dev/null
+++ b/common/liotarget
@@ -0,0 +1,111 @@
+#!/bin/bash
+#
+# Copyright (c) 2017 Virtuozzo Inc
+# All Rights Reserved.
+#
+# Written by Dmitry Monakhov <dmonakhov@openvz.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it would be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write the Free Software Foundation,
+# Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#
+# Functions for Linux-IO Target manipulation
+#
+
+_require_liotarget()
+{
+	which $TARGETCLI_PROG >>$seqres.full 2>&1  || \
+	    _notrun "this test requires 'targetcli' tool"
+	which $TARGETCLI_PROG >>$seqres.full 2>&1  || \
+	    _notrun "this test requires 'targetcli' tool"
+
+	$TARGETCLI_PROG ls /backstores/ramdisk >>$seqres.full 2>&1 ||\
+	    _notrun "kernel compiled w/o CONFIG_TARGET_CORE"
+	$TARGETCLI_PROG ls /backstores/fileio >>$seqres.full 2>&1 ||\
+	    _notrun "kernel compiled w/o CONFIG_TCM_FILEIO"
+	$TARGETCLI_PROG ls /loopback >>$seqres.full 2>&1 ||\
+	    _notrun "kernel compiled w/o CONFIG_LOOPBACK_TARGET"
+}
+
+_liotgt_create_fileio()
+{
+	local name=$1
+	local img=$2
+	local sz=$3
+
+	$TARGETCLI_PROG /backstores/fileio create \
+			name=$name file_or_dev=$img  size=$sz >>$seqres.full ||\
+	    _fail "Can not create /backstores/fileio/$name"
+
+	local cfg_path=`ls -d /sys/kernel/config/target/core/fileio_*/$name`
+	[ -d "$cfg_path" ] || _fail "Bad config path"
+	echo $cfg_path
+}
+
+_liotgt_set_attribute()
+{
+	local path=$1
+	local attr_name=$2
+	local attr_val=$3
+
+	[ -f $path/attrib/$attr_name ] || _fail "Bad attribute $attr_name"
+	echo "echo $attr_val >  $path/attrib/$attr_name " >>$seqres.full
+	echo $attr_val >  $path/attrib/$attr_name
+}
+
+_liotgt_create_loopback()
+{
+	local out=`$TARGETCLI_PROG /loopback/ create 2>&1`
+	[ $? -eq 0 ] || _fail "Can not create loopback target"
+	echo $out >>$seqres.full
+
+	local naa=`echo $out | gawk '{ print $3 }'`
+	echo ${naa:0:20} >>$seqres.full
+
+	echo ${naa:0:20}
+}
+
+_liotgt_find_dev()
+{
+	local found=""
+	local name=$1
+	local drives=`find /sys/devices -type f -name model`
+	for d in $drives;do
+		local dir=`dirname $d`
+		local vendor=`cat $dir/vendor`
+		local model=`cat $dir/model`
+		if [ "${vendor//[[:space:]]/}" == "LIO-ORG" ] && \
+		       [ "${model//[[:space:]]/}" == "$name" ]; then
+			found=/dev/$(ls $dir/block)
+			break
+		fi
+	done
+	[ -z "$found" ] && _fail "Can not find device with backend $name"
+	echo "$found"
+}
+
+_liotgt_attach_target()
+{
+	local path=$1
+	local name=`basename $path`
+	local naa=$(_liotgt_create_loopback)
+
+	$TARGETCLI_PROG /loopback/$naa/luns create $path >>$seqres.full 2>&1 ||\
+	    _fail "Can not attach $path to tcm_loop"
+	_liotgt_find_dev $name
+}
+
+_liotgt_cleanup()
+{
+	$TARGETCTL_PROG clear
+}
-- 
2.9.3

^ permalink raw reply related

* [PATCH 0/6] RFC add blkdev tests v2
From: Dmitry Monakhov @ 2017-04-06 13:19 UTC (permalink / raw)
  To: fstests; +Cc: linux-fsdevel, linux-block, Dmitry Monakhov

During LSFMM we have discussed how to test lower-backend of linux IO-stack.
Main idea was that xfstests is the most obvious solution which cover
most use-cases filesystem do care about. There were reasonable objections
that xfstests is not ideal place for that, especially when they mixed
with pure FS specific ones.

My opinion is that it is worth to have blkdev tests here, in xfstests,
instead of not have it at all. But tests have to be placed to separate
namespace "tests/blockdev" to prevent confusion.

Please review my RFC and tell me: Is my proposal too ugly? And we have to
have completely separate framework for basic blockdev sanity checks.
Assumptions:
  - All new feature and regression tests should goes to "tests/blockdev"
  - All tests belongs to 'blockdev' group
  - Pure blkdev tests (tests which behavior is independent from fs) is not
    added to 'auto' group. So it will not affect normal fs testing flow.

TOC:
0001-add-lio-target-helpers.patch
0002-add-blockdev-001-check-page-cache-coherency-after-BLKDISCARD
0003-new-blockdev-002-check-information-leak-for-lio-file
0004-new-blockdev-003-basic-blockdev-T10-DIF-TYPE1-integr
0005-new-blockdev-004-Check-that-live-fs-survives-blkdev
0006-new-blockdev-005-Check-that-busy-fs-survives-blkdev

^ permalink raw reply

* Re: [RFC PATCH] loop: set queue logical block size
From: Hannes Reinecke @ 2017-04-06 12:21 UTC (permalink / raw)
  To: Ming Lei, Omar Sandoval; +Cc: linux-block, kernel-team
In-Reply-To: <20170406120309.GA32165@ming.t460p>

On 04/06/2017 02:03 PM, Ming Lei wrote:
> On Thu, Apr 06, 2017 at 04:43:18PM +0800, Ming Lei wrote:
>> On Thu, Apr 06, 2017 at 01:19:45AM -0700, Omar Sandoval wrote:
>>> From: Omar Sandoval <osandov@fb.com>
>>>
>>> The request queue created when we create a loop device has the default
>>> logical block size of 512. When we associate the device with an fd, we
>>> set the block size on the block_device but don't update the logical
>>> block size of the request_queue. This makes it impossibe to use direct
>>> I/O with a backing file on a device with a block size >512, as the
>>> following check in __loop_update_dio() fails:
>>>
>>> 	sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
>>> 	if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
>>> 	    ...
>>>
>>> Fix it by updating the logical block size when we set the fd.
>>>
>>> Signed-off-by: Omar Sandoval <osandov@fb.com>
>>> ---
>>>  drivers/block/loop.c | 1 +
>>>  1 file changed, 1 insertion(+)
>>>
>>> diff --git a/drivers/block/loop.c b/drivers/block/loop.c
>>> index cc981f34e017..1bb22903ad1a 100644
>>> --- a/drivers/block/loop.c
>>> +++ b/drivers/block/loop.c
>>> @@ -941,6 +941,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
>>>  	/* let user-space know about the new size */
>>>  	kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
>>>  
>>> +	blk_queue_logical_block_size(lo->lo_queue, lo_blocksize);
>>>  	set_blocksize(bdev, lo_blocksize);
>>>  
>>>  	lo->lo_state = Lo_bound;
>>
>> Looks fine!
>>
>> Reviewed-by: Ming Lei <minlei@redhat.com>
> 
> Turns out I am wrong, and we can't change logical block size in this way
> because we need to support 512 byte sector filesystem image on backing
> device with bigger sector size.
> 
> And we don't support dio in this situation yet, but Hannes Reinecke's
> patch might help this case. So I have to recall the reviewed-by.
> 
Yes, please!

I've been waiting for it far too long.
Should I repost them?

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		   Teamlead Storage & Networking
hare@suse.de			               +49 911 74053 688
SUSE LINUX GmbH, Maxfeldstr. 5, 90409 N�rnberg
GF: F. Imend�rffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton
HRB 21284 (AG N�rnberg)

^ permalink raw reply

* Re: [RFC PATCH] loop: set queue logical block size
From: Ming Lei @ 2017-04-06 12:03 UTC (permalink / raw)
  To: Omar Sandoval; +Cc: linux-block, kernel-team
In-Reply-To: <20170406084313.GA4197@ming.t460p>

On Thu, Apr 06, 2017 at 04:43:18PM +0800, Ming Lei wrote:
> On Thu, Apr 06, 2017 at 01:19:45AM -0700, Omar Sandoval wrote:
> > From: Omar Sandoval <osandov@fb.com>
> > 
> > The request queue created when we create a loop device has the default
> > logical block size of 512. When we associate the device with an fd, we
> > set the block size on the block_device but don't update the logical
> > block size of the request_queue. This makes it impossibe to use direct
> > I/O with a backing file on a device with a block size >512, as the
> > following check in __loop_update_dio() fails:
> > 
> > 	sb_bsize = bdev_logical_block_size(inode->i_sb->s_bdev);
> > 	if (queue_logical_block_size(lo->lo_queue) >= sb_bsize &&
> > 	    ...
> > 
> > Fix it by updating the logical block size when we set the fd.
> > 
> > Signed-off-by: Omar Sandoval <osandov@fb.com>
> > ---
> >  drivers/block/loop.c | 1 +
> >  1 file changed, 1 insertion(+)
> > 
> > diff --git a/drivers/block/loop.c b/drivers/block/loop.c
> > index cc981f34e017..1bb22903ad1a 100644
> > --- a/drivers/block/loop.c
> > +++ b/drivers/block/loop.c
> > @@ -941,6 +941,7 @@ static int loop_set_fd(struct loop_device *lo, fmode_t mode,
> >  	/* let user-space know about the new size */
> >  	kobject_uevent(&disk_to_dev(bdev->bd_disk)->kobj, KOBJ_CHANGE);
> >  
> > +	blk_queue_logical_block_size(lo->lo_queue, lo_blocksize);
> >  	set_blocksize(bdev, lo_blocksize);
> >  
> >  	lo->lo_state = Lo_bound;
> 
> Looks fine!
> 
> Reviewed-by: Ming Lei <minlei@redhat.com>

Turns out I am wrong, and we can't change logical block size in this way
because we need to support 512 byte sector filesystem image on backing
device with bigger sector size.

And we don't support dio in this situation yet, but Hannes Reinecke's
patch might help this case. So I have to recall the reviewed-by.

Sorry for the noise, :-(

Thanks,
Ming

^ permalink raw reply

* Re: [PATCH] blk-mq-pci: Remove unneeded includes
From: Sagi Grimberg @ 2017-04-06 11:58 UTC (permalink / raw)
  To: Christoph Hellwig; +Cc: Jens Axboe, linux-block, Stephen Rothwell
In-Reply-To: <20170406115144.GA4786@lst.de>

> Stephen added the first two includes after a linux-next build
> failure.  Did this go through a long buildbot cycle to verify
> it's really not needed anymore?

Umm no. I just compiled it and ran and it worked...

If these are actually needed then we can safely discard
this patch.

^ permalink raw reply

* Re: [PATCH] blk-mq-pci: Remove unneeded includes
From: Christoph Hellwig @ 2017-04-06 11:51 UTC (permalink / raw)
  To: Sagi Grimberg; +Cc: Jens Axboe, linux-block, Stephen Rothwell
In-Reply-To: <1491474816-15422-1-git-send-email-sagi@grimberg.me>

Stephen added the first two includes after a linux-next build
failure.  Did this go through a long buildbot cycle to verify
it's really not needed anymore?

On Thu, Apr 06, 2017 at 01:33:36PM +0300, Sagi Grimberg wrote:
> Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
> ---
>  block/blk-mq-pci.c | 3 ---
>  1 file changed, 3 deletions(-)
> 
> diff --git a/block/blk-mq-pci.c b/block/blk-mq-pci.c
> index 0c3354cf3552..70b8a6765cc7 100644
> --- a/block/blk-mq-pci.c
> +++ b/block/blk-mq-pci.c
> @@ -10,12 +10,9 @@
>   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
>   * more details.
>   */
> -#include <linux/kobject.h>
> -#include <linux/blkdev.h>
>  #include <linux/blk-mq.h>
>  #include <linux/blk-mq-pci.h>
>  #include <linux/pci.h>
> -#include <linux/module.h>
>  
>  /**
>   * blk_mq_pci_map_queues - provide a default queue mapping for PCI device
> -- 
> 2.7.4
---end quoted text---

^ permalink raw reply

* Re: [PATCH 9/9] bio-integrity: Restore original iterator on verify stage
From: Christoph Hellwig @ 2017-04-06 11:49 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-kernel, linux-block, martin.petersen
In-Reply-To: <1491332201-26926-10-git-send-email-dmonakhov@openvz.org>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply

* Re: [PATCH 8/9] bio: add bvec_iter rewind API
From: Christoph Hellwig @ 2017-04-06 11:49 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-kernel, linux-block, martin.petersen
In-Reply-To: <1491332201-26926-9-git-send-email-dmonakhov@openvz.org>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

On Tue, Apr 04, 2017 at 10:56:40PM +0400, Dmitry Monakhov wrote:
> Some ->bi_end_io handlers (for example: pi_verify or decrypt handlers)

Just curious: are you planning to use it for the latter as well in
future patches?  If not can you at least give the relevant maintainers
a headsup?

^ permalink raw reply

* Re: [PATCH 7/9] Guard bvec iteration logic v3
From: Christoph Hellwig @ 2017-04-06 11:46 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-kernel, linux-block, martin.petersen
In-Reply-To: <1491332201-26926-8-git-send-email-dmonakhov@openvz.org>

>  	if (bio_no_advance_iter(bio))
>  		iter->bi_size -= bytes;
> -	else
> -		bvec_iter_advance(bio->bi_io_vec, iter, bytes);
> +	else {
> +		int err;
> +		err = bvec_iter_advance(bio->bi_io_vec, iter, bytes);
> +		if (unlikely(err))
> +			bio->bi_error = err;
> +	}

I don't think that setting bi_error here is a good idea without actually
completing the bio, which would be a much bigger change.

Maybe leave the error ignored here for now with a fixme comment, and
then we can look into proper error handling in a separate series.

^ permalink raw reply

* Re: [PATCH 6/9] T10: Move opencoded contants to common header
From: Christoph Hellwig @ 2017-04-06 11:44 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-kernel, linux-block, martin.petersen
In-Reply-To: <1491332201-26926-7-git-send-email-dmonakhov@openvz.org>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply

* Re: [PATCH 5/9] bio-integrity: fold bio_integrity_enabled to bio_integrity_prep
From: Christoph Hellwig @ 2017-04-06 11:43 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-kernel, linux-block, martin.petersen
In-Reply-To: <1491332201-26926-6-git-send-email-dmonakhov@openvz.org>

> --- a/Documentation/block/data-integrity.txt
> +++ b/Documentation/block/data-integrity.txt
> @@ -202,9 +202,6 @@ will require extra work due to the application tag.
>        added.  It is up to the caller to ensure that the bio does not
>        change while I/O is in progress.
>  
> -      bio_integrity_prep() should only be called if
> -      bio_integrity_enabled() returned 1.
> -

This should grow a blurb that bio_integrity_prep will complete the bio
if an error occurs.

>  /**
> - * bio_integrity_prep - Prepare bio for integrity I/O
> + * bio_integrity_setup - Prepare bio for integrity I/O
>   * @bio:	bio to prepare
>   *
>   * Description: Allocates a buffer for integrity metadata, maps the
> @@ -269,7 +231,7 @@ static int bio_integrity_process(struct bio *bio,
>   * block device's integrity function.  In the READ case, the buffer
>   * will be prepared for DMA and a suitable end_io handler set up.
>   */
> -int bio_integrity_prep(struct bio *bio)
> +static int bio_integrity_setup(struct bio *bio)

Instead of renaming the function I'd suggest simply merging the two,
the end result will be smaller and more readable.

> +	if (bio_data_dir(bio) == READ && bi->profile->verify_fn != NULL &&
> +	    (bi->flags & BLK_INTEGRITY_VERIFY))
> +		goto need_prep;
> +
> +	if (bio_data_dir(bio) == WRITE && bi->profile->generate_fn != NULL &&
> +	    (bi->flags & BLK_INTEGRITY_GENERATE))
> +		goto need_prep;

I'd invert the conditions to avoid the goto:

	if (bio_data_dir(bio) == READ) {
		if (!bi->profile->verify_fn ||
		    !(bi->flags & BLK_INTEGRITY_VERIFY))
			return 0;
	} else {
		if (!bi->profile->generate_fn ||
		    !(bi->flags & BLK_INTEGRITY_GENERATE))
			return 0;
	}

^ permalink raw reply

* Re: [PATCH 4/9] bio-integrity: fix interface for bio_integrity_trim v2
From: Christoph Hellwig @ 2017-04-06 11:36 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-kernel, linux-block, martin.petersen
In-Reply-To: <1491332201-26926-5-git-send-email-dmonakhov@openvz.org>

Please drop the v2 from the subject line and move your changelog either
into the cover letter (preferred) or at least below the --- line.

Otherwise looks good:

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply

* Re: [PATCH 3/9] bio-integrity:  bio_integrity_advance must update integrity seed
From: Christoph Hellwig @ 2017-04-06 11:35 UTC (permalink / raw)
  To: Dmitry Monakhov; +Cc: linux-kernel, linux-block, martin.petersen
In-Reply-To: <1491332201-26926-4-git-send-email-dmonakhov@openvz.org>

Looks good,

Reviewed-by: Christoph Hellwig <hch@lst.de>

^ permalink raw reply

* [PATCH] remove the mg_disk driver
From: Christoph Hellwig @ 2017-04-06 11:28 UTC (permalink / raw)
  To: axboe, donari75; +Cc: linux-block

This drivers was added in 2008, but as far as a I can tell we never had a
single platform that actually registered resources for the platform driver.

It's also been unmaintained for a long time and apparently has a ATA mode
that can be driven using the IDE/libata subsystem.

Signed-off-by: Christoph Hellwig <hch@lst.de>
---
 Documentation/blockdev/mflash.txt |   84 ---
 drivers/block/Kconfig             |   17 -
 drivers/block/Makefile            |    1 -
 drivers/block/mg_disk.c           | 1110 -------------------------------------
 include/linux/mg_disk.h           |   45 --
 5 files changed, 1257 deletions(-)
 delete mode 100644 Documentation/blockdev/mflash.txt
 delete mode 100644 drivers/block/mg_disk.c
 delete mode 100644 include/linux/mg_disk.h

diff --git a/Documentation/blockdev/mflash.txt b/Documentation/blockdev/mflash.txt
deleted file mode 100644
index f7e050551487..000000000000
--- a/Documentation/blockdev/mflash.txt
+++ /dev/null
@@ -1,84 +0,0 @@
-This document describes m[g]flash support in linux.
-
-Contents
-  1. Overview
-  2. Reserved area configuration
-  3. Example of mflash platform driver registration
-
-1. Overview
-
-Mflash and gflash are embedded flash drive. The only difference is mflash is
-MCP(Multi Chip Package) device. These two device operate exactly same way.
-So the rest mflash repersents mflash and gflash altogether.
-
-Internally, mflash has nand flash and other hardware logics and supports
-2 different operation (ATA, IO) modes. ATA mode doesn't need any new
-driver and currently works well under standard IDE subsystem. Actually it's
-one chip SSD. IO mode is ATA-like custom mode for the host that doesn't have
-IDE interface.
-
-Following are brief descriptions about IO mode.
-A. IO mode based on ATA protocol and uses some custom command. (read confirm,
-write confirm)
-B. IO mode uses SRAM bus interface.
-C. IO mode supports 4kB boot area, so host can boot from mflash.
-
-2. Reserved area configuration
-If host boot from mflash, usually needs raw area for boot loader image. All of
-the mflash's block device operation will be taken this value as start offset.
-Note that boot loader's size of reserved area and kernel configuration value
-must be same.
-
-3. Example of mflash platform driver registration
-Working mflash is very straight forward. Adding platform device stuff to board
-configuration file is all. Here is some pseudo example.
-
-static struct mg_drv_data mflash_drv_data = {
-	/* If you want to polling driver set to 1 */
-	.use_polling = 0,
-	/* device attribution */
-	.dev_attr = MG_BOOT_DEV
-};
-
-static struct resource mg_mflash_rsc[] = {
-	/* Base address of mflash */
-	[0] = {
-		.start = 0x08000000,
-		.end = 0x08000000 + SZ_64K - 1,
-		.flags = IORESOURCE_MEM
-	},
-	/* mflash interrupt pin */
-	[1] = {
-		.start = IRQ_GPIO(84),
-		.end = IRQ_GPIO(84),
-		.flags = IORESOURCE_IRQ
-	},
-	/* mflash reset pin */
-	[2] = {
-		.start = 43,
-		.end = 43,
-		.name = MG_RST_PIN,
-		.flags = IORESOURCE_IO
-	},
-	/* mflash reset-out pin
-	 * If you use mflash as storage device (i.e. other than MG_BOOT_DEV),
-	 * should assign this */
-	[3] = {
-		.start = 51,
-		.end = 51,
-		.name = MG_RSTOUT_PIN,
-		.flags = IORESOURCE_IO
-	}
-};
-
-static struct platform_device mflash_dev = {
-	.name = MG_DEV_NAME,
-	.id = -1,
-	.dev = {
-		.platform_data = &mflash_drv_data,
-	},
-	.num_resources = ARRAY_SIZE(mg_mflash_rsc),
-	.resource = mg_mflash_rsc
-};
-
-platform_device_register(&mflash_dev);
diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig
index a1c2e816128f..ebe8c1a6195e 100644
--- a/drivers/block/Kconfig
+++ b/drivers/block/Kconfig
@@ -434,23 +434,6 @@ config ATA_OVER_ETH
 	This driver provides Support for ATA over Ethernet block
 	devices like the Coraid EtherDrive (R) Storage Blade.
 
-config MG_DISK
-	tristate "mGine mflash, gflash support"
-	depends on ARM && GPIOLIB
-	help
-	  mGine mFlash(gFlash) block device driver
-
-config MG_DISK_RES
-	int "Size of reserved area before MBR"
-	depends on MG_DISK
-	default 0
-	help
-	  Define size of reserved area that usually used for boot. Unit is KB.
-	  All of the block device operation will be taken this value as start
-	  offset
-	  Examples:
-			1024 => 1 MB
-
 config SUNVDC
 	tristate "Sun Virtual Disk Client support"
 	depends on SUN_LDOMS
diff --git a/drivers/block/Makefile b/drivers/block/Makefile
index b12c772bbeb3..5ceead8b52d7 100644
--- a/drivers/block/Makefile
+++ b/drivers/block/Makefile
@@ -19,7 +19,6 @@ obj-$(CONFIG_BLK_CPQ_CISS_DA)  += cciss.o
 obj-$(CONFIG_BLK_DEV_DAC960)	+= DAC960.o
 obj-$(CONFIG_XILINX_SYSACE)	+= xsysace.o
 obj-$(CONFIG_CDROM_PKTCDVD)	+= pktcdvd.o
-obj-$(CONFIG_MG_DISK)		+= mg_disk.o
 obj-$(CONFIG_SUNVDC)		+= sunvdc.o
 obj-$(CONFIG_BLK_DEV_SKD)	+= skd.o
 obj-$(CONFIG_BLK_DEV_OSD)	+= osdblk.o
diff --git a/drivers/block/mg_disk.c b/drivers/block/mg_disk.c
deleted file mode 100644
index e88e7b06c616..000000000000
--- a/drivers/block/mg_disk.c
+++ /dev/null
@@ -1,1110 +0,0 @@
-/*
- *  drivers/block/mg_disk.c
- *
- *  Support for the mGine m[g]flash IO mode.
- *  Based on legacy hd.c
- *
- * (c) 2008 mGine Co.,LTD
- * (c) 2008 unsik Kim <donari75@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/fs.h>
-#include <linux/blkdev.h>
-#include <linux/hdreg.h>
-#include <linux/ata.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/mg_disk.h>
-#include <linux/slab.h>
-
-#define MG_RES_SEC (CONFIG_MG_DISK_RES << 1)
-
-/* name for block device */
-#define MG_DISK_NAME "mgd"
-
-#define MG_DISK_MAJ 0
-#define MG_DISK_MAX_PART 16
-#define MG_SECTOR_SIZE 512
-#define MG_MAX_SECTS 256
-
-/* Register offsets */
-#define MG_BUFF_OFFSET			0x8000
-#define MG_REG_OFFSET			0xC000
-#define MG_REG_FEATURE			(MG_REG_OFFSET + 2)	/* write case */
-#define MG_REG_ERROR			(MG_REG_OFFSET + 2)	/* read case */
-#define MG_REG_SECT_CNT			(MG_REG_OFFSET + 4)
-#define MG_REG_SECT_NUM			(MG_REG_OFFSET + 6)
-#define MG_REG_CYL_LOW			(MG_REG_OFFSET + 8)
-#define MG_REG_CYL_HIGH			(MG_REG_OFFSET + 0xA)
-#define MG_REG_DRV_HEAD			(MG_REG_OFFSET + 0xC)
-#define MG_REG_COMMAND			(MG_REG_OFFSET + 0xE)	/* write case */
-#define MG_REG_STATUS			(MG_REG_OFFSET + 0xE)	/* read  case */
-#define MG_REG_DRV_CTRL			(MG_REG_OFFSET + 0x10)
-#define MG_REG_BURST_CTRL		(MG_REG_OFFSET + 0x12)
-
-/* handy status */
-#define MG_STAT_READY	(ATA_DRDY | ATA_DSC)
-#define MG_READY_OK(s)	(((s) & (MG_STAT_READY | (ATA_BUSY | ATA_DF | \
-				 ATA_ERR))) == MG_STAT_READY)
-
-/* error code for others */
-#define MG_ERR_NONE		0
-#define MG_ERR_TIMEOUT		0x100
-#define MG_ERR_INIT_STAT	0x101
-#define MG_ERR_TRANSLATION	0x102
-#define MG_ERR_CTRL_RST		0x103
-#define MG_ERR_INV_STAT		0x104
-#define MG_ERR_RSTOUT		0x105
-
-#define MG_MAX_ERRORS	6	/* Max read/write errors */
-
-/* command */
-#define MG_CMD_RD 0x20
-#define MG_CMD_WR 0x30
-#define MG_CMD_SLEEP 0x99
-#define MG_CMD_WAKEUP 0xC3
-#define MG_CMD_ID 0xEC
-#define MG_CMD_WR_CONF 0x3C
-#define MG_CMD_RD_CONF 0x40
-
-/* operation mode */
-#define MG_OP_CASCADE (1 << 0)
-#define MG_OP_CASCADE_SYNC_RD (1 << 1)
-#define MG_OP_CASCADE_SYNC_WR (1 << 2)
-#define MG_OP_INTERLEAVE (1 << 3)
-
-/* synchronous */
-#define MG_BURST_LAT_4 (3 << 4)
-#define MG_BURST_LAT_5 (4 << 4)
-#define MG_BURST_LAT_6 (5 << 4)
-#define MG_BURST_LAT_7 (6 << 4)
-#define MG_BURST_LAT_8 (7 << 4)
-#define MG_BURST_LEN_4 (1 << 1)
-#define MG_BURST_LEN_8 (2 << 1)
-#define MG_BURST_LEN_16 (3 << 1)
-#define MG_BURST_LEN_32 (4 << 1)
-#define MG_BURST_LEN_CONT (0 << 1)
-
-/* timeout value (unit: ms) */
-#define MG_TMAX_CONF_TO_CMD	1
-#define MG_TMAX_WAIT_RD_DRQ	10
-#define MG_TMAX_WAIT_WR_DRQ	500
-#define MG_TMAX_RST_TO_BUSY	10
-#define MG_TMAX_HDRST_TO_RDY	500
-#define MG_TMAX_SWRST_TO_RDY	500
-#define MG_TMAX_RSTOUT		3000
-
-#define MG_DEV_MASK (MG_BOOT_DEV | MG_STORAGE_DEV | MG_STORAGE_DEV_SKIP_RST)
-
-/* main structure for mflash driver */
-struct mg_host {
-	struct device *dev;
-
-	struct request_queue *breq;
-	struct request *req;
-	spinlock_t lock;
-	struct gendisk *gd;
-
-	struct timer_list timer;
-	void (*mg_do_intr) (struct mg_host *);
-
-	u16 id[ATA_ID_WORDS];
-
-	u16 cyls;
-	u16 heads;
-	u16 sectors;
-	u32 n_sectors;
-	u32 nres_sectors;
-
-	void __iomem *dev_base;
-	unsigned int irq;
-	unsigned int rst;
-	unsigned int rstout;
-
-	u32 major;
-	u32 error;
-};
-
-/*
- * Debugging macro and defines
- */
-#undef DO_MG_DEBUG
-#ifdef DO_MG_DEBUG
-#  define MG_DBG(fmt, args...) \
-	printk(KERN_DEBUG "%s:%d "fmt, __func__, __LINE__, ##args)
-#else /* CONFIG_MG_DEBUG */
-#  define MG_DBG(fmt, args...) do { } while (0)
-#endif /* CONFIG_MG_DEBUG */
-
-static void mg_request(struct request_queue *);
-
-static bool mg_end_request(struct mg_host *host, int err, unsigned int nr_bytes)
-{
-	if (__blk_end_request(host->req, err, nr_bytes))
-		return true;
-
-	host->req = NULL;
-	return false;
-}
-
-static bool mg_end_request_cur(struct mg_host *host, int err)
-{
-	return mg_end_request(host, err, blk_rq_cur_bytes(host->req));
-}
-
-static void mg_dump_status(const char *msg, unsigned int stat,
-		struct mg_host *host)
-{
-	char *name = MG_DISK_NAME;
-
-	if (host->req)
-		name = host->req->rq_disk->disk_name;
-
-	printk(KERN_ERR "%s: %s: status=0x%02x { ", name, msg, stat & 0xff);
-	if (stat & ATA_BUSY)
-		printk("Busy ");
-	if (stat & ATA_DRDY)
-		printk("DriveReady ");
-	if (stat & ATA_DF)
-		printk("WriteFault ");
-	if (stat & ATA_DSC)
-		printk("SeekComplete ");
-	if (stat & ATA_DRQ)
-		printk("DataRequest ");
-	if (stat & ATA_CORR)
-		printk("CorrectedError ");
-	if (stat & ATA_ERR)
-		printk("Error ");
-	printk("}\n");
-	if ((stat & ATA_ERR) == 0) {
-		host->error = 0;
-	} else {
-		host->error = inb((unsigned long)host->dev_base + MG_REG_ERROR);
-		printk(KERN_ERR "%s: %s: error=0x%02x { ", name, msg,
-				host->error & 0xff);
-		if (host->error & ATA_BBK)
-			printk("BadSector ");
-		if (host->error & ATA_UNC)
-			printk("UncorrectableError ");
-		if (host->error & ATA_IDNF)
-			printk("SectorIdNotFound ");
-		if (host->error & ATA_ABORTED)
-			printk("DriveStatusError ");
-		if (host->error & ATA_AMNF)
-			printk("AddrMarkNotFound ");
-		printk("}");
-		if (host->error & (ATA_BBK | ATA_UNC | ATA_IDNF | ATA_AMNF)) {
-			if (host->req)
-				printk(", sector=%u",
-				       (unsigned int)blk_rq_pos(host->req));
-		}
-		printk("\n");
-	}
-}
-
-static unsigned int mg_wait(struct mg_host *host, u32 expect, u32 msec)
-{
-	u8 status;
-	unsigned long expire, cur_jiffies;
-	struct mg_drv_data *prv_data = host->dev->platform_data;
-
-	host->error = MG_ERR_NONE;
-	expire = jiffies + msecs_to_jiffies(msec);
-
-	/* These 2 times dummy status read prevents reading invalid
-	 * status. A very little time (3 times of mflash operating clk)
-	 * is required for busy bit is set. Use dummy read instead of
-	 * busy wait, because mflash's PLL is machine dependent.
-	 */
-	if (prv_data->use_polling) {
-		status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
-		status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
-	}
-
-	status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
-
-	do {
-		cur_jiffies = jiffies;
-		if (status & ATA_BUSY) {
-			if (expect == ATA_BUSY)
-				break;
-		} else {
-			/* Check the error condition! */
-			if (status & ATA_ERR) {
-				mg_dump_status("mg_wait", status, host);
-				break;
-			}
-
-			if (expect == MG_STAT_READY)
-				if (MG_READY_OK(status))
-					break;
-
-			if (expect == ATA_DRQ)
-				if (status & ATA_DRQ)
-					break;
-		}
-		if (!msec) {
-			mg_dump_status("not ready", status, host);
-			return MG_ERR_INV_STAT;
-		}
-
-		status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
-	} while (time_before(cur_jiffies, expire));
-
-	if (time_after_eq(cur_jiffies, expire) && msec)
-		host->error = MG_ERR_TIMEOUT;
-
-	return host->error;
-}
-
-static unsigned int mg_wait_rstout(u32 rstout, u32 msec)
-{
-	unsigned long expire;
-
-	expire = jiffies + msecs_to_jiffies(msec);
-	while (time_before(jiffies, expire)) {
-		if (gpio_get_value(rstout) == 1)
-			return MG_ERR_NONE;
-		msleep(10);
-	}
-
-	return MG_ERR_RSTOUT;
-}
-
-static void mg_unexpected_intr(struct mg_host *host)
-{
-	u32 status = inb((unsigned long)host->dev_base + MG_REG_STATUS);
-
-	mg_dump_status("mg_unexpected_intr", status, host);
-}
-
-static irqreturn_t mg_irq(int irq, void *dev_id)
-{
-	struct mg_host *host = dev_id;
-	void (*handler)(struct mg_host *) = host->mg_do_intr;
-
-	spin_lock(&host->lock);
-
-	host->mg_do_intr = NULL;
-	del_timer(&host->timer);
-	if (!handler)
-		handler = mg_unexpected_intr;
-	handler(host);
-
-	spin_unlock(&host->lock);
-
-	return IRQ_HANDLED;
-}
-
-/* local copy of ata_id_string() */
-static void mg_id_string(const u16 *id, unsigned char *s,
-			 unsigned int ofs, unsigned int len)
-{
-	unsigned int c;
-
-	BUG_ON(len & 1);
-
-	while (len > 0) {
-		c = id[ofs] >> 8;
-		*s = c;
-		s++;
-
-		c = id[ofs] & 0xff;
-		*s = c;
-		s++;
-
-		ofs++;
-		len -= 2;
-	}
-}
-
-/* local copy of ata_id_c_string() */
-static void mg_id_c_string(const u16 *id, unsigned char *s,
-			   unsigned int ofs, unsigned int len)
-{
-	unsigned char *p;
-
-	mg_id_string(id, s, ofs, len - 1);
-
-	p = s + strnlen(s, len - 1);
-	while (p > s && p[-1] == ' ')
-		p--;
-	*p = '\0';
-}
-
-static int mg_get_disk_id(struct mg_host *host)
-{
-	u32 i;
-	s32 err;
-	const u16 *id = host->id;
-	struct mg_drv_data *prv_data = host->dev->platform_data;
-	char fwrev[ATA_ID_FW_REV_LEN + 1];
-	char model[ATA_ID_PROD_LEN + 1];
-	char serial[ATA_ID_SERNO_LEN + 1];
-
-	if (!prv_data->use_polling)
-		outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-
-	outb(MG_CMD_ID, (unsigned long)host->dev_base + MG_REG_COMMAND);
-	err = mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_RD_DRQ);
-	if (err)
-		return err;
-
-	for (i = 0; i < (MG_SECTOR_SIZE >> 1); i++)
-		host->id[i] = le16_to_cpu(inw((unsigned long)host->dev_base +
-					MG_BUFF_OFFSET + i * 2));
-
-	outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
-	err = mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD);
-	if (err)
-		return err;
-
-	if ((id[ATA_ID_FIELD_VALID] & 1) == 0)
-		return MG_ERR_TRANSLATION;
-
-	host->n_sectors = ata_id_u32(id, ATA_ID_LBA_CAPACITY);
-	host->cyls = id[ATA_ID_CYLS];
-	host->heads = id[ATA_ID_HEADS];
-	host->sectors = id[ATA_ID_SECTORS];
-
-	if (MG_RES_SEC && host->heads && host->sectors) {
-		/* modify cyls, n_sectors */
-		host->cyls = (host->n_sectors - MG_RES_SEC) /
-			host->heads / host->sectors;
-		host->nres_sectors = host->n_sectors - host->cyls *
-			host->heads * host->sectors;
-		host->n_sectors -= host->nres_sectors;
-	}
-
-	mg_id_c_string(id, fwrev, ATA_ID_FW_REV, sizeof(fwrev));
-	mg_id_c_string(id, model, ATA_ID_PROD, sizeof(model));
-	mg_id_c_string(id, serial, ATA_ID_SERNO, sizeof(serial));
-	printk(KERN_INFO "mg_disk: model: %s\n", model);
-	printk(KERN_INFO "mg_disk: firm: %.8s\n", fwrev);
-	printk(KERN_INFO "mg_disk: serial: %s\n", serial);
-	printk(KERN_INFO "mg_disk: %d + reserved %d sectors\n",
-			host->n_sectors, host->nres_sectors);
-
-	if (!prv_data->use_polling)
-		outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-
-	return err;
-}
-
-
-static int mg_disk_init(struct mg_host *host)
-{
-	struct mg_drv_data *prv_data = host->dev->platform_data;
-	s32 err;
-	u8 init_status;
-
-	/* hdd rst low */
-	gpio_set_value(host->rst, 0);
-	err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY);
-	if (err)
-		return err;
-
-	/* hdd rst high */
-	gpio_set_value(host->rst, 1);
-	err = mg_wait(host, MG_STAT_READY, MG_TMAX_HDRST_TO_RDY);
-	if (err)
-		return err;
-
-	/* soft reset on */
-	outb(ATA_SRST | (prv_data->use_polling ? ATA_NIEN : 0),
-			(unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-	err = mg_wait(host, ATA_BUSY, MG_TMAX_RST_TO_BUSY);
-	if (err)
-		return err;
-
-	/* soft reset off */
-	outb(prv_data->use_polling ? ATA_NIEN : 0,
-			(unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-	err = mg_wait(host, MG_STAT_READY, MG_TMAX_SWRST_TO_RDY);
-	if (err)
-		return err;
-
-	init_status = inb((unsigned long)host->dev_base + MG_REG_STATUS) & 0xf;
-
-	if (init_status == 0xf)
-		return MG_ERR_INIT_STAT;
-
-	return err;
-}
-
-static void mg_bad_rw_intr(struct mg_host *host)
-{
-	if (host->req)
-		if (++host->req->errors >= MG_MAX_ERRORS ||
-		    host->error == MG_ERR_TIMEOUT)
-			mg_end_request_cur(host, -EIO);
-}
-
-static unsigned int mg_out(struct mg_host *host,
-		unsigned int sect_num,
-		unsigned int sect_cnt,
-		unsigned int cmd,
-		void (*intr_addr)(struct mg_host *))
-{
-	struct mg_drv_data *prv_data = host->dev->platform_data;
-
-	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
-		return host->error;
-
-	if (!prv_data->use_polling) {
-		host->mg_do_intr = intr_addr;
-		mod_timer(&host->timer, jiffies + 3 * HZ);
-	}
-	if (MG_RES_SEC)
-		sect_num += MG_RES_SEC;
-	outb((u8)sect_cnt, (unsigned long)host->dev_base + MG_REG_SECT_CNT);
-	outb((u8)sect_num, (unsigned long)host->dev_base + MG_REG_SECT_NUM);
-	outb((u8)(sect_num >> 8), (unsigned long)host->dev_base +
-			MG_REG_CYL_LOW);
-	outb((u8)(sect_num >> 16), (unsigned long)host->dev_base +
-			MG_REG_CYL_HIGH);
-	outb((u8)((sect_num >> 24) | ATA_LBA | ATA_DEVICE_OBS),
-			(unsigned long)host->dev_base + MG_REG_DRV_HEAD);
-	outb(cmd, (unsigned long)host->dev_base + MG_REG_COMMAND);
-	return MG_ERR_NONE;
-}
-
-static void mg_read_one(struct mg_host *host, struct request *req)
-{
-	u16 *buff = (u16 *)bio_data(req->bio);
-	u32 i;
-
-	for (i = 0; i < MG_SECTOR_SIZE >> 1; i++)
-		*buff++ = inw((unsigned long)host->dev_base + MG_BUFF_OFFSET +
-			      (i << 1));
-}
-
-static void mg_read(struct request *req)
-{
-	struct mg_host *host = req->rq_disk->private_data;
-
-	if (mg_out(host, blk_rq_pos(req), blk_rq_sectors(req),
-		   MG_CMD_RD, NULL) != MG_ERR_NONE)
-		mg_bad_rw_intr(host);
-
-	MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
-	       blk_rq_sectors(req), blk_rq_pos(req), bio_data(req->bio));
-
-	do {
-		if (mg_wait(host, ATA_DRQ,
-			    MG_TMAX_WAIT_RD_DRQ) != MG_ERR_NONE) {
-			mg_bad_rw_intr(host);
-			return;
-		}
-
-		mg_read_one(host, req);
-
-		outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base +
-				MG_REG_COMMAND);
-	} while (mg_end_request(host, 0, MG_SECTOR_SIZE));
-}
-
-static void mg_write_one(struct mg_host *host, struct request *req)
-{
-	u16 *buff = (u16 *)bio_data(req->bio);
-	u32 i;
-
-	for (i = 0; i < MG_SECTOR_SIZE >> 1; i++)
-		outw(*buff++, (unsigned long)host->dev_base + MG_BUFF_OFFSET +
-		     (i << 1));
-}
-
-static void mg_write(struct request *req)
-{
-	struct mg_host *host = req->rq_disk->private_data;
-	unsigned int rem = blk_rq_sectors(req);
-
-	if (mg_out(host, blk_rq_pos(req), rem,
-		   MG_CMD_WR, NULL) != MG_ERR_NONE) {
-		mg_bad_rw_intr(host);
-		return;
-	}
-
-	MG_DBG("requested %d sects (from %ld), buffer=0x%p\n",
-	       rem, blk_rq_pos(req), bio_data(req->bio));
-
-	if (mg_wait(host, ATA_DRQ,
-		    MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
-		mg_bad_rw_intr(host);
-		return;
-	}
-
-	do {
-		mg_write_one(host, req);
-
-		outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
-				MG_REG_COMMAND);
-
-		rem--;
-		if (rem > 1 && mg_wait(host, ATA_DRQ,
-					MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
-			mg_bad_rw_intr(host);
-			return;
-		} else if (mg_wait(host, MG_STAT_READY,
-					MG_TMAX_WAIT_WR_DRQ) != MG_ERR_NONE) {
-			mg_bad_rw_intr(host);
-			return;
-		}
-	} while (mg_end_request(host, 0, MG_SECTOR_SIZE));
-}
-
-static void mg_read_intr(struct mg_host *host)
-{
-	struct request *req = host->req;
-	u32 i;
-
-	/* check status */
-	do {
-		i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
-		if (i & ATA_BUSY)
-			break;
-		if (!MG_READY_OK(i))
-			break;
-		if (i & ATA_DRQ)
-			goto ok_to_read;
-	} while (0);
-	mg_dump_status("mg_read_intr", i, host);
-	mg_bad_rw_intr(host);
-	mg_request(host->breq);
-	return;
-
-ok_to_read:
-	mg_read_one(host, req);
-
-	MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
-	       blk_rq_pos(req), blk_rq_sectors(req) - 1, bio_data(req->bio));
-
-	/* send read confirm */
-	outb(MG_CMD_RD_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
-
-	if (mg_end_request(host, 0, MG_SECTOR_SIZE)) {
-		/* set handler if read remains */
-		host->mg_do_intr = mg_read_intr;
-		mod_timer(&host->timer, jiffies + 3 * HZ);
-	} else /* goto next request */
-		mg_request(host->breq);
-}
-
-static void mg_write_intr(struct mg_host *host)
-{
-	struct request *req = host->req;
-	u32 i;
-	bool rem;
-
-	/* check status */
-	do {
-		i = inb((unsigned long)host->dev_base + MG_REG_STATUS);
-		if (i & ATA_BUSY)
-			break;
-		if (!MG_READY_OK(i))
-			break;
-		if ((blk_rq_sectors(req) <= 1) || (i & ATA_DRQ))
-			goto ok_to_write;
-	} while (0);
-	mg_dump_status("mg_write_intr", i, host);
-	mg_bad_rw_intr(host);
-	mg_request(host->breq);
-	return;
-
-ok_to_write:
-	if ((rem = mg_end_request(host, 0, MG_SECTOR_SIZE))) {
-		/* write 1 sector and set handler if remains */
-		mg_write_one(host, req);
-		MG_DBG("sector %ld, remaining=%ld, buffer=0x%p\n",
-		       blk_rq_pos(req), blk_rq_sectors(req), bio_data(req->bio));
-		host->mg_do_intr = mg_write_intr;
-		mod_timer(&host->timer, jiffies + 3 * HZ);
-	}
-
-	/* send write confirm */
-	outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base + MG_REG_COMMAND);
-
-	if (!rem)
-		mg_request(host->breq);
-}
-
-static void mg_times_out(unsigned long data)
-{
-	struct mg_host *host = (struct mg_host *)data;
-	char *name;
-
-	spin_lock_irq(&host->lock);
-
-	if (!host->req)
-		goto out_unlock;
-
-	host->mg_do_intr = NULL;
-
-	name = host->req->rq_disk->disk_name;
-	printk(KERN_DEBUG "%s: timeout\n", name);
-
-	host->error = MG_ERR_TIMEOUT;
-	mg_bad_rw_intr(host);
-
-out_unlock:
-	mg_request(host->breq);
-	spin_unlock_irq(&host->lock);
-}
-
-static void mg_request_poll(struct request_queue *q)
-{
-	struct mg_host *host = q->queuedata;
-
-	while (1) {
-		if (!host->req) {
-			host->req = blk_fetch_request(q);
-			if (!host->req)
-				break;
-		}
-
-		switch (req_op(host->req)) {
-		case REQ_OP_READ:
-			mg_read(host->req);
-			break;
-		case REQ_OP_WRITE:
-			mg_write(host->req);
-			break;
-		default:
-			mg_end_request_cur(host, -EIO);
-			break;
-		}
-	}
-}
-
-static unsigned int mg_issue_req(struct request *req,
-		struct mg_host *host,
-		unsigned int sect_num,
-		unsigned int sect_cnt)
-{
-	switch (req_op(host->req)) {
-	case REQ_OP_READ:
-		if (mg_out(host, sect_num, sect_cnt, MG_CMD_RD, &mg_read_intr)
-				!= MG_ERR_NONE) {
-			mg_bad_rw_intr(host);
-			return host->error;
-		}
-		break;
-	case REQ_OP_WRITE:
-		/* TODO : handler */
-		outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-		if (mg_out(host, sect_num, sect_cnt, MG_CMD_WR, &mg_write_intr)
-				!= MG_ERR_NONE) {
-			mg_bad_rw_intr(host);
-			return host->error;
-		}
-		del_timer(&host->timer);
-		mg_wait(host, ATA_DRQ, MG_TMAX_WAIT_WR_DRQ);
-		outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-		if (host->error) {
-			mg_bad_rw_intr(host);
-			return host->error;
-		}
-		mg_write_one(host, req);
-		mod_timer(&host->timer, jiffies + 3 * HZ);
-		outb(MG_CMD_WR_CONF, (unsigned long)host->dev_base +
-				MG_REG_COMMAND);
-		break;
-	default:
-		mg_end_request_cur(host, -EIO);
-		break;
-	}
-	return MG_ERR_NONE;
-}
-
-/* This function also called from IRQ context */
-static void mg_request(struct request_queue *q)
-{
-	struct mg_host *host = q->queuedata;
-	struct request *req;
-	u32 sect_num, sect_cnt;
-
-	while (1) {
-		if (!host->req) {
-			host->req = blk_fetch_request(q);
-			if (!host->req)
-				break;
-		}
-		req = host->req;
-
-		/* check unwanted request call */
-		if (host->mg_do_intr)
-			return;
-
-		del_timer(&host->timer);
-
-		sect_num = blk_rq_pos(req);
-		/* deal whole segments */
-		sect_cnt = blk_rq_sectors(req);
-
-		/* sanity check */
-		if (sect_num >= get_capacity(req->rq_disk) ||
-				((sect_num + sect_cnt) >
-				 get_capacity(req->rq_disk))) {
-			printk(KERN_WARNING
-					"%s: bad access: sector=%d, count=%d\n",
-					req->rq_disk->disk_name,
-					sect_num, sect_cnt);
-			mg_end_request_cur(host, -EIO);
-			continue;
-		}
-
-		if (!mg_issue_req(req, host, sect_num, sect_cnt))
-			return;
-	}
-}
-
-static int mg_getgeo(struct block_device *bdev, struct hd_geometry *geo)
-{
-	struct mg_host *host = bdev->bd_disk->private_data;
-
-	geo->cylinders = (unsigned short)host->cyls;
-	geo->heads = (unsigned char)host->heads;
-	geo->sectors = (unsigned char)host->sectors;
-	return 0;
-}
-
-static const struct block_device_operations mg_disk_ops = {
-	.getgeo = mg_getgeo
-};
-
-#ifdef CONFIG_PM_SLEEP
-static int mg_suspend(struct device *dev)
-{
-	struct mg_drv_data *prv_data = dev->platform_data;
-	struct mg_host *host = prv_data->host;
-
-	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
-		return -EIO;
-
-	if (!prv_data->use_polling)
-		outb(ATA_NIEN, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-
-	outb(MG_CMD_SLEEP, (unsigned long)host->dev_base + MG_REG_COMMAND);
-	/* wait until mflash deep sleep */
-	msleep(1);
-
-	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD)) {
-		if (!prv_data->use_polling)
-			outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-		return -EIO;
-	}
-
-	return 0;
-}
-
-static int mg_resume(struct device *dev)
-{
-	struct mg_drv_data *prv_data = dev->platform_data;
-	struct mg_host *host = prv_data->host;
-
-	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
-		return -EIO;
-
-	outb(MG_CMD_WAKEUP, (unsigned long)host->dev_base + MG_REG_COMMAND);
-	/* wait until mflash wakeup */
-	msleep(1);
-
-	if (mg_wait(host, MG_STAT_READY, MG_TMAX_CONF_TO_CMD))
-		return -EIO;
-
-	if (!prv_data->use_polling)
-		outb(0, (unsigned long)host->dev_base + MG_REG_DRV_CTRL);
-
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(mg_pm, mg_suspend, mg_resume);
-
-static int mg_probe(struct platform_device *plat_dev)
-{
-	struct mg_host *host;
-	struct resource *rsc;
-	struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
-	int err = 0;
-
-	if (!prv_data) {
-		printk(KERN_ERR	"%s:%d fail (no driver_data)\n",
-				__func__, __LINE__);
-		err = -EINVAL;
-		goto probe_err;
-	}
-
-	/* alloc mg_host */
-	host = kzalloc(sizeof(struct mg_host), GFP_KERNEL);
-	if (!host) {
-		printk(KERN_ERR "%s:%d fail (no memory for mg_host)\n",
-				__func__, __LINE__);
-		err = -ENOMEM;
-		goto probe_err;
-	}
-	host->major = MG_DISK_MAJ;
-
-	/* link each other */
-	prv_data->host = host;
-	host->dev = &plat_dev->dev;
-
-	/* io remap */
-	rsc = platform_get_resource(plat_dev, IORESOURCE_MEM, 0);
-	if (!rsc) {
-		printk(KERN_ERR "%s:%d platform_get_resource fail\n",
-				__func__, __LINE__);
-		err = -EINVAL;
-		goto probe_err_2;
-	}
-	host->dev_base = ioremap(rsc->start, resource_size(rsc));
-	if (!host->dev_base) {
-		printk(KERN_ERR "%s:%d ioremap fail\n",
-				__func__, __LINE__);
-		err = -EIO;
-		goto probe_err_2;
-	}
-	MG_DBG("dev_base = 0x%x\n", (u32)host->dev_base);
-
-	/* get reset pin */
-	rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO,
-			MG_RST_PIN);
-	if (!rsc) {
-		printk(KERN_ERR "%s:%d get reset pin fail\n",
-				__func__, __LINE__);
-		err = -EIO;
-		goto probe_err_3;
-	}
-	host->rst = rsc->start;
-
-	/* init rst pin */
-	err = gpio_request(host->rst, MG_RST_PIN);
-	if (err)
-		goto probe_err_3;
-	gpio_direction_output(host->rst, 1);
-
-	/* reset out pin */
-	if (!(prv_data->dev_attr & MG_DEV_MASK)) {
-		err = -EINVAL;
-		goto probe_err_3a;
-	}
-
-	if (prv_data->dev_attr != MG_BOOT_DEV) {
-		rsc = platform_get_resource_byname(plat_dev, IORESOURCE_IO,
-				MG_RSTOUT_PIN);
-		if (!rsc) {
-			printk(KERN_ERR "%s:%d get reset-out pin fail\n",
-					__func__, __LINE__);
-			err = -EIO;
-			goto probe_err_3a;
-		}
-		host->rstout = rsc->start;
-		err = gpio_request(host->rstout, MG_RSTOUT_PIN);
-		if (err)
-			goto probe_err_3a;
-		gpio_direction_input(host->rstout);
-	}
-
-	/* disk reset */
-	if (prv_data->dev_attr == MG_STORAGE_DEV) {
-		/* If POR seq. not yet finished, wait */
-		err = mg_wait_rstout(host->rstout, MG_TMAX_RSTOUT);
-		if (err)
-			goto probe_err_3b;
-		err = mg_disk_init(host);
-		if (err) {
-			printk(KERN_ERR "%s:%d fail (err code : %d)\n",
-					__func__, __LINE__, err);
-			err = -EIO;
-			goto probe_err_3b;
-		}
-	}
-
-	/* get irq resource */
-	if (!prv_data->use_polling) {
-		host->irq = platform_get_irq(plat_dev, 0);
-		if (host->irq == -ENXIO) {
-			err = host->irq;
-			goto probe_err_3b;
-		}
-		err = request_irq(host->irq, mg_irq,
-				IRQF_TRIGGER_RISING,
-				MG_DEV_NAME, host);
-		if (err) {
-			printk(KERN_ERR "%s:%d fail (request_irq err=%d)\n",
-					__func__, __LINE__, err);
-			goto probe_err_3b;
-		}
-
-	}
-
-	/* get disk id */
-	err = mg_get_disk_id(host);
-	if (err) {
-		printk(KERN_ERR "%s:%d fail (err code : %d)\n",
-				__func__, __LINE__, err);
-		err = -EIO;
-		goto probe_err_4;
-	}
-
-	err = register_blkdev(host->major, MG_DISK_NAME);
-	if (err < 0) {
-		printk(KERN_ERR "%s:%d register_blkdev fail (err code : %d)\n",
-				__func__, __LINE__, err);
-		goto probe_err_4;
-	}
-	if (!host->major)
-		host->major = err;
-
-	spin_lock_init(&host->lock);
-
-	if (prv_data->use_polling)
-		host->breq = blk_init_queue(mg_request_poll, &host->lock);
-	else
-		host->breq = blk_init_queue(mg_request, &host->lock);
-
-	if (!host->breq) {
-		err = -ENOMEM;
-		printk(KERN_ERR "%s:%d (blk_init_queue) fail\n",
-				__func__, __LINE__);
-		goto probe_err_5;
-	}
-	host->breq->queuedata = host;
-
-	/* mflash is random device, thanx for the noop */
-	err = elevator_change(host->breq, "noop");
-	if (err) {
-		printk(KERN_ERR "%s:%d (elevator_init) fail\n",
-				__func__, __LINE__);
-		goto probe_err_6;
-	}
-	blk_queue_max_hw_sectors(host->breq, MG_MAX_SECTS);
-	blk_queue_logical_block_size(host->breq, MG_SECTOR_SIZE);
-
-	setup_timer(&host->timer, mg_times_out, (unsigned long)host);
-
-	host->gd = alloc_disk(MG_DISK_MAX_PART);
-	if (!host->gd) {
-		printk(KERN_ERR "%s:%d (alloc_disk) fail\n",
-				__func__, __LINE__);
-		err = -ENOMEM;
-		goto probe_err_7;
-	}
-	host->gd->major = host->major;
-	host->gd->first_minor = 0;
-	host->gd->fops = &mg_disk_ops;
-	host->gd->queue = host->breq;
-	host->gd->private_data = host;
-	sprintf(host->gd->disk_name, MG_DISK_NAME"a");
-
-	set_capacity(host->gd, host->n_sectors);
-
-	add_disk(host->gd);
-
-	return err;
-
-probe_err_7:
-	del_timer_sync(&host->timer);
-probe_err_6:
-	blk_cleanup_queue(host->breq);
-probe_err_5:
-	unregister_blkdev(host->major, MG_DISK_NAME);
-probe_err_4:
-	if (!prv_data->use_polling)
-		free_irq(host->irq, host);
-probe_err_3b:
-	gpio_free(host->rstout);
-probe_err_3a:
-	gpio_free(host->rst);
-probe_err_3:
-	iounmap(host->dev_base);
-probe_err_2:
-	kfree(host);
-probe_err:
-	return err;
-}
-
-static int mg_remove(struct platform_device *plat_dev)
-{
-	struct mg_drv_data *prv_data = plat_dev->dev.platform_data;
-	struct mg_host *host = prv_data->host;
-	int err = 0;
-
-	/* delete timer */
-	del_timer_sync(&host->timer);
-
-	/* remove disk */
-	if (host->gd) {
-		del_gendisk(host->gd);
-		put_disk(host->gd);
-	}
-	/* remove queue */
-	if (host->breq)
-		blk_cleanup_queue(host->breq);
-
-	/* unregister blk device */
-	unregister_blkdev(host->major, MG_DISK_NAME);
-
-	/* free irq */
-	if (!prv_data->use_polling)
-		free_irq(host->irq, host);
-
-	/* free reset-out pin */
-	if (prv_data->dev_attr != MG_BOOT_DEV)
-		gpio_free(host->rstout);
-
-	/* free rst pin */
-	if (host->rst)
-		gpio_free(host->rst);
-
-	/* unmap io */
-	if (host->dev_base)
-		iounmap(host->dev_base);
-
-	/* free mg_host */
-	kfree(host);
-
-	return err;
-}
-
-static struct platform_driver mg_disk_driver = {
-	.probe = mg_probe,
-	.remove = mg_remove,
-	.driver = {
-		.name = MG_DEV_NAME,
-		.pm = &mg_pm,
-	}
-};
-
-/****************************************************************************
- *
- * Module stuff
- *
- ****************************************************************************/
-
-static int __init mg_init(void)
-{
-	printk(KERN_INFO "mGine mflash driver, (c) 2008 mGine Co.\n");
-	return platform_driver_register(&mg_disk_driver);
-}
-
-static void __exit mg_exit(void)
-{
-	printk(KERN_INFO "mflash driver : bye bye\n");
-	platform_driver_unregister(&mg_disk_driver);
-}
-
-module_init(mg_init);
-module_exit(mg_exit);
-
-MODULE_LICENSE("GPL");
-MODULE_AUTHOR("unsik Kim <donari75@gmail.com>");
-MODULE_DESCRIPTION("mGine m[g]flash device driver");
diff --git a/include/linux/mg_disk.h b/include/linux/mg_disk.h
deleted file mode 100644
index e11f4d9f1c2e..000000000000
--- a/include/linux/mg_disk.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- *  include/linux/mg_disk.c
- *
- *  Private data for mflash platform driver
- *
- * (c) 2008 mGine Co.,LTD
- * (c) 2008 unsik Kim <donari75@gmail.com>
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License version 2 as
- *  published by the Free Software Foundation.
- */
-
-#ifndef __MG_DISK_H__
-#define __MG_DISK_H__
-
-/* name for platform device */
-#define MG_DEV_NAME "mg_disk"
-
-/* names of GPIO resource */
-#define MG_RST_PIN	"mg_rst"
-/* except MG_BOOT_DEV, reset-out pin should be assigned */
-#define MG_RSTOUT_PIN	"mg_rstout"
-
-/* device attribution */
-/* use mflash as boot device */
-#define MG_BOOT_DEV		(1 << 0)
-/* use mflash as storage device */
-#define MG_STORAGE_DEV		(1 << 1)
-/* same as MG_STORAGE_DEV, but bootloader already done reset sequence */
-#define MG_STORAGE_DEV_SKIP_RST	(1 << 2)
-
-/* private driver data */
-struct mg_drv_data {
-	/* disk resource */
-	u32 use_polling;
-
-	/* device attribution */
-	u32 dev_attr;
-
-	/* internally used */
-	void *host;
-};
-
-#endif
-- 
2.11.0

^ permalink raw reply related

* Re: [Nbd] [PATCH 3/4] treewide: convert PF_MEMALLOC manipulations to new helpers
From: Mel Gorman @ 2017-04-06 11:25 UTC (permalink / raw)
  To: Wouter Verhelst
  Cc: Michal Hocko, Vlastimil Babka, nbd-general, Chris Leech,
	linux-scsi, Josef Bacik, netdev, linux-kernel, linux-block,
	linux-mm, Eric Dumazet, Lee Duncan, Johannes Weiner,
	Andrew Morton, open-iscsi, David S. Miller
In-Reply-To: <20170406063810.dmv4fg2irsqgdvyq@grep.be>

On Thu, Apr 06, 2017 at 08:38:10AM +0200, Wouter Verhelst wrote:
> On Wed, Apr 05, 2017 at 01:30:31PM +0200, Michal Hocko wrote:
> > On Wed 05-04-17 09:46:59, Vlastimil Babka wrote:
> > > We now have memalloc_noreclaim_{save,restore} helpers for robust setting and
> > > clearing of PF_MEMALLOC. Let's convert the code which was using the generic
> > > tsk_restore_flags(). No functional change.
> > 
> > It would be really great to revisit why those places outside of the mm
> > proper really need this flag. I know this is a painful exercise but I
> > wouldn't be surprised if there were abusers there.
> [...]
> > > ---
> > >  drivers/block/nbd.c      | 7 ++++---
> > >  drivers/scsi/iscsi_tcp.c | 7 ++++---
> > >  net/core/dev.c           | 7 ++++---
> > >  net/core/sock.c          | 7 ++++---
> > >  4 files changed, 16 insertions(+), 12 deletions(-)
> 
> These were all done to make swapping over network safe. The idea is that
> if a socket has SOCK_MEMALLOC set, incoming packets for that socket can
> access PFMEMALLOC reserves (whereas other sockets cannot); this all in
> the hope that one packe destined to that socket will contain the TCP ACK
> that confirms the swapout was successful and we can now release RAM
> pages for other processes.
> 
> I don't know whether they need the PF_MEMALLOC flag specifically (not a
> kernel hacker), but they do need to interact with it at any rate.
> 

At the time it was required to get access to emergency reserves so swapping
can continue. The flip side is that the memory is then protected so pages
allocated from emergency reserves are not used for network traffic that
is not involved with swap. This means that under heavy swap load, it was
perfectly possible for unrelated traffic to get dropped for quite some
time.

-- 
Mel Gorman
SUSE Labs

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox