Skip to content

Commit 4c43ab1

Browse files
author
Al Viro
committed
generic_ci_d_compare(): use shortname_storage
... and check the "name might be unstable" predicate the right way. Reviewed-by: Jeff Layton <[email protected]> Reviewed-by: Gabriel Krisman Bertazi <[email protected]> Signed-off-by: Al Viro <[email protected]>
1 parent 7e32701 commit 4c43ab1

File tree

1 file changed

+8
-7
lines changed

1 file changed

+8
-7
lines changed

fs/libfs.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1789,7 +1789,7 @@ int generic_ci_d_compare(const struct dentry *dentry, unsigned int len,
17891789
{
17901790
const struct dentry *parent;
17911791
const struct inode *dir;
1792-
char strbuf[DNAME_INLINE_LEN];
1792+
union shortname_store strbuf;
17931793
struct qstr qstr;
17941794

17951795
/*
@@ -1809,22 +1809,23 @@ int generic_ci_d_compare(const struct dentry *dentry, unsigned int len,
18091809
if (!dir || !IS_CASEFOLDED(dir))
18101810
return 1;
18111811

1812+
qstr.len = len;
1813+
qstr.name = str;
18121814
/*
18131815
* If the dentry name is stored in-line, then it may be concurrently
18141816
* modified by a rename. If this happens, the VFS will eventually retry
18151817
* the lookup, so it doesn't matter what ->d_compare() returns.
18161818
* However, it's unsafe to call utf8_strncasecmp() with an unstable
18171819
* string. Therefore, we have to copy the name into a temporary buffer.
1820+
* As above, len is guaranteed to match str, so the shortname case
1821+
* is exactly when str points to ->d_shortname.
18181822
*/
1819-
if (len <= DNAME_INLINE_LEN - 1) {
1820-
memcpy(strbuf, str, len);
1821-
strbuf[len] = 0;
1822-
str = strbuf;
1823+
if (qstr.name == dentry->d_shortname.string) {
1824+
strbuf = dentry->d_shortname; // NUL is guaranteed to be in there
1825+
qstr.name = strbuf.string;
18231826
/* prevent compiler from optimizing out the temporary buffer */
18241827
barrier();
18251828
}
1826-
qstr.len = len;
1827-
qstr.name = str;
18281829

18291830
return utf8_strncasecmp(dentry->d_sb->s_encoding, name, &qstr);
18301831
}

0 commit comments

Comments
 (0)