diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-26 13:50:56 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-26 13:50:56 -0400 |
| commit | f8d613e2a665bf1be9628a3c3f9bafe7599b32c0 (patch) | |
| tree | 98d4da8d0e1a5fb1d9064626b4b96d95ccf26375 /include | |
| parent | 8a0599dd2471f2a2e409498c08a0ab339057ad06 (diff) | |
| parent | 5bc20fc59706214d9591c11e1938a629d3538c12 (diff) | |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/djm/tmem
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/djm/tmem:
xen: cleancache shim to Xen Transcendent Memory
ocfs2: add cleancache support
ext4: add cleancache support
btrfs: add cleancache support
ext3: add cleancache support
mm/fs: add hooks to support cleancache
mm: cleancache core ops functions and config
fs: add field to superblock to support cleancache
mm/fs: cleancache documentation
Fix up trivial conflict in fs/btrfs/extent_io.c due to includes
Diffstat (limited to 'include')
| -rw-r--r-- | include/linux/cleancache.h | 122 | ||||
| -rw-r--r-- | include/linux/fs.h | 5 | ||||
| -rw-r--r-- | include/xen/interface/xen.h | 22 |
3 files changed, 149 insertions, 0 deletions
diff --git a/include/linux/cleancache.h b/include/linux/cleancache.h new file mode 100644 index 000000000000..04ffb2e6c9d0 --- /dev/null +++ b/include/linux/cleancache.h | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | #ifndef _LINUX_CLEANCACHE_H | ||
| 2 | #define _LINUX_CLEANCACHE_H | ||
| 3 | |||
| 4 | #include <linux/fs.h> | ||
| 5 | #include <linux/exportfs.h> | ||
| 6 | #include <linux/mm.h> | ||
| 7 | |||
| 8 | #define CLEANCACHE_KEY_MAX 6 | ||
| 9 | |||
| 10 | /* | ||
| 11 | * cleancache requires every file with a page in cleancache to have a | ||
| 12 | * unique key unless/until the file is removed/truncated. For some | ||
| 13 | * filesystems, the inode number is unique, but for "modern" filesystems | ||
| 14 | * an exportable filehandle is required (see exportfs.h) | ||
| 15 | */ | ||
| 16 | struct cleancache_filekey { | ||
| 17 | union { | ||
| 18 | ino_t ino; | ||
| 19 | __u32 fh[CLEANCACHE_KEY_MAX]; | ||
| 20 | u32 key[CLEANCACHE_KEY_MAX]; | ||
| 21 | } u; | ||
| 22 | }; | ||
| 23 | |||
| 24 | struct cleancache_ops { | ||
| 25 | int (*init_fs)(size_t); | ||
| 26 | int (*init_shared_fs)(char *uuid, size_t); | ||
| 27 | int (*get_page)(int, struct cleancache_filekey, | ||
| 28 | pgoff_t, struct page *); | ||
| 29 | void (*put_page)(int, struct cleancache_filekey, | ||
| 30 | pgoff_t, struct page *); | ||
| 31 | void (*flush_page)(int, struct cleancache_filekey, pgoff_t); | ||
| 32 | void (*flush_inode)(int, struct cleancache_filekey); | ||
| 33 | void (*flush_fs)(int); | ||
| 34 | }; | ||
| 35 | |||
| 36 | extern struct cleancache_ops | ||
| 37 | cleancache_register_ops(struct cleancache_ops *ops); | ||
| 38 | extern void __cleancache_init_fs(struct super_block *); | ||
| 39 | extern void __cleancache_init_shared_fs(char *, struct super_block *); | ||
| 40 | extern int __cleancache_get_page(struct page *); | ||
| 41 | extern void __cleancache_put_page(struct page *); | ||
| 42 | extern void __cleancache_flush_page(struct address_space *, struct page *); | ||
| 43 | extern void __cleancache_flush_inode(struct address_space *); | ||
| 44 | extern void __cleancache_flush_fs(struct super_block *); | ||
| 45 | extern int cleancache_enabled; | ||
| 46 | |||
| 47 | #ifdef CONFIG_CLEANCACHE | ||
| 48 | static inline bool cleancache_fs_enabled(struct page *page) | ||
| 49 | { | ||
| 50 | return page->mapping->host->i_sb->cleancache_poolid >= 0; | ||
| 51 | } | ||
| 52 | static inline bool cleancache_fs_enabled_mapping(struct address_space *mapping) | ||
| 53 | { | ||
| 54 | return mapping->host->i_sb->cleancache_poolid >= 0; | ||
| 55 | } | ||
| 56 | #else | ||
| 57 | #define cleancache_enabled (0) | ||
| 58 | #define cleancache_fs_enabled(_page) (0) | ||
| 59 | #define cleancache_fs_enabled_mapping(_page) (0) | ||
| 60 | #endif | ||
| 61 | |||
| 62 | /* | ||
| 63 | * The shim layer provided by these inline functions allows the compiler | ||
| 64 | * to reduce all cleancache hooks to nothingness if CONFIG_CLEANCACHE | ||
| 65 | * is disabled, to a single global variable check if CONFIG_CLEANCACHE | ||
| 66 | * is enabled but no cleancache "backend" has dynamically enabled it, | ||
| 67 | * and, for the most frequent cleancache ops, to a single global variable | ||
| 68 | * check plus a superblock element comparison if CONFIG_CLEANCACHE is enabled | ||
| 69 | * and a cleancache backend has dynamically enabled cleancache, but the | ||
| 70 | * filesystem referenced by that cleancache op has not enabled cleancache. | ||
| 71 | * As a result, CONFIG_CLEANCACHE can be enabled by default with essentially | ||
| 72 | * no measurable performance impact. | ||
| 73 | */ | ||
| 74 | |||
| 75 | static inline void cleancache_init_fs(struct super_block *sb) | ||
| 76 | { | ||
| 77 | if (cleancache_enabled) | ||
| 78 | __cleancache_init_fs(sb); | ||
| 79 | } | ||
| 80 | |||
| 81 | static inline void cleancache_init_shared_fs(char *uuid, struct super_block *sb) | ||
| 82 | { | ||
| 83 | if (cleancache_enabled) | ||
| 84 | __cleancache_init_shared_fs(uuid, sb); | ||
| 85 | } | ||
| 86 | |||
| 87 | static inline int cleancache_get_page(struct page *page) | ||
| 88 | { | ||
| 89 | int ret = -1; | ||
| 90 | |||
| 91 | if (cleancache_enabled && cleancache_fs_enabled(page)) | ||
| 92 | ret = __cleancache_get_page(page); | ||
| 93 | return ret; | ||
| 94 | } | ||
| 95 | |||
| 96 | static inline void cleancache_put_page(struct page *page) | ||
| 97 | { | ||
| 98 | if (cleancache_enabled && cleancache_fs_enabled(page)) | ||
| 99 | __cleancache_put_page(page); | ||
| 100 | } | ||
| 101 | |||
| 102 | static inline void cleancache_flush_page(struct address_space *mapping, | ||
| 103 | struct page *page) | ||
| 104 | { | ||
| 105 | /* careful... page->mapping is NULL sometimes when this is called */ | ||
| 106 | if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping)) | ||
| 107 | __cleancache_flush_page(mapping, page); | ||
| 108 | } | ||
| 109 | |||
| 110 | static inline void cleancache_flush_inode(struct address_space *mapping) | ||
| 111 | { | ||
| 112 | if (cleancache_enabled && cleancache_fs_enabled_mapping(mapping)) | ||
| 113 | __cleancache_flush_inode(mapping); | ||
| 114 | } | ||
| 115 | |||
| 116 | static inline void cleancache_flush_fs(struct super_block *sb) | ||
| 117 | { | ||
| 118 | if (cleancache_enabled) | ||
| 119 | __cleancache_flush_fs(sb); | ||
| 120 | } | ||
| 121 | |||
| 122 | #endif /* _LINUX_CLEANCACHE_H */ | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 3f9d3251790d..241609346dfb 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -1428,6 +1428,11 @@ struct super_block { | |||
| 1428 | */ | 1428 | */ |
| 1429 | char __rcu *s_options; | 1429 | char __rcu *s_options; |
| 1430 | const struct dentry_operations *s_d_op; /* default d_op for dentries */ | 1430 | const struct dentry_operations *s_d_op; /* default d_op for dentries */ |
| 1431 | |||
| 1432 | /* | ||
| 1433 | * Saved pool identifier for cleancache (-1 means none) | ||
| 1434 | */ | ||
| 1435 | int cleancache_poolid; | ||
| 1431 | }; | 1436 | }; |
| 1432 | 1437 | ||
| 1433 | extern struct timespec current_fs_time(struct super_block *sb); | 1438 | extern struct timespec current_fs_time(struct super_block *sb); |
diff --git a/include/xen/interface/xen.h b/include/xen/interface/xen.h index b33257bc7e83..70213b4515eb 100644 --- a/include/xen/interface/xen.h +++ b/include/xen/interface/xen.h | |||
| @@ -58,6 +58,7 @@ | |||
| 58 | #define __HYPERVISOR_event_channel_op 32 | 58 | #define __HYPERVISOR_event_channel_op 32 |
| 59 | #define __HYPERVISOR_physdev_op 33 | 59 | #define __HYPERVISOR_physdev_op 33 |
| 60 | #define __HYPERVISOR_hvm_op 34 | 60 | #define __HYPERVISOR_hvm_op 34 |
| 61 | #define __HYPERVISOR_tmem_op 38 | ||
| 61 | 62 | ||
| 62 | /* Architecture-specific hypercall definitions. */ | 63 | /* Architecture-specific hypercall definitions. */ |
| 63 | #define __HYPERVISOR_arch_0 48 | 64 | #define __HYPERVISOR_arch_0 48 |
| @@ -461,6 +462,27 @@ typedef uint8_t xen_domain_handle_t[16]; | |||
| 461 | #define __mk_unsigned_long(x) x ## UL | 462 | #define __mk_unsigned_long(x) x ## UL |
| 462 | #define mk_unsigned_long(x) __mk_unsigned_long(x) | 463 | #define mk_unsigned_long(x) __mk_unsigned_long(x) |
| 463 | 464 | ||
| 465 | #define TMEM_SPEC_VERSION 1 | ||
| 466 | |||
| 467 | struct tmem_op { | ||
| 468 | uint32_t cmd; | ||
| 469 | int32_t pool_id; | ||
| 470 | union { | ||
| 471 | struct { /* for cmd == TMEM_NEW_POOL */ | ||
| 472 | uint64_t uuid[2]; | ||
| 473 | uint32_t flags; | ||
| 474 | } new; | ||
| 475 | struct { | ||
| 476 | uint64_t oid[3]; | ||
| 477 | uint32_t index; | ||
| 478 | uint32_t tmem_offset; | ||
| 479 | uint32_t pfn_offset; | ||
| 480 | uint32_t len; | ||
| 481 | GUEST_HANDLE(void) gmfn; /* guest machine page frame */ | ||
| 482 | } gen; | ||
| 483 | } u; | ||
| 484 | }; | ||
| 485 | |||
| 464 | #else /* __ASSEMBLY__ */ | 486 | #else /* __ASSEMBLY__ */ |
| 465 | 487 | ||
| 466 | /* In assembly code we cannot use C numeric constant suffixes. */ | 488 | /* In assembly code we cannot use C numeric constant suffixes. */ |
