fs/block_dev.c: Remove WARN_ON() when inode writeback fails
Subsystems (2)
PATCH 1/1 fs/block_dev.c: Remove WARN_ON() when inode writeback fails
If a block device is hot removed and later last reference to devices is put, we try to writeback the dirty inode. But device is gone and that writeback fails.
Currently we do a WARN_ON() which does not seem to be the right thing. Convert it to a ratelimited kernel warning.
--- fs/block_dev.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)
fs/block_dev.c +11 -3
@@ -48,12 +48,20 @@ inline struct block_device *I_BDEV(struc }EXPORT_SYMBOL (I_BDEV ); -static void bdev_write_inode (struct inode *inode) +static void bdev_write_inode (struct block_device *bdev) { +struct inode *inode = bdev->bd_inode; +int ret; +spin_lock (&inode->i_lock);while (inode->i_state &I_DIRTY ) {spin_unlock (&inode->i_lock); -WARN_ON_ONCE (write_inode_now (inode, true)); + ret =write_inode_now (inode, true); +if (ret) { +char name[BDEVNAME_SIZE ] ="" ; +pr_warn_ratelimited ("VFS: Dirty inode writeback failed for block device %s (err= %d).\n" , +bdevname (bdev, name), ret); + }spin_lock (&inode->i_lock); }spin_unlock (&inode->i_lock);
@@ -1489,7 +1497,7 @@ static void __blkdev_put(struct block_de* ->release can cause the queue to disappear, so flush all * dirty data before. */ -bdev_write_inode (bdev->bd_inode); +bdev_write_inode (bdev); }if (bdev->bd_contains == bdev) {if (disk->fops->release)
Quoted 9 lines · Vivek Goyal
If a block device is hot removed and later last reference to devices is put, we try to writeback the dirty inode. But device is gone and that writeback fails.
Currently we do a
WARN_ON()which does not seem to be the right thing. Convert it to a ratelimited kernel warning.Reported-by Andi Kleen <[email protected]>Signed-off-by Vivek Goyal <[email protected]>
Thanks.
Signature · 1 line
tejun
Hi Jens,
Do you have concerns with this patch? If not, can you please include it.
Thanks
Vivek
Quoted 49 lines · Vivek Goyal
If a block device is hot removed and later last reference to devices is put, we try to writeback the dirty inode. But device is gone and that writeback fails.
Currently we do a
WARN_ON()which does not seem to be the right thing. Convert it to a ratelimited kernel warning.Reported-by Andi Kleen <[email protected]>Signed-off-by Vivek Goyal <[email protected]>--- fs/block_dev.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-)Index:
rhvgoyal-linux/fs/block_dev.c
===================================================================fs/block_dev.c +11
-3@@ -48,12 +48,20 @@ inline struct block_device *I_BDEV(struc }EXPORT_SYMBOL (I_BDEV ); -static void bdev_write_inode (struct inode *inode) +static void bdev_write_inode (struct block_device *bdev) { +struct inode *inode = bdev->bd_inode; +int ret; +spin_lock (&inode->i_lock);while (inode->i_state &I_DIRTY ) {spin_unlock (&inode->i_lock); -WARN_ON_ONCE (write_inode_now (inode, true)); + ret =write_inode_now (inode, true); +if (ret) { +char name[BDEVNAME_SIZE ] ="" ; +pr_warn_ratelimited ("VFS: Dirty inode writeback failed for block device %s (err= %d).\n" , +bdevname (bdev, name), ret); + }spin_lock (&inode->i_lock); }spin_unlock (&inode->i_lock);@@ -1489,7 +1497,7 @@ static void __blkdev_put(struct block_de* ->release can cause the queue to disappear, so flush all * dirty data before. */ -bdev_write_inode (bdev->bd_inode); +bdev_write_inode (bdev); }if (bdev->bd_contains == bdev) {if (disk->fops->release)
Quoted 3 lines · Vivek Goyal
Hi Jens,
Do you have concerns with this patch? If not, can you please include it.
The concept is fine, but:
Quoted 5 lines
Quoted 5 lines
fs/block_dev.c +3
-1-static void bdev_write_inode (struct inode *inode) +static void bdev_write_inode (struct block_device *bdev) { +struct inode *inode = bdev->bd_inode; +int ret;
Quoted 8 lines
fs/block_dev.c inline struct block_device *I_BDEV(struc · line 61
Quoted 8 lines
fs/block_dev.c +4
-1+spin_lock (&inode->i_lock);while (inode->i_state &I_DIRTY ) {spin_unlock (&inode->i_lock); -WARN_ON_ONCE (write_inode_now (inode, true)); + ret =write_inode_now (inode, true); +if (ret) { +char name[BDEVNAME_SIZE ] ="" ;
that initializer isn't necessary.
Cheers,
Jeff