* [PATCH 1/2] block: add info when opening an exclusive opened block device for write
2019-05-14 14:45 [PATCH 0/2] block: add info messages when opening a block device O_WRITE and O_EXCL concurrently zhangyi (F)
@ 2019-05-14 14:45 ` zhangyi (F)
2019-05-14 14:45 ` [PATCH 2/2] block: add info when opening a write opend block device exclusively zhangyi (F)
1 sibling, 0 replies; 3+ messages in thread
From: zhangyi (F) @ 2019-05-14 14:45 UTC (permalink / raw)
To: viro; +Cc: linux-fsdevel, yi.zhang, miaoxie
Opening an exclusive opened block device for write make the exclusive
open isn't exclusive enough, it may lead to data corruption when some
one writing data through the counterpart raw block device, such as
corrupt a mounted file system. This patch add an info message when
opening an exclusive opened block device for write to hint the
potential data corruption.
Note that there are some legal cases such as file system or device
mapper online resize, so this message is just a hint and isn't always
mean that a risky written happens.
Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
---
fs/block_dev.c | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index bb28e2e..d92aa45 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1667,13 +1667,13 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
res = __blkdev_get(bdev, mode, 0);
+ mutex_lock(&bdev->bd_mutex);
+ spin_lock(&bdev_lock);
+
if (whole) {
struct gendisk *disk = whole->bd_disk;
/* finish claiming */
- mutex_lock(&bdev->bd_mutex);
- spin_lock(&bdev_lock);
-
if (!res) {
BUG_ON(!bd_may_claim(bdev, whole, holder));
/*
@@ -1710,6 +1710,22 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
mutex_unlock(&bdev->bd_mutex);
bdput(whole);
+ } else {
+ if (!res && (mode & FMODE_WRITE) && bdev->bd_holders) {
+ char name[BDEVNAME_SIZE];
+
+ /*
+ * Open an exclusive opened device for write may
+ * probability corrupt the device, such as a
+ * mounted file system, give a hint here.
+ */
+ pr_info_ratelimited("VFS: Open an exclusive opened "
+ "block device for write %s [%d %s].\n",
+ bdevname(bdev, name), current->pid,
+ current->comm);
+ }
+ spin_unlock(&bdev_lock);
+ mutex_unlock(&bdev->bd_mutex);
}
return res;
--
2.7.4
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 2/2] block: add info when opening a write opend block device exclusively
2019-05-14 14:45 [PATCH 0/2] block: add info messages when opening a block device O_WRITE and O_EXCL concurrently zhangyi (F)
2019-05-14 14:45 ` [PATCH 1/2] block: add info when opening an exclusive opened block device for write zhangyi (F)
@ 2019-05-14 14:45 ` zhangyi (F)
1 sibling, 0 replies; 3+ messages in thread
From: zhangyi (F) @ 2019-05-14 14:45 UTC (permalink / raw)
To: viro; +Cc: linux-fsdevel, yi.zhang, miaoxie
Just like open an exclusive opened block device for write, open a block
device exclusively which has been opened for write by some other
processes may also lead to potential data corruption. This patch record
the write openers and give a hint if that happens.
Signed-off-by: zhangyi (F) <yi.zhang@huawei.com>
---
fs/block_dev.c | 20 ++++++++++++++++++--
include/linux/fs.h | 1 +
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/fs/block_dev.c b/fs/block_dev.c
index d92aa45..c278195 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1606,6 +1606,8 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part)
bdev->bd_openers++;
if (for_part)
bdev->bd_part_count++;
+ if (mode & FMODE_WRITE)
+ bdev->bd_write_openers++;
mutex_unlock(&bdev->bd_mutex);
disk_unblock_events(disk);
/* only one opener holds refs to the module and disk */
@@ -1654,6 +1656,7 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
{
struct block_device *whole = NULL;
int res;
+ char name[BDEVNAME_SIZE];
WARN_ON_ONCE((mode & FMODE_EXCL) && !holder);
@@ -1673,6 +1676,19 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
if (whole) {
struct gendisk *disk = whole->bd_disk;
+ /*
+ * Open an write opened block device exclusively, the
+ * writing process may probability corrupt the device,
+ * such as a mounted file system, give a hint here.
+ */
+ if (!res && (bdev->bd_write_openers >
+ ((mode & FMODE_WRITE) ? 1 : 0)) && !bdev->bd_holders) {
+ pr_info_ratelimited("VFS: Open an write opened "
+ "block device exclusively %s [%d %s].\n",
+ bdevname(bdev, name), current->pid,
+ current->comm);
+ }
+
/* finish claiming */
if (!res) {
BUG_ON(!bd_may_claim(bdev, whole, holder));
@@ -1712,8 +1728,6 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder)
bdput(whole);
} else {
if (!res && (mode & FMODE_WRITE) && bdev->bd_holders) {
- char name[BDEVNAME_SIZE];
-
/*
* Open an exclusive opened device for write may
* probability corrupt the device, such as a
@@ -1848,6 +1862,8 @@ static void __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part)
struct block_device *victim = NULL;
mutex_lock_nested(&bdev->bd_mutex, for_part);
+ if (mode & FMODE_WRITE)
+ bdev->bd_write_openers--;
if (for_part)
bdev->bd_part_count--;
diff --git a/include/linux/fs.h b/include/linux/fs.h
index dd28e76..0dc066d 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -463,6 +463,7 @@ struct request_queue;
struct block_device {
dev_t bd_dev; /* not a kdev_t - it's a search key */
int bd_openers;
+ int bd_write_openers;
struct inode * bd_inode; /* will die */
struct super_block * bd_super;
struct mutex bd_mutex; /* open/close mutex */
--
2.7.4
^ permalink raw reply related [flat|nested] 3+ messages in thread