aboutsummaryrefslogtreecommitdiffstats
path: root/fs/namespace.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/namespace.c')
-rw-r--r--fs/namespace.c195
1 files changed, 89 insertions, 106 deletions
diff --git a/fs/namespace.c b/fs/namespace.c
index 1e4a5fe3d7b7..c53d3381b0d0 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -515,8 +515,20 @@ struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry,
515} 515}
516 516
517/* 517/*
518 * lookup_mnt increments the ref count before returning 518 * lookup_mnt - Return the first child mount mounted at path
519 * the vfsmount struct. 519 *
520 * "First" means first mounted chronologically. If you create the
521 * following mounts:
522 *
523 * mount /dev/sda1 /mnt
524 * mount /dev/sda2 /mnt
525 * mount /dev/sda3 /mnt
526 *
527 * Then lookup_mnt() on the base /mnt dentry in the root mount will
528 * return successively the root dentry and vfsmount of /dev/sda1, then
529 * /dev/sda2, then /dev/sda3, then NULL.
530 *
531 * lookup_mnt takes a reference to the found vfsmount.
520 */ 532 */
521struct vfsmount *lookup_mnt(struct path *path) 533struct vfsmount *lookup_mnt(struct path *path)
522{ 534{
@@ -621,21 +633,6 @@ static void attach_mnt(struct mount *mnt, struct path *path)
621 list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts); 633 list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts);
622} 634}
623 635
624static inline void __mnt_make_longterm(struct mount *mnt)
625{
626#ifdef CONFIG_SMP
627 atomic_inc(&mnt->mnt_longterm);
628#endif
629}
630
631/* needs vfsmount lock for write */
632static inline void __mnt_make_shortterm(struct mount *mnt)
633{
634#ifdef CONFIG_SMP
635 atomic_dec(&mnt->mnt_longterm);
636#endif
637}
638
639/* 636/*
640 * vfsmount lock must be held for write 637 * vfsmount lock must be held for write
641 */ 638 */
@@ -649,10 +646,8 @@ static void commit_tree(struct mount *mnt)
649 BUG_ON(parent == mnt); 646 BUG_ON(parent == mnt);
650 647
651 list_add_tail(&head, &mnt->mnt_list); 648 list_add_tail(&head, &mnt->mnt_list);
652 list_for_each_entry(m, &head, mnt_list) { 649 list_for_each_entry(m, &head, mnt_list)
653 m->mnt_ns = n; 650 m->mnt_ns = n;
654 __mnt_make_longterm(m);
655 }
656 651
657 list_splice(&head, n->list.prev); 652 list_splice(&head, n->list.prev);
658 653
@@ -725,56 +720,60 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root,
725 int flag) 720 int flag)
726{ 721{
727 struct super_block *sb = old->mnt.mnt_sb; 722 struct super_block *sb = old->mnt.mnt_sb;
728 struct mount *mnt = alloc_vfsmnt(old->mnt_devname); 723 struct mount *mnt;
724 int err;
729 725
730 if (mnt) { 726 mnt = alloc_vfsmnt(old->mnt_devname);
731 if (flag & (CL_SLAVE | CL_PRIVATE)) 727 if (!mnt)
732 mnt->mnt_group_id = 0; /* not a peer of original */ 728 return ERR_PTR(-ENOMEM);
733 else
734 mnt->mnt_group_id = old->mnt_group_id;
735
736 if ((flag & CL_MAKE_SHARED) && !mnt->mnt_group_id) {
737 int err = mnt_alloc_group_id(mnt);
738 if (err)
739 goto out_free;
740 }
741 729
742 mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD; 730 if (flag & (CL_SLAVE | CL_PRIVATE))
743 atomic_inc(&sb->s_active); 731 mnt->mnt_group_id = 0; /* not a peer of original */
744 mnt->mnt.mnt_sb = sb; 732 else
745 mnt->mnt.mnt_root = dget(root); 733 mnt->mnt_group_id = old->mnt_group_id;
746 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
747 mnt->mnt_parent = mnt;
748 br_write_lock(&vfsmount_lock);
749 list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
750 br_write_unlock(&vfsmount_lock);
751 734
752 if (flag & CL_SLAVE) { 735 if ((flag & CL_MAKE_SHARED) && !mnt->mnt_group_id) {
753 list_add(&mnt->mnt_slave, &old->mnt_slave_list); 736 err = mnt_alloc_group_id(mnt);
754 mnt->mnt_master = old; 737 if (err)
755 CLEAR_MNT_SHARED(mnt); 738 goto out_free;
756 } else if (!(flag & CL_PRIVATE)) {
757 if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old))
758 list_add(&mnt->mnt_share, &old->mnt_share);
759 if (IS_MNT_SLAVE(old))
760 list_add(&mnt->mnt_slave, &old->mnt_slave);
761 mnt->mnt_master = old->mnt_master;
762 }
763 if (flag & CL_MAKE_SHARED)
764 set_mnt_shared(mnt);
765
766 /* stick the duplicate mount on the same expiry list
767 * as the original if that was on one */
768 if (flag & CL_EXPIRE) {
769 if (!list_empty(&old->mnt_expire))
770 list_add(&mnt->mnt_expire, &old->mnt_expire);
771 }
772 } 739 }
740
741 mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD;
742 atomic_inc(&sb->s_active);
743 mnt->mnt.mnt_sb = sb;
744 mnt->mnt.mnt_root = dget(root);
745 mnt->mnt_mountpoint = mnt->mnt.mnt_root;
746 mnt->mnt_parent = mnt;
747 br_write_lock(&vfsmount_lock);
748 list_add_tail(&mnt->mnt_instance, &sb->s_mounts);
749 br_write_unlock(&vfsmount_lock);
750
751 if (flag & CL_SLAVE) {
752 list_add(&mnt->mnt_slave, &old->mnt_slave_list);
753 mnt->mnt_master = old;
754 CLEAR_MNT_SHARED(mnt);
755 } else if (!(flag & CL_PRIVATE)) {
756 if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old))
757 list_add(&mnt->mnt_share, &old->mnt_share);
758 if (IS_MNT_SLAVE(old))
759 list_add(&mnt->mnt_slave, &old->mnt_slave);
760 mnt->mnt_master = old->mnt_master;
761 }
762 if (flag & CL_MAKE_SHARED)
763 set_mnt_shared(mnt);
764
765 /* stick the duplicate mount on the same expiry list
766 * as the original if that was on one */
767 if (flag & CL_EXPIRE) {
768 if (!list_empty(&old->mnt_expire))
769 list_add(&mnt->mnt_expire, &old->mnt_expire);
770 }
771
773 return mnt; 772 return mnt;
774 773
775 out_free: 774 out_free:
776 free_vfsmnt(mnt); 775 free_vfsmnt(mnt);
777 return NULL; 776 return ERR_PTR(err);
778} 777}
779 778
780static inline void mntfree(struct mount *mnt) 779static inline void mntfree(struct mount *mnt)
@@ -804,7 +803,8 @@ static void mntput_no_expire(struct mount *mnt)
804put_again: 803put_again:
805#ifdef CONFIG_SMP 804#ifdef CONFIG_SMP
806 br_read_lock(&vfsmount_lock); 805 br_read_lock(&vfsmount_lock);
807 if (likely(atomic_read(&mnt->mnt_longterm))) { 806 if (likely(mnt->mnt_ns)) {
807 /* shouldn't be the last one */
808 mnt_add_count(mnt, -1); 808 mnt_add_count(mnt, -1);
809 br_read_unlock(&vfsmount_lock); 809 br_read_unlock(&vfsmount_lock);
810 return; 810 return;
@@ -939,7 +939,7 @@ EXPORT_SYMBOL(replace_mount_options);
939/* iterator; we want it to have access to namespace_sem, thus here... */ 939/* iterator; we want it to have access to namespace_sem, thus here... */
940static void *m_start(struct seq_file *m, loff_t *pos) 940static void *m_start(struct seq_file *m, loff_t *pos)
941{ 941{
942 struct proc_mounts *p = container_of(m, struct proc_mounts, m); 942 struct proc_mounts *p = proc_mounts(m);
943 943
944 down_read(&namespace_sem); 944 down_read(&namespace_sem);
945 return seq_list_start(&p->ns->list, *pos); 945 return seq_list_start(&p->ns->list, *pos);
@@ -947,7 +947,7 @@ static void *m_start(struct seq_file *m, loff_t *pos)
947 947
948static void *m_next(struct seq_file *m, void *v, loff_t *pos) 948static void *m_next(struct seq_file *m, void *v, loff_t *pos)
949{ 949{
950 struct proc_mounts *p = container_of(m, struct proc_mounts, m); 950 struct proc_mounts *p = proc_mounts(m);
951 951
952 return seq_list_next(v, &p->ns->list, pos); 952 return seq_list_next(v, &p->ns->list, pos);
953} 953}
@@ -959,7 +959,7 @@ static void m_stop(struct seq_file *m, void *v)
959 959
960static int m_show(struct seq_file *m, void *v) 960static int m_show(struct seq_file *m, void *v)
961{ 961{
962 struct proc_mounts *p = container_of(m, struct proc_mounts, m); 962 struct proc_mounts *p = proc_mounts(m);
963 struct mount *r = list_entry(v, struct mount, mnt_list); 963 struct mount *r = list_entry(v, struct mount, mnt_list);
964 return p->show(m, &r->mnt); 964 return p->show(m, &r->mnt);
965} 965}
@@ -1074,8 +1074,6 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill)
1074 list_del_init(&p->mnt_expire); 1074 list_del_init(&p->mnt_expire);
1075 list_del_init(&p->mnt_list); 1075 list_del_init(&p->mnt_list);
1076 __touch_mnt_namespace(p->mnt_ns); 1076 __touch_mnt_namespace(p->mnt_ns);
1077 if (p->mnt_ns)
1078 __mnt_make_shortterm(p);
1079 p->mnt_ns = NULL; 1077 p->mnt_ns = NULL;
1080 list_del_init(&p->mnt_child); 1078 list_del_init(&p->mnt_child);
1081 if (mnt_has_parent(p)) { 1079 if (mnt_has_parent(p)) {
@@ -1260,11 +1258,12 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
1260 struct path path; 1258 struct path path;
1261 1259
1262 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) 1260 if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt))
1263 return NULL; 1261 return ERR_PTR(-EINVAL);
1264 1262
1265 res = q = clone_mnt(mnt, dentry, flag); 1263 res = q = clone_mnt(mnt, dentry, flag);
1266 if (!q) 1264 if (IS_ERR(q))
1267 goto Enomem; 1265 return q;
1266
1268 q->mnt_mountpoint = mnt->mnt_mountpoint; 1267 q->mnt_mountpoint = mnt->mnt_mountpoint;
1269 1268
1270 p = mnt; 1269 p = mnt;
@@ -1286,8 +1285,8 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
1286 path.mnt = &q->mnt; 1285 path.mnt = &q->mnt;
1287 path.dentry = p->mnt_mountpoint; 1286 path.dentry = p->mnt_mountpoint;
1288 q = clone_mnt(p, p->mnt.mnt_root, flag); 1287 q = clone_mnt(p, p->mnt.mnt_root, flag);
1289 if (!q) 1288 if (IS_ERR(q))
1290 goto Enomem; 1289 goto out;
1291 br_write_lock(&vfsmount_lock); 1290 br_write_lock(&vfsmount_lock);
1292 list_add_tail(&q->mnt_list, &res->mnt_list); 1291 list_add_tail(&q->mnt_list, &res->mnt_list);
1293 attach_mnt(q, &path); 1292 attach_mnt(q, &path);
@@ -1295,7 +1294,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry,
1295 } 1294 }
1296 } 1295 }
1297 return res; 1296 return res;
1298Enomem: 1297out:
1299 if (res) { 1298 if (res) {
1300 LIST_HEAD(umount_list); 1299 LIST_HEAD(umount_list);
1301 br_write_lock(&vfsmount_lock); 1300 br_write_lock(&vfsmount_lock);
@@ -1303,9 +1302,11 @@ Enomem:
1303 br_write_unlock(&vfsmount_lock); 1302 br_write_unlock(&vfsmount_lock);
1304 release_mounts(&umount_list); 1303 release_mounts(&umount_list);
1305 } 1304 }
1306 return NULL; 1305 return q;
1307} 1306}
1308 1307
1308/* Caller should check returned pointer for errors */
1309
1309struct vfsmount *collect_mounts(struct path *path) 1310struct vfsmount *collect_mounts(struct path *path)
1310{ 1311{
1311 struct mount *tree; 1312 struct mount *tree;
@@ -1313,7 +1314,9 @@ struct vfsmount *collect_mounts(struct path *path)
1313 tree = copy_tree(real_mount(path->mnt), path->dentry, 1314 tree = copy_tree(real_mount(path->mnt), path->dentry,
1314 CL_COPY_ALL | CL_PRIVATE); 1315 CL_COPY_ALL | CL_PRIVATE);
1315 up_write(&namespace_sem); 1316 up_write(&namespace_sem);
1316 return tree ? &tree->mnt : NULL; 1317 if (IS_ERR(tree))
1318 return NULL;
1319 return &tree->mnt;
1317} 1320}
1318 1321
1319void drop_collected_mounts(struct vfsmount *mnt) 1322void drop_collected_mounts(struct vfsmount *mnt)
@@ -1608,14 +1611,15 @@ static int do_loopback(struct path *path, char *old_name,
1608 if (!check_mnt(real_mount(path->mnt)) || !check_mnt(old)) 1611 if (!check_mnt(real_mount(path->mnt)) || !check_mnt(old))
1609 goto out2; 1612 goto out2;
1610 1613
1611 err = -ENOMEM;
1612 if (recurse) 1614 if (recurse)
1613 mnt = copy_tree(old, old_path.dentry, 0); 1615 mnt = copy_tree(old, old_path.dentry, 0);
1614 else 1616 else
1615 mnt = clone_mnt(old, old_path.dentry, 0); 1617 mnt = clone_mnt(old, old_path.dentry, 0);
1616 1618
1617 if (!mnt) 1619 if (IS_ERR(mnt)) {
1618 goto out2; 1620 err = PTR_ERR(mnt);
1621 goto out;
1622 }
1619 1623
1620 err = graft_tree(mnt, path); 1624 err = graft_tree(mnt, path);
1621 if (err) { 1625 if (err) {
@@ -2209,23 +2213,6 @@ static struct mnt_namespace *alloc_mnt_ns(void)
2209 return new_ns; 2213 return new_ns;
2210} 2214}
2211 2215
2212void mnt_make_longterm(struct vfsmount *mnt)
2213{
2214 __mnt_make_longterm(real_mount(mnt));
2215}
2216
2217void mnt_make_shortterm(struct vfsmount *m)
2218{
2219#ifdef CONFIG_SMP
2220 struct mount *mnt = real_mount(m);
2221 if (atomic_add_unless(&mnt->mnt_longterm, -1, 1))
2222 return;
2223 br_write_lock(&vfsmount_lock);
2224 atomic_dec(&mnt->mnt_longterm);
2225 br_write_unlock(&vfsmount_lock);
2226#endif
2227}
2228
2229/* 2216/*
2230 * Allocate a new namespace structure and populate it with contents 2217 * Allocate a new namespace structure and populate it with contents
2231 * copied from the namespace of the passed in task structure. 2218 * copied from the namespace of the passed in task structure.
@@ -2246,10 +2233,10 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2246 down_write(&namespace_sem); 2233 down_write(&namespace_sem);
2247 /* First pass: copy the tree topology */ 2234 /* First pass: copy the tree topology */
2248 new = copy_tree(old, old->mnt.mnt_root, CL_COPY_ALL | CL_EXPIRE); 2235 new = copy_tree(old, old->mnt.mnt_root, CL_COPY_ALL | CL_EXPIRE);
2249 if (!new) { 2236 if (IS_ERR(new)) {
2250 up_write(&namespace_sem); 2237 up_write(&namespace_sem);
2251 kfree(new_ns); 2238 kfree(new_ns);
2252 return ERR_PTR(-ENOMEM); 2239 return ERR_CAST(new);
2253 } 2240 }
2254 new_ns->root = new; 2241 new_ns->root = new;
2255 br_write_lock(&vfsmount_lock); 2242 br_write_lock(&vfsmount_lock);
@@ -2265,18 +2252,13 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
2265 q = new; 2252 q = new;
2266 while (p) { 2253 while (p) {
2267 q->mnt_ns = new_ns; 2254 q->mnt_ns = new_ns;
2268 __mnt_make_longterm(q);
2269 if (fs) { 2255 if (fs) {
2270 if (&p->mnt == fs->root.mnt) { 2256 if (&p->mnt == fs->root.mnt) {
2271 fs->root.mnt = mntget(&q->mnt); 2257 fs->root.mnt = mntget(&q->mnt);
2272 __mnt_make_longterm(q);
2273 mnt_make_shortterm(&p->mnt);
2274 rootmnt = &p->mnt; 2258 rootmnt = &p->mnt;
2275 } 2259 }
2276 if (&p->mnt == fs->pwd.mnt) { 2260 if (&p->mnt == fs->pwd.mnt) {
2277 fs->pwd.mnt = mntget(&q->mnt); 2261 fs->pwd.mnt = mntget(&q->mnt);
2278 __mnt_make_longterm(q);
2279 mnt_make_shortterm(&p->mnt);
2280 pwdmnt = &p->mnt; 2262 pwdmnt = &p->mnt;
2281 } 2263 }
2282 } 2264 }
@@ -2320,7 +2302,6 @@ static struct mnt_namespace *create_mnt_ns(struct vfsmount *m)
2320 if (!IS_ERR(new_ns)) { 2302 if (!IS_ERR(new_ns)) {
2321 struct mount *mnt = real_mount(m); 2303 struct mount *mnt = real_mount(m);
2322 mnt->mnt_ns = new_ns; 2304 mnt->mnt_ns = new_ns;
2323 __mnt_make_longterm(mnt);
2324 new_ns->root = mnt; 2305 new_ns->root = mnt;
2325 list_add(&new_ns->list, &mnt->mnt_list); 2306 list_add(&new_ns->list, &mnt->mnt_list);
2326 } else { 2307 } else {
@@ -2615,7 +2596,7 @@ struct vfsmount *kern_mount_data(struct file_system_type *type, void *data)
2615 * it is a longterm mount, don't release mnt until 2596 * it is a longterm mount, don't release mnt until
2616 * we unmount before file sys is unregistered 2597 * we unmount before file sys is unregistered
2617 */ 2598 */
2618 mnt_make_longterm(mnt); 2599 real_mount(mnt)->mnt_ns = MNT_NS_INTERNAL;
2619 } 2600 }
2620 return mnt; 2601 return mnt;
2621} 2602}
@@ -2625,7 +2606,9 @@ void kern_unmount(struct vfsmount *mnt)
2625{ 2606{
2626 /* release long term mount so mount point can be released */ 2607 /* release long term mount so mount point can be released */
2627 if (!IS_ERR_OR_NULL(mnt)) { 2608 if (!IS_ERR_OR_NULL(mnt)) {
2628 mnt_make_shortterm(mnt); 2609 br_write_lock(&vfsmount_lock);
2610 real_mount(mnt)->mnt_ns = NULL;
2611 br_write_unlock(&vfsmount_lock);
2629 mntput(mnt); 2612 mntput(mnt);
2630 } 2613 }
2631} 2614}