[Patch] 2.4.5-ac13 ramfs and tmpfs accounting

2001-06-13 Thread Christoph Rohland

Hi Alan,

ramfs accounting does not get notified when a clean page gets dropped
from the inode.

Also tmpfs should use the new function to do accurate accounting. Else
the cached field in -ac will get spurious negative values.

The following patch fixes both.

Greetings
Christoph

diff -uNr 5-ac13/fs/ramfs/inode.c 5-ac13-a/fs/ramfs/inode.c
--- 5-ac13/fs/ramfs/inode.c Tue Jun 12 09:51:39 2001
+++ 5-ac13-a/fs/ramfs/inode.c   Wed Jun 13 09:54:22 2001
@@ -289,7 +289,7 @@
return 0;
 }
 
-static void ramfs_truncatepage(struct page *page)
+static void ramfs_removepage(struct page *page)
 {
struct inode *inode = (struct inode *)page->mapping->host;
 
@@ -659,7 +659,7 @@
writepage:  ramfs_writepage,
prepare_write:  ramfs_prepare_write,
commit_write:   ramfs_commit_write,
-   truncatepage:   ramfs_truncatepage,
+   removepage: ramfs_removepage,
 };
 
 static struct file_operations ramfs_file_operations = {
diff -uNr 5-ac13/include/linux/fs.h 5-ac13-a/include/linux/fs.h
--- 5-ac13/include/linux/fs.h   Tue Jun 12 17:34:25 2001
+++ 5-ac13-a/include/linux/fs.h Wed Jun 13 10:23:48 2001
@@ -368,7 +368,7 @@
int (*sync_page)(struct page *);
int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
-   void (*truncatepage)(struct page *); /* called from truncate_complete_page */
+   void (*removepage)(struct page *); /* called when page gets removed from the 
+inode */
/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
int (*bmap)(struct address_space *, long);
 };
diff -uNr 5-ac13/mm/filemap.c 5-ac13-a/mm/filemap.c
--- 5-ac13/mm/filemap.c Tue Jun 12 09:51:45 2001
+++ 5-ac13-a/mm/filemap.c   Wed Jun 13 09:56:43 2001
@@ -82,6 +82,9 @@
 {
struct address_space * mapping = page->mapping;
 
+   if (mapping->a_ops->removepage)
+   mapping->a_ops->removepage(page);
+   
mapping->nrpages--;
list_del(>list);
page->mapping = NULL;
@@ -206,9 +209,6 @@
if (!page->buffers || block_flushpage(page, 0))
lru_cache_del(page);
 
-   if (page->mapping->a_ops->truncatepage)
-   page->mapping->a_ops->truncatepage(page);
-   
/*
 * We remove the page from the page cache _after_ we have
 * destroyed all buffer-cache references to it. Otherwise some
diff -uNr 5-ac13/mm/shmem.c 5-ac13-a/mm/shmem.c
--- 5-ac13/mm/shmem.c   Tue Jun 12 09:51:45 2001
+++ 5-ac13-a/mm/shmem.c Wed Jun 13 09:56:20 2001
@@ -51,42 +51,16 @@
 
 #define BLOCKS_PER_PAGE (PAGE_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.
- *
- * The swap parameter is a performance hack for truncate.
- */
-
-static void shmem_recalc_inode(struct inode * inode, unsigned long swap)
+static void shmem_removepage(struct page *page)
 {
-   unsigned long freed;
+   struct inode *inode = (struct inode *)page->mapping->host;
+   struct shmem_sb_info * sbinfo = SHMEM_SB(inode->i_sb);
 
-   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 (>stat_lock);
-   sbinfo->free_blocks += freed;
-   spin_unlock (>stat_lock);
-   atomic_sub(freed-swap, _nrpages);
-   }
+   inode->i_blocks -= BLOCKS_PER_PAGE;
+   spin_lock (>stat_lock);
+   sbinfo->free_blocks++;
+   spin_unlock (>stat_lock);
+   atomic_dec(_nrpages);
 }
 
 static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long 
index) 
@@ -166,6 +140,7 @@
unsigned long freed = 0;
swp_entry_t **base, **ptr, **last;
struct shmem_inode_info * info = SHMEM_I(inode);
+   struct shmem_sb_info * sbinfo = SHMEM_SB(inode->i_sb);
 
down(>sem);
inode->i_ctime = inode->i_mtime = CURRENT_TIME;
@@ -202,7 +177,9 @@
 out:
info->max_index = index;
info->swapped -= freed;
-   shmem_recalc_inode(inode, freed);
+   spin_lock(>stat_lock);
+   sbinfo->free_blocks += freed;
+   spin_unlock(>stat_lock);
spin_unlock (>lock);
up(>sem);
 }
