From: Greg KH <gregkh@suse.de>
To: linux-kernel@vger.kernel.org, stable@kernel.org
Cc: stable-review@kernel.org, torvalds@linux-foundation.org,
akpm@linux-foundation.org, alan@lxorguk.ukuu.org.uk,
Jeff Moyer <jmoyer@redhat.com>,
Andrew Patterson <andrew.patterson@hp.com>,
Jens Axboe <axboe@kernel.dk>, NeilBrown <neilb@suse.de>
Subject: [26/73] Fix over-zealous flush_disk when changing device size.
Date: Fri, 04 Mar 2011 16:55:31 -0800 [thread overview]
Message-ID: <20110305005637.128325892@clark.kroah.org> (raw)
In-Reply-To: <20110305005720.GA16162@kroah.com>
2.6.37-stable review patch. If anyone has any objections, please let us know.
------------------
From: NeilBrown <neilb@suse.de>
commit 93b270f76e7ef3b81001576860c2701931cdc78b upstream.
There are two cases when we call flush_disk.
In one, the device has disappeared (check_disk_change) so any
data will hold becomes irrelevant.
In the oter, the device has changed size (check_disk_size_change)
so data we hold may be irrelevant.
In both cases it makes sense to discard any 'clean' buffers,
so they will be read back from the device if needed.
In the former case it makes sense to discard 'dirty' buffers
as there will never be anywhere safe to write the data. In the
second case it *does*not* make sense to discard dirty buffers
as that will lead to file system corruption when you simply enlarge
the containing devices.
flush_disk calls __invalidate_devices.
__invalidate_device calls both invalidate_inodes and invalidate_bdev.
invalidate_inodes *does* discard I_DIRTY inodes and this does lead
to fs corruption.
invalidate_bev *does*not* discard dirty pages, but I don't really care
about that at present.
So this patch adds a flag to __invalidate_device (calling it
__invalidate_device2) to indicate whether dirty buffers should be
killed, and this is passed to invalidate_inodes which can choose to
skip dirty inodes.
flusk_disk then passes true from check_disk_change and false from
check_disk_size_change.
dm avoids tripping over this problem by calling i_size_write directly
rathher than using check_disk_size_change.
md does use check_disk_size_change and so is affected.
This regression was introduced by commit 608aeef17a which causes
check_disk_size_change to call flush_disk, so it is suitable for any
kernel since 2.6.27.
Acked-by: Jeff Moyer <jmoyer@redhat.com>
Cc: Andrew Patterson <andrew.patterson@hp.com>
Cc: Jens Axboe <axboe@kernel.dk>
Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
---
block/genhd.c | 2 +-
drivers/block/floppy.c | 2 +-
fs/block_dev.c | 12 ++++++------
fs/inode.c | 9 ++++++++-
fs/internal.h | 2 +-
include/linux/fs.h | 2 +-
6 files changed, 18 insertions(+), 11 deletions(-)
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -1285,7 +1285,7 @@ int invalidate_partition(struct gendisk
struct block_device *bdev = bdget_disk(disk, partno);
if (bdev) {
fsync_bdev(bdev);
- res = __invalidate_device(bdev);
+ res = __invalidate_device(bdev, true);
bdput(bdev);
}
return res;
--- a/drivers/block/floppy.c
+++ b/drivers/block/floppy.c
@@ -3276,7 +3276,7 @@ static int set_geometry(unsigned int cmd
struct block_device *bdev = opened_bdev[cnt];
if (!bdev || ITYPE(drive_state[cnt].fd_device) != type)
continue;
- __invalidate_device(bdev);
+ __invalidate_device(bdev, true);
}
mutex_unlock(&open_lock);
} else {
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -1217,9 +1217,9 @@ EXPORT_SYMBOL(open_by_devnum);
* when a disk has been changed -- either by a media change or online
* resize.
*/
-static void flush_disk(struct block_device *bdev)
+static void flush_disk(struct block_device *bdev, bool kill_dirty)
{
- if (__invalidate_device(bdev)) {
+ if (__invalidate_device(bdev, kill_dirty)) {
char name[BDEVNAME_SIZE] = "";
if (bdev->bd_disk)
@@ -1256,7 +1256,7 @@ void check_disk_size_change(struct gendi
"%s: detected capacity change from %lld to %lld\n",
name, bdev_size, disk_size);
i_size_write(bdev->bd_inode, disk_size);
- flush_disk(bdev);
+ flush_disk(bdev, false);
}
}
EXPORT_SYMBOL(check_disk_size_change);
@@ -1308,7 +1308,7 @@ int check_disk_change(struct block_devic
if (!bdops->media_changed(bdev->bd_disk))
return 0;
- flush_disk(bdev);
+ flush_disk(bdev, true);
if (bdops->revalidate_disk)
bdops->revalidate_disk(bdev->bd_disk);
return 1;
@@ -1776,7 +1776,7 @@ void close_bdev_exclusive(struct block_d
EXPORT_SYMBOL(close_bdev_exclusive);
-int __invalidate_device(struct block_device *bdev)
+int __invalidate_device(struct block_device *bdev, bool kill_dirty)
{
struct super_block *sb = get_super(bdev);
int res = 0;
@@ -1789,7 +1789,7 @@ int __invalidate_device(struct block_dev
* hold).
*/
shrink_dcache_sb(sb);
- res = invalidate_inodes(sb);
+ res = invalidate_inodes(sb, kill_dirty);
drop_super(sb);
}
invalidate_bdev(bdev);
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -532,11 +532,14 @@ void evict_inodes(struct super_block *sb
/**
* invalidate_inodes - attempt to free all inodes on a superblock
* @sb: superblock to operate on
+ * @kill_dirty: flag to guide handling of dirty inodes
*
* Attempts to free all inodes for a given superblock. If there were any
* busy inodes return a non-zero value, else zero.
+ * If @kill_dirty is set, discard dirty inodes too, otherwise treat
+ * them as busy.
*/
-int invalidate_inodes(struct super_block *sb)
+int invalidate_inodes(struct super_block *sb, bool kill_dirty)
{
int busy = 0;
struct inode *inode, *next;
@@ -548,6 +551,10 @@ int invalidate_inodes(struct super_block
list_for_each_entry_safe(inode, next, &sb->s_inodes, i_sb_list) {
if (inode->i_state & (I_NEW | I_FREEING | I_WILL_FREE))
continue;
+ if (inode->i_state & I_DIRTY && !kill_dirty) {
+ busy = 1;
+ continue;
+ }
if (atomic_read(&inode->i_count)) {
busy = 1;
continue;
--- a/fs/internal.h
+++ b/fs/internal.h
@@ -107,4 +107,4 @@ extern void release_open_intent(struct n
*/
extern int get_nr_dirty_inodes(void);
extern void evict_inodes(struct super_block *);
-extern int invalidate_inodes(struct super_block *);
+extern int invalidate_inodes(struct super_block *, bool);
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2118,7 +2118,7 @@ extern void check_disk_size_change(struc
struct block_device *bdev);
extern int revalidate_disk(struct gendisk *);
extern int check_disk_change(struct block_device *);
-extern int __invalidate_device(struct block_device *);
+extern int __invalidate_device(struct block_device *, bool);
extern int invalidate_partition(struct gendisk *, int);
#endif
unsigned long invalidate_mapping_pages(struct address_space *mapping,
next prev parent reply other threads:[~2011-03-05 1:15 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-05 0:57 [00/73] 2.6.37.3-stable review Greg KH
2011-03-05 0:55 ` [01/73] usb: musb: omap2430: fix kernel panic on reboot Greg KH
2011-03-05 0:55 ` [02/73] USB: add quirks entry for Keytouch QWERTY Panel Greg KH
2011-03-05 0:55 ` [03/73] USB: Add Samsung SGH-I500/Android modem ID switch to visor driver Greg KH
2011-03-05 0:55 ` [04/73] USB: Add quirk for Samsung Android phone modem Greg KH
2011-03-05 0:55 ` [05/73] USB: serial/usb_wwan, fix tty NULL dereference Greg KH
2011-03-05 0:55 ` [06/73] sierra: add new ID for Airprime/Sierra USB IP modem Greg KH
2011-03-05 0:55 ` [07/73] Revert "Bluetooth: Enable USB autosuspend by default on btusb" Greg KH
2011-03-05 0:55 ` [08/73] p54pci: update receive dma buffers before and after processing Greg KH
2011-03-05 0:55 ` [09/73] Revert "drm/radeon/kms: switch back to min->max pll post divider iteration" Greg KH
2011-03-05 0:55 ` [10/73] tcp: fix inet_twsk_deschedule() Greg KH
2011-03-05 0:55 ` [11/73] mm: prevent concurrent unmap_mapping_range() on the same inode Greg KH
2011-03-05 0:55 ` [12/73] staging: brcm80211: remove assert to avoid panic since 2.6.37 kernel Greg KH
2011-03-05 0:55 ` [13/73] staging: brcm80211: bugfix for softmac crash on multi cpu configurations Greg KH
2011-03-05 0:55 ` [14/73] staging: usbip: vhci: update reference count for usb_device Greg KH
2011-03-05 0:55 ` [15/73] staging: usbip: vhci: give back URBs from in-flight unlink requests Greg KH
2011-03-05 0:55 ` [16/73] staging: usbip: vhci: refuse to enqueue for dead connections Greg KH
2011-03-05 0:55 ` [17/73] staging: usbip: vhci: use urb->dev->portnum to find port Greg KH
2011-03-05 0:55 ` [18/73] epoll: prevent creating circular epoll structures Greg KH
2011-03-05 0:55 ` [19/73] swiotlb: fix wrong panic Greg KH
2011-03-05 0:55 ` [20/73] ldm: corrupted partition table can cause kernel oops Greg KH
2011-03-05 0:55 ` [21/73] drivers/rtc/rtc-ds3232.c: fix time range difference between linux and RTC chip Greg KH
2011-03-05 0:55 ` [22/73] mm: fix dubious code in __count_immobile_pages() Greg KH
2011-03-05 0:55 ` [23/73] md: correctly handle probe of an mdp device Greg KH
2011-03-05 0:55 ` [24/73] md: avoid spinlock problem in blk_throtl_exit Greg KH
2011-03-05 0:55 ` [25/73] md: Fix - again - partition detection when array becomes active Greg KH
2011-03-05 0:55 ` Greg KH [this message]
2011-03-05 0:55 ` [27/73] PM: Make ACPI wakeup from S5 work again when CONFIG_PM_SLEEP is unset Greg KH
2011-03-05 0:55 ` [28/73] x86 quirk: Fix polarity for IRQ0 pin2 override on SB800 systems Greg KH
2011-03-05 0:55 ` [29/73] xhci: Avoid BUG() in interrupt context Greg KH
2011-03-05 0:55 ` [30/73] xhci: Clarify some expressions in the TRB math Greg KH
2011-03-05 0:55 ` [31/73] xhci: Fix errors in the running total calculations " Greg KH
2011-03-05 0:55 ` [32/73] xhci: Fix an error in count_sg_trbs_needed() Greg KH
2011-03-05 0:55 ` [33/73] USB: Reset USB 3.0 devices on (re)discovery Greg KH
2011-03-05 0:55 ` [34/73] USB: prevent buggy hubs from crashing the USB stack Greg KH
2011-03-05 0:55 ` [35/73] usb: musb: core: set has_tt flag Greg KH
2011-03-05 0:55 ` [36/73] ALSA: HDA: Add a new Conexant codec 506e (20590) Greg KH
2011-03-05 0:55 ` [37/73] ALSA: usb-audio: fix oops due to cleanup race when disconnecting Greg KH
2011-03-05 0:55 ` [38/73] ALSA: HDA: Fix mic initialization in VIA auto parser Greg KH
2011-03-05 0:55 ` [39/73] ALSA: HDA: Add ideapad quirk for two Dell machines Greg KH
2011-03-05 0:55 ` [40/73] ocfs2: Check heartbeat mode for kernel stacks only Greg KH
2011-03-05 0:55 ` [41/73] Ocfs2/refcounttree: Fix a bug for refcounttree to writeback clusters in a right number Greg KH
2011-03-05 0:55 ` [42/73] drm: fix unsigned vs signed comparison issue in modeset ctl ioctl Greg KH
2011-03-05 0:55 ` [43/73] ACPI / debugfs: Fix buffer overflows, double free Greg KH
2011-03-05 0:55 ` [44/73] mfd: Avoid tps6586x burst writes Greg KH
2011-03-05 0:55 ` [45/73] mfd: Fix NULL pointer due to non-initialized ucb1x00-ts absinfo Greg KH
2011-03-05 0:55 ` [46/73] x86: Use u32 instead of long to set reset vector back to 0 Greg KH
2011-03-05 0:55 ` [47/73] Bluetooth: add Atheros BT AR9285 fw supported Greg KH
2011-03-05 0:55 ` [48/73] Bluetooth: fix crash with quirky dongles doing sound Greg KH
2011-03-05 0:55 ` [49/73] Bluetooth: Add Atheros BT AR5BBU12 fw supported Greg KH
2011-03-05 0:55 ` [50/73] eukrea-tlv320: fix platform_name Greg KH
2011-03-05 0:55 ` [51/73] ASoC: correct pxa AC97 DAI names Greg KH
2011-03-05 0:55 ` [52/73] fuse: fix hang of single threaded fuseblk filesystem Greg KH
2011-03-05 0:55 ` [53/73] clockevents: Prevent oneshot mode when broadcast device is periodic Greg KH
2011-03-05 0:55 ` [54/73] ext2: Fix link count corruption under heavy link+rename load Greg KH
2011-03-05 0:56 ` [55/73] mm: vmstat: use a single setter function and callback for adjusting percpu thresholds Greg KH
2011-03-05 0:56 ` [56/73] e1000e: 82579 PHY incorrectly identified during init Greg KH
2011-03-05 0:56 ` [57/73] Staging: comedi: Add MODULE_LICENSE and similar to NI modules Greg KH
2011-03-05 0:56 ` [58/73] fix cfg80211_wext_siwfreq lock ordering Greg KH
2011-03-05 0:56 ` [59/73] tg3: Restrict phy ioctl access Greg KH
2011-03-05 0:56 ` [60/73] drm/i915: fix memory corruption with GM965 and >4GB RAM Greg KH
2011-03-05 0:56 ` [61/73] blk-throttle: Do not use kblockd workqueue for throtl work Greg KH
2011-03-05 0:56 ` [62/73] block: add @force_kblockd to __blk_run_queue() Greg KH
2011-03-05 0:56 ` [63/73] block: blk-flush shouldnt call directly into q->request_fn() __blk_run_queue() Greg KH
2011-03-05 0:56 ` [64/73] block: kill loop_mutex Greg KH
2011-03-05 0:56 ` [65/73] ath9k_htc: Fix an endian issue Greg KH
2011-03-05 0:56 ` [66/73] p54usb: add Senao NUB-350 usbid Greg KH
2011-03-05 0:56 ` [67/73] nilfs2: fix regression that i-flag is not set on changeless checkpoints Greg KH
2011-03-05 0:56 ` [68/73] carl9170: add Airlive X.USB a/b/g/n USBID Greg KH
2011-03-05 0:56 ` [69/73] r8169: disable ASPM Greg KH
2011-03-05 0:56 ` [70/73] dccp: fix oops on Reset after close Greg KH
2011-03-05 0:56 ` [71/73] e1000e: disable broken PHY wakeup for ICH10 LOMs, use MAC wakeup instead Greg KH
2011-03-05 0:56 ` [72/73] DNS: Fix a NULL pointer deref when trying to read an error key [CVE-2011-1076] Greg KH
2011-03-05 0:56 ` [73/73] arp_notify: unconditionally send gratuitous ARP for NETDEV_NOTIFY_PEERS Greg KH
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20110305005637.128325892@clark.kroah.org \
--to=gregkh@suse.de \
--cc=akpm@linux-foundation.org \
--cc=alan@lxorguk.ukuu.org.uk \
--cc=andrew.patterson@hp.com \
--cc=axboe@kernel.dk \
--cc=jmoyer@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=neilb@suse.de \
--cc=stable-review@kernel.org \
--cc=stable@kernel.org \
--cc=torvalds@linux-foundation.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®