diff options
| author | Andrew Morton <akpm@digeo.com> | 2002-11-21 19:32:45 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-11-21 19:32:45 -0800 |
| commit | b1ad1f4efce23ad0801492c0d5ffa8c0aa6a8cdb (patch) | |
| tree | 9c85c0ffe33fb8c8ab1e27e64502de1e2cff29ae /include/linux | |
| parent | 36fb7f8459cc42eca202f0ad7b2d051359406d57 (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.h | 3 | ||||
| -rw-r--r-- | include/linux/ext2_fs.h | 1 | ||||
| -rw-r--r-- | include/linux/page-flags.h | 5 |
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. |
