diff options
author | Jes Sorensen <jes@sgi.com> | 2006-01-09 18:59:24 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@hera.kernel.org> | 2006-01-09 18:59:24 -0500 |
commit | 1b1dcc1b57a49136f118a0f16367256ff9994a69 (patch) | |
tree | b0b36d4f41d28c9d6514fb309d33c1a084d6309b /fs/namei.c | |
parent | 794ee1baee1c26be40410233e6c20bceb2b03c08 (diff) |
[PATCH] mutex subsystem, semaphore to mutex: VFS, ->i_sem
This patch converts the inode semaphore to a mutex. I have tested it on
XFS and compiled as much as one can consider on an ia64. Anyway your
luck with it might be different.
Modified-by: Ingo Molnar <mingo@elte.hu>
(finished the conversion)
Signed-off-by: Jes Sorensen <jes@sgi.com>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'fs/namei.c')
-rw-r--r-- | fs/namei.c | 82 |
1 files changed, 41 insertions, 41 deletions
diff --git a/fs/namei.c b/fs/namei.c index 300eae088d5f..0a8f073435af 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -438,7 +438,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s | |||
438 | struct dentry * result; | 438 | struct dentry * result; |
439 | struct inode *dir = parent->d_inode; | 439 | struct inode *dir = parent->d_inode; |
440 | 440 | ||
441 | down(&dir->i_sem); | 441 | mutex_lock(&dir->i_mutex); |
442 | /* | 442 | /* |
443 | * First re-do the cached lookup just in case it was created | 443 | * First re-do the cached lookup just in case it was created |
444 | * while we waited for the directory semaphore.. | 444 | * while we waited for the directory semaphore.. |
@@ -464,7 +464,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s | |||
464 | else | 464 | else |
465 | result = dentry; | 465 | result = dentry; |
466 | } | 466 | } |
467 | up(&dir->i_sem); | 467 | mutex_unlock(&dir->i_mutex); |
468 | return result; | 468 | return result; |
469 | } | 469 | } |
470 | 470 | ||
@@ -472,7 +472,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s | |||
472 | * Uhhuh! Nasty case: the cache was re-populated while | 472 | * Uhhuh! Nasty case: the cache was re-populated while |
473 | * we waited on the semaphore. Need to revalidate. | 473 | * we waited on the semaphore. Need to revalidate. |
474 | */ | 474 | */ |
475 | up(&dir->i_sem); | 475 | mutex_unlock(&dir->i_mutex); |
476 | if (result->d_op && result->d_op->d_revalidate) { | 476 | if (result->d_op && result->d_op->d_revalidate) { |
477 | if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { | 477 | if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { |
478 | dput(result); | 478 | dput(result); |
@@ -1366,7 +1366,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
1366 | struct dentry *p; | 1366 | struct dentry *p; |
1367 | 1367 | ||
1368 | if (p1 == p2) { | 1368 | if (p1 == p2) { |
1369 | down(&p1->d_inode->i_sem); | 1369 | mutex_lock(&p1->d_inode->i_mutex); |
1370 | return NULL; | 1370 | return NULL; |
1371 | } | 1371 | } |
1372 | 1372 | ||
@@ -1374,30 +1374,30 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2) | |||
1374 | 1374 | ||
1375 | for (p = p1; p->d_parent != p; p = p->d_parent) { | 1375 | for (p = p1; p->d_parent != p; p = p->d_parent) { |
1376 | if (p->d_parent == p2) { | 1376 | if (p->d_parent == p2) { |
1377 | down(&p2->d_inode->i_sem); | 1377 | mutex_lock(&p2->d_inode->i_mutex); |
1378 | down(&p1->d_inode->i_sem); | 1378 | mutex_lock(&p1->d_inode->i_mutex); |
1379 | return p; | 1379 | return p; |
1380 | } | 1380 | } |
1381 | } | 1381 | } |
1382 | 1382 | ||
1383 | for (p = p2; p->d_parent != p; p = p->d_parent) { | 1383 | for (p = p2; p->d_parent != p; p = p->d_parent) { |
1384 | if (p->d_parent == p1) { | 1384 | if (p->d_parent == p1) { |
1385 | down(&p1->d_inode->i_sem); | 1385 | mutex_lock(&p1->d_inode->i_mutex); |
1386 | down(&p2->d_inode->i_sem); | 1386 | mutex_lock(&p2->d_inode->i_mutex); |
1387 | return p; | 1387 | return p; |
1388 | } | 1388 | } |
1389 | } | 1389 | } |
1390 | 1390 | ||
1391 | down(&p1->d_inode->i_sem); | 1391 | mutex_lock(&p1->d_inode->i_mutex); |
1392 | down(&p2->d_inode->i_sem); | 1392 | mutex_lock(&p2->d_inode->i_mutex); |
1393 | return NULL; | 1393 | return NULL; |
1394 | } | 1394 | } |
1395 | 1395 | ||
1396 | void unlock_rename(struct dentry *p1, struct dentry *p2) | 1396 | void unlock_rename(struct dentry *p1, struct dentry *p2) |
1397 | { | 1397 | { |
1398 | up(&p1->d_inode->i_sem); | 1398 | mutex_unlock(&p1->d_inode->i_mutex); |
1399 | if (p1 != p2) { | 1399 | if (p1 != p2) { |
1400 | up(&p2->d_inode->i_sem); | 1400 | mutex_unlock(&p2->d_inode->i_mutex); |
1401 | up(&p1->d_inode->i_sb->s_vfs_rename_sem); | 1401 | up(&p1->d_inode->i_sb->s_vfs_rename_sem); |
1402 | } | 1402 | } |
1403 | } | 1403 | } |
@@ -1563,14 +1563,14 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) | |||
1563 | 1563 | ||
1564 | dir = nd->dentry; | 1564 | dir = nd->dentry; |
1565 | nd->flags &= ~LOOKUP_PARENT; | 1565 | nd->flags &= ~LOOKUP_PARENT; |
1566 | down(&dir->d_inode->i_sem); | 1566 | mutex_lock(&dir->d_inode->i_mutex); |
1567 | path.dentry = lookup_hash(nd); | 1567 | path.dentry = lookup_hash(nd); |
1568 | path.mnt = nd->mnt; | 1568 | path.mnt = nd->mnt; |
1569 | 1569 | ||
1570 | do_last: | 1570 | do_last: |
1571 | error = PTR_ERR(path.dentry); | 1571 | error = PTR_ERR(path.dentry); |
1572 | if (IS_ERR(path.dentry)) { | 1572 | if (IS_ERR(path.dentry)) { |
1573 | up(&dir->d_inode->i_sem); | 1573 | mutex_unlock(&dir->d_inode->i_mutex); |
1574 | goto exit; | 1574 | goto exit; |
1575 | } | 1575 | } |
1576 | 1576 | ||
@@ -1579,7 +1579,7 @@ do_last: | |||
1579 | if (!IS_POSIXACL(dir->d_inode)) | 1579 | if (!IS_POSIXACL(dir->d_inode)) |
1580 | mode &= ~current->fs->umask; | 1580 | mode &= ~current->fs->umask; |
1581 | error = vfs_create(dir->d_inode, path.dentry, mode, nd); | 1581 | error = vfs_create(dir->d_inode, path.dentry, mode, nd); |
1582 | up(&dir->d_inode->i_sem); | 1582 | mutex_unlock(&dir->d_inode->i_mutex); |
1583 | dput(nd->dentry); | 1583 | dput(nd->dentry); |
1584 | nd->dentry = path.dentry; | 1584 | nd->dentry = path.dentry; |
1585 | if (error) | 1585 | if (error) |
@@ -1593,7 +1593,7 @@ do_last: | |||
1593 | /* | 1593 | /* |
1594 | * It already exists. | 1594 | * It already exists. |
1595 | */ | 1595 | */ |
1596 | up(&dir->d_inode->i_sem); | 1596 | mutex_unlock(&dir->d_inode->i_mutex); |
1597 | 1597 | ||
1598 | error = -EEXIST; | 1598 | error = -EEXIST; |
1599 | if (flag & O_EXCL) | 1599 | if (flag & O_EXCL) |
@@ -1665,7 +1665,7 @@ do_link: | |||
1665 | goto exit; | 1665 | goto exit; |
1666 | } | 1666 | } |
1667 | dir = nd->dentry; | 1667 | dir = nd->dentry; |
1668 | down(&dir->d_inode->i_sem); | 1668 | mutex_lock(&dir->d_inode->i_mutex); |
1669 | path.dentry = lookup_hash(nd); | 1669 | path.dentry = lookup_hash(nd); |
1670 | path.mnt = nd->mnt; | 1670 | path.mnt = nd->mnt; |
1671 | __putname(nd->last.name); | 1671 | __putname(nd->last.name); |
@@ -1680,13 +1680,13 @@ do_link: | |||
1680 | * Simple function to lookup and return a dentry and create it | 1680 | * Simple function to lookup and return a dentry and create it |
1681 | * if it doesn't exist. Is SMP-safe. | 1681 | * if it doesn't exist. Is SMP-safe. |
1682 | * | 1682 | * |
1683 | * Returns with nd->dentry->d_inode->i_sem locked. | 1683 | * Returns with nd->dentry->d_inode->i_mutex locked. |
1684 | */ | 1684 | */ |
1685 | struct dentry *lookup_create(struct nameidata *nd, int is_dir) | 1685 | struct dentry *lookup_create(struct nameidata *nd, int is_dir) |
1686 | { | 1686 | { |
1687 | struct dentry *dentry = ERR_PTR(-EEXIST); | 1687 | struct dentry *dentry = ERR_PTR(-EEXIST); |
1688 | 1688 | ||
1689 | down(&nd->dentry->d_inode->i_sem); | 1689 | mutex_lock(&nd->dentry->d_inode->i_mutex); |
1690 | /* | 1690 | /* |
1691 | * Yucky last component or no last component at all? | 1691 | * Yucky last component or no last component at all? |
1692 | * (foo/., foo/.., /////) | 1692 | * (foo/., foo/.., /////) |
@@ -1784,7 +1784,7 @@ asmlinkage long sys_mknod(const char __user * filename, int mode, unsigned dev) | |||
1784 | } | 1784 | } |
1785 | dput(dentry); | 1785 | dput(dentry); |
1786 | } | 1786 | } |
1787 | up(&nd.dentry->d_inode->i_sem); | 1787 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
1788 | path_release(&nd); | 1788 | path_release(&nd); |
1789 | out: | 1789 | out: |
1790 | putname(tmp); | 1790 | putname(tmp); |
@@ -1836,7 +1836,7 @@ asmlinkage long sys_mkdir(const char __user * pathname, int mode) | |||
1836 | error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); | 1836 | error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); |
1837 | dput(dentry); | 1837 | dput(dentry); |
1838 | } | 1838 | } |
1839 | up(&nd.dentry->d_inode->i_sem); | 1839 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
1840 | path_release(&nd); | 1840 | path_release(&nd); |
1841 | out: | 1841 | out: |
1842 | putname(tmp); | 1842 | putname(tmp); |
@@ -1885,7 +1885,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1885 | 1885 | ||
1886 | DQUOT_INIT(dir); | 1886 | DQUOT_INIT(dir); |
1887 | 1887 | ||
1888 | down(&dentry->d_inode->i_sem); | 1888 | mutex_lock(&dentry->d_inode->i_mutex); |
1889 | dentry_unhash(dentry); | 1889 | dentry_unhash(dentry); |
1890 | if (d_mountpoint(dentry)) | 1890 | if (d_mountpoint(dentry)) |
1891 | error = -EBUSY; | 1891 | error = -EBUSY; |
@@ -1897,7 +1897,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
1897 | dentry->d_inode->i_flags |= S_DEAD; | 1897 | dentry->d_inode->i_flags |= S_DEAD; |
1898 | } | 1898 | } |
1899 | } | 1899 | } |
1900 | up(&dentry->d_inode->i_sem); | 1900 | mutex_unlock(&dentry->d_inode->i_mutex); |
1901 | if (!error) { | 1901 | if (!error) { |
1902 | d_delete(dentry); | 1902 | d_delete(dentry); |
1903 | } | 1903 | } |
@@ -1932,14 +1932,14 @@ asmlinkage long sys_rmdir(const char __user * pathname) | |||
1932 | error = -EBUSY; | 1932 | error = -EBUSY; |
1933 | goto exit1; | 1933 | goto exit1; |
1934 | } | 1934 | } |
1935 | down(&nd.dentry->d_inode->i_sem); | 1935 | mutex_lock(&nd.dentry->d_inode->i_mutex); |
1936 | dentry = lookup_hash(&nd); | 1936 | dentry = lookup_hash(&nd); |
1937 | error = PTR_ERR(dentry); | 1937 | error = PTR_ERR(dentry); |
1938 | if (!IS_ERR(dentry)) { | 1938 | if (!IS_ERR(dentry)) { |
1939 | error = vfs_rmdir(nd.dentry->d_inode, dentry); | 1939 | error = vfs_rmdir(nd.dentry->d_inode, dentry); |
1940 | dput(dentry); | 1940 | dput(dentry); |
1941 | } | 1941 | } |
1942 | up(&nd.dentry->d_inode->i_sem); | 1942 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
1943 | exit1: | 1943 | exit1: |
1944 | path_release(&nd); | 1944 | path_release(&nd); |
1945 | exit: | 1945 | exit: |
@@ -1959,7 +1959,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1959 | 1959 | ||
1960 | DQUOT_INIT(dir); | 1960 | DQUOT_INIT(dir); |
1961 | 1961 | ||
1962 | down(&dentry->d_inode->i_sem); | 1962 | mutex_lock(&dentry->d_inode->i_mutex); |
1963 | if (d_mountpoint(dentry)) | 1963 | if (d_mountpoint(dentry)) |
1964 | error = -EBUSY; | 1964 | error = -EBUSY; |
1965 | else { | 1965 | else { |
@@ -1967,7 +1967,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1967 | if (!error) | 1967 | if (!error) |
1968 | error = dir->i_op->unlink(dir, dentry); | 1968 | error = dir->i_op->unlink(dir, dentry); |
1969 | } | 1969 | } |
1970 | up(&dentry->d_inode->i_sem); | 1970 | mutex_unlock(&dentry->d_inode->i_mutex); |
1971 | 1971 | ||
1972 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ | 1972 | /* We don't d_delete() NFS sillyrenamed files--they still exist. */ |
1973 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { | 1973 | if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { |
@@ -1979,7 +1979,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry) | |||
1979 | 1979 | ||
1980 | /* | 1980 | /* |
1981 | * Make sure that the actual truncation of the file will occur outside its | 1981 | * Make sure that the actual truncation of the file will occur outside its |
1982 | * directory's i_sem. Truncate can take a long time if there is a lot of | 1982 | * directory's i_mutex. Truncate can take a long time if there is a lot of |
1983 | * writeout happening, and we don't want to prevent access to the directory | 1983 | * writeout happening, and we don't want to prevent access to the directory |
1984 | * while waiting on the I/O. | 1984 | * while waiting on the I/O. |
1985 | */ | 1985 | */ |
@@ -2001,7 +2001,7 @@ asmlinkage long sys_unlink(const char __user * pathname) | |||
2001 | error = -EISDIR; | 2001 | error = -EISDIR; |
2002 | if (nd.last_type != LAST_NORM) | 2002 | if (nd.last_type != LAST_NORM) |
2003 | goto exit1; | 2003 | goto exit1; |
2004 | down(&nd.dentry->d_inode->i_sem); | 2004 | mutex_lock(&nd.dentry->d_inode->i_mutex); |
2005 | dentry = lookup_hash(&nd); | 2005 | dentry = lookup_hash(&nd); |
2006 | error = PTR_ERR(dentry); | 2006 | error = PTR_ERR(dentry); |
2007 | if (!IS_ERR(dentry)) { | 2007 | if (!IS_ERR(dentry)) { |
@@ -2015,7 +2015,7 @@ asmlinkage long sys_unlink(const char __user * pathname) | |||
2015 | exit2: | 2015 | exit2: |
2016 | dput(dentry); | 2016 | dput(dentry); |
2017 | } | 2017 | } |
2018 | up(&nd.dentry->d_inode->i_sem); | 2018 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
2019 | if (inode) | 2019 | if (inode) |
2020 | iput(inode); /* truncate the inode here */ | 2020 | iput(inode); /* truncate the inode here */ |
2021 | exit1: | 2021 | exit1: |
@@ -2075,7 +2075,7 @@ asmlinkage long sys_symlink(const char __user * oldname, const char __user * new | |||
2075 | error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); | 2075 | error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO); |
2076 | dput(dentry); | 2076 | dput(dentry); |
2077 | } | 2077 | } |
2078 | up(&nd.dentry->d_inode->i_sem); | 2078 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
2079 | path_release(&nd); | 2079 | path_release(&nd); |
2080 | out: | 2080 | out: |
2081 | putname(to); | 2081 | putname(to); |
@@ -2113,10 +2113,10 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de | |||
2113 | if (error) | 2113 | if (error) |
2114 | return error; | 2114 | return error; |
2115 | 2115 | ||
2116 | down(&old_dentry->d_inode->i_sem); | 2116 | mutex_lock(&old_dentry->d_inode->i_mutex); |
2117 | DQUOT_INIT(dir); | 2117 | DQUOT_INIT(dir); |
2118 | error = dir->i_op->link(old_dentry, dir, new_dentry); | 2118 | error = dir->i_op->link(old_dentry, dir, new_dentry); |
2119 | up(&old_dentry->d_inode->i_sem); | 2119 | mutex_unlock(&old_dentry->d_inode->i_mutex); |
2120 | if (!error) | 2120 | if (!error) |
2121 | fsnotify_create(dir, new_dentry->d_name.name); | 2121 | fsnotify_create(dir, new_dentry->d_name.name); |
2122 | return error; | 2122 | return error; |
@@ -2157,7 +2157,7 @@ asmlinkage long sys_link(const char __user * oldname, const char __user * newnam | |||
2157 | error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); | 2157 | error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); |
2158 | dput(new_dentry); | 2158 | dput(new_dentry); |
2159 | } | 2159 | } |
2160 | up(&nd.dentry->d_inode->i_sem); | 2160 | mutex_unlock(&nd.dentry->d_inode->i_mutex); |
2161 | out_release: | 2161 | out_release: |
2162 | path_release(&nd); | 2162 | path_release(&nd); |
2163 | out: | 2163 | out: |
@@ -2178,7 +2178,7 @@ exit: | |||
2178 | * sb->s_vfs_rename_sem. We might be more accurate, but that's another | 2178 | * sb->s_vfs_rename_sem. We might be more accurate, but that's another |
2179 | * story. | 2179 | * story. |
2180 | * c) we have to lock _three_ objects - parents and victim (if it exists). | 2180 | * c) we have to lock _three_ objects - parents and victim (if it exists). |
2181 | * And that - after we got ->i_sem on parents (until then we don't know | 2181 | * And that - after we got ->i_mutex on parents (until then we don't know |
2182 | * whether the target exists). Solution: try to be smart with locking | 2182 | * whether the target exists). Solution: try to be smart with locking |
2183 | * order for inodes. We rely on the fact that tree topology may change | 2183 | * order for inodes. We rely on the fact that tree topology may change |
2184 | * only under ->s_vfs_rename_sem _and_ that parent of the object we | 2184 | * only under ->s_vfs_rename_sem _and_ that parent of the object we |
@@ -2195,9 +2195,9 @@ exit: | |||
2195 | * stuff into VFS), but the former is not going away. Solution: the same | 2195 | * stuff into VFS), but the former is not going away. Solution: the same |
2196 | * trick as in rmdir(). | 2196 | * trick as in rmdir(). |
2197 | * e) conversion from fhandle to dentry may come in the wrong moment - when | 2197 | * e) conversion from fhandle to dentry may come in the wrong moment - when |
2198 | * we are removing the target. Solution: we will have to grab ->i_sem | 2198 | * we are removing the target. Solution: we will have to grab ->i_mutex |
2199 | * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on | 2199 | * in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on |
2200 | * ->i_sem on parents, which works but leads to some truely excessive | 2200 | * ->i_mutex on parents, which works but leads to some truely excessive |
2201 | * locking]. | 2201 | * locking]. |
2202 | */ | 2202 | */ |
2203 | static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | 2203 | static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, |
@@ -2222,7 +2222,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
2222 | 2222 | ||
2223 | target = new_dentry->d_inode; | 2223 | target = new_dentry->d_inode; |
2224 | if (target) { | 2224 | if (target) { |
2225 | down(&target->i_sem); | 2225 | mutex_lock(&target->i_mutex); |
2226 | dentry_unhash(new_dentry); | 2226 | dentry_unhash(new_dentry); |
2227 | } | 2227 | } |
2228 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) | 2228 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) |
@@ -2232,7 +2232,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, | |||
2232 | if (target) { | 2232 | if (target) { |
2233 | if (!error) | 2233 | if (!error) |
2234 | target->i_flags |= S_DEAD; | 2234 | target->i_flags |= S_DEAD; |
2235 | up(&target->i_sem); | 2235 | mutex_unlock(&target->i_mutex); |
2236 | if (d_unhashed(new_dentry)) | 2236 | if (d_unhashed(new_dentry)) |
2237 | d_rehash(new_dentry); | 2237 | d_rehash(new_dentry); |
2238 | dput(new_dentry); | 2238 | dput(new_dentry); |
@@ -2255,7 +2255,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | |||
2255 | dget(new_dentry); | 2255 | dget(new_dentry); |
2256 | target = new_dentry->d_inode; | 2256 | target = new_dentry->d_inode; |
2257 | if (target) | 2257 | if (target) |
2258 | down(&target->i_sem); | 2258 | mutex_lock(&target->i_mutex); |
2259 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) | 2259 | if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) |
2260 | error = -EBUSY; | 2260 | error = -EBUSY; |
2261 | else | 2261 | else |
@@ -2266,7 +2266,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, | |||
2266 | d_move(old_dentry, new_dentry); | 2266 | d_move(old_dentry, new_dentry); |
2267 | } | 2267 | } |
2268 | if (target) | 2268 | if (target) |
2269 | up(&target->i_sem); | 2269 | mutex_unlock(&target->i_mutex); |
2270 | dput(new_dentry); | 2270 | dput(new_dentry); |
2271 | return error; | 2271 | return error; |
2272 | } | 2272 | } |