Linux 4.7 compat: Fix deadlock during lookup on case-insensitive

We must not use d_add_ci if the dentry already has the real name. Otherwise,
d_add_ci()->d_alloc_parallel() will find itself on the lookup hash and wait
on itself causing deadlock.

Tested-by: satmandu
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Chunwei Chen <david.chen@osnexus.com>
Closes #5124
Closes #5141
Closes #5147
Closes #5148
This commit is contained in:
tuxoko 2016-09-22 19:09:16 -07:00 committed by Brian Behlendorf
parent dbc95a682c
commit c0716f13ef
1 changed files with 7 additions and 3 deletions

View File

@ -102,9 +102,13 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
struct dentry *new_dentry; struct dentry *new_dentry;
struct qstr ci_name; struct qstr ci_name;
ci_name.name = pn.pn_buf; if (strcmp(dname(dentry), pn.pn_buf) == 0) {
ci_name.len = strlen(pn.pn_buf); new_dentry = d_splice_alias(ip, dentry);
new_dentry = d_add_ci(dentry, ip, &ci_name); } else {
ci_name.name = pn.pn_buf;
ci_name.len = strlen(pn.pn_buf);
new_dentry = d_add_ci(dentry, ip, &ci_name);
}
kmem_free(pn.pn_buf, ZFS_MAXNAMELEN); kmem_free(pn.pn_buf, ZFS_MAXNAMELEN);
return (new_dentry); return (new_dentry);
} else { } else {