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

📄 inode.c

📁 基于组件方式开发操作系统的OSKIT源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	 */	if (inodes_stat.nr_inodes > max_inodes) {		struct list_head *tmp;		try_to_free_inodes(inodes_stat.nr_inodes >> 2);		tmp = inode_unused.next;		if (tmp != &inode_unused) {			inodes_stat.nr_free_inodes--;			list_del(tmp);			inode = list_entry(tmp, struct inode, i_list);			return inode;		}	}			spin_unlock(&inode_lock);	inode = (struct inode *)__get_free_pages(GFP_KERNEL,INODE_PAGE_ORDER);	if (inode) {		int size;		struct inode * tmp;		size = INODE_ALLOCATION_SIZE - 2*sizeof(struct inode);		tmp = inode;		spin_lock(&inode_lock);		do {			tmp++;			init_once(tmp);			list_add(&tmp->i_list, &inode_unused);			size -= sizeof(struct inode);		} while (size >= 0);		init_once(inode);		/*		 * Update the inode statistics		 */		inodes_stat.nr_inodes += INODES_PER_ALLOCATION;		inodes_stat.nr_free_inodes += INODES_PER_ALLOCATION - 1;		return inode;	}	/*	 * If the allocation failed, do an extensive pruning of 	 * the dcache and then try again to free some inodes.	 */	prune_dcache(inodes_stat.nr_inodes >> 2);	spin_lock(&inode_lock);	free_inodes();	{		struct list_head *tmp = inode_unused.next;		if (tmp != &inode_unused) {			inodes_stat.nr_free_inodes--;			list_del(tmp);			inode = list_entry(tmp, struct inode, i_list);			return inode;		}	}	spin_unlock(&inode_lock);	printk("grow_inodes: allocation failed\n");	return NULL;}/* * Called with the inode lock held. */static struct inode * find_inode(struct super_block * sb, unsigned long ino, struct list_head *head){	struct list_head *tmp;	struct inode * inode;	tmp = head;	for (;;) {		tmp = tmp->next;		inode = NULL;		if (tmp == head)			break;		inode = list_entry(tmp, struct inode, i_hash);		if (inode->i_sb != sb)			continue;		if (inode->i_ino != ino)			continue;		inode->i_count++;		break;	}	return inode;}/* * This just initializes the inode fields * to known values before returning the inode.. * * i_sb, i_ino, i_count, i_state and the lists have * been initialized elsewhere.. */void clean_inode(struct inode *inode){	memset(&inode->u, 0, sizeof(inode->u));	inode->i_sock = 0;	inode->i_op = NULL;	inode->i_nlink = 1;	inode->i_writecount = 0;	inode->i_size = 0;	inode->i_generation = 0;	memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));	sema_init(&inode->i_sem, 1);}/* * This is called by things like the networking layer * etc that want to get an inode without any inode * number, or filesystems that allocate new inodes with * no pre-existing information. */struct inode * get_empty_inode(void){	static unsigned long last_ino = 0;	struct inode * inode;	struct list_head * tmp;	spin_lock(&inode_lock);	tmp = inode_unused.next;	if (tmp != &inode_unused) {		list_del(tmp);		inodes_stat.nr_free_inodes--;		inode = list_entry(tmp, struct inode, i_list);add_new_inode:		list_add(&inode->i_list, &inode_in_use);		inode->i_sb = NULL;		inode->i_dev = 0;		inode->i_ino = ++last_ino;		inode->i_flags = 0;		inode->i_count = 1;		inode->i_state = 0;		spin_unlock(&inode_lock);		clean_inode(inode);		return inode;	}	/*	 * Warning: if this succeeded, we will now	 * return with the inode lock.	 */	inode = grow_inodes();	if (inode)		goto add_new_inode;	return inode;}/* * This is called with the inode lock held.. Be careful. * * 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){	struct inode * inode;	struct list_head * tmp = inode_unused.next;	if (tmp != &inode_unused) {		list_del(tmp);		inodes_stat.nr_free_inodes--;		inode = list_entry(tmp, struct inode, i_list);add_new_inode:		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_ino = ino;		inode->i_flags = 0;		inode->i_count = 1;		inode->i_state = I_LOCK;		spin_unlock(&inode_lock);		clean_inode(inode);		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;	}	/*	 * We need to expand. Note that "grow_inodes()" will	 * release the spinlock, but will return with the lock 	 * held again if the allocation succeeded.	 */	inode = grow_inodes();	if (inode) {		/* We released the lock, so.. */		struct inode * old = find_inode(sb, ino, head);		if (!old)			goto add_new_inode;		list_add(&inode->i_list, &inode_unused);		inodes_stat.nr_free_inodes++;		spin_unlock(&inode_lock);		wait_on_inode(old);		return old;	}	return inode;}static inline unsigned long hash(struct super_block *sb, unsigned long i_ino){	unsigned long tmp = i_ino | (unsigned long) sb;	tmp = tmp + (tmp >> HASH_BITS) + (tmp >> HASH_BITS*2);	return tmp & HASH_MASK;}/* Yeah, I know about quadratic hash. Maybe, later. */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);		if (!inode) {			spin_unlock(&inode_lock);			return res;		}		inode->i_count--; /* compensate find_inode() */	} else {		counter = max_reserved + 1;	}	goto retry;	}struct inode *igrab(struct inode *inode){	spin_lock(&inode_lock);	if (inode->i_state & I_FREEING)		inode = NULL;	else		inode->i_count++;	spin_unlock(&inode_lock);	if (inode)		wait_on_inode(inode);	return inode;}struct inode *iget(struct super_block *sb, unsigned long ino){	struct list_head * head = inode_hashtable + hash(sb,ino);	struct inode * inode;	spin_lock(&inode_lock);	inode = find_inode(sb, ino, head);	if (inode) {		spin_unlock(&inode_lock);		wait_on_inode(inode);		return inode;	}	/*	 * get_new_inode() will do the right thing, releasing	 * the inode lock and re-trying the search in case it	 * had to block at any point.	 */	return get_new_inode(sb, ino, head);}void insert_inode_hash(struct inode *inode){	struct list_head *head = inode_hashtable + hash(inode->i_sb, inode->i_ino);	spin_lock(&inode_lock);	list_add(&inode->i_hash, head);	spin_unlock(&inode_lock);}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);}void iput(struct inode *inode){	if (inode) {		struct super_operations *op = NULL;		if (inode->i_sb && inode->i_sb->s_op)			op = inode->i_sb->s_op;		if (op && op->put_inode)			op->put_inode(inode);		spin_lock(&inode_lock);		if (!--inode->i_count) {			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;				if (op && op->delete_inode) {					void (*delete)(struct inode *) = op->delete_inode;					spin_unlock(&inode_lock);					delete(inode);					spin_lock(&inode_lock);				}			}			if (list_empty(&inode->i_hash)) {				list_del(&inode->i_list);				INIT_LIST_HEAD(&inode->i_list);				inode->i_state|=I_FREEING;				spin_unlock(&inode_lock);				clear_inode(inode);				spin_lock(&inode_lock);				list_add(&inode->i_list, &inode_unused);				inodes_stat.nr_free_inodes++;			}			else if (!(inode->i_state & I_DIRTY)) {				list_del(&inode->i_list);				list_add(&inode->i_list, &inode_in_use);			}#ifdef INODE_PARANOIAif (inode->i_flock)printk(KERN_ERR "iput: inode %s/%ld still has locks!\n",kdevname(inode->i_dev), inode->i_ino);if (!list_empty(&inode->i_dentry))printk(KERN_ERR "iput: device %s inode %ld still has aliases!\n",kdevname(inode->i_dev), inode->i_ino);if (inode->i_count)printk(KERN_ERR "iput: device %s inode %ld count changed, count=%d\n",kdevname(inode->i_dev), inode->i_ino, inode->i_count);if (atomic_read(&inode->i_sem.count) != 1)printk(KERN_ERR "iput: Aieee, semaphore in use inode %s/%ld, count=%d\n",kdevname(inode->i_dev), inode->i_ino, atomic_read(&inode->i_sem.count));if (atomic_read(&inode->i_atomic_write.count) != 1)printk(KERN_ERR "iput: Aieee, atomic write semaphore in use inode %s/%ld, count=%d\n",kdevname(inode->i_dev), inode->i_ino, atomic_read(&inode->i_sem.count));#endif		}		if (inode->i_count > (1<<31)) {			printk(KERN_ERR "iput: inode %s/%ld count wrapped\n",				kdevname(inode->i_dev), inode->i_ino);		}		spin_unlock(&inode_lock);	}}int bmap(struct inode * inode, int block){	if (inode->i_op && inode->i_op->bmap)		return inode->i_op->bmap(inode, block);	return 0;}/* * Initialize the hash tables and default * value for max inodes */#define MAX_INODE (16384)void __init inode_init(void){	int i, max;	struct list_head *head = inode_hashtable;	i = HASH_SIZE;	do {		INIT_LIST_HEAD(head);		head++;		i--;	} while (i);	/* Initial guess at reasonable inode number */#ifndef OSKIT	max = num_physpages >> 1;	if (max > MAX_INODE)		max = MAX_INODE;	max_inodes = max;#else	max_inodes = 4096;#endif}#ifndef OSKIT/* This belongs in file_table.c, not here... */int fs_may_remount_ro(struct super_block *sb){	struct file *file;	/* Check that no files are currently opened for writing. */	for (file = inuse_filps; file; file = file->f_next) {		struct inode *inode;		if (!file->f_dentry)			continue;		inode = file->f_dentry->d_inode;		if (!inode || inode->i_sb != sb)			continue;		/* File with pending delete? */		if (inode->i_nlink == 0)			return 0;		/* Writable file? */		if (S_ISREG(inode->i_mode) && (file->f_mode & FMODE_WRITE))			return 0;	}	return 1; /* Tis' cool bro. */}#endif /* OSKIT */void update_atime (struct inode *inode){    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 (inode);}   /*  End Function update_atime  */

⌨️ 快捷键说明

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