Skip to contentSkip to conversation

vm_store

RFC PATCH In review Eric W. Biederman 2 participants 2 messages May 30, 1999

Subsystems (10)
lore
Share & tools
lore
#0 lore raw

RFC PATCH 1/1 vm_store

This patch creates the the abstraction of a vm_store, allowing the page cache to be seperated from the vfs layer.

It also seperates out what is the page cache, from filemap.c into mm/vm_store.c

The only vm_store operation implemented in this patch is clear_page. Allowing delete_from_swap_cache to stop being a special case.

Note: This is on top of some other patches, to see my whole series see:
http://www.ccr.net/ebiederm/files/patches9.tar.gz

arch/m68k/atari/stram.c +1 -1
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/arch/m68k/atari/stram.c linux-2.3.3.eb6/arch/m68k/atari/stram.c
@@ -944,7 +944,7 @@
 				/* Now get rid of the extra reference to
 				   the temporary page we've been using. */
 				if (PageSwapCache(page_map))
-					delete_from_swap_cache(page_map);
+						remove_store_page(page_map);
 				__free_page(page_map);
 	#ifdef DO_PROC
 				stat_swap_force++;
fs/dcache.c +1 -1
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/fs/dcache.c linux-2.3.3.eb6/fs/dcache.c
@@ -236,7 +236,7 @@
 		 * (We skip inodes that aren't immediately available.)
 		 */
 		if (inode) {
-			value = inode->i_nrpages;	
+			value = inode->vm_store->st_nrpages;	
 			if (value >= max_value)
 				continue;
 			if (inode->i_state || inode->i_count > 1)
fs/exec.c +1 -0
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/fs/exec.c linux-2.3.3.eb6/fs/exec.c
@@ -316,6 +316,7 @@
 		mpnt->vm_ops = NULL;
 		mpnt->vm_index = 0;
 		mpnt->vm_file = NULL;
+		mpnt->vm_store = NULL;
 		mpnt->vm_pte = 0;
 		insert_vm_struct(current->mm, mpnt);
 		current->mm->total_vm = (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT;
fs/inode.c +5 -3
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/fs/inode.c linux-2.3.3.eb6/fs/inode.c
@@ -231,14 +231,12 @@
  */
 void clear_inode(struct inode *inode)
 {
-	if (inode->i_nrpages)
-		truncate_inode_pages(inode, 0);
 	wait_on_inode(inode);
 	if (IS_QUOTAINIT(inode))
 		DQUOT_DROP(inode);
 	if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->clear_inode)
 		inode->i_sb->s_op->clear_inode(inode);
-
+	zap_inode_pages(inode);
 	inode->i_state = 0;
 }
 
@@ -549,6 +547,8 @@
 		inode = list_entry(tmp, struct inode, i_list);
 add_new_inode:
 		list_add(&inode->i_list, &inode_in_use);
+		inode->vm_store->st_id = 0;
+		inode->vm_store->generic_stp = &inode;
 		inode->i_sb = NULL;
 		inode->i_dev = 0;
 		inode->i_ino = ++last_ino;
@@ -589,6 +589,8 @@
 add_new_inode:
 		list_add(&inode->i_list, &inode_in_use);
 		list_add(&inode->i_hash, head);
+		inode->vm_store->st_id = 0;
+		inode->vm_store->generic_stp = &inode;
 		inode->i_sb = sb;
 		inode->i_dev = sb->s_dev;
 		inode->i_ino = ino;
fs/locks.c +2 -2
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/fs/locks.c linux-2.3.3.eb6/fs/locks.c
@@ -403,8 +403,8 @@
 	 */
 	if (IS_MANDLOCK(inode) &&
 	    (inode->i_mode & (S_ISGID | S_IXGRP)) == S_ISGID &&
-	    inode->i_mmap) {
-		struct vm_area_struct *vma = inode->i_mmap;
+	    inode->vm_store->st_mmap) {
+		struct vm_area_struct *vma = inode->vm_store->st_mmap;
 		error = -EAGAIN;
 		do {
 			if (vma->vm_flags & VM_MAYSHARE)
include/linux/fs.h +2 -4
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/include/linux/fs.h linux-2.3.3.eb6/include/linux/fs.h
@@ -18,6 +18,7 @@
 #include <linux/list.h>
 #include <linux/dcache.h>
 #include <linux/stat.h>
+#include <linux/vm_store.h>
 
 #include <asm/atomic.h>
 #include <asm/bitops.h>
@@ -356,17 +357,15 @@
 	unsigned long		i_blksize;
 	unsigned long		i_blocks;
 	unsigned long		i_version;
-	unsigned long		i_nrpages;
 	struct semaphore	i_sem;
 	struct semaphore	i_atomic_write;
 	struct inode_operations	*i_op;
 	struct super_block	*i_sb;
 	wait_queue_head_t	i_wait;
 	struct file_lock	*i_flock;
-	struct vm_area_struct	*i_mmap;
-	struct page		*i_pages;
 	struct dquot		*i_dquot[MAXQUOTAS];
 
+ 	struct vm_store		vm_store[1];
 	unsigned long		i_state;
 
 	unsigned int		i_flags;
@@ -788,7 +787,6 @@
 
 extern int check_disk_change(kdev_t dev);
 extern int invalidate_inodes(struct super_block * sb);
-extern void invalidate_inode_pages(struct inode *);
 extern void invalidate_buffers(kdev_t dev);
 extern int floppy_is_wp(int minor);
 extern void sync_inodes(kdev_t dev);
include/linux/mm.h +11 -2
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/include/linux/mm.h linux-2.3.3.eb6/include/linux/mm.h
@@ -16,6 +16,8 @@
 #include <asm/page.h>
 #include <asm/atomic.h>
 
+struct vm_store;
+
 /*
  * Linux kernel virtual memory manager primitives.
  * The idea being to have a "virtual" mm in the same way
@@ -60,6 +62,7 @@
 	 * except the value is potentially too large for the old vm_offset field.
 	 */
 	struct file * vm_file;
+	struct vm_store *vm_store;
 	unsigned long vm_pte;			/* shared mem */
 };
 
@@ -85,6 +88,10 @@
 #define VM_LOCKED	0x2000
 #define VM_IO           0x4000  /* Memory mapped I/O or similar */
 
+#define VM_SPARSE_MERGE	0x8000 /* Sparce VMA's with non continous
+				* indecies may be merged 
+				*/
+
 #define VM_STACK_FLAGS	0x0177
 
 /*
@@ -126,7 +133,7 @@
 	/* these must be first (free area handling) */
 	struct page *next;
 	struct page *prev;
-	struct inode *inode;
+	struct vm_store *store;
 	unsigned long key;
 	struct page *next_hash;
 	atomic_t count;
@@ -325,10 +332,12 @@
 extern int do_munmap(unsigned long, size_t);
 
 /* filemap.c */
-extern void remove_inode_page(struct page *);
 extern unsigned long page_unuse(struct page *);
 extern int shrink_mmap(int, int);
 extern void truncate_inode_pages(struct inode *, loff_t);
+extern void invalidate_inode_pages(struct inode *);
+extern void zap_inode_pages(struct inode *);
+extern void update_vm_cache(struct inode *, loff_t, const char *, int);
 extern unsigned long get_cached_page(struct inode *, unsigned long, int);
 extern void put_cached_page(unsigned long);
 
include/linux/pagemap.h +25 -22

107 lines not on this page · raw message

include/linux/swap.h +1 -2
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/include/linux/swap.h linux-2.3.3.eb6/include/linux/swap.h
@@ -66,7 +66,7 @@
 extern int nr_swap_pages;
 extern int nr_free_pages;
 extern atomic_t nr_async_pages;
-extern struct inode swapper_inode;
+extern struct vm_store swapper_store;
 extern unsigned long page_cache_size;
 extern int buffermem;
 
@@ -107,7 +107,6 @@
 /*
  * Make these inline later once they are working properly.
  */
-extern void delete_from_swap_cache(struct page *page);
 extern void free_page_and_swap_cache(unsigned long addr);
 
 /* linux/mm/swapfile.c */
include/linux/vm_store.h +52 -0

52 lines not on this page · raw message

ipc/shm.c +1 -0
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/ipc/shm.c linux-2.3.3.eb6/ipc/shm.c
@@ -513,6 +513,7 @@
 			 | VM_MAYREAD | VM_MAYEXEC | VM_READ | VM_EXEC
 			 | ((shmflg & SHM_RDONLY) ? 0 : VM_MAYWRITE | VM_WRITE);
 	shmd->vm_file = NULL;
+	shmd->vm_store = NULL;
 	shmd->vm_index = 0;
 	shmd->vm_ops = &shm_vm_ops;
 
mm/Makefile +2 -1
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/mm/Makefile linux-2.3.3.eb6/mm/Makefile
@@ -10,7 +10,8 @@
 O_TARGET := mm.o
 O_OBJS	 := memory.o mmap.o filemap.o mprotect.o mlock.o mremap.o \
 	    vmalloc.o slab.o \
-	    swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o
+	    swap.o vmscan.o page_io.o page_alloc.o swap_state.o swapfile.o \
+	    vm_store.o
 
 OX_OBJS := swap_syms.o
 
mm/filemap.c +78 -290

536 lines not on this page · raw message

mm/memory.c +3 -3
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/mm/memory.c linux-2.3.3.eb6/mm/memory.c
@@ -649,7 +649,7 @@
 			break;
 		if (swap_count(page_map->key) != 1)
 			break;
-		delete_from_swap_cache(page_map);
+		remove_store_page(page_map);
 		/* FallThrough */
 	case 1:
 		/* We can release the kernel lock now.. */
@@ -740,13 +740,13 @@
 	struct vm_area_struct * mpnt;
 
 	truncate_inode_pages(inode, offset);
-	if ((!inode->i_mmap) || (offset > PAGE_MAX_FILE_OFFSET)) {
+	if ((!inode->vm_store->st_mmap) || (offset > PAGE_MAX_FILE_OFFSET)) {
 		return;
 	}
 	index = offset >> PAGE_CACHE_SHIFT;
 	partial = offset & PAGE_CACHE_MASK;
 	trunk_index = index + (partial)? 1 : 0;
-	mpnt = inode->i_mmap;
+	mpnt = inode->vm_store->st_mmap;
 	do {
 		struct mm_struct *mm = mpnt->vm_mm;
 		unsigned long start = mpnt->vm_start;
mm/mmap.c +17 -7
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/mm/mmap.c linux-2.3.3.eb6/mm/mmap.c
@@ -74,10 +74,13 @@
 static inline void remove_shared_vm_struct(struct vm_area_struct *vma)
 {
 	struct file * file = vma->vm_file;
+	struct vm_store *store = vma->vm_store;
 
 	if (file) {
 		if (vma->vm_flags & VM_DENYWRITE)
 			file->f_dentry->d_inode->i_writecount++;
+	}
+	if (store) {
 		if(vma->vm_next_share)
 			vma->vm_next_share->vm_pprev_share = vma->vm_pprev_share;
 		*vma->vm_pprev_share = vma->vm_next_share;
@@ -280,6 +283,7 @@
 	vma->vm_ops = NULL;
 	vma->vm_index = 0;
 	vma->vm_file = NULL;
+	vma->vm_store = NULL;
 	vma->vm_pte = 0;
 
 	/* Clear old maps */
@@ -530,6 +534,7 @@
 		mpnt->vm_ops = area->vm_ops;
 		mpnt->vm_index = area->vm_index + ((end - area->vm_start) >> PAGE_SHIFT);
 		mpnt->vm_file = area->vm_file;
+		mpnt->vm_store = area->vm_store;
 		mpnt->vm_pte = area->vm_pte;
 		if (mpnt->vm_file)
 			mpnt->vm_file->f_count++;
@@ -755,6 +760,7 @@
 {
 	struct vm_area_struct **pprev;
 	struct file * file;
+	struct vm_store *store;
 
 	if (!mm->mmap_avl) {
 		pprev = &mm->mmap;
@@ -779,12 +785,14 @@
 		struct inode * inode = file->f_dentry->d_inode;
 		if (vmp->vm_flags & VM_DENYWRITE)
 			inode->i_writecount--;
-      
-		/* insert vmp into inode's share list */
-		if((vmp->vm_next_share = inode->i_mmap) != NULL)
-			inode->i_mmap->vm_pprev_share = &vmp->vm_next_share;
-		inode->i_mmap = vmp;
-		vmp->vm_pprev_share = &inode->i_mmap;
+	}
+	store = vmp->vm_store;
+	if (store) {
+      		/* insert vmp into store's share list */
+		if((vmp->vm_next_share = store->st_mmap) != NULL)
+			store->st_mmap->vm_pprev_share = &vmp->vm_next_share;
+		store->st_mmap = vmp;
+		vmp->vm_pprev_share = &store->st_mmap;
 	}
 }
 
@@ -818,7 +826,8 @@
 		next = mpnt->vm_next;
 
 		/* To share, we must have the same file, operations.. */
-		if ((mpnt->vm_file != prev->vm_file)||
+		if ((mpnt->vm_file != prev->vm_file)	||
+		    (mpnt->vm_store != prev->vm_store)	||
 		    (mpnt->vm_pte != prev->vm_pte)	||
 		    (mpnt->vm_ops != prev->vm_ops)	||
 		    (mpnt->vm_flags != prev->vm_flags)	||
@@ -829,6 +838,7 @@
 		 * If we have a file or it's a shared memory area
 		 * the offsets must be contiguous..
 		 */
+		/*  use VM_SPARCE_MERGE here? */
 		if ((mpnt->vm_file != NULL) || (mpnt->vm_flags & VM_SHM)) {
 			unsigned long off = prev->vm_index + 
 				((prev->vm_end - prev->vm_start) >> PAGE_SHIFT);
mm/page_alloc.c +1 -1
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/mm/page_alloc.c linux-2.3.3.eb6/mm/page_alloc.c
@@ -425,7 +425,7 @@
 	 * down the swap cache and give exclusive access to the page to
 	 * this process.
 	 */
-	delete_from_swap_cache(page_map);
+	remove_store_page(page_map);
 	set_pte(page_table, pte_mkwrite(pte_mkdirty(mk_pte(page, vma->vm_page_prot))));
   	return;
 }
mm/page_io.c +4 -4
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/mm/page_io.c linux-2.3.3.eb6/mm/page_io.c
@@ -237,7 +237,7 @@
 {
 	struct page *page = mem_map + MAP_NR(buf);
 
-	if (page->inode && page->inode != &swapper_inode)
+	if (page->store && page->store != &swapper_store)
 		panic ("Tried to swap a non-swapper page");
 
 	/*
@@ -274,16 +274,16 @@
 		printk ("VM: read_swap_page: page already in swap cache!\n");
 		return;
 	}
-	if (page->inode) {
+	if (page->store) {
 		printk ("VM: read_swap_page: page already in page cache!\n");
 		return;
 	}
-	page->inode = &swapper_inode;
+	page->store = &swapper_store;
 	page->key = entry;
 	atomic_inc(&page->count);	/* Protect from shrink_mmap() */
 	rw_swap_page(rw, entry, buffer, 1);
 	atomic_dec(&page->count);
-	page->inode = 0;
+	page->store = 0;
 	clear_bit(PG_swap_cache, &page->flags);
 }
 
mm/swap_state.c +21 -45

115 lines not on this page · raw message

mm/swap_syms.c +1 -1
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/mm/swap_syms.c linux-2.3.3.eb6/mm/swap_syms.c
@@ -13,4 +13,4 @@
 EXPORT_SYMBOL(si_swapinfo);
 EXPORT_SYMBOL(register_swap_unuse_function);
 EXPORT_SYMBOL(unregister_swap_unuse_function);
-EXPORT_SYMBOL(swapper_inode);
+EXPORT_SYMBOL(swapper_store);
mm/swapfile.c +1 -1
diff -uNrX /home/eric/projects/linux/linux-ignore-files linux-2.3.3.eb5/mm/swapfile.c linux-2.3.3.eb6/mm/swapfile.c
@@ -447,7 +447,7 @@
 		/* Now get rid of the extra reference to the temporary
                    page we've been using. */
 		if (PageSwapCache(page_map))
-			delete_from_swap_cache(page_map);
+			remove_store_page(page_map);
 		__free_page(page_map);
 		/*
 		 * Check for and clear any overflowed swap map counts.
mm/vm_store.c +254 -0

254 lines not on this page · raw message

--
To unsubscribe, send a message with 'unsubscribe linux-mm my@address' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/

#1 lore raw
Quoted 3 lines · Eric W. Biederman

This patch creates the the abstraction of a vm_store, allowing the page cache to be seperated from the vfs layer.

I don't think vm_store is very interesting, unless it can be made to contain the current "vm_ops" structure. At the very least you should move vm_ops into vm_store, I feel - before that is done I don't see any reason for vm_store existing at all..

I _assume_ that was the plan all along?

Linus

--
To unsubscribe, send a message with 'unsubscribe linux-mm my@address' in the body to [email protected]. For more info on Linux MM,
see: http://humbolt.geo.uu.nl/Linux-MM/