diff --git a/fs/affs/affs.h b/fs/affs/affs.h index d1c506c1f310..952c5b2059b1 100644 --- a/fs/affs/affs.h +++ b/fs/affs/affs.h @@ -306,6 +306,11 @@ affs_lock_dir(struct inode *inode) mutex_lock_nested(&AFFS_I(inode)->i_hash_lock, SINGLE_DEPTH_NESTING); } static inline void +affs_lock_subdir(struct inode *inode) +{ + mutex_lock_nested(&AFFS_I(inode)->i_hash_lock, SINGLE_DEPTH_NESTING + 1); +} +static inline void affs_unlock_dir(struct inode *inode) { mutex_unlock(&AFFS_I(inode)->i_hash_lock); diff --git a/fs/affs/amigaffs.c b/fs/affs/amigaffs.c index 6cc0fc9a4cbf..affa20d2b73d 100644 --- a/fs/affs/amigaffs.c +++ b/fs/affs/amigaffs.c @@ -293,7 +293,11 @@ affs_remove_header(struct dentry *dentry) * i_hash_lock of the inode must only be * taken after some checks */ - affs_lock_dir(inode); + if (inode == dir) { + retval = -EIO; + goto done_unlock; + } + affs_lock_subdir(inode); retval = affs_empty_dir(inode); affs_unlock_dir(inode); if (retval)