this isn't available from the kernel. Will figure out later.
obdfs/rw.c: added bit on page flags to indicate if page is in obdfs page
cache, to avoid searching list when inserting pages to page cache
/* CDEBUG(D_INFO, "free lock\n"); */ \
}
+/* We track if a page has been added to the OBD page cache by stting a
+ * flag on the page. We have chosen a bit that will hopefully not be
+ * used for a while.
+ */
+#define PG_obdcache 29
+#define OBDAddCachePage(page) test_and_set_bit(PG_obdcache, &(page)->flags)
+#define OBDClearCachePage(page) clear_bit(PG_obdcache, &(page)->flags)
+
static inline void obdfs_print_plist(struct inode *inode)
{
struct list_head *page_list = obdfs_iplist(inode);
CDEBUG(D_INFO, "src obdo %ld valid 0x%08x, dst inode %ld\n",
(long)oa->o_id, oa->o_valid, inode->i_ino);
+ /* If the inode is dirty, we won't overwrite the data there, as it
+ * is newer than the data on the disk. The ext2obd side only will
+ * change the block count, so we are guaranteed that is safe.
+ */
+ if (inode->i_state & I_DIRTY) {
+ CDEBUG(D_INODE, "dirty inode %ld, only copying blocks\n",
+ inode->i_ino);
+ oa->o_valid = OBD_MD_FLBLOCKS;
+ }
+
obdo_to_inode(inode, oa);
if (obdo_has_inline(oa)) {
return;
}
- print("Punching $count bytes starting at byte $start in object $id...\n");
+ print("Punching $count bytes starting at byte $start from object $id...\n");
my $obdo;
$obdo->{id} = $id;
#include <linux/obdfs.h>
+/* XXX temporary until the real function is available from kernel
+ * XXX set this to memory size in pages for max page cache size
+ */
+#define nr_free_buffer_pages() 32768
+
struct {
int nfract; /* Percentage of buffer cache dirty to
activate bdflush */
/* asynchronous setattr etc for the future ...
obdfs_flush_dirty_inodes(jiffies - pupd_prm.age_super);
*/
- /* XXX for debugging
dirty_limit = nr_free_buffer_pages() * pupd_prm.nfract / 100;
- * XXX */
- dirty_limit = 16384 * pupd_prm.nfract / 100;
CDEBUG(D_CACHE, "dirty_limit %ld, cache_count %ld, wrote %d\n",
dirty_limit, obdfs_cache_count, wrote);
--obdfs_cache_count;
CDEBUG(D_INFO, "deleting page %p from list [count %ld]\n",
pgrq->rq_page, obdfs_cache_count);
+ OBDClearCachePage(pgrq->rq_page);
list_del(&pgrq->rq_plist);
kmem_cache_free(obdfs_pgrq_cachep, pgrq);
}
/*
- * Find a specific page in the page cache. If it is found, we return
- * the write request struct associated with it, if not found return NULL.
+ * See whether a specific page in the page cache.
* Called with the list lock held.
*/
-static struct obdfs_pgrq *
-obdfs_find_in_page_list(struct inode *inode, struct page *page)
+#ifdef PG_obdcache
+#define obdfs_find_in_page_list(inode, page) OBDAddCachePage(page)
+#else
+static int obdfs_find_in_page_list(struct inode *inode, struct page *page)
{
struct list_head *page_list = obdfs_iplist(inode);
struct list_head *tmp;
if (list_empty(page_list)) {
CDEBUG(D_INFO, "empty list\n");
EXIT;
- return NULL;
+ return 0;
}
tmp = page_list;
while ( (tmp = tmp->next) != page_list ) {
if (pgrq->rq_page == page) {
CDEBUG(D_INFO, "found page %p in list\n", page);
EXIT;
- return pgrq;
+ return 1;
}
}
EXIT;
- return NULL;
+ return 0;
} /* obdfs_find_in_page_list */
+#endif
/* called with the list lock held */