diff options
-rw-r--r-- | fs/dcache.c | 21 | ||||
-rw-r--r-- | fs/namei.c | 4 |
2 files changed, 14 insertions, 11 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 1710d2484fd9..c6fd1f27da57 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -174,9 +174,12 @@ static struct dentry *d_kill(struct dentry *dentry) | |||
174 | dentry_stat.nr_dentry--; /* For d_free, below */ | 174 | dentry_stat.nr_dentry--; /* For d_free, below */ |
175 | /*drops the locks, at that point nobody can reach this dentry */ | 175 | /*drops the locks, at that point nobody can reach this dentry */ |
176 | dentry_iput(dentry); | 176 | dentry_iput(dentry); |
177 | parent = dentry->d_parent; | 177 | if (IS_ROOT(dentry)) |
178 | parent = NULL; | ||
179 | else | ||
180 | parent = dentry->d_parent; | ||
178 | d_free(dentry); | 181 | d_free(dentry); |
179 | return dentry == parent ? NULL : parent; | 182 | return parent; |
180 | } | 183 | } |
181 | 184 | ||
182 | /* | 185 | /* |
@@ -666,11 +669,12 @@ static void shrink_dcache_for_umount_subtree(struct dentry *dentry) | |||
666 | BUG(); | 669 | BUG(); |
667 | } | 670 | } |
668 | 671 | ||
669 | parent = dentry->d_parent; | 672 | if (IS_ROOT(dentry)) |
670 | if (parent == dentry) | ||
671 | parent = NULL; | 673 | parent = NULL; |
672 | else | 674 | else { |
675 | parent = dentry->d_parent; | ||
673 | atomic_dec(&parent->d_count); | 676 | atomic_dec(&parent->d_count); |
677 | } | ||
674 | 678 | ||
675 | list_del(&dentry->d_u.d_child); | 679 | list_del(&dentry->d_u.d_child); |
676 | detached++; | 680 | detached++; |
@@ -1723,7 +1727,7 @@ static int d_isparent(struct dentry *p1, struct dentry *p2) | |||
1723 | { | 1727 | { |
1724 | struct dentry *p; | 1728 | struct dentry *p; |
1725 | 1729 | ||
1726 | for (p = p2; p->d_parent != p; p = p->d_parent) { | 1730 | for (p = p2; !IS_ROOT(p); p = p->d_parent) { |
1727 | if (p->d_parent == p1) | 1731 | if (p->d_parent == p1) |
1728 | return 1; | 1732 | return 1; |
1729 | } | 1733 | } |
@@ -2168,10 +2172,9 @@ int is_subdir(struct dentry * new_dentry, struct dentry * old_dentry) | |||
2168 | seq = read_seqbegin(&rename_lock); | 2172 | seq = read_seqbegin(&rename_lock); |
2169 | for (;;) { | 2173 | for (;;) { |
2170 | if (new_dentry != old_dentry) { | 2174 | if (new_dentry != old_dentry) { |
2171 | struct dentry * parent = new_dentry->d_parent; | 2175 | if (IS_ROOT(new_dentry)) |
2172 | if (parent == new_dentry) | ||
2173 | break; | 2176 | break; |
2174 | new_dentry = parent; | 2177 | new_dentry = new_dentry->d_parent; |
2175 | continue; | 2178 | continue; |
2176 | } | 2179 | } |
2177 | result = 1; | 2180 | result = 1; |
diff --git a/fs/namei.c b/fs/namei.c index 2b8f823eda44..068a9e50c8c0 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1454,7 +1454,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
1454 | 1454 | ||
1455 | mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex); | 1455 | mutex_lock(&p1->d_inode->i_sb->s_vfs_rename_mutex); |
1456 | 1456 | ||
1457 | for (p = p1; p->d_parent != p; p = p->d_parent) { | 1457 | for (p = p1; !IS_ROOT(p); p = p->d_parent) { |
1458 | if (p->d_parent == p2) { | 1458 | if (p->d_parent == p2) { |
1459 | mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT); | 1459 | mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_PARENT); |
1460 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD); | 1460 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_CHILD); |
@@ -1462,7 +1462,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
1462 | } | 1462 | } |
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | for (p = p2; p->d_parent != p; p = p->d_parent) { | 1465 | for (p = p2; !IS_ROOT(p); p = p->d_parent) { |
1466 | if (p->d_parent == p1) { | 1466 | if (p->d_parent == p1) { |
1467 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT); | 1467 | mutex_lock_nested(&p1->d_inode->i_mutex, I_MUTEX_PARENT); |
1468 | mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD); | 1468 | mutex_lock_nested(&p2->d_inode->i_mutex, I_MUTEX_CHILD); |