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

📄 cache.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
字号:
/* *  cache.c * * Copyright (C) 1997 by Bill Hawes * * Routines to support directory cacheing using the page cache. * This cache code is almost directly taken from ncpfs. * * Please add a note about your changes to smbfs in the ChangeLog file. */#include <linux/sched.h>#include <linux/errno.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/dirent.h>#include <linux/smb_fs.h>#include <linux/pagemap.h>#include <asm/page.h>#include "smb_debug.h"#include "proto.h"/* * Force the next attempt to use the cache to be a timeout. * If we can't find the page that's fine, it will cause a refresh. */voidsmb_invalid_dir_cache(struct inode * dir){	struct smb_sb_info *server = server_from_inode(dir);	union  smb_dir_cache *cache = NULL;	struct page *page = NULL;	page = grab_cache_page(&dir->i_data, 0);	if (!page)		goto out;	if (!Page_Uptodate(page))		goto out_unlock;	cache = kmap(page);	cache->head.time = jiffies - SMB_MAX_AGE(server);	kunmap(page);	SetPageUptodate(page);out_unlock:	UnlockPage(page);	page_cache_release(page);out:	return;}/* * Mark all dentries for 'parent' as invalid, forcing them to be re-read */voidsmb_invalidate_dircache_entries(struct dentry *parent){	struct smb_sb_info *server = server_from_dentry(parent);	struct list_head *next;	struct dentry *dentry;	spin_lock(&dcache_lock);	next = parent->d_subdirs.next;	while (next != &parent->d_subdirs) {		dentry = list_entry(next, struct dentry, d_child);		dentry->d_fsdata = NULL;		smb_age_dentry(server, dentry);		next = next->next;	}	spin_unlock(&dcache_lock);}/* * dget, but require that fpos and parent matches what the dentry contains. * dentry is not known to be a valid pointer at entry. */struct dentry *smb_dget_fpos(struct dentry *dentry, struct dentry *parent, unsigned long fpos){	struct dentry *dent = dentry;	struct list_head *next;	if (d_validate(dent, parent)) {		if (dent->d_name.len <= SMB_MAXPATHLEN &&		    (unsigned long)dent->d_fsdata == fpos) {			if (!dent->d_inode) {				dput(dent);				dent = NULL;			}			return dent;		}		dput(dent);	}	/* If a pointer is invalid, we search the dentry. */	spin_lock(&dcache_lock);	next = parent->d_subdirs.next;	while (next != &parent->d_subdirs) {		dent = list_entry(next, struct dentry, d_child);		if ((unsigned long)dent->d_fsdata == fpos) {			if (dent->d_inode)				dget_locked(dent);			else				dent = NULL;			goto out_unlock;		}		next = next->next;	}	dent = NULL;out_unlock:	spin_unlock(&dcache_lock);	return dent;}/* * Create dentry/inode for this file and add it to the dircache. */intsmb_fill_cache(struct file *filp, void *dirent, filldir_t filldir,	       struct smb_cache_control *ctrl, struct qstr *qname,	       struct smb_fattr *entry){	struct dentry *newdent, *dentry = filp->f_dentry;	struct inode *newino, *inode = dentry->d_inode;	struct smb_cache_control ctl = *ctrl;	int valid = 0;	int hashed = 0;	ino_t ino = 0;	qname->hash = full_name_hash(qname->name, qname->len);	if (dentry->d_op && dentry->d_op->d_hash)		if (dentry->d_op->d_hash(dentry, qname) != 0)			goto end_advance;	newdent = d_lookup(dentry, qname);	if (!newdent) {		newdent = d_alloc(dentry, qname);		if (!newdent)			goto end_advance;	} else {		hashed = 1;		memcpy((char *) newdent->d_name.name, qname->name,		       newdent->d_name.len);	}	if (!newdent->d_inode) {		smb_renew_times(newdent);		entry->f_ino = iunique(inode->i_sb, 2);		newino = smb_iget(inode->i_sb, entry);		if (newino) {			smb_new_dentry(newdent);			d_instantiate(newdent, newino);			if (!hashed)				d_rehash(newdent);		}	} else		smb_set_inode_attr(newdent->d_inode, entry);        if (newdent->d_inode) {		ino = newdent->d_inode->i_ino;		newdent->d_fsdata = (void *) ctl.fpos;		smb_new_dentry(newdent);	}	if (ctl.idx >= SMB_DIRCACHE_SIZE) {		if (ctl.page) {			kunmap(ctl.page);			SetPageUptodate(ctl.page);			UnlockPage(ctl.page);			page_cache_release(ctl.page);		}		ctl.cache = NULL;		ctl.idx  -= SMB_DIRCACHE_SIZE;		ctl.ofs  += 1;		ctl.page  = grab_cache_page(&inode->i_data, ctl.ofs);		if (ctl.page)			ctl.cache = kmap(ctl.page);	}	if (ctl.cache) {		ctl.cache->dentry[ctl.idx] = newdent;		valid = 1;	}	dput(newdent);end_advance:	if (!valid)		ctl.valid = 0;	if (!ctl.filled && (ctl.fpos == filp->f_pos)) {		if (!ino)			ino = find_inode_number(dentry, qname);		if (!ino)			ino = iunique(inode->i_sb, 2);		ctl.filled = filldir(dirent, qname->name, qname->len,				     filp->f_pos, ino, DT_UNKNOWN);		if (!ctl.filled)			filp->f_pos += 1;	}	ctl.fpos += 1;	ctl.idx  += 1;	*ctrl = ctl;	return (ctl.valid || !ctl.filled);}

⌨️ 快捷键说明

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