Ignore:
Timestamp:
Mar 15, 2017, 2:42:58 AM (6 weeks ago)
Author:
brainslayer
Message:

use new squashfs in all kernels

File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/linux/universal/linux-4.4/fs/namespace.c

    r31161 r31662  
    639639
    640640/*
    641  * find the last mount at @dentry on vfsmount @mnt.
    642  * mount_lock must be held.
    643  */
    644 struct mount *__lookup_mnt_last(struct vfsmount *mnt, struct dentry *dentry)
    645 {
    646         struct mount *p, *res = NULL;
    647         p = __lookup_mnt(mnt, dentry);
    648         if (!p)
    649                 goto out;
    650         if (!(p->mnt.mnt_flags & MNT_UMOUNT))
    651                 res = p;
    652         hlist_for_each_entry_continue(p, mnt_hash) {
    653                 if (&p->mnt_parent->mnt != mnt || p->mnt_mountpoint != dentry)
    654                         break;
    655                 if (!(p->mnt.mnt_flags & MNT_UMOUNT))
    656                         res = p;
    657         }
    658 out:
    659         return res;
    660 }
    661 
    662 /*
    663641 * lookup_mnt - Return the first child mount mounted at path
    664642 *
     
    880858}
    881859
     860static void __attach_mnt(struct mount *mnt, struct mount *parent)
     861{
     862        hlist_add_head_rcu(&mnt->mnt_hash,
     863                           m_hash(&parent->mnt, mnt->mnt_mountpoint));
     864        list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
     865}
     866
    882867/*
    883868 * vfsmount lock must be held for write
     
    888873{
    889874        mnt_set_mountpoint(parent, mp, mnt);
    890         hlist_add_head_rcu(&mnt->mnt_hash, m_hash(&parent->mnt, mp->m_dentry));
    891         list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
    892 }
    893 
    894 static void attach_shadowed(struct mount *mnt,
    895                         struct mount *parent,
    896                         struct mount *shadows)
    897 {
    898         if (shadows) {
    899                 hlist_add_behind_rcu(&mnt->mnt_hash, &shadows->mnt_hash);
    900                 list_add(&mnt->mnt_child, &shadows->mnt_child);
    901         } else {
    902                 hlist_add_head_rcu(&mnt->mnt_hash,
    903                                 m_hash(&parent->mnt, mnt->mnt_mountpoint));
    904                 list_add_tail(&mnt->mnt_child, &parent->mnt_mounts);
    905         }
     875        __attach_mnt(mnt, parent);
     876}
     877
     878void mnt_change_mountpoint(struct mount *parent, struct mountpoint *mp, struct mount *mnt)
     879{
     880        struct mountpoint *old_mp = mnt->mnt_mp;
     881        struct dentry *old_mountpoint = mnt->mnt_mountpoint;
     882        struct mount *old_parent = mnt->mnt_parent;
     883
     884        list_del_init(&mnt->mnt_child);
     885        hlist_del_init(&mnt->mnt_mp_list);
     886        hlist_del_init_rcu(&mnt->mnt_hash);
     887
     888        attach_mnt(mnt, parent, mp);
     889
     890        put_mountpoint(old_mp);
     891
     892        /*
     893         * Safely avoid even the suggestion this code might sleep or
     894         * lock the mount hash by taking advantage of the knowledge that
     895         * mnt_change_mountpoint will not release the final reference
     896         * to a mountpoint.
     897         *
     898         * During mounting, the mount passed in as the parent mount will
     899         * continue to use the old mountpoint and during unmounting, the
     900         * old mountpoint will continue to exist until namespace_unlock,
     901         * which happens well after mnt_change_mountpoint.
     902         */
     903        spin_lock(&old_mountpoint->d_lock);
     904        old_mountpoint->d_lockref.count--;
     905        spin_unlock(&old_mountpoint->d_lock);
     906
     907        mnt_add_count(old_parent, -1);
    906908}
    907909
     
    909911 * vfsmount lock must be held for write
    910912 */
    911 static void commit_tree(struct mount *mnt, struct mount *shadows)
     913static void commit_tree(struct mount *mnt)
    912914{
    913915        struct mount *parent = mnt->mnt_parent;
     
    924926        list_splice(&head, n->list.prev);
    925927
    926         attach_shadowed(mnt, parent, shadows);
     928        __attach_mnt(mnt, parent);
    927929        touch_mnt_namespace(n);
    928930}
     
    17191721
    17201722                for (s = r; s; s = next_mnt(s, r)) {
    1721                         struct mount *t = NULL;
    17221723                        if (!(flag & CL_COPY_UNBINDABLE) &&
    17231724                            IS_MNT_UNBINDABLE(s)) {
     
    17411742                        lock_mount_hash();
    17421743                        list_add_tail(&q->mnt_list, &res->mnt_list);
    1743                         mnt_set_mountpoint(parent, p->mnt_mp, q);
    1744                         if (!list_empty(&parent->mnt_mounts)) {
    1745                                 t = list_last_entry(&parent->mnt_mounts,
    1746                                         struct mount, mnt_child);
    1747                                 if (t->mnt_mp != p->mnt_mp)
    1748                                         t = NULL;
    1749                         }
    1750                         attach_shadowed(q, parent, t);
     1744                        attach_mnt(q, parent, p->mnt_mp);
    17511745                        unlock_mount_hash();
    17521746                }
     
    19261920{
    19271921        HLIST_HEAD(tree_list);
     1922        struct mountpoint *smp;
    19281923        struct mount *child, *p;
    19291924        struct hlist_node *n;
    19301925        int err;
     1926
     1927        /* Preallocate a mountpoint in case the new mounts need
     1928         * to be tucked under other mounts.
     1929         */
     1930        smp = get_mountpoint(source_mnt->mnt.mnt_root);
     1931        if (IS_ERR(smp))
     1932                return PTR_ERR(smp);
    19311933
    19321934        if (IS_MNT_SHARED(dest_mnt)) {
     
    19491951        } else {
    19501952                mnt_set_mountpoint(dest_mnt, dest_mp, source_mnt);
    1951                 commit_tree(source_mnt, NULL);
     1953                commit_tree(source_mnt);
    19521954        }
    19531955
     
    19551957                struct mount *q;
    19561958                hlist_del_init(&child->mnt_hash);
    1957                 q = __lookup_mnt_last(&child->mnt_parent->mnt,
    1958                                       child->mnt_mountpoint);
    1959                 commit_tree(child, q);
    1960         }
     1959                q = __lookup_mnt(&child->mnt_parent->mnt,
     1960                                 child->mnt_mountpoint);
     1961                if (q)
     1962                        mnt_change_mountpoint(child, smp, q);
     1963                commit_tree(child);
     1964        }
     1965        put_mountpoint(smp);
    19611966        unlock_mount_hash();
    19621967
     
    19711976        cleanup_group_ids(source_mnt, NULL);
    19721977 out:
     1978        read_seqlock_excl(&mount_lock);
     1979        put_mountpoint(smp);
     1980        read_sequnlock_excl(&mount_lock);
     1981
    19731982        return err;
    19741983}
Note: See TracChangeset for help on using the changeset viewer.