/** * @file op_dcache.h * Compatibility functions for dcache lookups * * @remark Copyright 2002 OProfile authors * @remark Read the file COPYING * * @author Philippe Elie * @author John Levon */ #ifndef OP_DCACHE_H #define OP_DCACHE_H #include <linux/sched.h> #include <linux/unistd.h> #include <linux/mman.h> #include <linux/file.h> #include "oprofile.h" extern uint op_dname_top; extern struct qstr **op_dname_stack; extern char * op_pool_pos; extern char * op_pool_start; extern char * op_pool_end; uint do_hash(struct dentry * dentry, struct vfsmount * vfsmnt, struct dentry * root, struct vfsmount * rootmnt); inline static uint alloc_in_pool(char const * str, uint len); inline static int add_hash_entry(struct op_hash_index * entry, uint parent, char const * name, uint len); inline static uint name_hash(char const * name, uint len, uint parent); inline static uint name_hash(char const * name, uint len, uint parent) { uint hash=0; while (len--) hash = (hash + (name[len] << 4) + (name[len] >> 4)) * 11; return (hash ^ parent) % OP_HASH_MAP_NR; } /* empty ascending dname stack */ inline static void push_dname(struct qstr * dname) { op_dname_stack[op_dname_top] = dname; if (op_dname_top != DNAME_STACK_MAX) op_dname_top++; else printk(KERN_ERR "oprofile: overflowed dname stack !\n"); } inline static struct qstr * pop_dname(void) { if (op_dname_top == 0) return NULL; return op_dname_stack[--op_dname_top]; } inline static uint alloc_in_pool(char const * str, uint len) { char * place = op_pool_pos; if (op_pool_pos + len + 1 >= op_pool_end) return 0; strcpy(place, str); op_pool_pos += len + 1; return place - op_pool_start; } inline static char * get_from_pool(uint index) { return op_pool_start + index; } inline static int add_hash_entry(struct op_hash_index * entry, uint parent, char const * name, uint len) { entry->name = alloc_in_pool(name, len); if (!entry->name) return -1; entry->parent = parent; return 0; } #endif /* OP_DCACHE_H */