diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index dfc2e223bd10..aa8f26087116 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c @@ -118,12 +118,13 @@ static int ext4_expand_inode_array(struct ext4_xattr_inode_array **ea_inode_array, struct inode *inode); -#ifdef CONFIG_LOCKDEP -void ext4_xattr_inode_set_class(struct inode *ea_inode) +static inline void ext4_xattr_inode_set_class(struct inode *ea_inode, + int subclass) { - lockdep_set_subclass(&ea_inode->i_rwsem, 1); -} +#ifdef CONFIG_LOCKDEP + lockdep_set_subclass(&ea_inode->i_rwsem, subclass); #endif +} static __le32 ext4_xattr_block_csum(struct inode *inode, sector_t block_nr, @@ -458,7 +459,7 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, goto error; } - ext4_xattr_inode_set_class(inode); + ext4_xattr_inode_set_class(inode, 1); /* * Check whether this is an old Lustre-style xattr inode. Lustre @@ -1058,8 +1059,10 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, inode_lock(ea_inode); ret = ext4_reserve_inode_write(handle, ea_inode, &iloc); - if (ret) - goto out; + if (ret) { + inode_unlock(ea_inode); + return ret; + } ref_count = ext4_xattr_inode_get_ref(ea_inode); ref_count += ref_change; @@ -1074,7 +1077,9 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, ea_inode->i_ino, ea_inode->i_nlink); set_nlink(ea_inode, 1); + inode_unlock(ea_inode); ext4_orphan_del(handle, ea_inode); + ext4_xattr_inode_set_class(ea_inode, 1); } } else { WARN_ONCE(ref_count < 0, "EA inode %lu ref_count=%lld", @@ -1084,7 +1089,8 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, WARN_ONCE(ea_inode->i_nlink != 1, "EA inode %lu i_nlink=%u", ea_inode->i_ino, ea_inode->i_nlink); - + inode_unlock(ea_inode); + ext4_xattr_inode_set_class(ea_inode, 0); clear_nlink(ea_inode); ext4_orphan_add(handle, ea_inode); } @@ -1094,8 +1100,6 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, if (ret) ext4_warning_inode(ea_inode, "ext4_mark_iloc_dirty() failed ret=%d", ret); -out: - inode_unlock(ea_inode); return ret; } @@ -1500,7 +1504,7 @@ static struct inode *ext4_xattr_inode_create(handle_t *handle, ea_inode->i_op = &ext4_file_inode_operations; ea_inode->i_fop = &ext4_file_operations; ext4_set_aops(ea_inode); - ext4_xattr_inode_set_class(ea_inode); + ext4_xattr_inode_set_class(ea_inode, 1); unlock_new_inode(ea_inode); ext4_xattr_inode_set_ref(ea_inode, 1); ext4_xattr_inode_set_hash(ea_inode, hash); @@ -1511,6 +1515,7 @@ static struct inode *ext4_xattr_inode_create(handle_t *handle, if (ext4_xattr_inode_dec_ref(handle, ea_inode)) ext4_warning_inode(ea_inode, "cleanup dec ref error %d", err); + ext4_xattr_inode_set_class(ea_inode, 0); iput(ea_inode); return ERR_PTR(err); } @@ -1560,6 +1565,7 @@ ext4_xattr_inode_cache_find(struct inode *inode, const void *value, if (!IS_ERR(ea_inode) && !is_bad_inode(ea_inode) && (EXT4_I(ea_inode)->i_flags & EXT4_EA_INODE_FL) && + inode->i_nlink && i_size_read(ea_inode) == value_len && !ext4_xattr_inode_read(ea_inode, ea_data, value_len) && !ext4_xattr_inode_verify_hashes(ea_inode, NULL, ea_data, diff --git a/fs/ext4/xattr.h b/fs/ext4/xattr.h index 824faf0b15a8..32d6222ec9ec 100644 --- a/fs/ext4/xattr.h +++ b/fs/ext4/xattr.h @@ -218,10 +218,4 @@ static inline int ext4_init_security(handle_t *handle, struct inode *inode, } #endif -#ifdef CONFIG_LOCKDEP -extern void ext4_xattr_inode_set_class(struct inode *ea_inode); -#else -static inline void ext4_xattr_inode_set_class(struct inode *ea_inode) { } -#endif - extern int ext4_get_inode_usage(struct inode *inode, qsize_t *usage);