aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorJes Sorensen <jes@sgi.com>2006-01-09 18:59:24 -0500
committerIngo Molnar <mingo@hera.kernel.org>2006-01-09 18:59:24 -0500
commit1b1dcc1b57a49136f118a0f16367256ff9994a69 (patch)
treeb0b36d4f41d28c9d6514fb309d33c1a084d6309b /fs/namei.c
parent794ee1baee1c26be40410233e6c20bceb2b03c08 (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.c82
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
1396void unlock_rename(struct dentry *p1, struct dentry *p2) 1396void 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
1570do_last: 1570do_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 */
1685struct dentry *lookup_create(struct nameidata *nd, int is_dir) 1685struct 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);
1789out: 1789out:
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);
1841out: 1841out:
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);
1943exit1: 1943exit1:
1944 path_release(&nd); 1944 path_release(&nd);
1945exit: 1945exit:
@@ -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 */
2021exit1: 2021exit1:
@@ -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);
2080out: 2080out:
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);
2161out_release: 2161out_release:
2162 path_release(&nd); 2162 path_release(&nd);
2163out: 2163out:
@@ -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 */
2203static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, 2203static 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}