summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorAndrew Morton <akpm@digeo.com>2002-11-21 19:32:45 -0800
committerLinus Torvalds <torvalds@penguin.transmeta.com>2002-11-21 19:32:45 -0800
commitb1ad1f4efce23ad0801492c0d5ffa8c0aa6a8cdb (patch)
tree9c85c0ffe33fb8c8ab1e27e64502de1e2cff29ae /include/linux
parent36fb7f8459cc42eca202f0ad7b2d051359406d57 (diff)
[PATCH] no-buffer-head ext2 option
Implements a new set of block address_space_operations which will never attach buffer_heads to file pagecache. These can be turned on for ext2 with the `nobh' mount option. During write-intensive testing on a 7G machine, total buffer_head storage remained below 0.3 megabytes. And those buffer_heads are against ZONE_NORMAL pagecache and will be reclaimed by ZONE_NORMAL memory pressure. This work is, of course, a special for the huge highmem machines. Possibly it obsoletes the buffer_heads_over_limit stuff (which doesn't work terribly well), but that code is simple, and will provide relief for other filesystems. It should be noted that the nobh_prepare_write() function and the PageMappedToDisk() infrastructure is what is needed to solve the problem of user data corruption when the filesystem which backs a sparse MAP_SHARED mapping runs out of space. We can use this code in filemap_nopage() to ensure that all mapped pages have space allocated on-disk. Deliver SIGBUS on ENOSPC. This will require a new address_space op, I expect.
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/buffer_head.h3
-rw-r--r--include/linux/ext2_fs.h1
-rw-r--r--include/linux/page-flags.h5
3 files changed, 9 insertions, 0 deletions
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 8587dd6f7146..4e7a9bbf99dd 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -190,6 +190,9 @@ sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
int block_truncate_page(struct address_space *, loff_t, get_block_t *);
int file_fsync(struct file *, struct dentry *, int);
+int nobh_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
+int nobh_commit_write(struct file *, struct page *, unsigned, unsigned);
+int nobh_truncate_page(struct address_space *, loff_t);
#define OSYNC_METADATA (1<<0)
#define OSYNC_DATA (1<<1)
diff --git a/include/linux/ext2_fs.h b/include/linux/ext2_fs.h
index 0d008cfb99a8..d701ba88c688 100644
--- a/include/linux/ext2_fs.h
+++ b/include/linux/ext2_fs.h
@@ -308,6 +308,7 @@ struct ext2_inode {
#define EXT2_MOUNT_ERRORS_RO 0x0020 /* Remount fs ro on errors */
#define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */
#define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */
+#define EXT2_MOUNT_NOBH 0x0100 /* No buffer_heads */
#define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */
#define EXT2_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */
#define EXT2_MOUNT_POSIX_ACL 0x8000 /* POSIX Access Control Lists */
diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h
index 44480d80952f..f02449871c07 100644
--- a/include/linux/page-flags.h
+++ b/include/linux/page-flags.h
@@ -70,6 +70,7 @@
#define PG_chainlock 15 /* lock bit for ->pte_chain */
#define PG_direct 16 /* ->pte_chain points directly at pte */
+#define PG_mappedtodisk 17 /* Has blocks allocated on-disk */
/*
* Global page accounting. One instance per CPU. Only unsigned longs are
@@ -233,6 +234,10 @@ extern void get_full_page_state(struct page_state *ret);
#define ClearPageDirect(page) clear_bit(PG_direct, &(page)->flags)
#define TestClearPageDirect(page) test_and_clear_bit(PG_direct, &(page)->flags)
+#define PageMappedToDisk(page) test_bit(PG_mappedtodisk, &(page)->flags)
+#define SetPageMappedToDisk(page) set_bit(PG_mappedtodisk, &(page)->flags)
+#define ClearPageMappedToDisk(page) clear_bit(PG_mappedtodisk, &(page)->flags)
+
/*
* The PageSwapCache predicate doesn't use a PG_flag at this time,
* but it may again do so one day.