linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Andrea Arcangeli <andrea@suse.de>
To: Alexander Viro <viro@math.psu.edu>
Cc: Linus Torvalds <torvalds@transmeta.com>,
	Kernel Mailing List <linux-kernel@vger.kernel.org>
Subject: Re: Linux 2.4.10-pre11
Date: Fri, 21 Sep 2001 09:09:10 +0200	[thread overview]
Message-ID: <20010921090910.H729@athlon.random> (raw)
In-Reply-To: <20010921003136.H729@athlon.random> <Pine.GSO.4.21.0109201835320.5631-100000@weyl.math.psu.edu> <20010921010340.L729@athlon.random> <20010921054749.Z729@athlon.random> <20010921060625.A729@athlon.random> <20010921064621.C729@athlon.random>
In-Reply-To: <20010921064621.C729@athlon.random>; from andrea@suse.de on Fri, Sep 21, 2001 at 06:46:21AM +0200

On Fri, Sep 21, 2001 at 06:46:21AM +0200, Andrea Arcangeli wrote:
> On Fri, Sep 21, 2001 at 06:06:25AM +0200, Andrea Arcangeli wrote:
> > On Fri, Sep 21, 2001 at 05:47:49AM +0200, Andrea Arcangeli wrote:
> > > write and I cannot zero it out. It is getting harder to fix this one
> > > just inside the ->make_request callback... Hints?
> > 
> > I think the best fix is to have the ramdisk using the same aops of ramfs
> > and replace "Secure" with "Uptodate". We need to trap the security issue
> > at the higher layer and also this will avoid us having to map useless
> > bh, so it should be an improvement, only the filesystem will end
> > triggering the ->make_request callback of the ramdisk. Then if the fs
> > does I/O on stuff out of the physical address space we'll just clear it
> > out.
> 
> ok, here it is, this obsoletes the previous patch (so again against
> 2.4.10pre12), initrd works again.

rediffed against pre13 (I'm passing the bd_inode to the ->open/release,
so we can modify the a_ops of the physical address space, ramdisk needs
that in rd_open())

diff -urN ramdisk-ref/drivers/block/rd.c ramdisk/drivers/block/rd.c
--- ramdisk-ref/drivers/block/rd.c	Fri Sep 21 08:28:04 2001
+++ ramdisk/drivers/block/rd.c	Fri Sep 21 08:06:02 2001
@@ -186,17 +186,77 @@
 
 #endif
 
