From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932675Ab0IXQ21 (ORCPT ); Fri, 24 Sep 2010 12:28:27 -0400 Received: from kroah.org ([198.145.64.141]:38347 "EHLO coco.kroah.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932638Ab0IXQ2Z (ORCPT ); Fri, 24 Sep 2010 12:28:25 -0400 X-Mailbox-Line: From gregkh@clark.site Fri Sep 24 09:26:18 2010 Message-Id: <20100924162618.102958761@clark.site> User-Agent: quilt/0.48-11.2 Date: Fri, 24 Sep 2010 09:24:25 -0700 From: Greg KH 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, Jan Kara , Jens Axboe Subject: [37/80] bdi: Fix warnings in __mark_inode_dirty for /dev/zero and friends In-Reply-To: <20100924162706.GA7381@kroah.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 2.6.35-stable review patch. If anyone has any objections, please let us know. ------------------ From: Jan Kara commit 692ebd17c2905313fff3c504c249c6a0faad16ec upstream. Inodes of devices such as /dev/zero can get dirty for example via utime(2) syscall or due to atime update. Backing device of such inodes (zero_bdi, etc.) is however unable to handle dirty inodes and thus __mark_inode_dirty complains. In fact, inode should be rather dirtied against backing device of the filesystem holding it. This is generally a good rule except for filesystems such as 'bdev' or 'mtd_inodefs'. Inodes in these pseudofilesystems are referenced from ordinary filesystem inodes and carry mapping with real data of the device. Thus for these inodes we have to use inode->i_mapping->backing_dev_info as we did so far. We distinguish these filesystems by checking whether sb->s_bdi points to a non-trivial backing device or not. Example: Assume we have an ext3 filesystem on /dev/sda1 mounted on /. There's a device inode A described by a path "/dev/sdb" on this filesystem. This inode will be dirtied against backing device "8:0" after this patch. bdev filesystem contains block device inode B coupled with our inode A. When someone modifies a page of /dev/sdb, it's B that gets dirtied and the dirtying happens against the backing device "8:16". Thus both inodes get filed to a correct bdi list. Signed-off-by: Jan Kara Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/fs-writeback.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) --- a/fs/fs-writeback.c +++ b/fs/fs-writeback.c @@ -28,8 +28,6 @@ #include #include "internal.h" -#define inode_to_bdi(inode) ((inode)->i_mapping->backing_dev_info) - /* * We don't actually have pdflush, but this one is exported though /proc... */ @@ -62,6 +60,27 @@ int writeback_in_progress(struct backing return !list_empty(&bdi->work_list); } +static inline struct backing_dev_info *inode_to_bdi(struct inode *inode) +{ + struct super_block *sb = inode->i_sb; + struct backing_dev_info *bdi = inode->i_mapping->backing_dev_info; + + /* + * For inodes on standard filesystems, we use superblock's bdi. For + * inodes on virtual filesystems, we want to use inode mapping's bdi + * because they can possibly point to something useful (think about + * block_dev filesystem). + */ + if (sb->s_bdi && sb->s_bdi != &noop_backing_dev_info) { + /* Some device inodes could play dirty tricks. Catch them... */ + WARN(bdi != sb->s_bdi && bdi_cap_writeback_dirty(bdi), + "Dirtiable inode bdi %s != sb bdi %s\n", + bdi->name, sb->s_bdi->name); + return sb->s_bdi; + } + return bdi; +} + static void bdi_queue_work(struct backing_dev_info *bdi, struct wb_writeback_work *work) {