diff -Naur linux-2.6.28/mm/precache.c linux-2.6.28-tmem/mm/precache.c --- linux-2.6.28/mm/precache.c 1969-12-31 17:00:00.000000000 -0700 +++ linux-2.6.28-tmem/mm/precache.c 2009-01-05 18:07:10.000000000 -0700 @@ -0,0 +1,106 @@ +/* + * linux/mm/precache.c + * + * Copyright (C) 2008 Dan Magenheimer, Oracle Corp. + */ + +#include +#include +#include +#include +#include +#include +#include "tmem.h" + +static int precache_auto_allocate = 0; + +int precache_put(struct address_space *mapping, unsigned long index, + struct page *page) +{ + uint32_t tmem_pool = mapping->host->i_sb->precache_poolid; + uint64_t obj = (unsigned long) mapping->host->i_ino; + uint32_t ind = (uint32_t) index; + unsigned long mfn = pfn_to_mfn(page_to_pfn(page)); + + if ((int32_t)tmem_pool < 0) { + if (!precache_auto_allocate) return 0; + /* a put on a non-existent precache will auto-allocate one */ + if ((tmem_pool = tmem_new_pool(0,0,0)) < 0) + return 0; + printk("Mapping superblock for s_id=%s to precache_id=%d\n", + mapping->host->i_sb->s_id, tmem_pool); + mapping->host->i_sb->precache_poolid = tmem_pool; + } + if (ind != index) return 0; + + mb(); + return tmem_op(TMEM_PUT_PAGE, tmem_pool, obj, ind, mfn, 0, 0, 0); +} + +int precache_get(struct address_space *mapping, unsigned long index, + struct page *empty_page) +{ + uint32_t tmem_pool = mapping->host->i_sb->precache_poolid; + uint64_t obj = (unsigned long) mapping->host->i_ino; + uint32_t ind = (uint32_t) index; + unsigned long mfn = pfn_to_mfn(page_to_pfn(empty_page)); + + if ((int32_t)tmem_pool < 0) return 0; + if (ind != index) return 0; + + return tmem_op(TMEM_GET_PAGE, tmem_pool, obj, ind, mfn, 0, 0, 0); +} +EXPORT_SYMBOL(precache_get); + +int precache_flush(struct address_space *mapping, unsigned long index) +{ + uint32_t tmem_pool = mapping->host->i_sb->precache_poolid; + uint64_t obj = (unsigned long) mapping->host->i_ino; + uint32_t ind = (uint32_t) index; + + if ((int32_t)tmem_pool < 0) return 0; + if (ind != index) return 0; + + return tmem_op(TMEM_FLUSH_PAGE, tmem_pool, obj, ind, 0, 0, 0, 0); +} +EXPORT_SYMBOL(precache_flush); + +int precache_flush_inode(struct address_space *mapping) +{ + uint32_t tmem_pool = mapping->host->i_sb->precache_poolid; + uint64_t obj = (unsigned long) mapping->host->i_ino; + + if ((int32_t)tmem_pool < 0) return 0; + + return tmem_op(TMEM_FLUSH_OBJECT, tmem_pool, obj, 0, 0, 0, 0, 0); +} +EXPORT_SYMBOL(precache_flush_inode); + +int precache_flush_filesystem(struct super_block *sb) +{ + uint32_t tmem_pool = sb->precache_poolid; + int ret; + + if ((int32_t)tmem_pool < 0) return 0; + ret = tmem_op(TMEM_DESTROY_POOL, tmem_pool, 0, 0, 0, 0, 0, 0); + if (!ret) return 0; + printk("Unmapping superblock for s_id=%s from precache_id=%d\n", + sb->s_id, ret); + sb->precache_poolid = 0; + return 1; +} +EXPORT_SYMBOL(precache_flush_filesystem); + +void precache_init(struct super_block *sb) +{ + sb->precache_poolid = tmem_new_pool(0,0,0); +} +EXPORT_SYMBOL(precache_init); + +void shared_precache_init(struct super_block *sb, char *uuid) +{ + uint64_t uuid_lo = *(uint64_t *)uuid; + uint64_t uuid_hi = *(uint64_t *)(&uuid[8]); + sb->precache_poolid = tmem_new_pool(uuid_lo,uuid_hi,TMEM_POOL_SHARED); +} +EXPORT_SYMBOL(shared_precache_init);