+/*
+ * Copyright (C) 2000 Linus Torvalds.
+ *               2000 Transmeta Corp.
+ * aops copied from ramfs.
+ */
+static int ramdisk_readpage(struct file *file, struct page * page)
+{
+	if (!Page_Uptodate(page)) {
+		memset(kmap(page), 0, PAGE_CACHE_SIZE);
+		kunmap(page);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+	}
+	UnlockPage(page);
+	return 0;
+}
+
+/*
+ * Writing: just make sure the page gets marked dirty, so that
+ * the page stealer won't grab it.
+ */
+static int ramdisk_writepage(struct page *page)
+{
+	SetPageDirty(page);
+	UnlockPage(page);
+	return 0;
+}
+
+static int ramdisk_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	void *addr = kmap(page);
+	if (!Page_Uptodate(page)) {
+		memset(addr, 0, PAGE_CACHE_SIZE);
+		flush_dcache_page(page);
+		SetPageUptodate(page);
+	}
+	SetPageDirty(page);
+	return 0;
+}
+
+static int ramdisk_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to)
+{
+	kunmap(page);
+	return 0;
+}
+
+struct address_space_operations ramdisk_aops = {
+	readpage: ramdisk_readpage,
+	writepage: ramdisk_writepage,
+	prepare_write: ramdisk_prepare_write,
+	commit_write: ramdisk_commit_write,
+};
+
 static int rd_blkdev_pagecache_IO(int rw, struct buffer_head * sbh, int minor)
 {
-	struct address_space * mapping = rd_inode[minor]->i_mapping;
+	struct address_space * mapping;
 	unsigned long index;
-	int offset, size, err = 0;
+	int offset, size, err;
 
-	if (sbh->b_page->mapping == mapping) {
-		if (rw != READ)
-			SetPageDirty(sbh->b_page);
+	err = -EIO;
+	/*
+	 * If we did BLKFLSBUF just before doing read/write,
+	 * we could see a rd_inode before the opener had a chance
+	 * to return from rd_open(), that's ok, as soon as we
+	 * see the inode we can use its i_mapping, and the inode
+	 * cannot go away from under us.
+	 */
+	if (!rd_inode[minor])
 		goto out;
-	}
+	err = 0;
+	mapping = rd_inode[minor]->i_mapping;
 
 	index = sbh->b_rsector >> (PAGE_CACHE_SHIFT - 9);
 	offset = (sbh->b_rsector << 9) & ~PAGE_CACHE_MASK;
@@ -206,8 +266,7 @@
 		int count;
 		struct page ** hash;
 		struct page * page;
-		const char * src;
-		char * dst;
+		char * src, * dst;
 		int unlock = 0;
 
 		count = PAGE_CACHE_SIZE - offset;
@@ -217,20 +276,24 @@
 
 		hash = page_hash(mapping, index);
 		page = __find_get_page(mapping, index, hash);
-		if (!page && rw != READ) {
+		if (!page) {
 			page = grab_cache_page(mapping, index);
 			err = -ENOMEM;
 			if (!page)
 				goto out;
 			err = 0;
+
+			if (!Page_Uptodate(page)) {
+				memset(kmap(page), 0, PAGE_CACHE_SIZE);
+				kunmap(page);
+				flush_dcache_page(page);
+				SetPageUptodate(page);
+			}
+
 			unlock = 1;
 		}
 
 		index++;
-		if (!page) {
-			offset = 0;
-			continue;
-		}
 
 		if (rw == READ) {
 			src = kmap(page);
@@ -321,6 +384,13 @@
 				struct block_device * bdev = inode->i_bdev;
 
 				down(&bdev->bd_sem);
+				/*
+				 * We're the only users here, protected by the
+				 * bd_sem, but first check if we didn't just
+				 * flushed the ramdisk.
+				 */
+				if (!rd_inode[minor])
+					goto unlock;
 				if (bdev->bd_openers > 2) {
 					up(&bdev->bd_sem);
 					return -EBUSY;
@@ -328,8 +398,16 @@
 				bdev->bd_openers--;
 				bdev->bd_cache_openers--;
 				iput(rd_inode[minor]);
+				/*
+				 * Make sure the cache is flushed from here
+				 * and not from close(2), somebody
+				 * could reopen the device before we have a
+				 * chance to close it ourself.
+				 */
+				truncate_inode_pages(rd_inode[minor]->i_mapping, 0);
 				rd_inode[minor] = NULL;
 				rd_blocksizes[minor] = rd_blocksize;
+			unlock:
 				up(&bdev->bd_sem);
 			}
 			break;
@@ -420,6 +498,8 @@
 			/* bdev->bd_sem is held by caller */
 			bdev->bd_openers++;
 			bdev->bd_cache_openers++;
+
+			bdev->bd_inode->i_mapping->a_ops = &ramdisk_aops;
 		}
 	}
 
diff -urN ramdisk-ref/fs/block_dev.c ramdisk/fs/block_dev.c
--- ramdisk-ref/fs/block_dev.c	Fri Sep 21 07:48:12 2001
+++ ramdisk/fs/block_dev.c	Fri Sep 21 08:25:29 2001
@@ -736,7 +736,7 @@
 	if (bdev->bd_op) {
 		ret = 0;
 		if (bdev->bd_op->open)
-			ret = bdev->bd_op->open(inode,filp);
+			ret = bdev->bd_op->open(bdev->bd_inode,filp);
 		if (!ret) {
 			bdev->bd_openers++;
 			bdev->bd_cache_openers++;
@@ -835,7 +835,7 @@
 
 	/* release the device driver */
 	if (bdev->bd_op->release)
-		ret = bdev->bd_op->release(inode, NULL);
+		ret = bdev->bd_op->release(bd_inode, NULL);
 	if (!--bdev->bd_openers) {
 		bdev->bd_op = NULL;
 		bdev->bd_inode = NULL;


Andrea

  reply	other threads:[~2001-09-21  7:09 UTC|newest]

Thread overview: 110+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-09-18  0:08 Linux 2.4.10-pre11 Linus Torvalds
2001-09-17 23:17 ` Marcelo Tosatti
2001-09-18  1:08   ` Marcelo Tosatti
2001-09-18  3:37     ` Andrea Arcangeli
2001-09-18  2:25       ` Marcelo Tosatti
2001-09-18  3:58         ` Andrea Arcangeli
2001-09-18  2:53           ` Marcelo Tosatti
2001-09-18  4:54             ` Andrea Arcangeli
2001-09-18  3:33               ` Marcelo Tosatti
2001-09-18  5:06                 ` Andrea Arcangeli
2001-09-18  3:55                   ` Marcelo Tosatti
2001-09-18  5:32                     ` Andrea Arcangeli
2001-09-18  4:14                       ` Marcelo Tosatti
2001-09-18  5:59                         ` Andrea Arcangeli
2001-09-18  5:00                       ` Marcelo Tosatti
     [not found] ` <20010917211834.A31693@redhat.com>
     [not found]   ` <20010918035055.J698@athlon.random>
2001-09-18  2:02     ` Andrea Arcangeli
     [not found]     ` <20010917221653.B31693@redhat.com>
2001-09-18  2:27       ` Linus Torvalds
2001-09-18  3:14         ` Alan Cox
2001-09-18  3:26         ` Andrea Arcangeli
     [not found]       ` <20010918052201.N698@athlon.random>
2001-09-18  4:01         ` Benjamin LaHaise
2001-09-18  4:39           ` Andrea Arcangeli
2001-09-18  5:04             ` Alan Cox
2001-09-18  5:09               ` Andrea Arcangeli
2001-09-18  5:22             ` Benjamin LaHaise
2001-09-18  5:48               ` Andrea Arcangeli
2001-09-18  5:48 ` Andrew Morton
2001-09-18  6:11   ` Andrea Arcangeli
2001-09-18  5:02     ` Marcelo Tosatti
2001-09-18  6:40       ` Andrea Arcangeli
2001-09-18 16:06         ` Marcelo Tosatti
2001-09-18 19:18           ` Marcelo Tosatti
2001-09-18 21:05             ` Andrea Arcangeli
2001-09-19 13:57               ` Rik van Riel
2001-09-18 10:58   ` Martin Dalecki
2001-09-18  9:31 ` Alexander Viro
2001-09-18  9:39   ` Andrea Arcangeli
2001-09-18  9:44     ` Alexander Viro
2001-09-18  9:57       ` Andrea Arcangeli
2001-09-18 10:02         ` Alexander Viro
2001-09-18 10:17           ` Andrea Arcangeli
2001-09-18 10:28             ` Alexander Viro
2001-09-18 10:35               ` Andrea Arcangeli
2001-09-18 10:52                 ` Alexander Viro
2001-09-18 11:05             ` Helge Hafting
2001-09-18 12:40               ` Andrea Arcangeli
2001-09-18 17:02             ` Linus Torvalds
2001-09-18 16:45   ` Linus Torvalds
2001-09-18 18:19     ` Alexander Viro
2001-09-18 18:27       ` Linus Torvalds
2001-09-18 19:14         ` Andreas Dilger
2001-09-18 19:41           ` Alexander Viro
2001-09-18 20:33           ` Richard Gooch
2001-09-18 20:53             ` Alexander Viro
2001-09-18 21:06             ` Richard Gooch
2001-09-18 21:27               ` Alexander Viro
2001-09-18 19:29         ` Benjamin LaHaise
2001-09-18 20:17         ` Stephan von Krawczynski
2001-09-18 20:33           ` Alan Cox
2001-09-19 13:42           ` Rik van Riel
2001-09-19 14:27             ` Alexander Viro
2001-09-19  2:59         ` Michael Peddemors
2001-09-19 16:11         ` Alexander Viro
2001-09-19 18:25           ` Andrea Arcangeli
2001-09-19 19:21             ` Alexander Viro
2001-09-19 20:55               ` Andrea Arcangeli
2001-09-19 21:17                 ` Alexander Viro
2001-09-19 23:01                   ` Andrea Arcangeli
2001-09-19 23:03                   ` Andrea Arcangeli
2001-09-19 23:30                     ` Alexander Viro
2001-09-19 23:40                       ` Andrea Arcangeli
2001-09-20 13:56                         ` Alexander Viro
2001-09-20 14:38                           ` Chris Mason
2001-09-20 14:50                             ` Alexander Viro
2001-09-20 15:44                               ` Chris Mason
2001-09-20 16:43                                 ` Alexander Viro
2001-09-20 20:54                                   ` [PATCH] fs/block_dev.c cleanup Alexander Viro
2001-09-19 22:15                 ` Linux 2.4.10-pre11 Richard Gooch
2001-09-20  2:34               ` Andrea Arcangeli
2001-09-20 10:52                 ` Alexander Viro
2001-09-20 18:18                   ` Andrea Arcangeli
2001-09-20 18:33                     ` Alexander Viro
2001-09-20 18:59                       ` Andrea Arcangeli
2001-09-20 20:41                         ` Alexander Viro
2001-09-20 21:18                           ` Andrea Arcangeli
2001-09-20 21:40                             ` Alexander Viro
2001-09-20 22:13                               ` Andrea Arcangeli
2001-09-20 22:20                                 ` Alexander Viro
2001-09-20 22:31                                   ` Andrea Arcangeli
2001-09-20 22:44                                     ` Alexander Viro
2001-09-20 23:03                                       ` Andrea Arcangeli
2001-09-20 23:11                                         ` Alexander Viro
2001-09-21  1:50                                           ` Alexander Viro
2001-09-21  2:42                                             ` Andrea Arcangeli
2001-09-21  3:47                                         ` Andrea Arcangeli
2001-09-21  4:00                                           ` Alexander Viro
2001-09-21  4:06                                             ` Andrea Arcangeli
2001-09-21  4:06                                           ` Andrea Arcangeli
2001-09-21  4:46                                             ` Andrea Arcangeli
2001-09-21  7:09                                               ` Andrea Arcangeli [this message]
2001-09-19 20:41             ` Richard Gooch
2001-09-19 13:38       ` Rik van Riel
2001-09-19 16:35       ` Andrea Arcangeli
2001-09-18  3:18 Ed Tomlinson
2001-09-18  2:31 ` Magnus Naeslund(f)
2001-09-18  2:49   ` David B. Stevens
2001-09-18  3:38   ` Ed Tomlinson
2001-09-18  3:15 ` Alan Cox
2001-09-18  4:41   ` H. Peter Anvin
2001-09-18  6:14 Alexei Podtelezhnikov
2001-09-18 13:51 ` Rik van Riel

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=20010921090910.H729@athlon.random \
    --to=andrea@suse.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@transmeta.com \
    --cc=viro@math.psu.edu \
    /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;
as well as URLs for NNTP newsgroup(s).