Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 234236
b: refs/heads/master
c: c826cb7
h: refs/heads/master
v: v3
  • Loading branch information
Linus Torvalds committed Mar 15, 2011
1 parent 8c7a698 commit 146ff47
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 52 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 76ca07832842100b14a31ad8996dab7b0c28aa42
refs/heads/master: c826cb7dfce80512c26c984350077a25046bd215
88 changes: 37 additions & 51 deletions trunk/fs/dcache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1011,6 +1011,34 @@ void shrink_dcache_for_umount(struct super_block *sb)
}
}

/*
* This tries to ascend one level of parenthood, but
* we can race with renaming, so we need to re-check
* the parenthood after dropping the lock and check
* that the sequence number still matches.
*/
static struct dentry *try_to_ascend(struct dentry *old, int locked, unsigned seq)
{
struct dentry *new = old->d_parent;

rcu_read_lock();
spin_unlock(&old->d_lock);
spin_lock(&new->d_lock);

/*
* might go back up the wrong parent if we have had a rename
* or deletion
*/
if (new != old->d_parent ||
(!locked && read_seqretry(&rename_lock, seq))) {
spin_unlock(&new->d_lock);
new = NULL;
}
rcu_read_unlock();
return new;
}


/*
* Search for at least 1 mount point in the dentry's subdirs.
* We descend to the next level whenever the d_subdirs
Expand Down Expand Up @@ -1066,24 +1094,10 @@ int have_submounts(struct dentry *parent)
* All done at this level ... ascend and resume the search.
*/
if (this_parent != parent) {
struct dentry *tmp;
struct dentry *child;

tmp = this_parent->d_parent;
rcu_read_lock();
spin_unlock(&this_parent->d_lock);
child = this_parent;
this_parent = tmp;
spin_lock(&this_parent->d_lock);
/* might go back up the wrong parent if we have had a rename
* or deletion */
if (this_parent != child->d_parent ||
(!locked && read_seqretry(&rename_lock, seq))) {
spin_unlock(&this_parent->d_lock);
rcu_read_unlock();
struct dentry *child = this_parent;
this_parent = try_to_ascend(this_parent, locked, seq);
if (!this_parent)
goto rename_retry;
}
rcu_read_unlock();
next = child->d_u.d_child.next;
goto resume;
}
Expand Down Expand Up @@ -1181,24 +1195,10 @@ static int select_parent(struct dentry * parent)
* All done at this level ... ascend and resume the search.
*/
if (this_parent != parent) {
struct dentry *tmp;
struct dentry *child;

tmp = this_parent->d_parent;
rcu_read_lock();
spin_unlock(&this_parent->d_lock);
child = this_parent;
this_parent = tmp;
spin_lock(&this_parent->d_lock);
/* might go back up the wrong parent if we have had a rename
* or deletion */
if (this_parent != child->d_parent ||
(!locked && read_seqretry(&rename_lock, seq))) {
spin_unlock(&this_parent->d_lock);
rcu_read_unlock();
struct dentry *child = this_parent;
this_parent = try_to_ascend(this_parent, locked, seq);
if (!this_parent)
goto rename_retry;
}
rcu_read_unlock();
next = child->d_u.d_child.next;
goto resume;
}
Expand Down Expand Up @@ -2942,28 +2942,14 @@ void d_genocide(struct dentry *root)
spin_unlock(&dentry->d_lock);
}
if (this_parent != root) {
struct dentry *tmp;
struct dentry *child;

tmp = this_parent->d_parent;
struct dentry *child = this_parent;
if (!(this_parent->d_flags & DCACHE_GENOCIDE)) {
this_parent->d_flags |= DCACHE_GENOCIDE;
this_parent->d_count--;
}
rcu_read_lock();
spin_unlock(&this_parent->d_lock);
child = this_parent;
this_parent = tmp;
spin_lock(&this_parent->d_lock);
/* might go back up the wrong parent if we have had a rename
* or deletion */
if (this_parent != child->d_parent ||
(!locked && read_seqretry(&rename_lock, seq))) {
spin_unlock(&this_parent->d_lock);
rcu_read_unlock();
this_parent = try_to_ascend(this_parent, locked, seq);
if (!this_parent)
goto rename_retry;
}
rcu_read_unlock();
next = child->d_u.d_child.next;
goto resume;
}
Expand Down

0 comments on commit 146ff47

Please sign in to comment.