ANDROID: mnt: Propagate remount correctly
authorDaniel Rosenberg <drosen@google.com>
Sat, 12 Jan 2019 02:44:18 +0000 (18:44 -0800)
committerMichael Benedict <michaelbt@live.com>
Sat, 5 Oct 2019 02:31:14 +0000 (12:31 +1000)
This switches over to propagation_next to respect
namepsace semantics.

Test: Remounting to change the options of a fs with mount based
      options should propagate to all shared copies of that mount,
      and the slaves/indirect slaves of those.
Bug: 122428178
Signed-off-by: Daniel Rosenberg <drosen@google.com>
Change-Id: Ic35cd2782a646435689f5bedfa1f218fe4ab8254

fs/pnode.c

index 8702b2f3bce0466bbd473450dbe6eb6c4746fc4f..9a3811651cd58eca57a376abbb6391781adcdec3 100644 (file)
@@ -687,44 +687,26 @@ int propagate_umount(struct list_head *list)
        return 0;
 }
 
-/*
- *  Iterates over all slaves, and slaves of slaves.
- */
-static struct mount *next_descendent(struct mount *root, struct mount *cur)
-{
-       if (!IS_MNT_NEW(cur) && !list_empty(&cur->mnt_slave_list))
-               return first_slave(cur);
-       do {
-               struct mount *master = cur->mnt_master;
-
-               if (!master || cur->mnt_slave.next != &master->mnt_slave_list) {
-                       struct mount *next = next_slave(cur);
-
-                       return (next == root) ? NULL : next;
-               }
-               cur = master;
-       } while (cur != root);
-       return NULL;
-}
-
 void propagate_remount(struct mount *mnt)
 {
-       struct mount *m = mnt;
+       struct mount *parent = mnt->mnt_parent;
+       struct mount *p = mnt, *m;
 #ifdef CONFIG_RKP_NS_PROT
        struct super_block *sb = mnt->mnt->mnt_sb;
 #else
        struct super_block *sb = mnt->mnt.mnt_sb;
 #endif
 
-       if (sb->s_op->copy_mnt_data) {
-               m = next_descendent(mnt, m);
-               while (m) {
+       if (!sb->s_op->copy_mnt_data) 
+                       return;
+       for (p = propagation_next(parent, parent); p;
+                                                       p = propagation_next(p, parent)) {
+               m = __lookup_mnt(&p->mnt, mnt->mnt_mountpoint);
+               if (m)
 #ifdef CONFIG_RKP_NS_PROT
                        sb->s_op->copy_mnt_data(m->mnt->data, mnt->mnt->data);
 #else
                        sb->s_op->copy_mnt_data(m->mnt.data, mnt->mnt.data);
 #endif
-                       m = next_descendent(mnt, m);
-               }
        }
 }