Message ID | 20180924215655.3676-20-krisman@collabora.co.uk |
---|---|
State | Superseded |
Headers | show |
Series | Ext4 Encoding and Case-insensitive support | expand |
On Mon, Sep 24, 2018 at 05:56:49PM -0400, Gabriel Krisman Bertazi wrote: > This prevents a soft hang if called d_add_ci is called from the FS > layer, when doing a CI search but the result dentry is the exact match. This isn't the right way to fix this problem. Take a look at how xfs handles this in fs/xfs/xfs_iops.c:xfs_vn_ci_lookup(). This logic should be in the file system, not in d_add_ci(). Also, we don't want to use d_same_name(), since that is *not* guaranteed to do an exact match. It happens to do so for ext4 since we don't provide d_compare, but it's better just check for an exact match and call d_splice_alias() instead of d_add_ci() in ext4_lookup(). Also note that d_same_name() is *not* guaranteeed to do an exact match, in particular if the file system provides d_compare (which granted, ext4 doesn't right now). It's simpler to just do a direct strcmp in ext4_lookup. - Ted P.S. Apologies for not having a chance to look at this series in detail until now. It's been a crazy month...
"Theodore Y. Ts'o" <tytso@mit.edu> writes: > On Mon, Sep 24, 2018 at 05:56:49PM -0400, Gabriel Krisman Bertazi wrote: >> This prevents a soft hang if called d_add_ci is called from the FS >> layer, when doing a CI search but the result dentry is the exact match. > > This isn't the right way to fix this problem. Take a look at how xfs > handles this in fs/xfs/xfs_iops.c:xfs_vn_ci_lookup(). This logic > should be in the file system, not in d_add_ci(). Also, we don't want > to use d_same_name(), since that is *not* guaranteed to do an exact > match. It happens to do so for ext4 since we don't provide d_compare, > but it's better just check for an exact match and call > d_splice_alias() instead of d_add_ci() in ext4_lookup(). > > Also note that d_same_name() is *not* guaranteeed to do an exact > match, in particular if the file system provides d_compare (which > granted, ext4 doesn't right now). It's simpler to just do a direct > strcmp in ext4_lookup. > > - Ted > > P.S. Apologies for not having a chance to look at this series in > detail until now. It's been a crazy month... Hey Ted, No worries. Thanks for the review. I'm aware of how xfs does it. I was looking for a generic way but I see its problems now. I will have it addressed in the next iteration. thanks.
diff --git a/fs/dcache.c b/fs/dcache.c index 0e8e5de3c48a..3b55023cca7e 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2059,6 +2059,20 @@ struct dentry *d_obtain_root(struct inode *inode) } EXPORT_SYMBOL(d_obtain_root); +static inline bool d_same_name(const struct dentry *dentry, + const struct dentry *parent, + const struct qstr *name) +{ + if (likely(!(parent->d_flags & DCACHE_OP_COMPARE))) { + if (dentry->d_name.len != name->len) + return false; + return dentry_cmp(dentry, name->name, name->len) == 0; + } + return parent->d_op->d_compare(dentry, + dentry->d_name.len, dentry->d_name.name, + name) == 0; +} + /** * d_add_ci - lookup or allocate new dentry with case-exact name * @inode: the inode case-insensitive lookup has found @@ -2080,6 +2094,10 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, { struct dentry *found, *res; + /* Trivial case: CI search is exact match. */ + if (d_same_name(dentry, dentry->d_parent, name)) + return d_splice_alias(inode, dentry); + /* * First check if a dentry matching the name already exists, * if not go ahead and create it now. @@ -2112,21 +2130,6 @@ struct dentry *d_add_ci(struct dentry *dentry, struct inode *inode, } EXPORT_SYMBOL(d_add_ci); - -static inline bool d_same_name(const struct dentry *dentry, - const struct dentry *parent, - const struct qstr *name) -{ - if (likely(!(parent->d_flags & DCACHE_OP_COMPARE))) { - if (dentry->d_name.len != name->len) - return false; - return dentry_cmp(dentry, name->name, name->len) == 0; - } - return parent->d_op->d_compare(dentry, - dentry->d_name.len, dentry->d_name.name, - name) == 0; -} - /** * __d_lookup_rcu - search for a dentry (racy, store-free) * @parent: parent dentry
This prevents a soft hang if called d_add_ci is called from the FS layer, when doing a CI search but the result dentry is the exact match. Signed-off-by: Gabriel Krisman Bertazi <krisman@collabora.co.uk> --- fs/dcache.c | 33 ++++++++++++++++++--------------- 1 file changed, 18 insertions(+), 15 deletions(-)