分类: LINUX
2010-11-27 21:04:56
iget()中调用iget_locked(sb, sd->s_ino)来建立inode对象,这个iget_locked()也是VFS的一个非常重要的函数。其定义为:
---------------------------------------------------------------------
fs/inode.c
592 static unsigned long hash(struct super_block *sb, unsigned long hashval)
593 {
594 unsigned long tmp;
595
596 tmp = (hashval * (unsigned long)sb) ^ (GOLDEN_RATIO_PRIME + hashval) /
597 L1_CACHE_BYTES;
598 tmp = tmp ^ ((tmp ^ GOLDEN_RATIO_PRIME) >> I_HASHBITS);
599 return tmp & I_HASHMASK;
600 }
1047 /**
1048 * iget_locked - obtain an inode from a mounted file system
1049 * @sb: super block of file system
1050 * @ino: inode number to get
1051 *
1052 * iget_locked() uses ifind_fast() to search for the inode specified by @ino in
1053 * the inode cache and if present it is returned with an increased reference
1054 * count. This is for file systems where the inode number is sufficient for
1055 * unique identification of an inode.
1056 *
1057 * If the inode is not in cache, get_new_inode_fast() is called to allocate a
1058 * new inode and this is returned locked, hashed, and with the I_NEW flag set.
1059 * The file system gets to fill it in before unlocking it via
1060 * unlock_new_inode().
1061 */
1062 struct inode *iget_locked(struct super_block *sb, unsigned long ino)
1063 {
1064 struct hlist_head *head = inode_hashtable + hash(sb, ino);
1065 struct inode *inode;
1066
1067 inode = ifind_fast(sb, head, ino);
1068 if (inode)
1069 return inode;
1070 /*
1071 * get_new_inode_fast() will do the right thing, re-trying the search
1072 * in case it had to block at any point.
1073 */
1074 return get_new_inode_fast(sb, head, ino);
1075 }
1076 EXPORT_SYMBOL(iget_locked);
---------------------------------------------------------------------
1、获得inode可能存在的哈希链表的头,并有局部变量head指向它。
2、调用ifind_fast(sb, head, ino)来在inode缓存中超找有ino指定的inode。如果找到则增加其引用计数并返回该inode对象地址。
---------------------------------------------------------------------
fs/inode.c
567 /*
568 * find_inode_fast is the fast path version of find_inode, see the comment at
569 * iget_locked for details.
570 */
571 static struct inode *find_inode_fast(struct super_block *sb,
572 struct hlist_head *head, unsigned long ino)
573 {
574 struct hlist_node *node;
575 struct inode *inode = NULL;
576
577 repeat:
578 hlist_for_each_entry(inode, node, head, i_hash) {
579 if (inode->i_ino != ino)
580 continue;
581 if (inode->i_sb != sb)
582 continue;
583 if (inode->i_state & (I_FREEING|I_CLEAR|I_WILL_FREE)) {
584 __wait_on_freeing_inode(inode);
585 goto repeat;
586 }
587 break;
588 }
589 return node ? inode : NULL;
590 }
897 /**
898 * ifind_fast - internal function, you want ilookup() or iget().
899 * @sb: super block of file system to search
900 * @head: head of the list to search
901 * @ino: inode number to search for
902 *
903 * ifind_fast() searches for the inode @ino in the inode cache. This is for
904 * file systems where the inode number is sufficient for unique identification
905 * of an inode.
906 *
907 * If the inode is in the cache, the inode is returned with an incremented
908 * reference count.
909 *
910 * Otherwise NULL is returned.
911 */
912 static struct inode *ifind_fast(struct super_block *sb,
913 struct hlist_head *head, unsigned long ino)
914 {
915 struct inode *inode;
916
917 spin_lock(&inode_lock);
918 inode = find_inode_fast(sb, head, ino);
919 if (inode) {
920 __iget(inode);
921 spin_unlock(&inode_lock);
922 wait_on_inode(inode);
923 return inode;
924 }
925 spin_unlock(&inode_lock);
926 return NULL;
927 }
---------------------------------------------------------------------
3、在inode缓存中没有找到所要的inode对象,则调用get_new_inode_fast(sb, head, ino)分配、初始化inode对象并返回该inode对象。这个函数定义为:
---------------------------------------------------------------------
fs/inode.c
760 /*
761 * get_new_inode_fast is the fast path version of get_new_inode, see the
762 * comment at iget_locked for details.
763 */
764 static struct inode *get_new_inode_fast(struct super_block *sb,
765 struct hlist_head *head, unsigned long ino)
766 {
767 struct inode *inode;
768
769 inode = alloc_inode(sb);
770 if (inode) {
771 struct inode *old;
772
773 spin_lock(&inode_lock);
774 /* We released the lock, so.. */
775 old = find_inode_fast(sb, head, ino);
776 if (!old) {
777 inode->i_ino = ino;
778 __inode_add_to_lists(sb, head, inode);
779 inode->i_state = I_NEW;
780 spin_unlock(&inode_lock);
781
782 /* Return the locked inode with I_NEW set, the
783 * caller is responsible for filling in the contents
784 */
785 return inode;
786 }
787
788 /*
789 * Uhhuh, somebody else created the same inode under
790 * us. Use the old inode instead of the one we just
791 * allocated.
792 */
793 __iget(old);
794 spin_unlock(&inode_lock);
795 destroy_inode(inode);
796 inode = old;
797 wait_on_inode(inode);
798 }
799 return inode;
800 }
---------------------------------------------------------------------
get_new_inode_fast()接受三个参数,分别位inode所在文件系统的超级块对象地址,inode可能存在的哈希表的表头以及inode节点号。
这个函数执行如下操作:
a.调用alloc_inode(sb)来分配一个inode对象:
---------------------------------------------------------------------
fs/inode.c
202 static struct inode *alloc_inode(struct super_block *sb)
203 {
204 struct inode *inode;
205
206 if (sb->s_op->alloc_inode)
207 inode = sb->s_op->alloc_inode(sb);
208 else
209 inode = kmem_cache_alloc(inode_cachep, GFP_KERNEL);
210
211 if (!inode)
212 return NULL;
213
214 if (unlikely(inode_init_always(sb, inode))) {
215 if (inode->i_sb->s_op->destroy_inode)
216 inode->i_sb->s_op->destroy_inode(inode);
217 else
218 kmem_cache_free(inode_cachep, inode);
219 return NULL;
220 }
221
222 return inode;
223 }
---------------------------------------------------------------------
sysfs的super_operations操作集sysfs_ops是没有alloc_inode()方法的。
inode_init_always(sb, inode)函数完成对于inode的基本的初始化:
---------------------------------------------------------------------
fs/inode.c
118 /**
119 * inode_init_always - perform inode structure intialisation
120 * @sb: superblock inode belongs to
121 * @inode: inode to initialise
122 *
123 * These are initializations that need to be done on every inode
124 * allocation as the fields are not initialised by slab allocation.
125 */
126 int inode_init_always(struct super_block *sb, struct inode *inode)
127 {
128 static const struct address_space_operations empty_aops;
129 static const struct inode_operations empty_iops;
130 static const struct file_operations empty_fops;
131 struct address_space *const mapping = &inode->i_data;
132
133 inode->i_sb = sb;
134 inode->i_blkbits = sb->s_blocksize_bits;
135 inode->i_flags = 0;
136 atomic_set(&inode->i_count, 1);
137 inode->i_op = &empty_iops;
138 inode->i_fop = &empty_fops;
139 inode->i_nlink = 1;
140 inode->i_uid = 0;
141 inode->i_gid = 0;
142 atomic_set(&inode->i_writecount, 0);
143 inode->i_size = 0;
144 inode->i_blocks = 0;
145 inode->i_bytes = 0;
146 inode->i_generation = 0;
147 #ifdef CONFIG_QUOTA
148 memset(&inode->i_dquot, 0, sizeof(inode->i_dquot));
149 #endif
150 inode->i_pipe = NULL;
151 inode->i_bdev = NULL;
152 inode->i_cdev = NULL;
153 inode->i_rdev = 0;
154 inode->dirtied_when = 0;
155
156 if (security_inode_alloc(inode))
157 goto out;
158 spin_lock_init(&inode->i_lock);
159 lockdep_set_class(&inode->i_lock, &sb->s_type->i_lock_key);
160
161 mutex_init(&inode->i_mutex);
162 lockdep_set_class(&inode->i_mutex, &sb->s_type->i_mutex_key);
163
164 init_rwsem(&inode->i_alloc_sem);
165 lockdep_set_class(&inode->i_alloc_sem, &sb->s_type->i_alloc_sem_key);
166
167 mapping->a_ops = &empty_aops;
168 mapping->host = inode;
169 mapping->flags = 0;
170 mapping_set_gfp_mask(mapping, GFP_HIGHUSER_MOVABLE);
171 mapping->assoc_mapping = NULL;
172 mapping->backing_dev_info = &default_backing_dev_info;
173 mapping->writeback_index = 0;
174
175 /*
176 * If the block_device provides a backing_dev_info for client
177 * inodes then use that. Otherwise the inode share the bdev's
178 * backing_dev_info.
179 */
180 if (sb->s_bdev) {
181 struct backing_dev_info *bdi;
182
183 bdi = sb->s_bdev->bd_inode->i_mapping->backing_dev_info;
184 mapping->backing_dev_info = bdi;
185 }
186 inode->i_private = NULL;
187 inode->i_mapping = mapping;
188 #ifdef CONFIG_FS_POSIX_ACL
189 inode->i_acl = inode->i_default_acl = ACL_NOT_CACHED;
190 #endif
191
192 #ifdef CONFIG_FSNOTIFY
193 inode->i_fsnotify_mask = 0;
194 #endif
195
196 return 0;
197 out:
198 return -ENOMEM;
199 }
200 EXPORT_SYMBOL(inode_init_always);
---------------------------------------------------------------------
然后返回刚刚创建并初始化的inode对象地址。
b.获得inode锁node_lock。
c.再次在inode缓存中查找对应于inode号的inode对象。若这次找到了,则增加它的引用计数,销毁新分配的inode对象。并返回inode对象地址。
d.依然没有找到。则将inode对象的i_ino设置为inode号ino,调用__inode_add_to_lists(sb, head, inode)函数将inode对象添加进对应的inode哈希表中(inode->i_hash),添加进inode_in_use链表中(inode->i_list)添加进super_block的所有inode链表中(inode->i_sb_list、sb->s_inodes)。
e.设置inode的i_state字段为I_NEW。
f.释放inode锁inode_lock
g.返回新创建的inode对象地址。