aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namei.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namei.c')
-rw-r--r--fs/namei.c226
1 files changed, 170 insertions, 56 deletions
diff --git a/fs/namei.c b/fs/namei.c
index 529e917ad2fc..16109da68bbf 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -896,51 +896,120 @@ int follow_up(struct path *path)
896} 896}
897 897
898/* 898/*
899 * serialization is taken care of in namespace.c 899 * Perform an automount
900 * - return -EISDIR to tell follow_managed() to stop and return the path we
901 * were called with.
900 */ 902 */
901static void __follow_mount_rcu(struct nameidata *nd, struct path *path, 903static int follow_automount(struct path *path, unsigned flags,
902 struct inode **inode) 904 bool *need_mntput)
903{ 905{
904 while (d_mountpoint(path->dentry)) { 906 struct vfsmount *mnt;
905 struct vfsmount *mounted; 907
906 mounted = __lookup_mnt(path->mnt, path->dentry, 1); 908 if (!path->dentry->d_op || !path->dentry->d_op->d_automount)
907 if (!mounted) 909 return -EREMOTE;
908 return; 910
909 path->mnt = mounted; 911 /* We want to mount if someone is trying to open/create a file of any
910 path->dentry = mounted->mnt_root; 912 * type under the mountpoint, wants to traverse through the mountpoint
911 nd->seq = read_seqcount_begin(&path->dentry->d_seq); 913 * or wants to open the mounted directory.
912 *inode = path->dentry->d_inode; 914 *
915 * We don't want to mount if someone's just doing a stat and they've
916 * set AT_SYMLINK_NOFOLLOW - unless they're stat'ing a directory and
917 * appended a '/' to the name.
918 */
919 if (!(flags & LOOKUP_FOLLOW) &&
920 !(flags & (LOOKUP_CONTINUE | LOOKUP_DIRECTORY |
921 LOOKUP_OPEN | LOOKUP_CREATE)))
922 return -EISDIR;
923
924 current->total_link_count++;
925 if (current->total_link_count >= 40)
926 return -ELOOP;
927
928 mnt = path->dentry->d_op->d_automount(path);
929 if (IS_ERR(mnt)) {
930 /*
931 * The filesystem is allowed to return -EISDIR here to indicate
932 * it doesn't want to automount. For instance, autofs would do
933 * this so that its userspace daemon can mount on this dentry.
934 *
935 * However, we can only permit this if it's a terminal point in
936 * the path being looked up; if it wasn't then the remainder of
937 * the path is inaccessible and we should say so.
938 */
939 if (PTR_ERR(mnt) == -EISDIR && (flags & LOOKUP_CONTINUE))
940 return -EREMOTE;
941 return PTR_ERR(mnt);
913 } 942 }
914} 943 if (!mnt) /* mount collision */
944 return 0;
915 945
916static int __follow_mount(struct path *path) 946 if (mnt->mnt_sb == path->mnt->mnt_sb &&
917{ 947 mnt->mnt_root == path->dentry) {
918 int res = 0; 948 mntput(mnt);
919 while (d_mountpoint(path->dentry)) { 949 return -ELOOP;
920 struct vfsmount *mounted = lookup_mnt(path);
921 if (!mounted)
922 break;
923 dput(path->dentry);
924 if (res)
925 mntput(path->mnt);
926 path->mnt = mounted;
927 path->dentry = dget(mounted->mnt_root);
928 res = 1;
929 } 950 }
930 return res; 951
952 dput(path->dentry);
953 if (*need_mntput)
954 mntput(path->mnt);
955 path->mnt = mnt;
956 path->dentry = dget(mnt->mnt_root);
957 *need_mntput = true;
958 return 0;
931} 959}
932 960
933static void follow_mount(struct path *path) 961/*
962 * Handle a dentry that is managed in some way.
963 * - Flagged as mountpoint
964 * - Flagged as automount point
965 *
966 * This may only be called in refwalk mode.
967 *
968 * Serialization is taken care of in namespace.c
969 */
970static int follow_managed(struct path *path, unsigned flags)
934{ 971{
935 while (d_mountpoint(path->dentry)) { 972 unsigned managed;
936 struct vfsmount *mounted = lookup_mnt(path); 973 bool need_mntput = false;
937 if (!mounted) 974 int ret;
938 break; 975
939 dput(path->dentry); 976 /* Given that we're not holding a lock here, we retain the value in a
940 mntput(path->mnt); 977 * local variable for each dentry as we look at it so that we don't see
941 path->mnt = mounted; 978 * the components of that value change under us */
942 path->dentry = dget(mounted->mnt_root); 979 while (managed = ACCESS_ONCE(path->dentry->d_flags),
980 managed &= DCACHE_MANAGED_DENTRY,
981 unlikely(managed != 0)) {
982 /* Transit to a mounted filesystem. */
983 if (managed & DCACHE_MOUNTED) {
984 struct vfsmount *mounted = lookup_mnt(path);
985 if (mounted) {
986 dput(path->dentry);
987 if (need_mntput)
988 mntput(path->mnt);
989 path->mnt = mounted;
990 path->dentry = dget(mounted->mnt_root);
991 need_mntput = true;
992 continue;
993 }
994
995 /* Something is mounted on this dentry in another
996 * namespace and/or whatever was mounted there in this
997 * namespace got unmounted before we managed to get the
998 * vfsmount_lock */
999 }
1000
1001 /* Handle an automount point */
1002 if (managed & DCACHE_NEED_AUTOMOUNT) {
1003 ret = follow_automount(path, flags, &need_mntput);
1004 if (ret < 0)
1005 return ret == -EISDIR ? 0 : ret;
1006 continue;
1007 }
1008
1009 /* We didn't change the current path point */
1010 break;
943 } 1011 }
1012 return 0;
944} 1013}
945 1014
946int follow_down(struct path *path) 1015int follow_down(struct path *path)
@@ -958,13 +1027,37 @@ int follow_down(struct path *path)
958 return 0; 1027 return 0;
959} 1028}
960 1029
1030/*
1031 * Skip to top of mountpoint pile in rcuwalk mode. We abort the rcu-walk if we
1032 * meet an automount point and we're not walking to "..". True is returned to
1033 * continue, false to abort.
1034 */
1035static bool __follow_mount_rcu(struct nameidata *nd, struct path *path,
1036 struct inode **inode, bool reverse_transit)
1037{
1038 while (d_mountpoint(path->dentry)) {
1039 struct vfsmount *mounted;
1040 mounted = __lookup_mnt(path->mnt, path->dentry, 1);
1041 if (!mounted)
1042 break;
1043 path->mnt = mounted;
1044 path->dentry = mounted->mnt_root;
1045 nd->seq = read_seqcount_begin(&path->dentry->d_seq);
1046 *inode = path->dentry->d_inode;
1047 }
1048
1049 if (unlikely(path->dentry->d_flags & DCACHE_NEED_AUTOMOUNT))
1050 return reverse_transit;
1051 return true;
1052}
1053
961static int follow_dotdot_rcu(struct nameidata *nd) 1054static int follow_dotdot_rcu(struct nameidata *nd)
962{ 1055{
963 struct inode *inode = nd->inode; 1056 struct inode *inode = nd->inode;
964 1057
965 set_root_rcu(nd); 1058 set_root_rcu(nd);
966 1059
967 while(1) { 1060 while (1) {
968 if (nd->path.dentry == nd->root.dentry && 1061 if (nd->path.dentry == nd->root.dentry &&
969 nd->path.mnt == nd->root.mnt) { 1062 nd->path.mnt == nd->root.mnt) {
970 break; 1063 break;
@@ -987,12 +1080,28 @@ static int follow_dotdot_rcu(struct nameidata *nd)
987 nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq); 1080 nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
988 inode = nd->path.dentry->d_inode; 1081 inode = nd->path.dentry->d_inode;
989 } 1082 }
990 __follow_mount_rcu(nd, &nd->path, &inode); 1083 __follow_mount_rcu(nd, &nd->path, &inode, true);
991 nd->inode = inode; 1084 nd->inode = inode;
992 1085
993 return 0; 1086 return 0;
994} 1087}
995 1088
1089/*
1090 * Skip to top of mountpoint pile in refwalk mode for follow_dotdot()
1091 */
1092static void follow_mount(struct path *path)
1093{
1094 while (d_mountpoint(path->dentry)) {
1095 struct vfsmount *mounted = lookup_mnt(path);
1096 if (!mounted)
1097 break;
1098 dput(path->dentry);
1099 mntput(path->mnt);
1100 path->mnt = mounted;
1101 path->dentry = dget(mounted->mnt_root);
1102 }
1103}
1104
996static void follow_dotdot(struct nameidata *nd) 1105static void follow_dotdot(struct nameidata *nd)
997{ 1106{
998 set_root(nd); 1107 set_root(nd);
@@ -1057,12 +1166,14 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
1057 struct vfsmount *mnt = nd->path.mnt; 1166 struct vfsmount *mnt = nd->path.mnt;
1058 struct dentry *dentry, *parent = nd->path.dentry; 1167 struct dentry *dentry, *parent = nd->path.dentry;
1059 struct inode *dir; 1168 struct inode *dir;
1169 int err;
1170
1060 /* 1171 /*
1061 * See if the low-level filesystem might want 1172 * See if the low-level filesystem might want
1062 * to use its own hash.. 1173 * to use its own hash..
1063 */ 1174 */
1064 if (unlikely(parent->d_flags & DCACHE_OP_HASH)) { 1175 if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
1065 int err = parent->d_op->d_hash(parent, nd->inode, name); 1176 err = parent->d_op->d_hash(parent, nd->inode, name);
1066 if (err < 0) 1177 if (err < 0)
1067 return err; 1178 return err;
1068 } 1179 }
@@ -1092,20 +1203,25 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
1092done2: 1203done2:
1093 path->mnt = mnt; 1204 path->mnt = mnt;
1094 path->dentry = dentry; 1205 path->dentry = dentry;
1095 __follow_mount_rcu(nd, path, inode); 1206 if (likely(__follow_mount_rcu(nd, path, inode, false)))
1096 } else { 1207 return 0;
1097 dentry = __d_lookup(parent, name); 1208 if (nameidata_drop_rcu(nd))
1098 if (!dentry) 1209 return -ECHILD;
1099 goto need_lookup; 1210 /* fallthru */
1211 }
1212 dentry = __d_lookup(parent, name);
1213 if (!dentry)
1214 goto need_lookup;
1100found: 1215found:
1101 if (dentry->d_flags & DCACHE_OP_REVALIDATE) 1216 if (dentry->d_flags & DCACHE_OP_REVALIDATE)
1102 goto need_revalidate; 1217 goto need_revalidate;
1103done: 1218done:
1104 path->mnt = mnt; 1219 path->mnt = mnt;
1105 path->dentry = dentry; 1220 path->dentry = dentry;
1106 __follow_mount(path); 1221 err = follow_managed(path, nd->flags);
1107 *inode = path->dentry->d_inode; 1222 if (unlikely(err < 0))
1108 } 1223 return err;
1224 *inode = path->dentry->d_inode;
1109 return 0; 1225 return 0;
1110 1226
1111need_lookup: 1227need_lookup:
@@ -2203,11 +2319,9 @@ static struct file *do_last(struct nameidata *nd, struct path *path,
2203 if (open_flag & O_EXCL) 2319 if (open_flag & O_EXCL)
2204 goto exit_dput; 2320 goto exit_dput;
2205 2321
2206 if (__follow_mount(path)) { 2322 error = follow_managed(path, nd->flags);
2207 error = -ELOOP; 2323 if (error < 0)
2208 if (open_flag & O_NOFOLLOW) 2324 goto exit_dput;
2209 goto exit_dput;
2210 }
2211 2325
2212 error = -ENOENT; 2326 error = -ENOENT;
2213 if (!path->dentry->d_inode) 2327 if (!path->dentry->d_inode)