aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c271
1 files changed, 186 insertions, 85 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 6dbbd42d8b95..4acdac043b6b 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -28,7 +28,10 @@
28#include <linux/syscalls.h> 28#include <linux/syscalls.h>
29#include <linux/mount.h> 29#include <linux/mount.h>
30#include <linux/audit.h> 30#include <linux/audit.h>
31#include <linux/capability.h>
31#include <linux/file.h> 32#include <linux/file.h>
33#include <linux/fcntl.h>
34#include <linux/namei.h>
32#include <asm/namei.h> 35#include <asm/namei.h>
33#include <asm/uaccess.h> 36#include <asm/uaccess.h>
34 37
@@ -112,7 +115,7 @@
112 * POSIX.1 2.4: an empty pathname is invalid (ENOENT). 115 * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
113 * PATH_MAX includes the nul terminator --RR. 116 * PATH_MAX includes the nul terminator --RR.
114 */ 117 */
115static inline int do_getname(const char __user *filename, char *page) 118static int do_getname(const char __user *filename, char *page)
116{ 119{
117 int retval; 120 int retval;
118 unsigned long len = PATH_MAX; 121 unsigned long len = PATH_MAX;
@@ -395,7 +398,7 @@ static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name,
395 * short-cut DAC fails, then call permission() to do more 398 * short-cut DAC fails, then call permission() to do more
396 * complete permission check. 399 * complete permission check.
397 */ 400 */
398static inline int exec_permission_lite(struct inode *inode, 401static int exec_permission_lite(struct inode *inode,
399 struct nameidata *nd) 402 struct nameidata *nd)
400{ 403{
401 umode_t mode = inode->i_mode; 404 umode_t mode = inode->i_mode;
@@ -438,7 +441,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
438 struct dentry * result; 441 struct dentry * result;
439 struct inode *dir = parent->d_inode; 442 struct inode *dir = parent->d_inode;
440 443
441 down(&dir->i_sem); 444 mutex_lock(&dir->i_mutex);
442 /* 445 /*
443 * First re-do the cached lookup just in case it was created 446 * First re-do the cached lookup just in case it was created
444 * while we waited for the directory semaphore.. 447 * while we waited for the directory semaphore..
@@ -464,7 +467,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
464 else 467 else
465 result = dentry; 468 result = dentry;
466 } 469 }
467 up(&dir->i_sem); 470 mutex_unlock(&dir->i_mutex);
468 return result; 471 return result;
469 } 472 }
470 473
@@ -472,7 +475,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
472 * Uhhuh! Nasty case: the cache was re-populated while 475 * Uhhuh! Nasty case: the cache was re-populated while
473 * we waited on the semaphore. Need to revalidate. 476 * we waited on the semaphore. Need to revalidate.
474 */ 477 */
475 up(&dir->i_sem); 478 mutex_unlock(&dir->i_mutex);
476 if (result->d_op && result->d_op->d_revalidate) { 479 if (result->d_op && result->d_op->d_revalidate) {
477 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { 480 if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) {
478 dput(result); 481 dput(result);
@@ -485,7 +488,7 @@ static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, s
485static int __emul_lookup_dentry(const char *, struct nameidata *); 488static int __emul_lookup_dentry(const char *, struct nameidata *);
486 489
487/* SMP-safe */ 490/* SMP-safe */
488static inline int 491static __always_inline int
489walk_init_root(const char *name, struct nameidata *nd) 492walk_init_root(const char *name, struct nameidata *nd)
490{ 493{
491 read_lock(&current->fs->lock); 494 read_lock(&current->fs->lock);
@@ -503,7 +506,7 @@ walk_init_root(const char *name, struct nameidata *nd)
503 return 1; 506 return 1;
504} 507}
505 508
506static inline int __vfs_follow_link(struct nameidata *nd, const char *link) 509static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *link)
507{ 510{
508 int res = 0; 511 int res = 0;
509 char *name; 512 char *name;
@@ -543,7 +546,7 @@ struct path {
543 struct dentry *dentry; 546 struct dentry *dentry;
544}; 547};
545 548
546static inline int __do_follow_link(struct path *path, struct nameidata *nd) 549static __always_inline int __do_follow_link(struct path *path, struct nameidata *nd)
547{ 550{
548 int error; 551 int error;
549 void *cookie; 552 void *cookie;
@@ -689,7 +692,7 @@ int follow_down(struct vfsmount **mnt, struct dentry **dentry)
689 return 0; 692 return 0;
690} 693}
691 694
692static inline void follow_dotdot(struct nameidata *nd) 695static __always_inline void follow_dotdot(struct nameidata *nd)
693{ 696{
694 while(1) { 697 while(1) {
695 struct vfsmount *parent; 698 struct vfsmount *parent;
@@ -1062,7 +1065,8 @@ set_it:
1062} 1065}
1063 1066
1064/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */ 1067/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
1065int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata *nd) 1068static int fastcall do_path_lookup(int dfd, const char *name,
1069 unsigned int flags, struct nameidata *nd)
1066{ 1070{
1067 int retval = 0; 1071 int retval = 0;
1068 1072
@@ -1082,9 +1086,38 @@ int fastcall path_lookup(const char *name, unsigned int flags, struct nameidata
1082 } 1086 }
1083 nd->mnt = mntget(current->fs->rootmnt); 1087 nd->mnt = mntget(current->fs->rootmnt);
1084 nd->dentry = dget(current->fs->root); 1088 nd->dentry = dget(current->fs->root);
1085 } else { 1089 } else if (dfd == AT_FDCWD) {
1086 nd->mnt = mntget(current->fs->pwdmnt); 1090 nd->mnt = mntget(current->fs->pwdmnt);
1087 nd->dentry = dget(current->fs->pwd); 1091 nd->dentry = dget(current->fs->pwd);
1092 } else {
1093 struct file *file;
1094 int fput_needed;
1095 struct dentry *dentry;
1096
1097 file = fget_light(dfd, &fput_needed);
1098 if (!file) {
1099 retval = -EBADF;
1100 goto out_fail;
1101 }
1102
1103 dentry = file->f_dentry;
1104
1105 if (!S_ISDIR(dentry->d_inode->i_mode)) {
1106 retval = -ENOTDIR;
1107 fput_light(file, fput_needed);
1108 goto out_fail;
1109 }
1110
1111 retval = file_permission(file, MAY_EXEC);
1112 if (retval) {
1113 fput_light(file, fput_needed);
1114 goto out_fail;
1115 }
1116
1117 nd->mnt = mntget(file->f_vfsmnt);
1118 nd->dentry = dget(dentry);
1119
1120 fput_light(file, fput_needed);
1088 } 1121 }
1089 read_unlock(&current->fs->lock); 1122 read_unlock(&current->fs->lock);
1090 current->total_link_count = 0; 1123 current->total_link_count = 0;
@@ -1093,11 +1126,19 @@ out:
1093 if (unlikely(current->audit_context 1126 if (unlikely(current->audit_context
1094 && nd && nd->dentry && nd->dentry->d_inode)) 1127 && nd && nd->dentry && nd->dentry->d_inode))
1095 audit_inode(name, nd->dentry->d_inode, flags); 1128 audit_inode(name, nd->dentry->d_inode, flags);
1129out_fail:
1096 return retval; 1130 return retval;
1097} 1131}
1098 1132
1099static int __path_lookup_intent_open(const char *name, unsigned int lookup_flags, 1133int fastcall path_lookup(const char *name, unsigned int flags,
1100 struct nameidata *nd, int open_flags, int create_mode) 1134 struct nameidata *nd)
1135{
1136 return do_path_lookup(AT_FDCWD, name, flags, nd);
1137}
1138
1139static int __path_lookup_intent_open(int dfd, const char *name,
1140 unsigned int lookup_flags, struct nameidata *nd,
1141 int open_flags, int create_mode)
1101{ 1142{
1102 struct file *filp = get_empty_filp(); 1143 struct file *filp = get_empty_filp();
1103 int err; 1144 int err;
@@ -1107,7 +1148,7 @@ static int __path_lookup_intent_open(const char *name, unsigned int lookup_flags
1107 nd->intent.open.file = filp; 1148 nd->intent.open.file = filp;
1108 nd->intent.open.flags = open_flags; 1149 nd->intent.open.flags = open_flags;
1109 nd->intent.open.create_mode = create_mode; 1150 nd->intent.open.create_mode = create_mode;
1110 err = path_lookup(name, lookup_flags|LOOKUP_OPEN, nd); 1151 err = do_path_lookup(dfd, name, lookup_flags|LOOKUP_OPEN, nd);
1111 if (IS_ERR(nd->intent.open.file)) { 1152 if (IS_ERR(nd->intent.open.file)) {
1112 if (err == 0) { 1153 if (err == 0) {
1113 err = PTR_ERR(nd->intent.open.file); 1154 err = PTR_ERR(nd->intent.open.file);
@@ -1125,10 +1166,10 @@ static int __path_lookup_intent_open(const char *name, unsigned int lookup_flags
1125 * @nd: pointer to nameidata 1166 * @nd: pointer to nameidata
1126 * @open_flags: open intent flags 1167 * @open_flags: open intent flags
1127 */ 1168 */
1128int path_lookup_open(const char *name, unsigned int lookup_flags, 1169int path_lookup_open(int dfd, const char *name, unsigned int lookup_flags,
1129 struct nameidata *nd, int open_flags) 1170 struct nameidata *nd, int open_flags)
1130{ 1171{
1131 return __path_lookup_intent_open(name, lookup_flags, nd, 1172 return __path_lookup_intent_open(dfd, name, lookup_flags, nd,
1132 open_flags, 0); 1173 open_flags, 0);
1133} 1174}
1134 1175
@@ -1140,12 +1181,12 @@ int path_lookup_open(const char *name, unsigned int lookup_flags,
1140 * @open_flags: open intent flags 1181 * @open_flags: open intent flags
1141 * @create_mode: create intent flags 1182 * @create_mode: create intent flags
1142 */ 1183 */
1143static int path_lookup_create(const char *name, unsigned int lookup_flags, 1184static int path_lookup_create(int dfd, const char *name,
1144 struct nameidata *nd, int open_flags, 1185 unsigned int lookup_flags, struct nameidata *nd,
1145 int create_mode) 1186 int open_flags, int create_mode)
1146{ 1187{
1147 return __path_lookup_intent_open(name, lookup_flags|LOOKUP_CREATE, nd, 1188 return __path_lookup_intent_open(dfd, name, lookup_flags|LOOKUP_CREATE,
1148 open_flags, create_mode); 1189 nd, open_flags, create_mode);
1149} 1190}
1150 1191
1151int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags, 1192int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
@@ -1155,7 +1196,7 @@ int __user_path_lookup_open(const char __user *name, unsigned int lookup_flags,
1155 int err = PTR_ERR(tmp); 1196 int err = PTR_ERR(tmp);
1156 1197
1157 if (!IS_ERR(tmp)) { 1198 if (!IS_ERR(tmp)) {
1158 err = __path_lookup_intent_open(tmp, lookup_flags, nd, open_flags, 0); 1199 err = __path_lookup_intent_open(AT_FDCWD, tmp, lookup_flags, nd, open_flags, 0);
1159 putname(tmp); 1200 putname(tmp);
1160 } 1201 }
1161 return err; 1202 return err;
@@ -1247,18 +1288,24 @@ access:
1247 * that namei follows links, while lnamei does not. 1288 * that namei follows links, while lnamei does not.
1248 * SMP-safe 1289 * SMP-safe
1249 */ 1290 */
1250int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd) 1291int fastcall __user_walk_fd(int dfd, const char __user *name, unsigned flags,
1292 struct nameidata *nd)
1251{ 1293{
1252 char *tmp = getname(name); 1294 char *tmp = getname(name);
1253 int err = PTR_ERR(tmp); 1295 int err = PTR_ERR(tmp);
1254 1296
1255 if (!IS_ERR(tmp)) { 1297 if (!IS_ERR(tmp)) {
1256 err = path_lookup(tmp, flags, nd); 1298 err = do_path_lookup(dfd, tmp, flags, nd);
1257 putname(tmp); 1299 putname(tmp);
1258 } 1300 }
1259 return err; 1301 return err;
1260} 1302}
1261 1303
1304int fastcall __user_walk(const char __user *name, unsigned flags, struct nameidata *nd)
1305{
1306 return __user_walk_fd(AT_FDCWD, name, flags, nd);
1307}
1308
1262/* 1309/*
1263 * It's inline, so penalty for filesystems that don't use sticky bit is 1310 * It's inline, so penalty for filesystems that don't use sticky bit is
1264 * minimal. 1311 * minimal.
@@ -1293,7 +1340,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
1293 * 10. We don't allow removal of NFS sillyrenamed files; it's handled by 1340 * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
1294 * nfs_async_unlink(). 1341 * nfs_async_unlink().
1295 */ 1342 */
1296static inline int may_delete(struct inode *dir,struct dentry *victim,int isdir) 1343static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
1297{ 1344{
1298 int error; 1345 int error;
1299 1346
@@ -1366,7 +1413,7 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
1366 struct dentry *p; 1413 struct dentry *p;
1367 1414
1368 if (p1 == p2) { 1415 if (p1 == p2) {
1369 down(&p1->d_inode->i_sem); 1416 mutex_lock(&p1->d_inode->i_mutex);
1370 return NULL; 1417 return NULL;
1371 } 1418 }
1372 1419
@@ -1374,30 +1421,30 @@ struct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
1374 1421
1375 for (p = p1; p->d_parent != p; p = p->d_parent) { 1422 for (p = p1; p->d_parent != p; p = p->d_parent) {
1376 if (p->d_parent == p2) { 1423 if (p->d_parent == p2) {
1377 down(&p2->d_inode->i_sem); 1424 mutex_lock(&p2->d_inode->i_mutex);
1378 down(&p1->d_inode->i_sem); 1425 mutex_lock(&p1->d_inode->i_mutex);
1379 return p; 1426 return p;
1380 } 1427 }
1381 } 1428 }
1382 1429
1383 for (p = p2; p->d_parent != p; p = p->d_parent) { 1430 for (p = p2; p->d_parent != p; p = p->d_parent) {
1384 if (p->d_parent == p1) { 1431 if (p->d_parent == p1) {
1385 down(&p1->d_inode->i_sem); 1432 mutex_lock(&p1->d_inode->i_mutex);
1386 down(&p2->d_inode->i_sem); 1433 mutex_lock(&p2->d_inode->i_mutex);
1387 return p; 1434 return p;
1388 } 1435 }
1389 } 1436 }
1390 1437
1391 down(&p1->d_inode->i_sem); 1438 mutex_lock(&p1->d_inode->i_mutex);
1392 down(&p2->d_inode->i_sem); 1439 mutex_lock(&p2->d_inode->i_mutex);
1393 return NULL; 1440 return NULL;
1394} 1441}
1395 1442
1396void unlock_rename(struct dentry *p1, struct dentry *p2) 1443void unlock_rename(struct dentry *p1, struct dentry *p2)
1397{ 1444{
1398 up(&p1->d_inode->i_sem); 1445 mutex_unlock(&p1->d_inode->i_mutex);
1399 if (p1 != p2) { 1446 if (p1 != p2) {
1400 up(&p2->d_inode->i_sem); 1447 mutex_unlock(&p2->d_inode->i_mutex);
1401 up(&p1->d_inode->i_sb->s_vfs_rename_sem); 1448 up(&p1->d_inode->i_sb->s_vfs_rename_sem);
1402 } 1449 }
1403} 1450}
@@ -1491,7 +1538,7 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1491 if (!error) { 1538 if (!error) {
1492 DQUOT_INIT(inode); 1539 DQUOT_INIT(inode);
1493 1540
1494 error = do_truncate(dentry, 0, NULL); 1541 error = do_truncate(dentry, 0, ATTR_MTIME|ATTR_CTIME, NULL);
1495 } 1542 }
1496 put_write_access(inode); 1543 put_write_access(inode);
1497 if (error) 1544 if (error)
@@ -1517,7 +1564,8 @@ int may_open(struct nameidata *nd, int acc_mode, int flag)
1517 * for symlinks (where the permissions are checked later). 1564 * for symlinks (where the permissions are checked later).
1518 * SMP-safe 1565 * SMP-safe
1519 */ 1566 */
1520int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) 1567int open_namei(int dfd, const char *pathname, int flag,
1568 int mode, struct nameidata *nd)
1521{ 1569{
1522 int acc_mode, error; 1570 int acc_mode, error;
1523 struct path path; 1571 struct path path;
@@ -1539,7 +1587,8 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1539 * The simplest case - just a plain lookup. 1587 * The simplest case - just a plain lookup.
1540 */ 1588 */
1541 if (!(flag & O_CREAT)) { 1589 if (!(flag & O_CREAT)) {
1542 error = path_lookup_open(pathname, lookup_flags(flag), nd, flag); 1590 error = path_lookup_open(dfd, pathname, lookup_flags(flag),
1591 nd, flag);
1543 if (error) 1592 if (error)
1544 return error; 1593 return error;
1545 goto ok; 1594 goto ok;
@@ -1548,7 +1597,7 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1548 /* 1597 /*
1549 * Create - we need to know the parent. 1598 * Create - we need to know the parent.
1550 */ 1599 */
1551 error = path_lookup_create(pathname, LOOKUP_PARENT, nd, flag, mode); 1600 error = path_lookup_create(dfd,pathname,LOOKUP_PARENT,nd,flag,mode);
1552 if (error) 1601 if (error)
1553 return error; 1602 return error;
1554 1603
@@ -1563,14 +1612,14 @@ int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd)
1563 1612
1564 dir = nd->dentry; 1613 dir = nd->dentry;
1565 nd->flags &= ~LOOKUP_PARENT; 1614 nd->flags &= ~LOOKUP_PARENT;
1566 down(&dir->d_inode->i_sem); 1615 mutex_lock(&dir->d_inode->i_mutex);
1567 path.dentry = lookup_hash(nd); 1616 path.dentry = lookup_hash(nd);
1568 path.mnt = nd->mnt; 1617 path.mnt = nd->mnt;
1569 1618
1570do_last: 1619do_last:
1571 error = PTR_ERR(path.dentry); 1620 error = PTR_ERR(path.dentry);
1572 if (IS_ERR(path.dentry)) { 1621 if (IS_ERR(path.dentry)) {
1573 up(&dir->d_inode->i_sem); 1622 mutex_unlock(&dir->d_inode->i_mutex);
1574 goto exit; 1623 goto exit;
1575 } 1624 }
1576 1625
@@ -1579,7 +1628,7 @@ do_last:
1579 if (!IS_POSIXACL(dir->d_inode)) 1628 if (!IS_POSIXACL(dir->d_inode))
1580 mode &= ~current->fs->umask; 1629 mode &= ~current->fs->umask;
1581 error = vfs_create(dir->d_inode, path.dentry, mode, nd); 1630 error = vfs_create(dir->d_inode, path.dentry, mode, nd);
1582 up(&dir->d_inode->i_sem); 1631 mutex_unlock(&dir->d_inode->i_mutex);
1583 dput(nd->dentry); 1632 dput(nd->dentry);
1584 nd->dentry = path.dentry; 1633 nd->dentry = path.dentry;
1585 if (error) 1634 if (error)
@@ -1593,7 +1642,7 @@ do_last:
1593 /* 1642 /*
1594 * It already exists. 1643 * It already exists.
1595 */ 1644 */
1596 up(&dir->d_inode->i_sem); 1645 mutex_unlock(&dir->d_inode->i_mutex);
1597 1646
1598 error = -EEXIST; 1647 error = -EEXIST;
1599 if (flag & O_EXCL) 1648 if (flag & O_EXCL)
@@ -1665,7 +1714,7 @@ do_link:
1665 goto exit; 1714 goto exit;
1666 } 1715 }
1667 dir = nd->dentry; 1716 dir = nd->dentry;
1668 down(&dir->d_inode->i_sem); 1717 mutex_lock(&dir->d_inode->i_mutex);
1669 path.dentry = lookup_hash(nd); 1718 path.dentry = lookup_hash(nd);
1670 path.mnt = nd->mnt; 1719 path.mnt = nd->mnt;
1671 __putname(nd->last.name); 1720 __putname(nd->last.name);
@@ -1680,13 +1729,13 @@ do_link:
1680 * Simple function to lookup and return a dentry and create it 1729 * Simple function to lookup and return a dentry and create it
1681 * if it doesn't exist. Is SMP-safe. 1730 * if it doesn't exist. Is SMP-safe.
1682 * 1731 *
1683 * Returns with nd->dentry->d_inode->i_sem locked. 1732 * Returns with nd->dentry->d_inode->i_mutex locked.
1684 */ 1733 */
1685struct dentry *lookup_create(struct nameidata *nd, int is_dir) 1734struct dentry *lookup_create(struct nameidata *nd, int is_dir)
1686{ 1735{
1687 struct dentry *dentry = ERR_PTR(-EEXIST); 1736 struct dentry *dentry = ERR_PTR(-EEXIST);
1688 1737
1689 down(&nd->dentry->d_inode->i_sem); 1738 mutex_lock(&nd->dentry->d_inode->i_mutex);
1690 /* 1739 /*
1691 * Yucky last component or no last component at all? 1740 * Yucky last component or no last component at all?
1692 * (foo/., foo/.., /////) 1741 * (foo/., foo/.., /////)
@@ -1743,7 +1792,8 @@ int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
1743 return error; 1792 return error;
1744} 1793}
1745 1794
1746asmlinkage long sys_mknod(const char __user * filename, int mode, unsigned dev) 1795asmlinkage long sys_mknodat(int dfd, const char __user *filename, int mode,
1796 unsigned dev)
1747{ 1797{
1748 int error = 0; 1798 int error = 0;
1749 char * tmp; 1799 char * tmp;
@@ -1756,7 +1806,7 @@ asmlinkage long sys_mknod(const char __user * filename, int mode, unsigned dev)
1756 if (IS_ERR(tmp)) 1806 if (IS_ERR(tmp))
1757 return PTR_ERR(tmp); 1807 return PTR_ERR(tmp);
1758 1808
1759 error = path_lookup(tmp, LOOKUP_PARENT, &nd); 1809 error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
1760 if (error) 1810 if (error)
1761 goto out; 1811 goto out;
1762 dentry = lookup_create(&nd, 0); 1812 dentry = lookup_create(&nd, 0);
@@ -1784,7 +1834,7 @@ asmlinkage long sys_mknod(const char __user * filename, int mode, unsigned dev)
1784 } 1834 }
1785 dput(dentry); 1835 dput(dentry);
1786 } 1836 }
1787 up(&nd.dentry->d_inode->i_sem); 1837 mutex_unlock(&nd.dentry->d_inode->i_mutex);
1788 path_release(&nd); 1838 path_release(&nd);
1789out: 1839out:
1790 putname(tmp); 1840 putname(tmp);
@@ -1792,6 +1842,11 @@ out:
1792 return error; 1842 return error;
1793} 1843}
1794 1844
1845asmlinkage long sys_mknod(const char __user *filename, int mode, unsigned dev)
1846{
1847 return sys_mknodat(AT_FDCWD, filename, mode, dev);
1848}
1849
1795int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode) 1850int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1796{ 1851{
1797 int error = may_create(dir, dentry, NULL); 1852 int error = may_create(dir, dentry, NULL);
@@ -1814,7 +1869,7 @@ int vfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1814 return error; 1869 return error;
1815} 1870}
1816 1871
1817asmlinkage long sys_mkdir(const char __user * pathname, int mode) 1872asmlinkage long sys_mkdirat(int dfd, const char __user *pathname, int mode)
1818{ 1873{
1819 int error = 0; 1874 int error = 0;
1820 char * tmp; 1875 char * tmp;
@@ -1825,7 +1880,7 @@ asmlinkage long sys_mkdir(const char __user * pathname, int mode)
1825 struct dentry *dentry; 1880 struct dentry *dentry;
1826 struct nameidata nd; 1881 struct nameidata nd;
1827 1882
1828 error = path_lookup(tmp, LOOKUP_PARENT, &nd); 1883 error = do_path_lookup(dfd, tmp, LOOKUP_PARENT, &nd);
1829 if (error) 1884 if (error)
1830 goto out; 1885 goto out;
1831 dentry = lookup_create(&nd, 1); 1886 dentry = lookup_create(&nd, 1);
@@ -1836,7 +1891,7 @@ asmlinkage long sys_mkdir(const char __user * pathname, int mode)
1836 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode); 1891 error = vfs_mkdir(nd.dentry->d_inode, dentry, mode);
1837 dput(dentry); 1892 dput(dentry);
1838 } 1893 }
1839 up(&nd.dentry->d_inode->i_sem); 1894 mutex_unlock(&nd.dentry->d_inode->i_mutex);
1840 path_release(&nd); 1895 path_release(&nd);
1841out: 1896out:
1842 putname(tmp); 1897 putname(tmp);
@@ -1845,6 +1900,11 @@ out:
1845 return error; 1900 return error;
1846} 1901}
1847 1902
1903asmlinkage long sys_mkdir(const char __user *pathname, int mode)
1904{
1905 return sys_mkdirat(AT_FDCWD, pathname, mode);
1906}
1907
1848/* 1908/*
1849 * We try to drop the dentry early: we should have 1909 * We try to drop the dentry early: we should have
1850 * a usage count of 2 if we're the only user of this 1910 * a usage count of 2 if we're the only user of this
@@ -1885,7 +1945,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
1885 1945
1886 DQUOT_INIT(dir); 1946 DQUOT_INIT(dir);
1887 1947
1888 down(&dentry->d_inode->i_sem); 1948 mutex_lock(&dentry->d_inode->i_mutex);
1889 dentry_unhash(dentry); 1949 dentry_unhash(dentry);
1890 if (d_mountpoint(dentry)) 1950 if (d_mountpoint(dentry))
1891 error = -EBUSY; 1951 error = -EBUSY;
@@ -1897,7 +1957,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
1897 dentry->d_inode->i_flags |= S_DEAD; 1957 dentry->d_inode->i_flags |= S_DEAD;
1898 } 1958 }
1899 } 1959 }
1900 up(&dentry->d_inode->i_sem); 1960 mutex_unlock(&dentry->d_inode->i_mutex);
1901 if (!error) { 1961 if (!error) {
1902 d_delete(dentry); 1962 d_delete(dentry);
1903 } 1963 }
@@ -1906,7 +1966,7 @@ int vfs_rmdir(struct inode *dir, struct dentry *dentry)
1906 return error; 1966 return error;
1907} 1967}
1908 1968
1909asmlinkage long sys_rmdir(const char __user * pathname) 1969static long do_rmdir(int dfd, const char __user *pathname)
1910{ 1970{
1911 int error = 0; 1971 int error = 0;
1912 char * name; 1972 char * name;
@@ -1917,7 +1977,7 @@ asmlinkage long sys_rmdir(const char __user * pathname)
1917 if(IS_ERR(name)) 1977 if(IS_ERR(name))
1918 return PTR_ERR(name); 1978 return PTR_ERR(name);
1919 1979
1920 error = path_lookup(name, LOOKUP_PARENT, &nd); 1980 error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
1921 if (error) 1981 if (error)
1922 goto exit; 1982 goto exit;
1923 1983
@@ -1932,14 +1992,14 @@ asmlinkage long sys_rmdir(const char __user * pathname)
1932 error = -EBUSY; 1992 error = -EBUSY;
1933 goto exit1; 1993 goto exit1;
1934 } 1994 }
1935 down(&nd.dentry->d_inode->i_sem); 1995 mutex_lock(&nd.dentry->d_inode->i_mutex);
1936 dentry = lookup_hash(&nd); 1996 dentry = lookup_hash(&nd);
1937 error = PTR_ERR(dentry); 1997 error = PTR_ERR(dentry);
1938 if (!IS_ERR(dentry)) { 1998 if (!IS_ERR(dentry)) {
1939 error = vfs_rmdir(nd.dentry->d_inode, dentry); 1999 error = vfs_rmdir(nd.dentry->d_inode, dentry);
1940 dput(dentry); 2000 dput(dentry);
1941 } 2001 }
1942 up(&nd.dentry->d_inode->i_sem); 2002 mutex_unlock(&nd.dentry->d_inode->i_mutex);
1943exit1: 2003exit1:
1944 path_release(&nd); 2004 path_release(&nd);
1945exit: 2005exit:
@@ -1947,6 +2007,11 @@ exit:
1947 return error; 2007 return error;
1948} 2008}
1949 2009
2010asmlinkage long sys_rmdir(const char __user *pathname)
2011{
2012 return do_rmdir(AT_FDCWD, pathname);
2013}
2014
1950int vfs_unlink(struct inode *dir, struct dentry *dentry) 2015int vfs_unlink(struct inode *dir, struct dentry *dentry)
1951{ 2016{
1952 int error = may_delete(dir, dentry, 0); 2017 int error = may_delete(dir, dentry, 0);
@@ -1959,7 +2024,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
1959 2024
1960 DQUOT_INIT(dir); 2025 DQUOT_INIT(dir);
1961 2026
1962 down(&dentry->d_inode->i_sem); 2027 mutex_lock(&dentry->d_inode->i_mutex);
1963 if (d_mountpoint(dentry)) 2028 if (d_mountpoint(dentry))
1964 error = -EBUSY; 2029 error = -EBUSY;
1965 else { 2030 else {
@@ -1967,7 +2032,7 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
1967 if (!error) 2032 if (!error)
1968 error = dir->i_op->unlink(dir, dentry); 2033 error = dir->i_op->unlink(dir, dentry);
1969 } 2034 }
1970 up(&dentry->d_inode->i_sem); 2035 mutex_unlock(&dentry->d_inode->i_mutex);
1971 2036
1972 /* We don't d_delete() NFS sillyrenamed files--they still exist. */ 2037 /* We don't d_delete() NFS sillyrenamed files--they still exist. */
1973 if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) { 2038 if (!error && !(dentry->d_flags & DCACHE_NFSFS_RENAMED)) {
@@ -1979,11 +2044,11 @@ int vfs_unlink(struct inode *dir, struct dentry *dentry)
1979 2044
1980/* 2045/*
1981 * Make sure that the actual truncation of the file will occur outside its 2046 * 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 2047 * 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 2048 * writeout happening, and we don't want to prevent access to the directory
1984 * while waiting on the I/O. 2049 * while waiting on the I/O.
1985 */ 2050 */
1986asmlinkage long sys_unlink(const char __user * pathname) 2051static long do_unlinkat(int dfd, const char __user *pathname)
1987{ 2052{
1988 int error = 0; 2053 int error = 0;
1989 char * name; 2054 char * name;
@@ -1995,13 +2060,13 @@ asmlinkage long sys_unlink(const char __user * pathname)
1995 if(IS_ERR(name)) 2060 if(IS_ERR(name))
1996 return PTR_ERR(name); 2061 return PTR_ERR(name);
1997 2062
1998 error = path_lookup(name, LOOKUP_PARENT, &nd); 2063 error = do_path_lookup(dfd, name, LOOKUP_PARENT, &nd);
1999 if (error) 2064 if (error)
2000 goto exit; 2065 goto exit;
2001 error = -EISDIR; 2066 error = -EISDIR;
2002 if (nd.last_type != LAST_NORM) 2067 if (nd.last_type != LAST_NORM)
2003 goto exit1; 2068 goto exit1;
2004 down(&nd.dentry->d_inode->i_sem); 2069 mutex_lock(&nd.dentry->d_inode->i_mutex);
2005 dentry = lookup_hash(&nd); 2070 dentry = lookup_hash(&nd);
2006 error = PTR_ERR(dentry); 2071 error = PTR_ERR(dentry);
2007 if (!IS_ERR(dentry)) { 2072 if (!IS_ERR(dentry)) {
@@ -2015,7 +2080,7 @@ asmlinkage long sys_unlink(const char __user * pathname)
2015 exit2: 2080 exit2:
2016 dput(dentry); 2081 dput(dentry);
2017 } 2082 }
2018 up(&nd.dentry->d_inode->i_sem); 2083 mutex_unlock(&nd.dentry->d_inode->i_mutex);
2019 if (inode) 2084 if (inode)
2020 iput(inode); /* truncate the inode here */ 2085 iput(inode); /* truncate the inode here */
2021exit1: 2086exit1:
@@ -2030,6 +2095,22 @@ slashes:
2030 goto exit2; 2095 goto exit2;
2031} 2096}
2032 2097
2098asmlinkage long sys_unlinkat(int dfd, const char __user *pathname, int flag)
2099{
2100 if ((flag & ~AT_REMOVEDIR) != 0)
2101 return -EINVAL;
2102
2103 if (flag & AT_REMOVEDIR)
2104 return do_rmdir(dfd, pathname);
2105
2106 return do_unlinkat(dfd, pathname);
2107}
2108
2109asmlinkage long sys_unlink(const char __user *pathname)
2110{
2111 return do_unlinkat(AT_FDCWD, pathname);
2112}
2113
2033int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode) 2114int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, int mode)
2034{ 2115{
2035 int error = may_create(dir, dentry, NULL); 2116 int error = may_create(dir, dentry, NULL);
@@ -2051,7 +2132,8 @@ int vfs_symlink(struct inode *dir, struct dentry *dentry, const char *oldname, i
2051 return error; 2132 return error;
2052} 2133}
2053 2134
2054asmlinkage long sys_symlink(const char __user * oldname, const char __user * newname) 2135asmlinkage long sys_symlinkat(const char __user *oldname,
2136 int newdfd, const char __user *newname)
2055{ 2137{
2056 int error = 0; 2138 int error = 0;
2057 char * from; 2139 char * from;
@@ -2066,7 +2148,7 @@ asmlinkage long sys_symlink(const char __user * oldname, const char __user * new
2066 struct dentry *dentry; 2148 struct dentry *dentry;
2067 struct nameidata nd; 2149 struct nameidata nd;
2068 2150
2069 error = path_lookup(to, LOOKUP_PARENT, &nd); 2151 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
2070 if (error) 2152 if (error)
2071 goto out; 2153 goto out;
2072 dentry = lookup_create(&nd, 0); 2154 dentry = lookup_create(&nd, 0);
@@ -2075,7 +2157,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); 2157 error = vfs_symlink(nd.dentry->d_inode, dentry, from, S_IALLUGO);
2076 dput(dentry); 2158 dput(dentry);
2077 } 2159 }
2078 up(&nd.dentry->d_inode->i_sem); 2160 mutex_unlock(&nd.dentry->d_inode->i_mutex);
2079 path_release(&nd); 2161 path_release(&nd);
2080out: 2162out:
2081 putname(to); 2163 putname(to);
@@ -2084,6 +2166,11 @@ out:
2084 return error; 2166 return error;
2085} 2167}
2086 2168
2169asmlinkage long sys_symlink(const char __user *oldname, const char __user *newname)
2170{
2171 return sys_symlinkat(oldname, AT_FDCWD, newname);
2172}
2173
2087int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry) 2174int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_dentry)
2088{ 2175{
2089 struct inode *inode = old_dentry->d_inode; 2176 struct inode *inode = old_dentry->d_inode;
@@ -2113,10 +2200,10 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2113 if (error) 2200 if (error)
2114 return error; 2201 return error;
2115 2202
2116 down(&old_dentry->d_inode->i_sem); 2203 mutex_lock(&old_dentry->d_inode->i_mutex);
2117 DQUOT_INIT(dir); 2204 DQUOT_INIT(dir);
2118 error = dir->i_op->link(old_dentry, dir, new_dentry); 2205 error = dir->i_op->link(old_dentry, dir, new_dentry);
2119 up(&old_dentry->d_inode->i_sem); 2206 mutex_unlock(&old_dentry->d_inode->i_mutex);
2120 if (!error) 2207 if (!error)
2121 fsnotify_create(dir, new_dentry->d_name.name); 2208 fsnotify_create(dir, new_dentry->d_name.name);
2122 return error; 2209 return error;
@@ -2131,7 +2218,8 @@ int vfs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *new_de
2131 * with linux 2.0, and to avoid hard-linking to directories 2218 * with linux 2.0, and to avoid hard-linking to directories
2132 * and other special files. --ADM 2219 * and other special files. --ADM
2133 */ 2220 */
2134asmlinkage long sys_link(const char __user * oldname, const char __user * newname) 2221asmlinkage long sys_linkat(int olddfd, const char __user *oldname,
2222 int newdfd, const char __user *newname)
2135{ 2223{
2136 struct dentry *new_dentry; 2224 struct dentry *new_dentry;
2137 struct nameidata nd, old_nd; 2225 struct nameidata nd, old_nd;
@@ -2142,10 +2230,10 @@ asmlinkage long sys_link(const char __user * oldname, const char __user * newnam
2142 if (IS_ERR(to)) 2230 if (IS_ERR(to))
2143 return PTR_ERR(to); 2231 return PTR_ERR(to);
2144 2232
2145 error = __user_walk(oldname, 0, &old_nd); 2233 error = __user_walk_fd(olddfd, oldname, 0, &old_nd);
2146 if (error) 2234 if (error)
2147 goto exit; 2235 goto exit;
2148 error = path_lookup(to, LOOKUP_PARENT, &nd); 2236 error = do_path_lookup(newdfd, to, LOOKUP_PARENT, &nd);
2149 if (error) 2237 if (error)
2150 goto out; 2238 goto out;
2151 error = -EXDEV; 2239 error = -EXDEV;
@@ -2157,7 +2245,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); 2245 error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry);
2158 dput(new_dentry); 2246 dput(new_dentry);
2159 } 2247 }
2160 up(&nd.dentry->d_inode->i_sem); 2248 mutex_unlock(&nd.dentry->d_inode->i_mutex);
2161out_release: 2249out_release:
2162 path_release(&nd); 2250 path_release(&nd);
2163out: 2251out:
@@ -2168,6 +2256,11 @@ exit:
2168 return error; 2256 return error;
2169} 2257}
2170 2258
2259asmlinkage long sys_link(const char __user *oldname, const char __user *newname)
2260{
2261 return sys_linkat(AT_FDCWD, oldname, AT_FDCWD, newname);
2262}
2263
2171/* 2264/*
2172 * The worst of all namespace operations - renaming directory. "Perverted" 2265 * The worst of all namespace operations - renaming directory. "Perverted"
2173 * doesn't even start to describe it. Somebody in UCB had a heck of a trip... 2266 * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
@@ -2178,7 +2271,7 @@ exit:
2178 * sb->s_vfs_rename_sem. We might be more accurate, but that's another 2271 * sb->s_vfs_rename_sem. We might be more accurate, but that's another
2179 * story. 2272 * story.
2180 * c) we have to lock _three_ objects - parents and victim (if it exists). 2273 * 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 2274 * 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 2275 * 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 2276 * 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 2277 * only under ->s_vfs_rename_sem _and_ that parent of the object we
@@ -2195,9 +2288,9 @@ exit:
2195 * stuff into VFS), but the former is not going away. Solution: the same 2288 * stuff into VFS), but the former is not going away. Solution: the same
2196 * trick as in rmdir(). 2289 * trick as in rmdir().
2197 * e) conversion from fhandle to dentry may come in the wrong moment - when 2290 * 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 2291 * 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 2292 * 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 2293 * ->i_mutex on parents, which works but leads to some truely excessive
2201 * locking]. 2294 * locking].
2202 */ 2295 */
2203static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, 2296static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
@@ -2222,7 +2315,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
2222 2315
2223 target = new_dentry->d_inode; 2316 target = new_dentry->d_inode;
2224 if (target) { 2317 if (target) {
2225 down(&target->i_sem); 2318 mutex_lock(&target->i_mutex);
2226 dentry_unhash(new_dentry); 2319 dentry_unhash(new_dentry);
2227 } 2320 }
2228 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) 2321 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
@@ -2232,7 +2325,7 @@ static int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry,
2232 if (target) { 2325 if (target) {
2233 if (!error) 2326 if (!error)
2234 target->i_flags |= S_DEAD; 2327 target->i_flags |= S_DEAD;
2235 up(&target->i_sem); 2328 mutex_unlock(&target->i_mutex);
2236 if (d_unhashed(new_dentry)) 2329 if (d_unhashed(new_dentry))
2237 d_rehash(new_dentry); 2330 d_rehash(new_dentry);
2238 dput(new_dentry); 2331 dput(new_dentry);
@@ -2255,7 +2348,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
2255 dget(new_dentry); 2348 dget(new_dentry);
2256 target = new_dentry->d_inode; 2349 target = new_dentry->d_inode;
2257 if (target) 2350 if (target)
2258 down(&target->i_sem); 2351 mutex_lock(&target->i_mutex);
2259 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry)) 2352 if (d_mountpoint(old_dentry)||d_mountpoint(new_dentry))
2260 error = -EBUSY; 2353 error = -EBUSY;
2261 else 2354 else
@@ -2266,7 +2359,7 @@ static int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry,
2266 d_move(old_dentry, new_dentry); 2359 d_move(old_dentry, new_dentry);
2267 } 2360 }
2268 if (target) 2361 if (target)
2269 up(&target->i_sem); 2362 mutex_unlock(&target->i_mutex);
2270 dput(new_dentry); 2363 dput(new_dentry);
2271 return error; 2364 return error;
2272} 2365}
@@ -2314,7 +2407,8 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
2314 return error; 2407 return error;
2315} 2408}
2316 2409
2317static inline int do_rename(const char * oldname, const char * newname) 2410static int do_rename(int olddfd, const char *oldname,
2411 int newdfd, const char *newname)
2318{ 2412{
2319 int error = 0; 2413 int error = 0;
2320 struct dentry * old_dir, * new_dir; 2414 struct dentry * old_dir, * new_dir;
@@ -2322,11 +2416,11 @@ static inline int do_rename(const char * oldname, const char * newname)
2322 struct dentry * trap; 2416 struct dentry * trap;
2323 struct nameidata oldnd, newnd; 2417 struct nameidata oldnd, newnd;
2324 2418
2325 error = path_lookup(oldname, LOOKUP_PARENT, &oldnd); 2419 error = do_path_lookup(olddfd, oldname, LOOKUP_PARENT, &oldnd);
2326 if (error) 2420 if (error)
2327 goto exit; 2421 goto exit;
2328 2422
2329 error = path_lookup(newname, LOOKUP_PARENT, &newnd); 2423 error = do_path_lookup(newdfd, newname, LOOKUP_PARENT, &newnd);
2330 if (error) 2424 if (error)
2331 goto exit1; 2425 goto exit1;
2332 2426
@@ -2390,7 +2484,8 @@ exit:
2390 return error; 2484 return error;
2391} 2485}
2392 2486
2393asmlinkage long sys_rename(const char __user * oldname, const char __user * newname) 2487asmlinkage long sys_renameat(int olddfd, const char __user *oldname,
2488 int newdfd, const char __user *newname)
2394{ 2489{
2395 int error; 2490 int error;
2396 char * from; 2491 char * from;
@@ -2402,13 +2497,18 @@ asmlinkage long sys_rename(const char __user * oldname, const char __user * newn
2402 to = getname(newname); 2497 to = getname(newname);
2403 error = PTR_ERR(to); 2498 error = PTR_ERR(to);
2404 if (!IS_ERR(to)) { 2499 if (!IS_ERR(to)) {
2405 error = do_rename(from,to); 2500 error = do_rename(olddfd, from, newdfd, to);
2406 putname(to); 2501 putname(to);
2407 } 2502 }
2408 putname(from); 2503 putname(from);
2409 return error; 2504 return error;
2410} 2505}
2411 2506
2507asmlinkage long sys_rename(const char __user *oldname, const char __user *newname)
2508{
2509 return sys_renameat(AT_FDCWD, oldname, AT_FDCWD, newname);
2510}
2511
2412int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link) 2512int vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen, const char *link)
2413{ 2513{
2414 int len; 2514 int len;
@@ -2552,6 +2652,7 @@ struct inode_operations page_symlink_inode_operations = {
2552}; 2652};
2553 2653
2554EXPORT_SYMBOL(__user_walk); 2654EXPORT_SYMBOL(__user_walk);
2655EXPORT_SYMBOL(__user_walk_fd);
2555EXPORT_SYMBOL(follow_down); 2656EXPORT_SYMBOL(follow_down);
2556EXPORT_SYMBOL(follow_up); 2657EXPORT_SYMBOL(follow_up);
2557EXPORT_SYMBOL(get_write_access); /* binfmt_aout */ 2658EXPORT_SYMBOL(get_write_access); /* binfmt_aout */