public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Christoph Rohland <cr@sap.com>
To: Alexander Viro <viro@math.psu.edu>
Cc: Legacy Fishtank <garzik@havoc.gtf.org>,
	Alan Cox <alan@lxorguk.ukuu.org.uk>,
	Linus Torvalds <torvalds@transmeta.com>,
	linux-kernel@vger.kernel.org
Subject: Re: 2.5.2-pre2 forces ramfs on
Date: Thu, 27 Dec 2001 11:39:22 +0100	[thread overview]
Message-ID: <m3ofkl6j6t.fsf@linux.local> (raw)
In-Reply-To: <Pine.GSO.4.21.0112261228180.2716-100000@weyl.math.psu.edu>
In-Reply-To: <Pine.GSO.4.21.0112261228180.2716-100000@weyl.math.psu.edu> (Alexander Viro's message of "Wed, 26 Dec 2001 12:36:09 -0500 (EST)")

[-- Attachment #1: Type: text/plain, Size: 687 bytes --]

Hi Al,

On Wed, 26 Dec 2001, Alexander Viro wrote:
> What's more, quite a few ramfs methods are good candidates for
> library functions, since they are already shared with other
> filesystems and number of such cases is going to grow.

Comments on the following set of patches?

1) Add a removepage operation to the address_space_operations which
   simplifies the size checking heavily. This is not strictly needed.
2) Add a ramfs(2) incorporation to shmem.c which disables the swapping
   and does not allocate the swap vector for shmem.c files.

We would gain a full ramfs with size checking, error checking and
correct time stamping with a very small change.

Greetings
		Christoph