@@ -257,7 +234,6 @@
entry = shmem_swp_entry(info, 

[Patch] 2.4.5-ac13 ramfs and tmpfs accounting

2001-06-13 Thread Christoph Rohland

Hi Alan,

ramfs accounting does not get notified when a clean page gets dropped
from the inode.

Also tmpfs should use the new function to do accurate accounting. Else
the cached field in -ac will get spurious negative values.

The following patch fixes both.

Greetings
Christoph

diff -uNr 5-ac13/fs/ramfs/inode.c 5-ac13-a/fs/ramfs/inode.c
--- 5-ac13/fs/ramfs/inode.c Tue Jun 12 09:51:39 2001
+++ 5-ac13-a/fs/ramfs/inode.c   Wed Jun 13 09:54:22 2001
@@ -289,7 +289,7 @@
return 0;
 }
 
-static void ramfs_truncatepage(struct page *page)
+static void ramfs_removepage(struct page *page)
 {
struct inode *inode = (struct inode *)page-mapping-host;
 
@@ -659,7 +659,7 @@
writepage:  ramfs_writepage,
prepare_write:  ramfs_prepare_write,
commit_write:   ramfs_commit_write,
-   truncatepage:   ramfs_truncatepage,
+   removepage: ramfs_removepage,
 };
 
 static struct file_operations ramfs_file_operations = {
diff -uNr 5-ac13/include/linux/fs.h 5-ac13-a/include/linux/fs.h
--- 5-ac13/include/linux/fs.h   Tue Jun 12 17:34:25 2001
+++ 5-ac13-a/include/linux/fs.h Wed Jun 13 10:23:48 2001
@@ -368,7 +368,7 @@
int (*sync_page)(struct page *);
int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
-   void (*truncatepage)(struct page *); /* called from truncate_complete_page */
+   void (*removepage)(struct page *); /* called when page gets removed from the 
+inode */
/* Unfortunately this kludge is needed for FIBMAP. Don't use it */
int (*bmap)(struct address_space *, long);
 };
diff -uNr 5-ac13/mm/filemap.c 5-ac13-a/mm/filemap.c
--- 5-ac13/mm/filemap.c Tue Jun 12 09:51:45 2001
+++ 5-ac13-a/mm/filemap.c   Wed Jun 13 09:56:43 2001
@@ -82,6 +82,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;
@@ -206,9 +209,6 @@
if (!page-buffers || block_flushpage(page, 0))
lru_cache_del(page);
 
-   if (page-mapping-a_ops-truncatepage)
-   page-mapping-a_ops-truncatepage(page);
-   
/*
 * We remove the page from the page cache _after_ we have
 * destroyed all buffer-cache references to it. Otherwise some
diff -uNr 5-ac13/mm/shmem.c 5-ac13-a/mm/shmem.c
--- 5-ac13/mm/shmem.c   Tue Jun 12 09:51:45 2001
+++ 5-ac13-a/mm/shmem.c Wed Jun 13 09:56:20 2001
@@ -51,42 +51,16 @@
 
 #define BLOCKS_PER_PAGE (PAGE_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.
- *
- * The swap parameter is a performance hack for truncate.
- */
-
-static void shmem_recalc_inode(struct inode * inode, unsigned long swap)
+static void shmem_removepage(struct page *page)
 {
-   unsigned long freed;
+   struct inode *inode = (struct inode *)page-mapping-host;
+   struct shmem_sb_info * sbinfo = SHMEM_SB(inode-i_sb);
 
-   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_sub(freed-swap, shmem_nrpages);
-   }
+   inode-i_blocks -= BLOCKS_PER_PAGE;
+   spin_lock (sbinfo-stat_lock);
+   sbinfo-free_blocks++;
+   spin_unlock (sbinfo-stat_lock);
+   atomic_dec(shmem_nrpages);
 }
 
 static swp_entry_t * shmem_swp_entry (struct shmem_inode_info *info, unsigned long 
index) 
@@ -166,6 +140,7 @@
unsigned long freed = 0;
swp_entry_t **base, **ptr, **last;
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;
@@ -202,7 +177,9 @@
 out:
info-max_index = index;
info-swapped -= freed;
-   shmem_recalc_inode(inode, freed);
+   spin_lock(sbinfo-stat_lock);
+   sbinfo-free_blocks += freed;
+   spin_unlock(sbinfo-stat_lock);
spin_unlock (info-lock);
up(info-sem);
 }
@@ -257,7 +234,6 @@
entry =