From patchwork Wed Apr 21 15:21:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kirill A. Shutemov" X-Patchwork-Id: 50661 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id DD27DB7C48 for ; Thu, 22 Apr 2010 01:23:52 +1000 (EST) Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1O4bkV-0006Vm-W6; Wed, 21 Apr 2010 15:22:00 +0000 Received: from mail-bw0-f218.google.com ([209.85.218.218]) by bombadil.infradead.org with esmtp (Exim 4.69 #1 (Red Hat Linux)) id 1O4bkS-0006Tx-UA for linux-mtd@lists.infradead.org; Wed, 21 Apr 2010 15:21:57 +0000 Received: by bwz10 with SMTP id 10so7482647bwz.4 for ; Wed, 21 Apr 2010 08:21:54 -0700 (PDT) Received: by 10.204.42.6 with SMTP id q6mr1946432bke.156.1271863314272; Wed, 21 Apr 2010 08:21:54 -0700 (PDT) Received: from localhost.localdomain (a88-114-220-92.elisa-laajakaista.fi [88.114.220.92]) by mx.google.com with ESMTPS id 16sm4159208bwz.5.2010.04.21.08.21.49 (version=SSLv3 cipher=RC4-MD5); Wed, 21 Apr 2010 08:21:50 -0700 (PDT) From: "Kirill A. Shutemov" To: David Woodhouse Subject: [PATCH] mtd: Do not corrupt backing device for inode Date: Wed, 21 Apr 2010 18:21:09 +0300 Message-Id: <1271863269-5423-1-git-send-email-kirill@shutemov.name> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <20100415172300.GF3561@quack.suse.cz> References: <20100415172300.GF3561@quack.suse.cz> X-CRM114-Version: 20090807-BlameThorstenAndJenny ( TRE 0.7.6 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20100421_112157_154448_87130556 X-CRM114-Status: GOOD ( 12.50 ) X-Spam-Score: 0.0 (/) X-Spam-Report: SpamAssassin version 3.3.1 on bombadil.infradead.org summary: Content analysis details: (0.0 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, low trust [209.85.218.218 listed in list.dnswl.org] Cc: Jan Kara , linux-kernel@vger.kernel.org, David Howells , Alexander Shishkin , linux-mtd@lists.infradead.org, Alexander Viro , linux-fsdevel@vger.kernel.org, "Kirill A. Shutemov" X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org We cannot modify file->f_mapping->backing_dev_info directly, because it will corrupt backing device for inode, since inode->i_mapping == file->f_mapping (see __dentry_open() in fs/open.c). So we have to copy f_mapping first. Signed-off-by: Kirill A. Shutemov --- drivers/mtd/mtdchar.c | 22 +++++++++++++++++++++- 1 files changed, 21 insertions(+), 1 deletions(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 5b081cb..d85be4d 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -88,8 +88,23 @@ static int mtd_open(struct inode *inode, struct file *file) goto out; } - if (mtd->backing_dev_info) + if (mtd->backing_dev_info) { + /* + * We assume that file->f_mapping is equal to inode->i_mapping. + */ + BUG_ON(file->f_mapping != inode->i_mapping); + + /* + * We cannot modify file->f_mapping->backing_dev_info directly, + * because it will corrupt backing device for inode, since + * inode->i_mapping is equal to file->f_mapping. So we have to + * copy f_mapping first. + */ + file->f_mapping = kmalloc(sizeof(*file->f_mapping), GFP_KERNEL); + memcpy(file->f_mapping, inode->i_mapping, + sizeof(*file->f_mapping)); file->f_mapping->backing_dev_info = mtd->backing_dev_info; + } /* You can't open it RW if it's not a writeable device */ if ((file->f_mode & FMODE_WRITE) && !(mtd->flags & MTD_WRITEABLE)) { @@ -129,6 +144,11 @@ static int mtd_close(struct inode *inode, struct file *file) file->private_data = NULL; kfree(mfi); + if (mtd->backing_dev_info) { + kfree(file->f_mapping); + file->f_mapping = inode->i_mapping; + } + return 0; } /* mtd_close */