[-- Attachment #2: patch-removepage --]
[-- Type: text/plain, Size: 4090 bytes --]

diff -uNr 17-rc1/include/linux/fs.h 17-rc1-removepage/include/linux/fs.h
--- 17-rc1/include/linux/fs.h	Sun Dec 16 10:27:45 2001
+++ 17-rc1-removepage/include/linux/fs.h	Sun Dec 16 10:36:26 2001
@@ -391,6 +391,7 @@
 	int (*releasepage) (struct page *, int);
 #define KERNEL_HAS_O_DIRECT /* this is for modules out of the kernel */
 	int (*direct_IO)(int, struct inode *, struct kiobuf *, unsigned long, int);
+	void (*removepage)(struct page *); /* called when page gets removed from the inode */
 };
 
 struct address_space {
diff -uNr 17-rc1/mm/filemap.c 17-rc1-removepage/mm/filemap.c
--- 17-rc1/mm/filemap.c	Sun Dec 16 10:27:48 2001
+++ 17-rc1-removepage/mm/filemap.c	Sun Dec 16 10:31:55 2001
@@ -96,6 +96,9 @@
 {
 	struct address_space * mapping = page->mapping;
 
+	if (mapping->a_ops->removepage)
+		mapping->a_ops->removepage(page);
+	
 	mapping->nrpages--;
 	list_del(&page->list);
 	page->mapping = NULL;
diff -uNr 17-rc1/mm/shmem.c 17-rc1-removepage/mm/shmem.c
--- 17-rc1/mm/shmem.c	Sun Dec 16 10:27:48 2001
+++ 17-rc1-removepage/mm/shmem.c	Sun Dec 16 11:17:47 2001
@@ -47,43 +47,25 @@
 
 LIST_HEAD (shmem_inodes);
 static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
-atomic_t shmem_nrpages = ATOMIC_INIT(0); /* Not used right now */
+atomic_t shmem_nrpages = ATOMIC_INIT(0);
 
 #define BLOCKS_PER_PAGE (PAGE_CACHE_SIZE/512)
 
-/*
- * shmem_recalc_inode - recalculate the size of an inode
- *
- * @inode: inode to recalc
- * @swap:  additional swap pages freed externally
- *
- * We have to calculate the free blocks since the mm can drop pages
- * behind our back
- *
- * But we know that normally
- * inodes->i_blocks/BLOCKS_PER_PAGE == 
- * 			inode->i_mapping->nrpages + info->swapped
- *
- * So the mm freed 
- * inodes->i_blocks/BLOCKS_PER_PAGE - 
- * 			(inode->i_mapping->nrpages + info->swapped)
- *
- * It has to be called with the spinlock held.
- */
-
-static void shmem_recalc_inode(struct inode * inode)
+static void shmem_removepage(struct page *page)
 {
-	unsigned long freed;
+	struct inode * inode;
+	struct shmem_sb_info * sbinfo;
 
-	freed = (inode->i_blocks/BLOCKS_PER_PAGE) -
-		(inode->i_mapping->nrpages + SHMEM_I(inode)->swapped);
-	if (freed){
-		struct shmem_sb_info * sbinfo = SHMEM_SB(inode->i_sb);
-		inode->i_blocks -= freed*BLOCKS_PER_PAGE;
-		spin_lock (&sbinfo->stat_lock);
-		sbinfo->free_blocks += freed;
-		spin_unlock (&sbinfo->stat_lock);
-	}
+	atomic_dec(&shmem_nrpages);
+	if (PageLaunder(page))
+		return;
+
+	inode = page->mapping->host;
+	sbinfo = SHMEM_SB(inode->i_sb);
+	inode->i_blocks -= BLOCKS_PER_PAGE;
+	spin_lock (&sbinfo->stat_lock);
+	sbinfo->free_blocks++;
+	spin_unlock (&sbinfo->stat_lock);
 }
 
 /*
@@ -315,6 +297,7 @@
 	unsigned long index;
 	unsigned long freed = 0;
 	struct shmem_inode_info * info = SHMEM_I(inode);
+	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 
 	down(&info->sem);
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
@@ -325,8 +308,11 @@
 		freed += shmem_truncate_indirect(info, index);
 
 	info->swapped -= freed;
-	shmem_recalc_inode(inode);
+	inode->i_blocks -= freed*BLOCKS_PER_PAGE;
 	spin_unlock (&info->lock);
+	spin_lock (&sbinfo->stat_lock);
+	sbinfo->free_blocks += freed;
+	spin_unlock (&sbinfo->stat_lock);
 	up(&info->sem);
 }
 
@@ -385,6 +371,7 @@
 	return 0;
 found:
 	delete_from_swap_cache(page);
+	atomic_inc(&shmem_nrpages);
 	add_to_page_cache(page, info->inode->i_mapping, offset + idx);
 	SetPageDirty(page);
 	SetPageUptodate(page);
@@ -446,7 +433,6 @@
 	entry = shmem_swp_entry(info, index, 0);
 	if (IS_ERR(entry))	/* this had been allocated on page allocation */
 		BUG();
-	shmem_recalc_inode(inode);
 	if (entry->val)
 		BUG();
 
@@ -517,7 +503,6 @@
 		return page;
 	}
 	
-	shmem_recalc_inode(inode);
 	if (entry->val) {
 		unsigned long flags;
 
@@ -583,6 +568,7 @@
 
 	/* We have the page */
 	SetPageUptodate(page);
+	atomic_inc(&shmem_nrpages);
 	return page;
 no_space:
 	spin_unlock (&sbinfo->stat_lock);
@@ -1325,6 +1311,7 @@
 
 
 static struct address_space_operations shmem_aops = {
+	removepage:	shmem_removepage,
 	writepage:	shmem_writepage,
 };
 

[-- Attachment #3: patch-ramfs2 --]
[-- Type: text/plain, Size: 4430 bytes --]

diff -uNr 17-rc1-removepage/mm/shmem.c c/mm/shmem.c
--- 17-rc1-removepage/mm/shmem.c	Sun Dec 16 11:31:21 2001
+++ c/mm/shmem.c	Sun Dec 16 15:04:34 2001
@@ -36,15 +36,28 @@
 #define ENTRIES_PER_PAGE (PAGE_CACHE_SIZE/sizeof(unsigned long))
 
 #define SHMEM_SB(sb) (&sb->u.shmem_sb)
+#define SHMEM_NOSWAP(info) ((info)->locked == 2)
 
 static struct super_operations shmem_ops;
 static struct address_space_operations shmem_aops;
+static struct address_space_operations shmem_noswap_aops;
 static struct file_operations shmem_file_operations;
 static struct inode_operations shmem_inode_operations;
 static struct file_operations shmem_dir_operations;
 static struct inode_operations shmem_dir_inode_operations;
 static struct vm_operations_struct shmem_vm_ops;
 
+static struct super_block *shmem_read_super(struct super_block * sb, void * data, int silent);
+
+#ifdef CONFIG_TMPFS
+/* type "shm" will be tagged obsolete in 2.5 */
+static DECLARE_FSTYPE(shmem_fs_type, "shm", shmem_read_super, FS_LITTER);
+static DECLARE_FSTYPE(tmpfs_fs_type, "tmpfs", shmem_read_super, FS_LITTER);
+static DECLARE_FSTYPE(ramfs2_fs_type, "ramfs2", shmem_read_super, FS_LITTER);
+#else
+static DECLARE_FSTYPE(tmpfs_fs_type, "tmpfs", shmem_read_super, FS_LITTER|FS_NOMOUNT);
+#endif
+
 LIST_HEAD (shmem_inodes);
 static spinlock_t shmem_ilock = SPIN_LOCK_UNLOCKED;
 atomic_t shmem_nrpages = ATOMIC_INIT(0);
@@ -299,8 +312,11 @@
 	struct shmem_inode_info * info = SHMEM_I(inode);
 	struct shmem_sb_info *sbinfo = SHMEM_SB(inode->i_sb);
 
-	down(&info->sem);
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
+	if (SHMEM_NOSWAP(info))
+		return;
+
+	down(&info->sem);
 	spin_lock (&info->lock);
 	index = (inode->i_size + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
 
@@ -352,6 +368,9 @@
 	unsigned long idx;
 	int offset;
 	
+	if (SHMEM_NOSWAP(info))
+		return 0;
+
 	idx = 0;
 	spin_lock (&info->lock);
 	offset = shmem_clear_swp (entry, info->i_direct, SHMEM_NR_DIRECT);
@@ -484,6 +503,9 @@
 	if (page)
 		return page;
 
+	if (SHMEM_NOSWAP(info))
+		goto noswap_alloc;
+
 	entry = shmem_alloc_entry (info, idx);
 	if (IS_ERR(entry))
 		return (void *)entry;
@@ -543,6 +565,7 @@
 		info->swapped--;
 		spin_unlock (&info->lock);
 	} else {
+	noswap_alloc:
 		sbinfo = SHMEM_SB(inode->i_sb);
 		spin_unlock (&info->lock);
 		spin_lock (&sbinfo->stat_lock);
@@ -628,8 +651,11 @@
 	struct inode * inode = file->f_dentry->d_inode;
 	struct shmem_inode_info * info = SHMEM_I(inode);
 
+	if (SHMEM_NOSWAP(info))
+		return;
+
 	down(&info->sem);
-	info->locked = lock;
+	info->locked = (lock != 0);
 	up(&info->sem);
 }
 
@@ -668,12 +694,19 @@
 		inode->i_blksize = PAGE_CACHE_SIZE;
 		inode->i_blocks = 0;
 		inode->i_rdev = NODEV;
-		inode->i_mapping->a_ops = &shmem_aops;
 		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 		info = SHMEM_I(inode);
 		info->inode = inode;
 		spin_lock_init (&info->lock);
 		sema_init (&info->sem, 1);
+
+		if (sb->s_type == &ramfs2_fs_type) {
+			info->locked = 2;
+			inode->i_mapping->a_ops = &shmem_noswap_aops;
+		} else {
+			inode->i_mapping->a_ops = &shmem_aops;
+		}
+
 		switch (mode & S_IFMT) {
 		default:
 			init_special_inode(inode, mode, dev);
@@ -1310,6 +1343,11 @@
 
 
 
+static struct address_space_operations shmem_noswap_aops = {
+	removepage:	shmem_removepage,
+	writepage:	fail_writepage,
+};
+
 static struct address_space_operations shmem_aops = {
 	removepage:	shmem_removepage,
 	writepage:	shmem_writepage,
@@ -1363,13 +1401,6 @@
 	nopage:	shmem_nopage,
 };
 
-#ifdef CONFIG_TMPFS
-/* type "shm" will be tagged obsolete in 2.5 */
-static DECLARE_FSTYPE(shmem_fs_type, "shm", shmem_read_super, FS_LITTER);
-static DECLARE_FSTYPE(tmpfs_fs_type, "tmpfs", shmem_read_super, FS_LITTER);
-#else
-static DECLARE_FSTYPE(tmpfs_fs_type, "tmpfs", shmem_read_super, FS_LITTER|FS_NOMOUNT);
-#endif
 static struct vfsmount *shm_mnt;
 
 static int __init init_shmem_fs(void)
@@ -1382,6 +1413,11 @@
 		return error;
 	}
 #ifdef CONFIG_TMPFS
+	if ((error = register_filesystem(&ramfs2_fs_type))) {
+		printk (KERN_ERR "Could not register ramfs2\n");
+		return error;
+	}
+
 	if ((error = register_filesystem(&shmem_fs_type))) {
 		printk (KERN_ERR "Could not register shm fs\n");
 		return error;
@@ -1407,6 +1443,7 @@
 {
 #ifdef CONFIG_TMPFS
 	unregister_filesystem(&shmem_fs_type);
+	unregister_filesystem(&ramfs2_fs_type);
 #endif
 	unregister_filesystem(&tmpfs_fs_type);
 	mntput(shm_mnt);

  parent reply	other threads:[~2001-12-27 10:50 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-12-26  3:41 2.5.2-pre2 forces ramfs on Keith Owens
2001-12-26  4:17 ` Linus Torvalds
2001-12-26 15:04   ` Alan Cox
2001-12-26 17:20     ` Legacy Fishtank
2001-12-26 17:36       ` Alexander Viro
2001-12-26 17:52         ` Legacy Fishtank
2001-12-27 10:39         ` Christoph Rohland [this message]
2002-01-05 22:35         ` Eric W. Biederman
2001-12-26 22:04     ` Linus Torvalds
2001-12-26  4:26 ` Alexander Viro

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=m3ofkl6j6t.fsf@linux.local \
    --to=cr@sap.com \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=garzik@havoc.gtf.org \
    --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