⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dcache.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
字号:
/* *  linux/fs/ext2/dcache.c * *  Copyright (C) 1992, 1993, 1994  Remy Card (card@masi.ibp.fr) *                                  Laboratoire MASI - Institut Blaise Pascal *                                  Universite Pierre et Marie Curie (Paris VI) * *//* * dcache.c contains the code that handles the directory cache used by * lookup() and readdir() */#include <asm/segment.h>#include <linux/fs.h>#include <linux/ext2_fs.h>#include <linux/string.h>#ifndef DONT_USE_DCACHE#define DCACHE_NAME_LEN	32struct dir_cache_entry {	unsigned short dev;	unsigned long dir;	unsigned long ino;	char name[DCACHE_NAME_LEN + 1];	int len;	struct dir_cache_entry * queue_prev;	struct dir_cache_entry * queue_next;	struct dir_cache_entry * prev;	struct dir_cache_entry * next;};static struct dir_cache_entry * first = NULL;static struct dir_cache_entry * last = NULL;static struct dir_cache_entry * first_free = NULL;static int cache_initialized = 0;#ifdef EXT2FS_DEBUG_CACHEstatic int hits = 0;static int misses = 0;#endif#define CACHE_SIZE 128static struct dir_cache_entry dcache[CACHE_SIZE];#define HASH_QUEUES 16static struct dir_cache_entry * queue_head[HASH_QUEUES];static struct dir_cache_entry * queue_tail[HASH_QUEUES];#define hash(dev,dir)	((dev ^ dir) % HASH_QUEUES)/* * Initialize the cache */static void init_cache (void){	int i;	dcache[0].prev = NULL;	dcache[0].next = &dcache[1];	dcache[0].queue_next = dcache[0].queue_prev = NULL;	for (i = 1; i < CACHE_SIZE - 1; i++) {		dcache[i].prev = &dcache[i - 1];		dcache[i].next = &dcache[i + 1];		dcache[i].queue_next = dcache[i].queue_prev = NULL;	}	dcache[i].prev = &dcache[i - 1];	dcache[i].next = NULL;	dcache[i].queue_next = dcache[i].queue_prev = NULL;	first_free = &dcache[0];	for (i = 0; i < HASH_QUEUES; i++)		queue_tail[i] = queue_head[i] = NULL;	cache_initialized = 1;}/* * Find a name in the cache */static struct dir_cache_entry * find_name (int queue, unsigned short dev,					   unsigned long dir,					   const char * name, int len){	struct dir_cache_entry * p;	for (p = queue_head[queue]; p != NULL && (p->dev != dev ||	     p->dir != dir || p->len != len ||	     strncmp (name, p->name, p->len) != 0);	     p = p->queue_next)		;	return p;}#ifdef EXT2FS_DEBUG_CACHE/* * List the cache entries for debugging */static void show_cache (const char * func_name){	struct dir_cache_entry * p;	printk ("%s: cache status\n", func_name);	for (p = first; p != NULL; p = p->next)		printk ("dev:%04x, dir=%4lu, name=%s\n",			p->dev, p->dir, p->name);}#endif/* * Add an entry at the beginning of the cache */static void add_to_cache (struct dir_cache_entry * p){	p->prev = NULL;	p->next = first;	if (first)		first->prev = p;	if (!last)		last = p;	first = p;}/* * Add an entry at the beginning of a queue */static void add_to_queue (int queue, struct dir_cache_entry * p){	p->queue_prev = NULL;	p->queue_next = queue_head[queue];	if (queue_head[queue])		queue_head[queue]->queue_prev = p;	if (!queue_tail[queue])		queue_tail[queue] = p;	queue_head[queue] = p;}/* * Remove an entry from the cache */static void remove_from_cache (struct dir_cache_entry * p){	if (p->prev)		p->prev->next = p->next;	else		first = p->next;	if (p->next)		p->next->prev = p->prev;	else		last = p->prev;	p->prev = NULL;	p->next = NULL;}/* * Remove an entry from a queue */static void remove_from_queue (int queue, struct dir_cache_entry * p){	if (p->queue_prev)		p->queue_prev->queue_next = p->queue_next;	else		queue_head[queue] = p->queue_next;	if (p->queue_next)		p->queue_next->queue_prev = p->queue_prev;	else		queue_tail[queue] = p->queue_prev;	p->queue_prev = NULL;	p->queue_next = NULL;}/* * Invalidate all cache entries on a device (called by put_super() when * a file system is unmounted) */void ext2_dcache_invalidate (unsigned short dev){	struct dir_cache_entry * p;	struct dir_cache_entry * p2;	if (!cache_initialized)		init_cache ();	for (p = first; p != NULL; p = p2) {		p2 = p->next;		if (p->dev == dev) {			remove_from_cache (p);			remove_from_queue (hash (p->dev, p->dir), p);			p->next = first_free;			first_free = p;		}	}#ifdef EXT2FS_DEBUG_CACHE	show_cache ("dcache_invalidate");#endif}/* * Lookup a directory entry in the cache */unsigned long ext2_dcache_lookup (unsigned short dev, unsigned long dir,				  const char * name, int len){	char our_name[EXT2_NAME_LEN];	int queue;	struct dir_cache_entry * p;	if (!cache_initialized)		init_cache ();	if (len > DCACHE_NAME_LEN)		return 0;	memcpy (our_name, (char *) name, len);	our_name[len] = '\0';#ifdef EXT2FS_DEBUG_CACHE	printk ("dcache_lookup (%04x, %lu, %s, %d)\n", dev, dir, our_name, len);#endif	queue = hash (dev, dir);	if ((p = find_name (queue, dev, dir, our_name, len))) {		if (p != first) {			remove_from_cache (p);			add_to_cache (p);		}		if (p != queue_head[queue]) {			remove_from_queue (queue, p);			add_to_queue (queue, p);		}#ifdef EXT2FS_DEBUG_CACHE		hits++;		printk ("dcache_lookup: %s,hit,inode=%lu,hits=%d,misses=%d\n",			our_name, p->ino, hits, misses);		show_cache ("dcache_lookup");#endif		return p->ino;	} else {#ifdef EXT2FS_DEBUG_CACHE		misses++;		printk ("dcache_lookup: %s,miss,hits=%d,misses=%d\n",			our_name, hits, misses);		show_cache ("dcache_lookup");#endif		return 0;	}}/* * Add a directory entry to the cache * * This function is called by ext2_lookup(), ext2_readdir() * and the functions which create directory entries */void ext2_dcache_add (unsigned short dev, unsigned long dir, const char * name,		      int len, unsigned long ino){	struct dir_cache_entry * p;	int queue;	if (!cache_initialized)		init_cache ();#ifdef EXT2FS_DEBUG_CACHE	printk ("dcache_add (%04x, %lu, %s, %d, %lu)\n",		dev, dir, name, len, ino);#endif	if (len > DCACHE_NAME_LEN)		return;	queue = hash (dev, dir);	if ((p = find_name (queue, dev, dir, name, len))) {		p->dir = dir;		p->ino = ino;		if (p != first) {			remove_from_cache (p);			add_to_cache (p);		}		if (p != queue_head[queue]) {			remove_from_queue (queue, p);			add_to_queue (queue, p);		}	} else {		if (first_free) {			p = first_free;			first_free = p->next;		} else {			if (!last)				panic ("dcache_add: last == NULL\n");			else {				p = last;				last = p->prev;				if (last)					last->next = NULL;				remove_from_queue (hash (p->dev, p->dir), p);			}		}		p->dev = dev;		p->dir = dir;		p->ino = ino;		strncpy (p->name, name, len);		p->len = len;		p->name[len] = '\0';		add_to_cache (p);		add_to_queue (queue, p);	}#ifdef EXT2FS_DEBUG_CACHE	show_cache ("dcache_add");#endif}/* * Remove a directory from the cache * * This function is called by the functions which remove directory entries */void ext2_dcache_remove (unsigned short dev, unsigned long dir,			 const char * name, int len){	struct dir_cache_entry * p;	int queue;	if (!cache_initialized)		init_cache ();#ifdef EXT2FS_DEBUG_CACHE	printk ("dcache_remove (%04x, %lu, %s, %d)\n", dev, dir, name, len);#endif	if (len > DCACHE_NAME_LEN)		return;	queue = hash (dev, dir);	if ((p = find_name (queue, dev, dir, name, len))) {		remove_from_cache (p);		remove_from_queue (queue, p);		p->next = first_free;		first_free = p;	}#ifdef EXT2FS_DEBUG_CACHE	show_cache ("dcache_remove");#endif}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -