fs: increase d_name lock coverage
Cover d_name with d_lock in more cases, where there may be concurrent modification to it. Signed-off-by: Nick Piggin <npiggin@kernel.dk>
This commit is contained in:
parent
b23fb0a603
commit
9abca36087
14
fs/dcache.c
14
fs/dcache.c
@ -1350,6 +1350,11 @@ static struct dentry *__d_instantiate_unique(struct dentry *entry,
|
|||||||
list_for_each_entry(alias, &inode->i_dentry, d_alias) {
|
list_for_each_entry(alias, &inode->i_dentry, d_alias) {
|
||||||
struct qstr *qstr = &alias->d_name;
|
struct qstr *qstr = &alias->d_name;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Don't need alias->d_lock here, because aliases with
|
||||||
|
* d_parent == entry->d_parent are not subject to name or
|
||||||
|
* parent changes, because the parent inode i_mutex is held.
|
||||||
|
*/
|
||||||
if (qstr->hash != hash)
|
if (qstr->hash != hash)
|
||||||
continue;
|
continue;
|
||||||
if (alias->d_parent != entry->d_parent)
|
if (alias->d_parent != entry->d_parent)
|
||||||
@ -2313,7 +2318,9 @@ static int prepend_path(const struct path *path, struct path *root,
|
|||||||
}
|
}
|
||||||
parent = dentry->d_parent;
|
parent = dentry->d_parent;
|
||||||
prefetch(parent);
|
prefetch(parent);
|
||||||
|
spin_lock(&dentry->d_lock);
|
||||||
error = prepend_name(buffer, buflen, &dentry->d_name);
|
error = prepend_name(buffer, buflen, &dentry->d_name);
|
||||||
|
spin_unlock(&dentry->d_lock);
|
||||||
if (!error)
|
if (!error)
|
||||||
error = prepend(buffer, buflen, "/", 1);
|
error = prepend(buffer, buflen, "/", 1);
|
||||||
if (error)
|
if (error)
|
||||||
@ -2515,10 +2522,13 @@ static char *__dentry_path(struct dentry *dentry, char *buf, int buflen)
|
|||||||
|
|
||||||
while (!IS_ROOT(dentry)) {
|
while (!IS_ROOT(dentry)) {
|
||||||
struct dentry *parent = dentry->d_parent;
|
struct dentry *parent = dentry->d_parent;
|
||||||
|
int error;
|
||||||
|
|
||||||
prefetch(parent);
|
prefetch(parent);
|
||||||
if ((prepend_name(&end, &buflen, &dentry->d_name) != 0) ||
|
spin_lock(&dentry->d_lock);
|
||||||
(prepend(&end, &buflen, "/", 1) != 0))
|
error = prepend_name(&end, &buflen, &dentry->d_name);
|
||||||
|
spin_unlock(&dentry->d_lock);
|
||||||
|
if (error != 0 || prepend(&end, &buflen, "/", 1) != 0)
|
||||||
goto Elong;
|
goto Elong;
|
||||||
|
|
||||||
retval = end;
|
retval = end;
|
||||||
|
Loading…
Reference in New Issue
Block a user