aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2013-09-12 14:22:53 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2013-11-09 00:16:30 -0500
commitb18825a7c8e37a7cf6abb97a12a6ad71af160de7 (patch)
treec3556fc0195f15382d636188f3d4e5fa418d7379 /fs/namei.c
parentafabada957a6b28abfd37eb52efeefdfe6871c4b (diff)
VFS: Put a small type field into struct dentry::d_flags
Put a type field into struct dentry::d_flags to indicate if the dentry is one of the following types that relate particularly to pathwalk: Miss (negative dentry) Directory "Automount" directory (defective - no i_op->lookup()) Symlink Other (regular, socket, fifo, device) The type field is set to one of the first five types on a dentry by calls to __d_instantiate() and d_obtain_alias() from information in the inode (if one is given). The type is cleared by dentry_unlink_inode() when it reconstitutes an existing dentry as a negative dentry. Accessors provided are: d_set_type(dentry, type) d_is_directory(dentry) d_is_autodir(dentry) d_is_symlink(dentry) d_is_file(dentry) d_is_negative(dentry) d_is_positive(dentry) A bunch of checks in pathname resolution switched to those. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c95
1 files changed, 38 insertions, 57 deletions
diff --git a/fs/namei.c b/fs/namei.c
index e5c0118ba9f8..e1fa43346c61 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1501,18 +1501,9 @@ static void terminate_walk(struct nameidata *nd)
1501 * so we keep a cache of "no, this doesn't need follow_link" 1501 * so we keep a cache of "no, this doesn't need follow_link"
1502 * for the common case. 1502 * for the common case.
1503 */ 1503 */
1504static inline int should_follow_link(struct inode *inode, int follow) 1504static inline int should_follow_link(struct dentry *dentry, int follow)
1505{ 1505{
1506 if (unlikely(!(inode->i_opflags & IOP_NOFOLLOW))) { 1506 return unlikely(d_is_symlink(dentry)) ? follow : 0;
1507 if (likely(inode->i_op->follow_link))
1508 return follow;
1509
1510 /* This gets set once for the inode lifetime */
1511 spin_lock(&inode->i_lock);
1512 inode->i_opflags |= IOP_NOFOLLOW;
1513 spin_unlock(&inode->i_lock);
1514 }
1515 return 0;
1516} 1507}
1517 1508
1518static inline int walk_component(struct nameidata *nd, struct path *path, 1509static inline int walk_component(struct nameidata *nd, struct path *path,
@@ -1542,7 +1533,7 @@ static inline int walk_component(struct nameidata *nd, struct path *path,
1542 if (!inode) 1533 if (!inode)
1543 goto out_path_put; 1534 goto out_path_put;
1544 1535
1545 if (should_follow_link(inode, follow)) { 1536 if (should_follow_link(path->dentry, follow)) {
1546 if (nd->flags & LOOKUP_RCU) { 1537 if (nd->flags & LOOKUP_RCU) {
1547 if (unlikely(unlazy_walk(nd, path->dentry))) { 1538 if (unlikely(unlazy_walk(nd, path->dentry))) {
1548 err = -ECHILD; 1539 err = -ECHILD;
@@ -1601,26 +1592,6 @@ static inline int nested_symlink(struct path *path, struct nameidata *nd)
1601} 1592}
1602 1593
1603/* 1594/*
1604 * We really don't want to look at inode->i_op->lookup
1605 * when we don't have to. So we keep a cache bit in
1606 * the inode ->i_opflags field that says "yes, we can
1607 * do lookup on this inode".
1608 */
1609static inline int can_lookup(struct inode *inode)
1610{
1611 if (likely(inode->i_opflags & IOP_LOOKUP))
1612 return 1;
1613 if (likely(!inode->i_op->lookup))
1614 return 0;
1615
1616 /* We do this once for the lifetime of the inode */
1617 spin_lock(&inode->i_lock);
1618 inode->i_opflags |= IOP_LOOKUP;
1619 spin_unlock(&inode->i_lock);
1620 return 1;
1621}
1622
1623/*
1624 * We can do the critical dentry name comparison and hashing 1595 * We can do the critical dentry name comparison and hashing
1625 * operations one word at a time, but we are limited to: 1596 * operations one word at a time, but we are limited to:
1626 * 1597 *
@@ -1823,7 +1794,7 @@ static int link_path_walk(const char *name, struct nameidata *nd)
1823 if (err) 1794 if (err)
1824 return err; 1795 return err;
1825 } 1796 }
1826 if (!can_lookup(nd->inode)) { 1797 if (!d_is_directory(nd->path.dentry)) {
1827 err = -ENOTDIR; 1798 err = -ENOTDIR;
1828 break; 1799 break;
1829 } 1800 }
@@ -1841,9 +1812,10 @@ static int path_init(int dfd, const char *name, unsigned int flags,
1841 nd->flags = flags | LOOKUP_JUMPED; 1812 nd->flags = flags | LOOKUP_JUMPED;
1842 nd->depth = 0; 1813 nd->depth = 0;
1843 if (flags & LOOKUP_ROOT) { 1814 if (flags & LOOKUP_ROOT) {
1844 struct inode *inode = nd->root.dentry->d_inode; 1815 struct dentry *root = nd->root.dentry;
1816 struct inode *inode = root->d_inode;
1845 if (*name) { 1817 if (*name) {
1846 if (!can_lookup(inode)) 1818 if (!d_is_directory(root))
1847 return -ENOTDIR; 1819 return -ENOTDIR;
1848 retval = inode_permission(inode, MAY_EXEC); 1820 retval = inode_permission(inode, MAY_EXEC);
1849 if (retval) 1821 if (retval)
@@ -1899,7 +1871,7 @@ static int path_init(int dfd, const char *name, unsigned int flags,
1899 dentry = f.file->f_path.dentry; 1871 dentry = f.file->f_path.dentry;
1900 1872
1901 if (*name) { 1873 if (*name) {
1902 if (!can_lookup(dentry->d_inode)) { 1874 if (!d_is_directory(dentry)) {
1903 fdput(f); 1875 fdput(f);
1904 return -ENOTDIR; 1876 return -ENOTDIR;
1905 } 1877 }
@@ -1981,7 +1953,7 @@ static int path_lookupat(int dfd, const char *name,
1981 err = complete_walk(nd); 1953 err = complete_walk(nd);
1982 1954
1983 if (!err && nd->flags & LOOKUP_DIRECTORY) { 1955 if (!err && nd->flags & LOOKUP_DIRECTORY) {
1984 if (!can_lookup(nd->inode)) { 1956 if (!d_is_directory(nd->path.dentry)) {
1985 path_put(&nd->path); 1957 path_put(&nd->path);
1986 err = -ENOTDIR; 1958 err = -ENOTDIR;
1987 } 1959 }
@@ -2273,7 +2245,7 @@ done:
2273 } 2245 }
2274 path->dentry = dentry; 2246 path->dentry = dentry;
2275 path->mnt = mntget(nd->path.mnt); 2247 path->mnt = mntget(nd->path.mnt);
2276 if (should_follow_link(dentry->d_inode, nd->flags & LOOKUP_FOLLOW)) 2248 if (should_follow_link(dentry, nd->flags & LOOKUP_FOLLOW))
2277 return 1; 2249 return 1;
2278 follow_mount(path); 2250 follow_mount(path);
2279 error = 0; 2251 error = 0;
@@ -2417,12 +2389,14 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
2417 * 10. We don't allow removal of NFS sillyrenamed files; it's handled by 2389 * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
2418 * nfs_async_unlink(). 2390 * nfs_async_unlink().
2419 */ 2391 */
2420static int may_delete(struct inode *dir,struct dentry *victim,int isdir) 2392static int may_delete(struct inode *dir, struct dentry *victim, bool isdir)
2421{ 2393{
2394 struct inode *inode = victim->d_inode;
2422 int error; 2395 int error;
2423 2396
2424 if (!victim->d_inode) 2397 if (d_is_negative(victim))
2425 return -ENOENT; 2398 return -ENOENT;
2399 BUG_ON(!inode);
2426 2400
2427 BUG_ON(victim->d_parent->d_inode != dir); 2401 BUG_ON(victim->d_parent->d_inode != dir);
2428 audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE); 2402 audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
@@ -2432,15 +2406,16 @@ static int may_delete(struct inode *dir,struct dentry *victim,int isdir)
2432 return error; 2406 return error;
2433 if (IS_APPEND(dir)) 2407 if (IS_APPEND(dir))
2434 return -EPERM; 2408 return -EPERM;
2435 if (check_sticky(dir, victim->d_inode)||IS_APPEND(victim->d_inode)|| 2409
2436 IS_IMMUTABLE(victim->d_inode) || IS_SWAPFILE(victim->d_inode)) 2410 if (check_sticky(dir, inode) || IS_APPEND(inode) ||
2411 IS_IMMUTABLE(inode) || IS_SWAPFILE(inode))
2437 return -EPERM; 2412 return -EPERM;
2438 if (isdir) { 2413 if (isdir) {
2439 if (!S_ISDIR(victim->d_inode->i_mode)) 2414 if (!d_is_directory(victim) && !d_is_autodir(victim))
2440 return -ENOTDIR; 2415 return -ENOTDIR;
2441 if (IS_ROOT(victim)) 2416 if (IS_ROOT(victim))
2442 return -EBUSY; 2417 return -EBUSY;
2443 } else if (S_ISDIR(victim->d_inode->i_mode)) 2418 } else if (d_is_directory(victim) || d_is_autodir(victim))
2444 return -EISDIR; 2419 return -EISDIR;
2445 if (IS_DEADDIR(dir)) 2420 if (IS_DEADDIR(dir))
2446 return -ENOENT; 2421 return -ENOENT;
@@ -2974,7 +2949,7 @@ retry_lookup:
2974 /* 2949 /*
2975 * create/update audit record if it already exists. 2950 * create/update audit record if it already exists.
2976 */ 2951 */
2977 if (path->dentry->d_inode) 2952 if (d_is_positive(path->dentry))
2978 audit_inode(name, path->dentry, 0); 2953 audit_inode(name, path->dentry, 0);
2979 2954
2980 /* 2955 /*
@@ -3003,12 +2978,12 @@ retry_lookup:
3003finish_lookup: 2978finish_lookup:
3004 /* we _can_ be in RCU mode here */ 2979 /* we _can_ be in RCU mode here */
3005 error = -ENOENT; 2980 error = -ENOENT;
3006 if (!inode) { 2981 if (d_is_negative(path->dentry)) {
3007 path_to_nameidata(path, nd); 2982 path_to_nameidata(path, nd);
3008 goto out; 2983 goto out;
3009 } 2984 }
3010 2985
3011 if (should_follow_link(inode, !symlink_ok)) { 2986 if (should_follow_link(path->dentry, !symlink_ok)) {
3012 if (nd->flags & LOOKUP_RCU) { 2987 if (nd->flags & LOOKUP_RCU) {
3013 if (unlikely(unlazy_walk(nd, path->dentry))) { 2988 if (unlikely(unlazy_walk(nd, path->dentry))) {
3014 error = -ECHILD; 2989 error = -ECHILD;
@@ -3037,10 +3012,11 @@ finish_open:
3037 } 3012 }
3038 audit_inode(name, nd->path.dentry, 0); 3013 audit_inode(name, nd->path.dentry, 0);
3039 error = -EISDIR; 3014 error = -EISDIR;
3040 if ((open_flag & O_CREAT) && S_ISDIR(nd->inode->i_mode)) 3015 if ((open_flag & O_CREAT) &&
3016 (d_is_directory(nd->path.dentry) || d_is_autodir(nd->path.dentry)))
3041 goto out; 3017 goto out;
3042 error = -ENOTDIR; 3018 error = -ENOTDIR;
3043 if ((nd->flags & LOOKUP_DIRECTORY) && !can_lookup(nd->inode)) 3019 if ((nd->flags & LOOKUP_DIRECTORY) && !d_is_directory(nd->path.dentry))
3044 goto out; 3020 goto out;
3045 if (!S_ISREG(nd->inode->i_mode)) 3021 if (!S_ISREG(nd->inode->i_mode))
3046 will_truncate = false; 3022 will_truncate = false;
@@ -3266,7 +3242,7 @@ struct file *do_file_open_root(struct dentry *dentry, struct vfsmount *mnt,
3266 nd.root.mnt = mnt; 3242 nd.root.mnt = mnt;
3267 nd.root.dentry = dentry; 3243 nd.root.dentry = dentry;
3268 3244
3269 if (dentry->d_inode->i_op->follow_link && op->intent & LOOKUP_OPEN) 3245 if (d_is_symlink(dentry) && op->intent & LOOKUP_OPEN)
3270 return ERR_PTR(-ELOOP); 3246 return ERR_PTR(-ELOOP);
3271 3247
3272 file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU); 3248 file = path_openat(-1, &filename, &nd, op, flags | LOOKUP_RCU);
@@ -3316,8 +3292,9 @@ struct dentry *kern_path_create(int dfd, const char *pathname,
3316 goto unlock; 3292 goto unlock;
3317 3293
3318 error = -EEXIST; 3294 error = -EEXIST;
3319 if (dentry->d_inode) 3295 if (d_is_positive(dentry))
3320 goto fail; 3296 goto fail;
3297
3321 /* 3298 /*
3322 * Special case - lookup gave negative, but... we had foo/bar/ 3299 * Special case - lookup gave negative, but... we had foo/bar/
3323 * From the vfs_mknod() POV we just have a negative dentry - 3300 * From the vfs_mknod() POV we just have a negative dentry -
@@ -3706,7 +3683,7 @@ retry:
3706 if (nd.last.name[nd.last.len]) 3683 if (nd.last.name[nd.last.len])
3707 goto slashes; 3684 goto slashes;
3708 inode = dentry->d_inode; 3685 inode = dentry->d_inode;
3709 if (!inode) 3686 if (d_is_negative(dentry))
3710 goto slashes; 3687 goto slashes;
3711 ihold(inode); 3688 ihold(inode);
3712 error = security_path_unlink(&nd.path, dentry); 3689 error = security_path_unlink(&nd.path, dentry);
@@ -3731,8 +3708,12 @@ exit1:
3731 return error; 3708 return error;
3732 3709
3733slashes: 3710slashes:
3734 error = !dentry->d_inode ? -ENOENT : 3711 if (d_is_negative(dentry))
3735 S_ISDIR(dentry->d_inode->i_mode) ? -EISDIR : -ENOTDIR; 3712 error = -ENOENT;
3713 else if (d_is_directory(dentry) || d_is_autodir(dentry))
3714 error = -EISDIR;
3715 else
3716 error = -ENOTDIR;
3736 goto exit2; 3717 goto exit2;
3737} 3718}
3738 3719
@@ -4046,7 +4027,7 @@ int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,
4046 struct inode *new_dir, struct dentry *new_dentry) 4027 struct inode *new_dir, struct dentry *new_dentry)
4047{ 4028{
4048 int error; 4029 int error;
4049 int is_dir = S_ISDIR(old_dentry->d_inode->i_mode); 4030 int is_dir = d_is_directory(old_dentry) || d_is_autodir(old_dentry);
4050 const unsigned char *old_name; 4031 const unsigned char *old_name;
4051 4032
4052 if (old_dentry->d_inode == new_dentry->d_inode) 4033 if (old_dentry->d_inode == new_dentry->d_inode)
@@ -4134,10 +4115,10 @@ retry:
4134 goto exit3; 4115 goto exit3;
4135 /* source must exist */ 4116 /* source must exist */
4136 error = -ENOENT; 4117 error = -ENOENT;
4137 if (!old_dentry->d_inode) 4118 if (d_is_negative(old_dentry))
4138 goto exit4; 4119 goto exit4;
4139 /* unless the source is a directory trailing slashes give -ENOTDIR */ 4120 /* unless the source is a directory trailing slashes give -ENOTDIR */
4140 if (!S_ISDIR(old_dentry->d_inode->i_mode)) { 4121 if (!d_is_directory(old_dentry) && !d_is_autodir(old_dentry)) {
4141 error = -ENOTDIR; 4122 error = -ENOTDIR;
4142 if (oldnd.last.name[oldnd.last.len]) 4123 if (oldnd.last.name[oldnd.last.len])
4143 goto exit4; 4124 goto exit4;