Chinaunix首页 | 论坛 | 博客
  • 博客访问: 816887
  • 博文数量: 117
  • 博客积分: 2583
  • 博客等级: 少校
  • 技术积分: 1953
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-06 22:58
个人简介

Coder

文章分类
文章存档

2013年(1)

2012年(10)

2011年(12)

2010年(77)

2009年(13)

2008年(4)

分类: LINUX

2010-08-07 00:20:10

前面sysfs_get_inode()中调用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 }

---------------------------------------------------------------------

sysfssuper_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.获得inodenode_lock

 

c.再次在inode缓存中查找对应于inode号的inode对象。若这次找到了,则增加它的引用计数,销毁新分配的inode对象。并返回inode对象地址。

 

d.依然没有找到。则将inode对象的i_ino设置为inodeino,调用__inode_add_to_lists(sb, head, inode)函数将inode对象添加进对应的inode哈希表中(inode->i_hash),添加进inode_in_use链表中(inode->i_list)添加进super_block的所有inode链表中(inode->i_sb_listsb->s_inodes)

 

e.设置inodei_state字段为I_NEW

 

f.释放inodeinode_lock

 

g.返回新创建的inode对象地址。

阅读(3115) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~