aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2013-12-23 16:02:16 -0500
committerJan Kara <jack@suse.cz>2013-12-23 16:02:16 -0500
commit4ea7772f828a2f1cf6fbf96a3e6f99ae149d2724 (patch)
tree2515839eb42739317490f2365ea303435ea236f3
parent301d4c9a286bc7dc4fb3cda21131be91a582fa79 (diff)
udf: Fix lockdep warning from udf_symlink()
Lockdep is complaining about UDF: ============================================= [ INFO: possible recursive locking detected ] 3.12.0+ #16 Not tainted --------------------------------------------- ln/7386 is trying to acquire lock: (&ei->i_data_sem){+.+...}, at: [<ffffffff8142f06d>] udf_get_block+0x8d/0x130 but task is already holding lock: (&ei->i_data_sem){+.+...}, at: [<ffffffff81431a8d>] udf_symlink+0x8d/0x690 other info that might help us debug this: Possible unsafe locking scenario: CPU0 ---- lock(&ei->i_data_sem); lock(&ei->i_data_sem); *** DEADLOCK *** This is because we hold i_data_sem of the symlink inode while calling udf_add_entry() for the directory. I don't think this can ever lead to deadlocks since we never hold i_data_sem for two inodes in any other place. The fix is simple - move unlock of i_data_sem for symlink inode up. We don't need it for anything when linking symlink inode to directory. Reported-by: Christoph Hellwig <hch@infradead.org> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/udf/namei.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
index 5f6fc17d6bc5..9737cba1357d 100644
--- a/fs/udf/namei.c
+++ b/fs/udf/namei.c
@@ -1010,6 +1010,7 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
1010 else 1010 else
1011 udf_truncate_tail_extent(inode); 1011 udf_truncate_tail_extent(inode);
1012 mark_inode_dirty(inode); 1012 mark_inode_dirty(inode);
1013 up_write(&iinfo->i_data_sem);
1013 1014
1014 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err); 1015 fi = udf_add_entry(dir, dentry, &fibh, &cfi, &err);
1015 if (!fi) 1016 if (!fi)
@@ -1023,7 +1024,6 @@ static int udf_symlink(struct inode *dir, struct dentry *dentry,
1023 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL); 1024 udf_write_fi(dir, &cfi, fi, &fibh, NULL, NULL);
1024 if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB) 1025 if (UDF_I(dir)->i_alloc_type == ICBTAG_FLAG_AD_IN_ICB)
1025 mark_inode_dirty(dir); 1026 mark_inode_dirty(dir);
1026 up_write(&iinfo->i_data_sem);
1027 if (fibh.sbh != fibh.ebh) 1027 if (fibh.sbh != fibh.ebh)
1028 brelse(fibh.ebh); 1028 brelse(fibh.ebh);
1029 brelse(fibh.sbh); 1029 brelse(fibh.sbh);