On Wed, Mar 20, 2019 at 02:37:17PM +0800, Qu Wenruo wrote: > @@ -5726,18 +5734,29 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, > struct dentry *dentry) > struct btrfs_root *root = BTRFS_I(dir)->root; > struct btrfs_root *sub_root = root; > struct btrfs_key location; > + u8 di_type = 0; > int index; > int ret = 0; > > if (dentry->d_name.len > BTRFS_NAME_LEN) > return ERR_PTR(-ENAMETOOLONG); > > - ret = btrfs_inode_by_name(dir, dentry, &location); > + ret = btrfs_inode_by_name(dir, dentry, &location, &di_type); > if (ret < 0) > return ERR_PTR(ret); > > if (location.type == BTRFS_INODE_ITEM_KEY) { > inode = btrfs_iget(dir->i_sb, &location, root, NULL); > + > + /* Do extra check against inode mode with di_type */ > + if (btrfs_inode_type(inode) != di_type) { > + btrfs_crit(fs_info, > +"inode mode mismatch with dir: inode mode=0%o btrfs type=%u dir type=%u", > + inode->i_mode, btrfs_inode_type(inode), > + di_type); > + iput(inode);
The iput here seems suspicious. > + return ERR_PTR(-EUCLEAN); > + } > return inode; > } 5792 index = srcu_read_lock(&fs_info->subvol_srcu); 5793 ret = fixup_tree_root_location(fs_info, dir, dentry, 5794 &location, &sub_root); 5795 if (ret < 0) { 5796 if (ret != -ENOENT) 5797 inode = ERR_PTR(ret); 5798 else 5799 inode = new_simple_dir(dir->i_sb, &location, sub_root); 5800 } else { 5801 inode = btrfs_iget(dir->i_sb, &location, sub_root, NULL); 5802 } The iget happens after this block so either there's another one in the caller to pair, or the above iput is wrong.