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

📄 inode.c

📁 嵌入式系统设计与实例开发实验教材二源码 多线程应用程序设计 串行端口程序设计 AD接口实验 CAN总线通信实验 GPS通信实验 Linux内核移植与编译实验 IC卡读写实验 SD驱动使
💻 C
📖 第 1 页 / 共 3 页
字号:
 * * We no longer cache the sb_flags in i_flags - see fs.h *	-- rmk@arm.uk.linux.org */static struct inode * get_new_inode(struct super_block *sb, unsigned long ino, struct list_head *head, find_inode_t find_actor, void *opaque){	struct inode * inode;	inode = alloc_inode();	if (inode) {		struct inode * old;		spin_lock(&inode_lock);		/* We released the lock, so.. */		old = find_inode(sb, ino, head, find_actor, opaque);		if (!old) {			inodes_stat.nr_inodes++;			list_add(&inode->i_list, &inode_in_use);			list_add(&inode->i_hash, head);			inode->i_sb = sb;			inode->i_dev = sb->s_dev;			inode->i_blkbits = sb->s_blocksize_bits;			inode->i_ino = ino;			inode->i_flags = 0;			atomic_set(&inode->i_count, 1);			inode->i_state = I_LOCK;			spin_unlock(&inode_lock);			clean_inode(inode);			/* reiserfs specific hack right here.  We don't			** want this to last, and are looking for VFS changes			** that will allow us to get rid of it.			** -- mason@suse.com 			*/			if (sb->s_op->read_inode2) {				sb->s_op->read_inode2(inode, opaque) ;			} else {				sb->s_op->read_inode(inode);			}			/*			 * This is special!  We do not need the spinlock			 * when clearing I_LOCK, because we're guaranteed			 * that nobody else tries to do anything about the			 * state of the inode when it is locked, as we			 * just created it (so there can be no old holders			 * that haven't tested I_LOCK).			 */			inode->i_state &= ~I_LOCK;			wake_up(&inode->i_wait);			return inode;		}		/*		 * Uhhuh, somebody else created the same inode under		 * us. Use the old inode instead of the one we just		 * allocated.		 */		__iget(old);		spin_unlock(&inode_lock);		destroy_inode(inode);		inode = old;		wait_on_inode(inode);	}	return inode;}static inline unsigned long hash(struct super_block *sb, unsigned long i_ino){	unsigned long tmp = i_ino + ((unsigned long) sb / L1_CACHE_BYTES);	tmp = tmp + (tmp >> I_HASHBITS);	return tmp & I_HASHMASK;}/* Yeah, I know about quadratic hash. Maybe, later. *//** *	iunique - get a unique inode number *	@sb: superblock *	@max_reserved: highest reserved inode number * *	Obtain an inode number that is unique on the system for a given *	superblock. This is used by file systems that have no natural *	permanent inode numbering system. An inode number is returned that *	is higher than the reserved limit but unique. * *	BUGS: *	With a large number of inodes live on the file system this function *	currently becomes quite slow. */ ino_t iunique(struct super_block *sb, ino_t max_reserved){	static ino_t counter = 0;	struct inode *inode;	struct list_head * head;	ino_t res;	spin_lock(&inode_lock);retry:	if (counter > max_reserved) {		head = inode_hashtable + hash(sb,counter);		inode = find_inode(sb, res = counter++, head, NULL, NULL);		if (!inode) {			spin_unlock(&inode_lock);			return res;		}	} else {		counter = max_reserved + 1;	}	goto retry;	}struct inode *igrab(struct inode *inode){	spin_lock(&inode_lock);	if (!(inode->i_state & I_FREEING))		__iget(inode);	else		/*		 * Handle the case where s_op->clear_inode is not been		 * called yet, and somebody is calling igrab		 * while the inode is getting freed.		 */		inode = NULL;	spin_unlock(&inode_lock);	return inode;}struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque){	struct list_head * head = inode_hashtable + hash(sb,ino);	struct inode * inode;	spin_lock(&inode_lock);	inode = find_inode(sb, ino, head, find_actor, opaque);	if (inode) {		__iget(inode);		spin_unlock(&inode_lock);		wait_on_inode(inode);		return inode;	}	spin_unlock(&inode_lock);	/*	 * get_new_inode() will do the right thing, re-trying the search	 * in case it had to block at any point.	 */	return get_new_inode(sb, ino, head, find_actor, opaque);}/** *	insert_inode_hash - hash an inode *	@inode: unhashed inode * *	Add an inode to the inode hash for this superblock. If the inode *	has no superblock it is added to a separate anonymous chain. */ void insert_inode_hash(struct inode *inode){	struct list_head *head = &anon_hash_chain;	if (inode->i_sb)		head = inode_hashtable + hash(inode->i_sb, inode->i_ino);	spin_lock(&inode_lock);	list_add(&inode->i_hash, head);	spin_unlock(&inode_lock);}/** *	remove_inode_hash - remove an inode from the hash *	@inode: inode to unhash * *	Remove an inode from the superblock or anonymous hash. */ void remove_inode_hash(struct inode *inode){	spin_lock(&inode_lock);	list_del(&inode->i_hash);	INIT_LIST_HEAD(&inode->i_hash);	spin_unlock(&inode_lock);}/** *	iput	- put an inode  *	@inode: inode to put * *	Puts an inode, dropping its usage count. If the inode use count hits *	zero the inode is also then freed and may be destroyed. */ void iput(struct inode *inode){	if (inode) {		struct super_block *sb = inode->i_sb;		struct super_operations *op = NULL;		if (inode->i_state == I_CLEAR)			BUG();		if (sb && sb->s_op)			op = sb->s_op;		if (op && op->put_inode)			op->put_inode(inode);		if (!atomic_dec_and_lock(&inode->i_count, &inode_lock))			return;		if (!inode->i_nlink) {			list_del(&inode->i_hash);			INIT_LIST_HEAD(&inode->i_hash);			list_del(&inode->i_list);			INIT_LIST_HEAD(&inode->i_list);			inode->i_state|=I_FREEING;			inodes_stat.nr_inodes--;			spin_unlock(&inode_lock);			if (inode->i_data.nrpages)				truncate_inode_pages(&inode->i_data, 0);			if (op && op->delete_inode) {				void (*delete)(struct inode *) = op->delete_inode;				if (!is_bad_inode(inode))					DQUOT_INIT(inode);				/* s_op->delete_inode internally recalls clear_inode() */				delete(inode);			} else				clear_inode(inode);			if (inode->i_state != I_CLEAR)				BUG();		} else {			if (!list_empty(&inode->i_hash)) {				if (!(inode->i_state & (I_DIRTY|I_LOCK))) {					list_del(&inode->i_list);					list_add(&inode->i_list, &inode_unused);				}				inodes_stat.nr_unused++;				spin_unlock(&inode_lock);				if (!sb || (sb->s_flags & MS_ACTIVE))					return;				write_inode_now(inode, 1);				spin_lock(&inode_lock);				inodes_stat.nr_unused--;				list_del_init(&inode->i_hash);			}			list_del_init(&inode->i_list);			inode->i_state|=I_FREEING;			inodes_stat.nr_inodes--;			spin_unlock(&inode_lock);			if (inode->i_data.nrpages)				truncate_inode_pages(&inode->i_data, 0);			clear_inode(inode);		}		destroy_inode(inode);	}}void force_delete(struct inode *inode){	/*	 * Kill off unused inodes ... iput() will unhash and	 * delete the inode if we set i_nlink to zero.	 */	if (atomic_read(&inode->i_count) == 1)		inode->i_nlink = 0;}/** *	bmap	- find a block number in a file *	@inode: inode of file *	@block: block to find * *	Returns the block number on the device holding the inode that *	is the disk block number for the block of the file requested. *	That is, asked for block 4 of inode 1 the function will return the *	disk block relative to the disk start that holds that block of the  *	file. */ int bmap(struct inode * inode, int block){	int res = 0;	if (inode->i_mapping->a_ops->bmap)		res = inode->i_mapping->a_ops->bmap(inode->i_mapping, block);	return res;}/* * Initialize the hash tables. */void __init inode_init(unsigned long mempages){	struct list_head *head;	unsigned long order;	unsigned int nr_hash;	int i;	mempages >>= (14 - PAGE_SHIFT);	mempages *= sizeof(struct list_head);	for (order = 0; ((1UL << order) << PAGE_SHIFT) < mempages; order++)		;	do {		unsigned long tmp;		nr_hash = (1UL << order) * PAGE_SIZE /			sizeof(struct list_head);		i_hash_mask = (nr_hash - 1);		tmp = nr_hash;		i_hash_shift = 0;		while ((tmp >>= 1UL) != 0UL)			i_hash_shift++;		inode_hashtable = (struct list_head *)			__get_free_pages(GFP_ATOMIC, order);	} while (inode_hashtable == NULL && --order >= 0);	printk("Inode-cache hash table entries: %d (order: %ld, %ld bytes)\n",			nr_hash, order, (PAGE_SIZE << order));	if (!inode_hashtable)		panic("Failed to allocate inode hash table\n");	head = inode_hashtable;	i = nr_hash;	do {		INIT_LIST_HEAD(head);		head++;		i--;	} while (i);	/* inode slab cache */	inode_cachep = kmem_cache_create("inode_cache", sizeof(struct inode),					 0, SLAB_HWCACHE_ALIGN, init_once,					 NULL);	if (!inode_cachep)		panic("cannot create inode slab cache");	unused_inodes_flush_task.routine = try_to_sync_unused_inodes;}/** *	update_atime	-	update the access time *	@inode: inode accessed * *	Update the accessed time on an inode and mark it for writeback. *	This function automatically handles read only file systems and media, *	as well as the "noatime" flag and inode specific "noatime" markers. */ void update_atime (struct inode *inode){	if (inode->i_atime == CURRENT_TIME)		return;	if ( IS_NOATIME (inode) ) return;	if ( IS_NODIRATIME (inode) && S_ISDIR (inode->i_mode) ) return;	if ( IS_RDONLY (inode) ) return;	inode->i_atime = CURRENT_TIME;	mark_inode_dirty_sync (inode);}   /*  End Function update_atime  *//* *	Quota functions that want to walk the inode lists.. */#ifdef CONFIG_QUOTA/* Functions back in dquot.c */void put_dquot_list(struct list_head *);int remove_inode_dquot_ref(struct inode *, short, struct list_head *);void remove_dquot_ref(struct super_block *sb, short type){	struct inode *inode;	struct list_head *act_head;	LIST_HEAD(tofree_head);	if (!sb->dq_op)		return;	/* nothing to do */	/* We have to be protected against other CPUs */	lock_kernel();		/* This lock is for quota code */	spin_lock(&inode_lock);	/* This lock is for inodes code */ 	list_for_each(act_head, &inode_in_use) {		inode = list_entry(act_head, struct inode, i_list);		if (inode->i_sb == sb && IS_QUOTAINIT(inode))			remove_inode_dquot_ref(inode, type, &tofree_head);	}	list_for_each(act_head, &inode_unused) {		inode = list_entry(act_head, struct inode, i_list);		if (inode->i_sb == sb && IS_QUOTAINIT(inode))			remove_inode_dquot_ref(inode, type, &tofree_head);	}	list_for_each(act_head, &sb->s_dirty) {		inode = list_entry(act_head, struct inode, i_list);		if (IS_QUOTAINIT(inode))			remove_inode_dquot_ref(inode, type, &tofree_head);	}	list_for_each(act_head, &sb->s_locked_inodes) {		inode = list_entry(act_head, struct inode, i_list);		if (IS_QUOTAINIT(inode))			remove_inode_dquot_ref(inode, type, &tofree_head);	}	spin_unlock(&inode_lock);	unlock_kernel();	put_dquot_list(&tofree_head);}#endif

⌨️ 快捷键说明

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