diff options
Diffstat (limited to 'fs/nilfs2/inode.c')
| -rw-r--r-- | fs/nilfs2/inode.c | 32 | 
1 files changed, 24 insertions, 8 deletions
diff --git a/fs/nilfs2/inode.c b/fs/nilfs2/inode.c index e1fa69b341b9..8b5969538f39 100644 --- a/fs/nilfs2/inode.c +++ b/fs/nilfs2/inode.c @@ -49,6 +49,8 @@ struct nilfs_iget_args {  	int for_gc;  }; +static int nilfs_iget_test(struct inode *inode, void *opaque); +  void nilfs_inode_add_blocks(struct inode *inode, int n)  {  	struct nilfs_root *root = NILFS_I(inode)->i_root; @@ -348,6 +350,17 @@ const struct address_space_operations nilfs_aops = {  	.is_partially_uptodate  = block_is_partially_uptodate,  }; +static int nilfs_insert_inode_locked(struct inode *inode, +				     struct nilfs_root *root, +				     unsigned long ino) +{ +	struct nilfs_iget_args args = { +		.ino = ino, .root = root, .cno = 0, .for_gc = 0 +	}; + +	return insert_inode_locked4(inode, ino, nilfs_iget_test, &args); +} +  struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)  {  	struct super_block *sb = dir->i_sb; @@ -383,7 +396,7 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)  	if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) {  		err = nilfs_bmap_read(ii->i_bmap, NULL);  		if (err < 0) -			goto failed_bmap; +			goto failed_after_creation;  		set_bit(NILFS_I_BMAP, &ii->i_state);  		/* No lock is needed; iget() ensures it. */ @@ -399,21 +412,24 @@ struct inode *nilfs_new_inode(struct inode *dir, umode_t mode)  	spin_lock(&nilfs->ns_next_gen_lock);  	inode->i_generation = nilfs->ns_next_generation++;  	spin_unlock(&nilfs->ns_next_gen_lock); -	insert_inode_hash(inode); +	if (nilfs_insert_inode_locked(inode, root, ino) < 0) { +		err = -EIO; +		goto failed_after_creation; +	}  	err = nilfs_init_acl(inode, dir);  	if (unlikely(err)) -		goto failed_acl; /* never occur. When supporting +		goto failed_after_creation; /* never occur. When supporting  				    nilfs_init_acl(), proper cancellation of  				    above jobs should be considered */  	return inode; - failed_acl: - failed_bmap: + failed_after_creation:  	clear_nlink(inode); +	unlock_new_inode(inode);  	iput(inode);  /* raw_inode will be deleted through -			 generic_delete_inode() */ +			 nilfs_evict_inode() */  	goto failed;   failed_ifile_create_inode: @@ -461,8 +477,8 @@ int nilfs_read_inode_common(struct inode *inode,  	inode->i_atime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec);  	inode->i_ctime.tv_nsec = le32_to_cpu(raw_inode->i_ctime_nsec);  	inode->i_mtime.tv_nsec = le32_to_cpu(raw_inode->i_mtime_nsec); -	if (inode->i_nlink == 0 && inode->i_mode == 0) -		return -EINVAL; /* this inode is deleted */ +	if (inode->i_nlink == 0) +		return -ESTALE; /* this inode is deleted */  	inode->i_blocks = le64_to_cpu(raw_inode->i_blocks);  	ii->i_flags = le32_to_cpu(raw_inode->i_flags);  | 
