···7979 * pathname in *buf*, including the NUL termination character. On error, a8080 * negative integer is returned.8181 */8282-__bpf_kfunc int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz)8282+__bpf_kfunc int bpf_path_d_path(const struct path *path, char *buf, size_t buf__sz)8383{8484 int len;8585 char *ret;
+13-20
fs/configfs/symlink.c
···114114}115115116116117117-static int get_target(const char *symname, struct path *path,118118- struct config_item **target, struct super_block *sb)117117+static int get_target(const char *symname, struct config_item **target,118118+ struct super_block *sb)119119{120120+ struct path path __free(path_put) = {};120121 int ret;121122122122- ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, path);123123- if (!ret) {124124- if (path->dentry->d_sb == sb) {125125- *target = configfs_get_config_item(path->dentry);126126- if (!*target) {127127- ret = -ENOENT;128128- path_put(path);129129- }130130- } else {131131- ret = -EPERM;132132- path_put(path);133133- }134134- }135135-136136- return ret;123123+ ret = kern_path(symname, LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &path);124124+ if (ret)125125+ return ret;126126+ if (path.dentry->d_sb != sb)127127+ return -EPERM;128128+ *target = configfs_get_config_item(path.dentry);129129+ if (!*target)130130+ return -ENOENT;131131+ return 0;137132}138133139134···136141 struct dentry *dentry, const char *symname)137142{138143 int ret;139139- struct path path;140144 struct configfs_dirent *sd;141145 struct config_item *parent_item;142146 struct config_item *target_item = NULL;···182188 * AV, a thoroughly annoyed bastard.183189 */184190 inode_unlock(dir);185185- ret = get_target(symname, &path, &target_item, dentry->d_sb);191191+ ret = get_target(symname, &target_item, dentry->d_sb);186192 inode_lock(dir);187193 if (ret)188194 goto out_put;···204210 }205211206212 config_item_put(target_item);207207- path_put(&path);208213209214out_put:210215 config_item_put(parent_item);
···6464#endif6565 struct list_head mnt_mounts; /* list of children, anchored here */6666 struct list_head mnt_child; /* and going through their mnt_child */6767- struct list_head mnt_instance; /* mount instance on sb->s_mounts */6767+ struct mount *mnt_next_for_sb; /* the next two fields are hlist_node, */6868+ struct mount * __aligned(1) *mnt_pprev_for_sb;6969+ /* except that LSB of pprev is stolen */7070+#define WRITE_HOLD 1 /* ... for use by mnt_hold_writers() */6871 const char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */6972 struct list_head mnt_list;7073 struct list_head mnt_expire; /* link in fs-specific expiry list */···157154158155extern seqlock_t mount_lock;159156157157+DEFINE_LOCK_GUARD_0(mount_writer, write_seqlock(&mount_lock),158158+ write_sequnlock(&mount_lock))159159+DEFINE_LOCK_GUARD_0(mount_locked_reader, read_seqlock_excl(&mount_lock),160160+ read_sequnlock_excl(&mount_lock))161161+160162struct proc_mounts {161163 struct mnt_namespace *ns;162164 struct path root;···237229{238230}239231#endif232232+233233+static inline struct mount *topmost_overmount(struct mount *m)234234+{235235+ while (m->overmount)236236+ m = m->overmount;237237+ return m;238238+}239239+240240+static inline bool __test_write_hold(struct mount * __aligned(1) *val)241241+{242242+ return (unsigned long)val & WRITE_HOLD;243243+}244244+245245+static inline bool test_write_hold(const struct mount *m)246246+{247247+ return __test_write_hold(m->mnt_pprev_for_sb);248248+}249249+250250+static inline void set_write_hold(struct mount *m)251251+{252252+ m->mnt_pprev_for_sb = (void *)((unsigned long)m->mnt_pprev_for_sb253253+ | WRITE_HOLD);254254+}255255+256256+static inline void clear_write_hold(struct mount *m)257257+{258258+ m->mnt_pprev_for_sb = (void *)((unsigned long)m->mnt_pprev_for_sb259259+ & ~WRITE_HOLD);260260+}240261241262struct mnt_namespace *mnt_ns_from_dentry(struct dentry *dentry);
···8282static struct mnt_namespace *emptied_ns; /* protected by namespace_sem */8383static DEFINE_SEQLOCK(mnt_ns_tree_lock);84848585+static inline void namespace_lock(void);8686+static void namespace_unlock(void);8787+DEFINE_LOCK_GUARD_0(namespace_excl, namespace_lock(), namespace_unlock())8888+DEFINE_LOCK_GUARD_0(namespace_shared, down_read(&namespace_sem),8989+ up_read(&namespace_sem))9090+9191+DEFINE_FREE(mntput, struct vfsmount *, if (!IS_ERR(_T)) mntput(_T))9292+8593#ifdef CONFIG_FSNOTIFY8694LIST_HEAD(notify_list); /* protected by namespace_sem */8795#endif···195187static void mnt_ns_tree_remove(struct mnt_namespace *ns)196188{197189 /* remove from global mount namespace list */198198- if (!is_anon_ns(ns)) {190190+ if (!RB_EMPTY_NODE(&ns->mnt_ns_tree_node)) {199191 mnt_ns_tree_write_lock();200192 rb_erase(&ns->mnt_ns_tree_node, &mnt_ns_tree);201193 list_bidir_del_rcu(&ns->mnt_ns_list);···428420 * mnt_want/drop_write() will _keep_ the filesystem429421 * r/w.430422 */431431-bool __mnt_is_readonly(struct vfsmount *mnt)423423+bool __mnt_is_readonly(const struct vfsmount *mnt)432424{433425 return (mnt->mnt_flags & MNT_READONLY) || sb_rdonly(mnt->mnt_sb);434426}···468460#endif469461}470462471471-static int mnt_is_readonly(struct vfsmount *mnt)463463+static int mnt_is_readonly(const struct vfsmount *mnt)472464{473465 if (READ_ONCE(mnt->mnt_sb->s_readonly_remount))474466 return 1;···509501 mnt_inc_writers(mnt);510502 /*511503 * The store to mnt_inc_writers must be visible before we pass512512- * MNT_WRITE_HOLD loop below, so that the slowpath can see our513513- * incremented count after it has set MNT_WRITE_HOLD.504504+ * WRITE_HOLD loop below, so that the slowpath can see our505505+ * incremented count after it has set WRITE_HOLD.514506 */515507 smp_mb();516508 might_lock(&mount_lock.lock);517517- while (READ_ONCE(mnt->mnt.mnt_flags) & MNT_WRITE_HOLD) {509509+ while (__test_write_hold(READ_ONCE(mnt->mnt_pprev_for_sb))) {518510 if (!IS_ENABLED(CONFIG_PREEMPT_RT)) {519511 cpu_relax();520512 } else {521513 /*522514 * This prevents priority inversion, if the task523523- * setting MNT_WRITE_HOLD got preempted on a remote515515+ * setting WRITE_HOLD got preempted on a remote524516 * CPU, and it prevents life lock if the task setting525525- * MNT_WRITE_HOLD has a lower priority and is bound to517517+ * WRITE_HOLD has a lower priority and is bound to526518 * the same CPU as the task that is spinning here.527519 */528520 preempt_enable();529529- lock_mount_hash();530530- unlock_mount_hash();521521+ read_seqlock_excl(&mount_lock);522522+ read_sequnlock_excl(&mount_lock);531523 preempt_disable();532524 }533525 }534526 /*535527 * The barrier pairs with the barrier sb_start_ro_state_change() making536536- * sure that if we see MNT_WRITE_HOLD cleared, we will also see528528+ * sure that if we see WRITE_HOLD cleared, we will also see537529 * s_readonly_remount set (or even SB_RDONLY / MNT_READONLY flags) in538530 * mnt_is_readonly() and bail in case we are racing with remount539531 * read-only.···671663 * a call to mnt_unhold_writers() in order to stop preventing write access to672664 * @mnt.673665 *674674- * Context: This function expects lock_mount_hash() to be held serializing675675- * setting MNT_WRITE_HOLD.666666+ * Context: This function expects to be in mount_locked_reader scope serializing667667+ * setting WRITE_HOLD.676668 * Return: On success 0 is returned.677669 * On error, -EBUSY is returned.678670 */679671static inline int mnt_hold_writers(struct mount *mnt)680672{681681- mnt->mnt.mnt_flags |= MNT_WRITE_HOLD;673673+ set_write_hold(mnt);682674 /*683683- * After storing MNT_WRITE_HOLD, we'll read the counters. This store675675+ * After storing WRITE_HOLD, we'll read the counters. This store684676 * should be visible before we do.685677 */686678 smp_mb();···696688 * sum up each counter, if we read a counter before it is incremented,697689 * but then read another CPU's count which it has been subsequently698690 * decremented from -- we would see more decrements than we should.699699- * MNT_WRITE_HOLD protects against this scenario, because691691+ * WRITE_HOLD protects against this scenario, because700692 * mnt_want_write first increments count, then smp_mb, then spins on701701- * MNT_WRITE_HOLD, so it can't be decremented by another CPU while693693+ * WRITE_HOLD, so it can't be decremented by another CPU while702694 * we're counting up here.703695 */704696 if (mnt_get_writers(mnt) > 0)···714706 * Stop preventing write access to @mnt allowing callers to gain write access715707 * to @mnt again.716708 *717717- * This function can only be called after a successful call to718718- * mnt_hold_writers().709709+ * This function can only be called after a call to mnt_hold_writers().719710 *720720- * Context: This function expects lock_mount_hash() to be held.711711+ * Context: This function expects to be in the same mount_locked_reader scope712712+ * as the matching mnt_hold_writers().721713 */722714static inline void mnt_unhold_writers(struct mount *mnt)723715{716716+ if (!test_write_hold(mnt))717717+ return;724718 /*725725- * MNT_READONLY must become visible before ~MNT_WRITE_HOLD, so writers719719+ * MNT_READONLY must become visible before ~WRITE_HOLD, so writers726720 * that become unheld will see MNT_READONLY.727721 */728722 smp_wmb();729729- mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD;723723+ clear_write_hold(mnt);724724+}725725+726726+static inline void mnt_del_instance(struct mount *m)727727+{728728+ struct mount **p = m->mnt_pprev_for_sb;729729+ struct mount *next = m->mnt_next_for_sb;730730+731731+ if (next)732732+ next->mnt_pprev_for_sb = p;733733+ *p = next;734734+}735735+736736+static inline void mnt_add_instance(struct mount *m, struct super_block *s)737737+{738738+ struct mount *first = s->s_mounts;739739+740740+ if (first)741741+ first->mnt_pprev_for_sb = &m->mnt_next_for_sb;742742+ m->mnt_next_for_sb = first;743743+ m->mnt_pprev_for_sb = &s->s_mounts;744744+ s->s_mounts = m;730745}731746732747static int mnt_make_readonly(struct mount *mnt)···765734766735int sb_prepare_remount_readonly(struct super_block *sb)767736{768768- struct mount *mnt;769737 int err = 0;770738771771- /* Racy optimization. Recheck the counter under MNT_WRITE_HOLD */739739+ /* Racy optimization. Recheck the counter under WRITE_HOLD */772740 if (atomic_long_read(&sb->s_remove_count))773741 return -EBUSY;774742775775- lock_mount_hash();776776- list_for_each_entry(mnt, &sb->s_mounts, mnt_instance) {777777- if (!(mnt->mnt.mnt_flags & MNT_READONLY)) {778778- err = mnt_hold_writers(mnt);743743+ guard(mount_locked_reader)();744744+745745+ for (struct mount *m = sb->s_mounts; m; m = m->mnt_next_for_sb) {746746+ if (!(m->mnt.mnt_flags & MNT_READONLY)) {747747+ err = mnt_hold_writers(m);779748 if (err)780749 break;781750 }···785754786755 if (!err)787756 sb_start_ro_state_change(sb);788788- list_for_each_entry(mnt, &sb->s_mounts, mnt_instance) {789789- if (mnt->mnt.mnt_flags & MNT_WRITE_HOLD)790790- mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD;757757+ for (struct mount *m = sb->s_mounts; m; m = m->mnt_next_for_sb) {758758+ if (test_write_hold(m))759759+ clear_write_hold(m);791760 }792792- unlock_mount_hash();793761794762 return err;795763}···847817}848818849819/**850850- * __lookup_mnt - find first child mount820820+ * __lookup_mnt - mount hash lookup851821 * @mnt: parent mount852852- * @dentry: mountpoint822822+ * @dentry: dentry of mountpoint853823 *854854- * If @mnt has a child mount @c mounted @dentry find and return it.824824+ * If @mnt has a child mount @c mounted on @dentry find and return it.825825+ * Caller must either hold the spinlock component of @mount_lock or826826+ * hold rcu_read_lock(), sample the seqcount component before the call827827+ * and recheck it afterwards.855828 *856856- * Note that the child mount @c need not be unique. There are cases857857- * where shadow mounts are created. For example, during mount858858- * propagation when a source mount @mnt whose root got overmounted by a859859- * mount @o after path lookup but before @namespace_sem could be860860- * acquired gets copied and propagated. So @mnt gets copied including861861- * @o. When @mnt is propagated to a destination mount @d that already862862- * has another mount @n mounted at the same mountpoint then the source863863- * mount @mnt will be tucked beneath @n, i.e., @n will be mounted on864864- * @mnt and @mnt mounted on @d. Now both @n and @o are mounted at @mnt865865- * on @dentry.866866- *867867- * Return: The first child of @mnt mounted @dentry or NULL.829829+ * Return: The child of @mnt mounted on @dentry or %NULL.868830 */869831struct mount *__lookup_mnt(struct vfsmount *mnt, struct dentry *dentry)870832{···869847 return NULL;870848}871849872872-/*873873- * lookup_mnt - Return the first child mount mounted at path850850+/**851851+ * lookup_mnt - Return the child mount mounted at given location852852+ * @path: location in the namespace874853 *875875- * "First" means first mounted chronologically. If you create the876876- * following mounts:877877- *878878- * mount /dev/sda1 /mnt879879- * mount /dev/sda2 /mnt880880- * mount /dev/sda3 /mnt881881- *882882- * Then lookup_mnt() on the base /mnt dentry in the root mount will883883- * return successively the root dentry and vfsmount of /dev/sda1, then884884- * /dev/sda2, then /dev/sda3, then NULL.885885- *886886- * lookup_mnt takes a reference to the found vfsmount.854854+ * Acquires and returns a new reference to mount at given location855855+ * or %NULL if nothing is mounted there.887856 */888857struct vfsmount *lookup_mnt(const struct path *path)889858{···911898{912899 struct mnt_namespace *ns = current->nsproxy->mnt_ns;913900 struct mount *mnt, *n;914914- bool is_covered = false;915901916916- down_read(&namespace_sem);917917- rbtree_postorder_for_each_entry_safe(mnt, n, &ns->mounts, mnt_node) {918918- is_covered = (mnt->mnt_mountpoint == dentry);919919- if (is_covered)920920- break;921921- }922922- up_read(&namespace_sem);902902+ guard(namespace_shared)();923903924924- return is_covered;904904+ rbtree_postorder_for_each_entry_safe(mnt, n, &ns->mounts, mnt_node)905905+ if (mnt->mnt_mountpoint == dentry)906906+ return true;907907+908908+ return false;925909}926910927911struct pinned_mountpoint {928912 struct hlist_node node;929913 struct mountpoint *mp;914914+ struct mount *parent;930915};931916932917static bool lookup_mountpoint(struct dentry *dentry, struct pinned_mountpoint *m)···10151004 }10161005}1017100610181018-static inline int check_mnt(struct mount *mnt)10071007+static inline int check_mnt(const struct mount *mnt)10191008{10201009 return mnt->mnt_ns == current->nsproxy->mnt_ns;10211010}···12171206 touch_mnt_namespace(n);12181207}1219120812091209+static void setup_mnt(struct mount *m, struct dentry *root)12101210+{12111211+ struct super_block *s = root->d_sb;12121212+12131213+ atomic_inc(&s->s_active);12141214+ m->mnt.mnt_sb = s;12151215+ m->mnt.mnt_root = dget(root);12161216+ m->mnt_mountpoint = m->mnt.mnt_root;12171217+ m->mnt_parent = m;12181218+12191219+ guard(mount_locked_reader)();12201220+ mnt_add_instance(m, s);12211221+}12221222+12201223/**12211224 * vfs_create_mount - Create a mount for a configured superblock12221225 * @fc: The configuration context with the superblock attached···12541229 if (fc->sb_flags & SB_KERNMOUNT)12551230 mnt->mnt.mnt_flags = MNT_INTERNAL;1256123112571257- atomic_inc(&fc->root->d_sb->s_active);12581258- mnt->mnt.mnt_sb = fc->root->d_sb;12591259- mnt->mnt.mnt_root = dget(fc->root);12601260- mnt->mnt_mountpoint = mnt->mnt.mnt_root;12611261- mnt->mnt_parent = mnt;12321232+ setup_mnt(mnt, fc->root);1262123312631263- lock_mount_hash();12641264- list_add_tail(&mnt->mnt_instance, &mnt->mnt.mnt_sb->s_mounts);12651265- unlock_mount_hash();12661234 return &mnt->mnt;12671235}12681236EXPORT_SYMBOL(vfs_create_mount);···13131295static struct mount *clone_mnt(struct mount *old, struct dentry *root,13141296 int flag)13151297{13161316- struct super_block *sb = old->mnt.mnt_sb;13171298 struct mount *mnt;13181299 int err;13191300···13371320 if (mnt->mnt_group_id)13381321 set_mnt_shared(mnt);1339132213401340- atomic_inc(&sb->s_active);13411323 mnt->mnt.mnt_idmap = mnt_idmap_get(mnt_idmap(&old->mnt));1342132413431343- mnt->mnt.mnt_sb = sb;13441344- mnt->mnt.mnt_root = dget(root);13451345- mnt->mnt_mountpoint = mnt->mnt.mnt_root;13461346- mnt->mnt_parent = mnt;13471347- lock_mount_hash();13481348- list_add_tail(&mnt->mnt_instance, &sb->s_mounts);13491349- unlock_mount_hash();13251325+ setup_mnt(mnt, root);1350132613511327 if (flag & CL_PRIVATE) // we are done with it13521328 return mnt;···14451435 mnt->mnt.mnt_flags |= MNT_DOOMED;14461436 rcu_read_unlock();1447143714481448- list_del(&mnt->mnt_instance);14381438+ mnt_del_instance(mnt);14491439 if (unlikely(!list_empty(&mnt->mnt_expire)))14501440 list_del(&mnt->mnt_expire);14511441···17861776 down_write(&namespace_sem);17871777}1788177817891789-DEFINE_GUARD(namespace_lock, struct rw_semaphore *, namespace_lock(), namespace_unlock())17901790-17911779enum umount_tree_flags {17921780 UMOUNT_SYNC = 1,17931781 UMOUNT_PROPAGATE = 2,···18501842 if (how & UMOUNT_PROPAGATE)18511843 propagate_umount(&tmp_list);1852184418451845+ bulk_make_private(&tmp_list);18461846+18531847 while (!list_empty(&tmp_list)) {18541848 struct mnt_namespace *ns;18551849 bool disconnect;···18761866 umount_mnt(p);18771867 }18781868 }18791879- change_mnt_propagation(p, MS_PRIVATE);18801869 if (disconnect)18811870 hlist_add_head(&p->mnt_umount, &unmounted);18821871···20352026 struct pinned_mountpoint mp = {};20362027 struct mount *mnt;2037202820382038- namespace_lock();20392039- lock_mount_hash();20292029+ guard(namespace_excl)();20302030+ guard(mount_writer)();20312031+20402032 if (!lookup_mountpoint(dentry, &mp))20412041- goto out_unlock;20332033+ return;2042203420432035 event++;20442036 while (mp.node.next) {···20512041 else umount_tree(mnt, UMOUNT_CONNECTED);20522042 }20532043 unpin_mountpoint(&mp);20542054-out_unlock:20552055- unlock_mount_hash();20562056- namespace_unlock();20572044}2058204520592046/*···20892082}2090208320912084// caller is responsible for flags being sane20922092-int path_umount(struct path *path, int flags)20852085+int path_umount(const struct path *path, int flags)20932086{20942087 struct mount *mnt = real_mount(path->mnt);20952088 int ret;···23052298 return p;23062299}2307230023082308-struct path *collect_paths(const struct path *path,23012301+const struct path *collect_paths(const struct path *path,23092302 struct path *prealloc, unsigned count)23102303{23112304 struct mount *root = real_mount(path->mnt);···23132306 struct path *res = prealloc, *to_free = NULL;23142307 unsigned n = 0;2315230823162316- guard(rwsem_read)(&namespace_sem);23092309+ guard(namespace_shared)();2317231023182311 if (!check_mnt(root))23192312 return ERR_PTR(-EINVAL);···23392332 return res;23402333}2341233423422342-void drop_collected_paths(struct path *paths, struct path *prealloc)23352335+void drop_collected_paths(const struct path *paths, const struct path *prealloc)23432336{23442344- for (struct path *p = paths; p->mnt; p++)23372337+ for (const struct path *p = paths; p->mnt; p++)23452338 path_put(p);23462339 if (paths != prealloc)23472340 kfree(paths);···23682361 return;23692362 }2370236323712371- scoped_guard(namespace_lock, &namespace_sem) {23642364+ scoped_guard(namespace_excl) {23722365 if (!anon_ns_root(m))23732366 return;23742367···23792372 }23802373}2381237423752375+/* locks: namespace_shared && pinned(mnt) || mount_locked_reader */23822376static bool __has_locked_children(struct mount *mnt, struct dentry *dentry)23832377{23842378 struct mount *child;···2396238823972389bool has_locked_children(struct mount *mnt, struct dentry *dentry)23982390{23992399- bool res;24002400-24012401- read_seqlock_excl(&mount_lock);24022402- res = __has_locked_children(mnt, dentry);24032403- read_sequnlock_excl(&mount_lock);24042404- return res;23912391+ guard(mount_locked_reader)();23922392+ return __has_locked_children(mnt, dentry);24052393}2406239424072395/*···24052401 * specified subtree. Such references can act as pins for mount namespaces24062402 * that aren't checked by the mount-cycle checking code, thereby allowing24072403 * cycles to be made.24042404+ *24052405+ * locks: mount_locked_reader || namespace_shared && pinned(subtree)24082406 */24092407static bool check_for_nsfs_mounts(struct mount *subtree)24102408{24112411- struct mount *p;24122412- bool ret = false;24132413-24142414- lock_mount_hash();24152415- for (p = subtree; p; p = next_mnt(p, subtree))24092409+ for (struct mount *p = subtree; p; p = next_mnt(p, subtree))24162410 if (mnt_ns_loop(p->mnt.mnt_root))24172417- goto out;24182418-24192419- ret = true;24202420-out:24212421- unlock_mount_hash();24222422- return ret;24112411+ return false;24122412+ return true;24232413}2424241424252415/**···24332435 struct mount *old_mnt = real_mount(path->mnt);24342436 struct mount *new_mnt;2435243724362436- guard(rwsem_read)(&namespace_sem);24382438+ guard(namespace_shared)();2437243924382440 if (IS_MNT_UNBINDABLE(old_mnt))24392441 return ERR_PTR(-EINVAL);···25542556/**25552557 * attach_recursive_mnt - attach a source mount tree25562558 * @source_mnt: mount tree to be attached25572557- * @dest_mnt: mount that @source_mnt will be mounted on25582558- * @dest_mp: the mountpoint @source_mnt will be mounted at25592559+ * @dest: the context for mounting at the place where the tree should go25592560 *25602561 * NOTE: in the table below explains the semantics when a source mount25612562 * of a given type is attached to a destination mount of a given type.···26172620 * Otherwise a negative error code is returned.26182621 */26192622static int attach_recursive_mnt(struct mount *source_mnt,26202620- struct mount *dest_mnt,26212621- struct mountpoint *dest_mp)26232623+ const struct pinned_mountpoint *dest)26222624{26232625 struct user_namespace *user_ns = current->nsproxy->mnt_ns->user_ns;26262626+ struct mount *dest_mnt = dest->parent;26272627+ struct mountpoint *dest_mp = dest->mp;26242628 HLIST_HEAD(tree_list);26252629 struct mnt_namespace *ns = dest_mnt->mnt_ns;26262630 struct pinned_mountpoint root = {};···27012703 child->mnt_mountpoint);27022704 commit_tree(child);27032705 if (q) {27062706+ struct mount *r = topmost_overmount(child);27042707 struct mountpoint *mp = root.mp;27052705- struct mount *r = child;27062706- while (unlikely(r->overmount))27072707- r = r->overmount;27082708+27082709 if (unlikely(shorter) && child != source_mnt)27092710 mp = shorter;27102711 mnt_change_mountpoint(r, mp, q);···27322735 return err;27332736}2734273727352735-/**27362736- * do_lock_mount - lock mount and mountpoint27372737- * @path: target path27382738- * @beneath: whether the intention is to mount beneath @path27392739- *27402740- * Follow the mount stack on @path until the top mount @mnt is found. If27412741- * the initial @path->{mnt,dentry} is a mountpoint lookup the first27422742- * mount stacked on top of it. Then simply follow @{mnt,mnt->mnt_root}27432743- * until nothing is stacked on top of it anymore.27442744- *27452745- * Acquire the inode_lock() on the top mount's ->mnt_root to protect27462746- * against concurrent removal of the new mountpoint from another mount27472747- * namespace.27482748- *27492749- * If @beneath is requested, acquire inode_lock() on @mnt's mountpoint27502750- * @mp on @mnt->mnt_parent must be acquired. This protects against a27512751- * concurrent unlink of @mp->mnt_dentry from another mount namespace27522752- * where @mnt doesn't have a child mount mounted @mp. A concurrent27532753- * removal of @mnt->mnt_root doesn't matter as nothing will be mounted27542754- * on top of it for @beneath.27552755- *27562756- * In addition, @beneath needs to make sure that @mnt hasn't been27572757- * unmounted or moved from its current mountpoint in between dropping27582758- * @mount_lock and acquiring @namespace_sem. For the !@beneath case @mnt27592759- * being unmounted would be detected later by e.g., calling27602760- * check_mnt(mnt) in the function it's called from. For the @beneath27612761- * case however, it's useful to detect it directly in do_lock_mount().27622762- * If @mnt hasn't been unmounted then @mnt->mnt_mountpoint still points27632763- * to @mnt->mnt_mp->m_dentry. But if @mnt has been unmounted it will27642764- * point to @mnt->mnt_root and @mnt->mnt_mp will be NULL.27652765- *27662766- * Return: Either the target mountpoint on the top mount or the top27672767- * mount's mountpoint.27682768- */27692769-static int do_lock_mount(struct path *path, struct pinned_mountpoint *pinned, bool beneath)27382738+static inline struct mount *where_to_mount(const struct path *path,27392739+ struct dentry **dentry,27402740+ bool beneath)27702741{27712771- struct vfsmount *mnt = path->mnt;27722772- struct dentry *dentry;27732773- struct path under = {};27742774- int err = -ENOENT;27422742+ struct mount *m;2775274327762776- for (;;) {27772777- struct mount *m = real_mount(mnt);27442744+ if (unlikely(beneath)) {27452745+ m = topmost_overmount(real_mount(path->mnt));27462746+ *dentry = m->mnt_mountpoint;27472747+ return m->mnt_parent;27482748+ }27492749+ m = __lookup_mnt(path->mnt, path->dentry);27502750+ if (unlikely(m)) {27512751+ m = topmost_overmount(m);27522752+ *dentry = m->mnt.mnt_root;27532753+ return m;27542754+ }27552755+ *dentry = path->dentry;27562756+ return real_mount(path->mnt);27572757+}2778275827792779- if (beneath) {27802780- path_put(&under);27812781- read_seqlock_excl(&mount_lock);27822782- under.mnt = mntget(&m->mnt_parent->mnt);27832783- under.dentry = dget(m->mnt_mountpoint);27842784- read_sequnlock_excl(&mount_lock);27852785- dentry = under.dentry;27862786- } else {27872787- dentry = path->dentry;27592759+/**27602760+ * do_lock_mount - acquire environment for mounting27612761+ * @path: target path27622762+ * @res: context to set up27632763+ * @beneath: whether the intention is to mount beneath @path27642764+ *27652765+ * To mount something at given location, we need27662766+ * namespace_sem locked exclusive27672767+ * inode of dentry we are mounting on locked exclusive27682768+ * struct mountpoint for that dentry27692769+ * struct mount we are mounting on27702770+ *27712771+ * Results are stored in caller-supplied context (pinned_mountpoint);27722772+ * on success we have res->parent and res->mp pointing to parent and27732773+ * mountpoint respectively and res->node inserted into the ->m_list27742774+ * of the mountpoint, making sure the mountpoint won't disappear.27752775+ * On failure we have res->parent set to ERR_PTR(-E...), res->mp27762776+ * left NULL, res->node - empty.27772777+ * In case of success do_lock_mount returns with locks acquired (in27782778+ * proper order - inode lock nests outside of namespace_sem).27792779+ *27802780+ * Request to mount on overmounted location is treated as "mount on27812781+ * top of whatever's overmounting it"; request to mount beneath27822782+ * a location - "mount immediately beneath the topmost mount at that27832783+ * place".27842784+ *27852785+ * In all cases the location must not have been unmounted and the27862786+ * chosen mountpoint must be allowed to be mounted on. For "beneath"27872787+ * case we also require the location to be at the root of a mount27882788+ * that has a parent (i.e. is not a root of some namespace).27892789+ */27902790+static void do_lock_mount(const struct path *path,27912791+ struct pinned_mountpoint *res,27922792+ bool beneath)27932793+{27942794+ int err;27952795+27962796+ if (unlikely(beneath) && !path_mounted(path)) {27972797+ res->parent = ERR_PTR(-EINVAL);27982798+ return;27992799+ }28002800+28012801+ do {28022802+ struct dentry *dentry, *d;28032803+ struct mount *m, *n;28042804+28052805+ scoped_guard(mount_locked_reader) {28062806+ m = where_to_mount(path, &dentry, beneath);28072807+ if (&m->mnt != path->mnt) {28082808+ mntget(&m->mnt);28092809+ dget(dentry);28102810+ }27882811 }2789281227902813 inode_lock(dentry->d_inode);27912814 namespace_lock();2792281527932793- if (unlikely(cant_mount(dentry) || !is_mounted(mnt)))27942794- break; // not to be mounted on28162816+ // check if the chain of mounts (if any) has changed.28172817+ scoped_guard(mount_locked_reader)28182818+ n = where_to_mount(path, &d, beneath);2795281927962796- if (beneath && unlikely(m->mnt_mountpoint != dentry ||27972797- &m->mnt_parent->mnt != under.mnt)) {28202820+ if (unlikely(n != m || dentry != d))28212821+ err = -EAGAIN; // something moved, retry28222822+ else if (unlikely(cant_mount(dentry) || !is_mounted(path->mnt)))28232823+ err = -ENOENT; // not to be mounted on28242824+ else if (beneath && &m->mnt == path->mnt && !m->overmount)28252825+ err = -EINVAL;28262826+ else28272827+ err = get_mountpoint(dentry, res);28282828+28292829+ if (unlikely(err)) {28302830+ res->parent = ERR_PTR(err);27982831 namespace_unlock();27992832 inode_unlock(dentry->d_inode);28002800- continue; // got moved28332833+ } else {28342834+ res->parent = m;28012835 }28022802-28032803- mnt = lookup_mnt(path);28042804- if (unlikely(mnt)) {28052805- namespace_unlock();28062806- inode_unlock(dentry->d_inode);28072807- path_put(path);28082808- path->mnt = mnt;28092809- path->dentry = dget(mnt->mnt_root);28102810- continue; // got overmounted28362836+ /*28372837+ * Drop the temporary references. This is subtle - on success28382838+ * we are doing that under namespace_sem, which would normally28392839+ * be forbidden. However, in that case we are guaranteed that28402840+ * refcounts won't reach zero, since we know that path->mnt28412841+ * is mounted and thus all mounts reachable from it are pinned28422842+ * and stable, along with their mountpoints and roots.28432843+ */28442844+ if (&m->mnt != path->mnt) {28452845+ dput(dentry);28462846+ mntput(&m->mnt);28112847 }28122812- err = get_mountpoint(dentry, pinned);28132813- if (err)28142814- break;28152815- if (beneath) {28162816- /*28172817- * @under duplicates the references that will stay28182818- * at least until namespace_unlock(), so the path_put()28192819- * below is safe (and OK to do under namespace_lock -28202820- * we are not dropping the final references here).28212821- */28222822- path_put(&under);28232823- }28242824- return 0;28252825- }28262826- namespace_unlock();28272827- inode_unlock(dentry->d_inode);28282828- if (beneath)28292829- path_put(&under);28302830- return err;28482848+ } while (err == -EAGAIN);28312849}2832285028332833-static inline int lock_mount(struct path *path, struct pinned_mountpoint *m)28342834-{28352835- return do_lock_mount(path, m, false);28362836-}28372837-28382838-static void unlock_mount(struct pinned_mountpoint *m)28512851+static void __unlock_mount(struct pinned_mountpoint *m)28392852{28402853 inode_unlock(m->mp->m_dentry->d_inode);28412854 read_seqlock_excl(&mount_lock);···28542847 namespace_unlock();28552848}2856284928572857-static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)28502850+static inline void unlock_mount(struct pinned_mountpoint *m)28512851+{28522852+ if (!IS_ERR(m->parent))28532853+ __unlock_mount(m);28542854+}28552855+28562856+#define LOCK_MOUNT_MAYBE_BENEATH(mp, path, beneath) \28572857+ struct pinned_mountpoint mp __cleanup(unlock_mount) = {}; \28582858+ do_lock_mount((path), &mp, (beneath))28592859+#define LOCK_MOUNT(mp, path) LOCK_MOUNT_MAYBE_BENEATH(mp, (path), false)28602860+#define LOCK_MOUNT_EXACT(mp, path) \28612861+ struct pinned_mountpoint mp __cleanup(unlock_mount) = {}; \28622862+ lock_mount_exact((path), &mp)28632863+28642864+static int graft_tree(struct mount *mnt, const struct pinned_mountpoint *mp)28582865{28592866 if (mnt->mnt.mnt_sb->s_flags & SB_NOUSER)28602867 return -EINVAL;2861286828622862- if (d_is_dir(mp->m_dentry) !=28692869+ if (d_is_dir(mp->mp->m_dentry) !=28632870 d_is_dir(mnt->mnt.mnt_root))28642871 return -ENOTDIR;2865287228662866- return attach_recursive_mnt(mnt, p, mp);28732873+ return attach_recursive_mnt(mnt, mp);28672874}2868287528692876static int may_change_propagation(const struct mount *m)···29132892/*29142893 * recursively change the type of the mountpoint.29152894 */29162916-static int do_change_type(struct path *path, int ms_flags)28952895+static int do_change_type(const struct path *path, int ms_flags)29172896{29182897 struct mount *m;29192898 struct mount *mnt = real_mount(path->mnt);29202899 int recurse = ms_flags & MS_REC;29212900 int type;29222922- int err = 0;29012901+ int err;2923290229242903 if (!path_mounted(path))29252904 return -EINVAL;···29282907 if (!type)29292908 return -EINVAL;2930290929312931- namespace_lock();29102910+ guard(namespace_excl)();29112911+29322912 err = may_change_propagation(mnt);29332913 if (err)29342934- goto out_unlock;29142914+ return err;2935291529362916 if (type == MS_SHARED) {29372917 err = invent_group_ids(mnt, recurse);29382918 if (err)29392939- goto out_unlock;29192919+ return err;29402920 }2941292129422922 for (m = mnt; m; m = (recurse ? next_mnt(m, mnt) : NULL))29432923 change_mnt_propagation(m, type);2944292429452945- out_unlock:29462946- namespace_unlock();29472947- return err;29252925+ return 0;29482926}2949292729502928/* may_copy_tree() - check if a mount tree can be copied···29892969 *29902970 * Returns true if the mount tree can be copied, false otherwise.29912971 */29922992-static inline bool may_copy_tree(struct path *path)29722972+static inline bool may_copy_tree(const struct path *path)29932973{29942974 struct mount *mnt = real_mount(path->mnt);29952975 const struct dentry_operations *d_op;···30112991}301229923013299330143014-static struct mount *__do_loopback(struct path *old_path, int recurse)29942994+static struct mount *__do_loopback(const struct path *old_path, int recurse)30152995{30162996 struct mount *old = real_mount(old_path->mnt);30172997···30333013/*30343014 * do loopback mount.30353015 */30363036-static int do_loopback(struct path *path, const char *old_name,30373037- int recurse)30163016+static int do_loopback(const struct path *path, const char *old_name,30173017+ int recurse)30383018{30393039- struct path old_path;30403040- struct mount *mnt = NULL, *parent;30413041- struct pinned_mountpoint mp = {};30193019+ struct path old_path __free(path_put) = {};30203020+ struct mount *mnt = NULL;30423021 int err;30433022 if (!old_name || !*old_name)30443023 return -EINVAL;···30453026 if (err)30463027 return err;3047302830483048- err = -EINVAL;30493029 if (mnt_ns_loop(old_path.dentry))30503050- goto out;30303030+ return -EINVAL;3051303130523052- err = lock_mount(path, &mp);30533053- if (err)30543054- goto out;30323032+ LOCK_MOUNT(mp, path);30333033+ if (IS_ERR(mp.parent))30343034+ return PTR_ERR(mp.parent);3055303530563056- parent = real_mount(path->mnt);30573057- if (!check_mnt(parent))30583058- goto out2;30363036+ if (!check_mnt(mp.parent))30373037+ return -EINVAL;3059303830603039 mnt = __do_loopback(&old_path, recurse);30613061- if (IS_ERR(mnt)) {30623062- err = PTR_ERR(mnt);30633063- goto out2;30643064- }30403040+ if (IS_ERR(mnt))30413041+ return PTR_ERR(mnt);3065304230663066- err = graft_tree(mnt, parent, mp.mp);30433043+ err = graft_tree(mnt, &mp);30673044 if (err) {30683045 lock_mount_hash();30693046 umount_tree(mnt, UMOUNT_SYNC);30703047 unlock_mount_hash();30713048 }30723072-out2:30733073- unlock_mount(&mp);30743074-out:30753075- path_put(&old_path);30763049 return err;30773050}3078305130793079-static struct file *open_detached_copy(struct path *path, bool recursive)30523052+static struct mnt_namespace *get_detached_copy(const struct path *path, bool recursive)30803053{30813054 struct mnt_namespace *ns, *mnt_ns = current->nsproxy->mnt_ns, *src_mnt_ns;30823055 struct user_namespace *user_ns = mnt_ns->user_ns;30833056 struct mount *mnt, *p;30843084- struct file *file;3085305730863058 ns = alloc_mnt_ns(user_ns, true);30873059 if (IS_ERR(ns))30883088- return ERR_CAST(ns);30603060+ return ns;3089306130903090- namespace_lock();30623062+ guard(namespace_excl)();3091306330923064 /*30933065 * Record the sequence number of the source mount namespace.···3095308530963086 mnt = __do_loopback(path, recursive);30973087 if (IS_ERR(mnt)) {30983098- namespace_unlock();30993099- free_mnt_ns(ns);30883088+ emptied_ns = ns;31003089 return ERR_CAST(mnt);31013090 }3102309131033103- lock_mount_hash();31043092 for (p = mnt; p; p = next_mnt(p, mnt)) {31053093 mnt_add_to_ns(ns, p);31063094 ns->nr_mounts++;31073095 }31083096 ns->root = mnt;31093109- mntget(&mnt->mnt);31103110- unlock_mount_hash();31113111- namespace_unlock();30973097+ return ns;30983098+}30993099+31003100+static struct file *open_detached_copy(struct path *path, bool recursive)31013101+{31023102+ struct mnt_namespace *ns = get_detached_copy(path, recursive);31033103+ struct file *file;31043104+31053105+ if (IS_ERR(ns))31063106+ return ERR_CAST(ns);3112310731133108 mntput(path->mnt);31143114- path->mnt = &mnt->mnt;31093109+ path->mnt = mntget(&ns->root->mnt);31153110 file = dentry_open(path, O_PATH, current_cred());31163111 if (IS_ERR(file))31173112 dissolve_on_fput(path->mnt);···32333218 touch_mnt_namespace(mnt->mnt_ns);32343219}3235322032363236-static void mnt_warn_timestamp_expiry(struct path *mountpoint, struct vfsmount *mnt)32213221+static void mnt_warn_timestamp_expiry(const struct path *mountpoint,32223222+ struct vfsmount *mnt)32373223{32383224 struct super_block *sb = mnt->mnt_sb;32393225···32683252 * superblock it refers to. This is triggered by specifying MS_REMOUNT|MS_BIND32693253 * to mount(2).32703254 */32713271-static int do_reconfigure_mnt(struct path *path, unsigned int mnt_flags)32553255+static int do_reconfigure_mnt(const struct path *path, unsigned int mnt_flags)32723256{32733257 struct super_block *sb = path->mnt->mnt_sb;32743258 struct mount *mnt = real_mount(path->mnt);···33053289 * If you've mounted a non-root directory somewhere and want to do remount33063290 * on it - tough luck.33073291 */33083308-static int do_remount(struct path *path, int ms_flags, int sb_flags,32923292+static int do_remount(const struct path *path, int ms_flags, int sb_flags,33093293 int mnt_flags, void *data)33103294{33113295 int err;···33633347 return 0;33643348}3365334933663366-static int do_set_group(struct path *from_path, struct path *to_path)33503350+static int do_set_group(const struct path *from_path, const struct path *to_path)33673351{33683368- struct mount *from, *to;33523352+ struct mount *from = real_mount(from_path->mnt);33533353+ struct mount *to = real_mount(to_path->mnt);33693354 int err;3370335533713371- from = real_mount(from_path->mnt);33723372- to = real_mount(to_path->mnt);33733373-33743374- namespace_lock();33563356+ guard(namespace_excl)();3375335733763358 err = may_change_propagation(from);33773359 if (err)33783378- goto out;33603360+ return err;33793361 err = may_change_propagation(to);33803362 if (err)33813381- goto out;33633363+ return err;3382336433833383- err = -EINVAL;33843365 /* To and From paths should be mount roots */33853366 if (!path_mounted(from_path))33863386- goto out;33673367+ return -EINVAL;33873368 if (!path_mounted(to_path))33883388- goto out;33693369+ return -EINVAL;3389337033903371 /* Setting sharing groups is only allowed across same superblock */33913372 if (from->mnt.mnt_sb != to->mnt.mnt_sb)33923392- goto out;33733373+ return -EINVAL;3393337433943375 /* From mount root should be wider than To mount root */33953376 if (!is_subdir(to->mnt.mnt_root, from->mnt.mnt_root))33963396- goto out;33773377+ return -EINVAL;3397337833983379 /* From mount should not have locked children in place of To's root */33993380 if (__has_locked_children(from, to->mnt.mnt_root))34003400- goto out;33813381+ return -EINVAL;3401338234023383 /* Setting sharing groups is only allowed on private mounts */34033384 if (IS_MNT_SHARED(to) || IS_MNT_SLAVE(to))34043404- goto out;33853385+ return -EINVAL;3405338634063387 /* From should not be private */34073388 if (!IS_MNT_SHARED(from) && !IS_MNT_SLAVE(from))34083408- goto out;33893389+ return -EINVAL;3409339034103391 if (IS_MNT_SLAVE(from)) {34113392 hlist_add_behind(&to->mnt_slave, &from->mnt_slave);···34143401 list_add(&to->mnt_share, &from->mnt_share);34153402 set_mnt_shared(to);34163403 }34173417-34183418- err = 0;34193419-out:34203420- namespace_unlock();34213421- return err;34043404+ return 0;34223405}3423340634243407/**···3458344934593450/**34603451 * can_move_mount_beneath - check that we can mount beneath the top mount34613461- * @from: mount to mount beneath34623462- * @to: mount under which to mount34633463- * @mp: mountpoint of @to34523452+ * @mnt_from: mount we are trying to move34533453+ * @mnt_to: mount under which to mount34543454+ * @mp: mountpoint of @mnt_to34643455 *34653465- * - Make sure that @to->dentry is actually the root of a mount under34663466- * which we can mount another mount.34673456 * - Make sure that nothing can be mounted beneath the caller's current34683457 * root or the rootfs of the namespace.34693458 * - Make sure that the caller can unmount the topmost mount ensuring34703459 * that the caller could reveal the underlying mountpoint.34713471- * - Ensure that nothing has been mounted on top of @from before we34603460+ * - Ensure that nothing has been mounted on top of @mnt_from before we34723461 * grabbed @namespace_sem to avoid creating pointless shadow mounts.34733462 * - Prevent mounting beneath a mount if the propagation relationship34743463 * between the source mount, parent mount, and top mount would lead to···34753468 * Context: This function expects namespace_lock() to be held.34763469 * Return: On success 0, and on error a negative error code is returned.34773470 */34783478-static int can_move_mount_beneath(const struct path *from,34793479- const struct path *to,34713471+static int can_move_mount_beneath(const struct mount *mnt_from,34723472+ const struct mount *mnt_to,34803473 const struct mountpoint *mp)34813474{34823482- struct mount *mnt_from = real_mount(from->mnt),34833483- *mnt_to = real_mount(to->mnt),34843484- *parent_mnt_to = mnt_to->mnt_parent;34853485-34863486- if (!mnt_has_parent(mnt_to))34873487- return -EINVAL;34883488-34893489- if (!path_mounted(to))34903490- return -EINVAL;34753475+ struct mount *parent_mnt_to = mnt_to->mnt_parent;3491347634923477 if (IS_MNT_LOCKED(mnt_to))34933478 return -EINVAL;3494347934953480 /* Avoid creating shadow mounts during mount propagation. */34963496- if (path_overmounted(from))34813481+ if (mnt_from->overmount)34973482 return -EINVAL;3498348334993484 /*···35763577 return check_anonymous_mnt(mnt);35773578}3578357935793579-static int do_move_mount(struct path *old_path,35803580- struct path *new_path, enum mnt_tree_flags_t flags)35803580+static int do_move_mount(const struct path *old_path,35813581+ const struct path *new_path,35823582+ enum mnt_tree_flags_t flags)35813583{35823582- struct mnt_namespace *ns;35833583- struct mount *p;35843584- struct mount *old;35853585- struct mount *parent;35863586- struct pinned_mountpoint mp;35843584+ struct mount *old = real_mount(old_path->mnt);35873585 int err;35883586 bool beneath = flags & MNT_TREE_BENEATH;3589358735903590- err = do_lock_mount(new_path, &mp, beneath);35913591- if (err)35923592- return err;35883588+ if (!path_mounted(old_path))35893589+ return -EINVAL;3593359035943594- old = real_mount(old_path->mnt);35953595- p = real_mount(new_path->mnt);35963596- parent = old->mnt_parent;35973597- ns = old->mnt_ns;35913591+ if (d_is_dir(new_path->dentry) != d_is_dir(old_path->dentry))35923592+ return -EINVAL;3598359335993599- err = -EINVAL;35943594+ LOCK_MOUNT_MAYBE_BENEATH(mp, new_path, beneath);35953595+ if (IS_ERR(mp.parent))35963596+ return PTR_ERR(mp.parent);3600359736013598 if (check_mnt(old)) {36023599 /* if the source is in our namespace... */36033600 /* ... it should be detachable from parent */36043601 if (!mnt_has_parent(old) || IS_MNT_LOCKED(old))36053605- goto out;36023602+ return -EINVAL;36033603+ /* ... which should not be shared */36043604+ if (IS_MNT_SHARED(old->mnt_parent))36053605+ return -EINVAL;36063606 /* ... and the target should be in our namespace */36073607- if (!check_mnt(p))36083608- goto out;36093609- /* parent of the source should not be shared */36103610- if (IS_MNT_SHARED(parent))36113611- goto out;36073607+ if (!check_mnt(mp.parent))36083608+ return -EINVAL;36123609 } else {36133610 /*36143611 * otherwise the source must be the root of some anon namespace.36153612 */36163613 if (!anon_ns_root(old))36173617- goto out;36143614+ return -EINVAL;36183615 /*36193616 * Bail out early if the target is within the same namespace -36203617 * subsequent checks would've rejected that, but they lose36213618 * some corner cases if we check it early.36223619 */36233623- if (ns == p->mnt_ns)36243624- goto out;36203620+ if (old->mnt_ns == mp.parent->mnt_ns)36213621+ return -EINVAL;36253622 /*36263623 * Target should be either in our namespace or in an acceptable36273624 * anon namespace, sensu check_anonymous_mnt().36283625 */36293629- if (!may_use_mount(p))36303630- goto out;36263626+ if (!may_use_mount(mp.parent))36273627+ return -EINVAL;36313628 }3632362936333633- if (!path_mounted(old_path))36343634- goto out;36353635-36363636- if (d_is_dir(new_path->dentry) !=36373637- d_is_dir(old_path->dentry))36383638- goto out;36393639-36403630 if (beneath) {36413641- err = can_move_mount_beneath(old_path, new_path, mp.mp);36423642- if (err)36433643- goto out;36313631+ struct mount *over = real_mount(new_path->mnt);3644363236453645- err = -EINVAL;36463646- p = p->mnt_parent;36333633+ if (mp.parent != over->mnt_parent)36343634+ over = mp.parent->overmount;36353635+ err = can_move_mount_beneath(old, over, mp.mp);36363636+ if (err)36373637+ return err;36473638 }3648363936493640 /*36503641 * Don't move a mount tree containing unbindable mounts to a destination36513642 * mount which is shared.36523643 */36533653- if (IS_MNT_SHARED(p) && tree_contains_unbindable(old))36543654- goto out;36553655- err = -ELOOP;36443644+ if (IS_MNT_SHARED(mp.parent) && tree_contains_unbindable(old))36453645+ return -EINVAL;36563646 if (!check_for_nsfs_mounts(old))36573657- goto out;36583658- if (mount_is_ancestor(old, p))36593659- goto out;36473647+ return -ELOOP;36483648+ if (mount_is_ancestor(old, mp.parent))36493649+ return -ELOOP;3660365036613661- err = attach_recursive_mnt(old, p, mp.mp);36623662-out:36633663- unlock_mount(&mp);36643664- return err;36513651+ return attach_recursive_mnt(old, &mp);36653652}3666365336673667-static int do_move_mount_old(struct path *path, const char *old_name)36543654+static int do_move_mount_old(const struct path *path, const char *old_name)36683655{36693669- struct path old_path;36563656+ struct path old_path __free(path_put) = {};36703657 int err;3671365836723659 if (!old_name || !*old_name)···36623677 if (err)36633678 return err;3664367936653665- err = do_move_mount(&old_path, path, 0);36663666- path_put(&old_path);36673667- return err;36803680+ return do_move_mount(&old_path, path, 0);36683681}3669368236703683/*36713684 * add a mount into a namespace's mount tree36723685 */36733673-static int do_add_mount(struct mount *newmnt, struct mountpoint *mp,36743674- const struct path *path, int mnt_flags)36863686+static int do_add_mount(struct mount *newmnt, const struct pinned_mountpoint *mp,36873687+ int mnt_flags)36753688{36763676- struct mount *parent = real_mount(path->mnt);36893689+ struct mount *parent = mp->parent;36903690+36913691+ if (IS_ERR(parent))36923692+ return PTR_ERR(parent);3677369336783694 mnt_flags &= ~MNT_INTERNAL_FLAGS;36793695···36883702 }3689370336903704 /* Refuse the same filesystem on the same mount point */36913691- if (path->mnt->mnt_sb == newmnt->mnt.mnt_sb && path_mounted(path))37053705+ if (parent->mnt.mnt_sb == newmnt->mnt.mnt_sb &&37063706+ parent->mnt.mnt_root == mp->mp->m_dentry)36923707 return -EBUSY;3693370836943709 if (d_is_symlink(newmnt->mnt.mnt_root))36953710 return -EINVAL;3696371136973712 newmnt->mnt.mnt_flags = mnt_flags;36983698- return graft_tree(newmnt, parent, mp);37133713+ return graft_tree(newmnt, mp);36993714}3700371537013716static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags);···37053718 * Create a new mount using a superblock configuration and request it37063719 * be added to the namespace tree.37073720 */37083708-static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint,37213721+static int do_new_mount_fc(struct fs_context *fc, const struct path *mountpoint,37093722 unsigned int mnt_flags)37103723{37113711- struct vfsmount *mnt;37123712- struct pinned_mountpoint mp = {};37133713- struct super_block *sb = fc->root->d_sb;37243724+ struct super_block *sb;37253725+ struct vfsmount *mnt __free(mntput) = fc_mount(fc);37143726 int error;3715372737163716- error = security_sb_kern_mount(sb);37173717- if (!error && mount_too_revealing(sb, &mnt_flags))37183718- error = -EPERM;37193719-37203720- if (unlikely(error)) {37213721- fc_drop_locked(fc);37223722- return error;37233723- }37243724-37253725- up_write(&sb->s_umount);37263726-37273727- mnt = vfs_create_mount(fc);37283728 if (IS_ERR(mnt))37293729 return PTR_ERR(mnt);3730373037313731+ sb = fc->root->d_sb;37323732+ error = security_sb_kern_mount(sb);37333733+ if (unlikely(error))37343734+ return error;37353735+37363736+ if (unlikely(mount_too_revealing(sb, &mnt_flags)))37373737+ return -EPERM;37383738+37313739 mnt_warn_timestamp_expiry(mountpoint, mnt);3732374037333733- error = lock_mount(mountpoint, &mp);37343734- if (!error) {37353735- error = do_add_mount(real_mount(mnt), mp.mp,37363736- mountpoint, mnt_flags);37373737- unlock_mount(&mp);37383738- }37393739- if (error < 0)37403740- mntput(mnt);37413741+ LOCK_MOUNT(mp, mountpoint);37423742+ error = do_add_mount(real_mount(mnt), &mp, mnt_flags);37433743+ if (!error)37443744+ retain_and_null_ptr(mnt); // consumed on success37413745 return error;37423746}37433747···37363758 * create a new mount for userspace and request it to be added into the37373759 * namespace's tree37383760 */37393739-static int do_new_mount(struct path *path, const char *fstype, int sb_flags,37403740- int mnt_flags, const char *name, void *data)37613761+static int do_new_mount(const struct path *path, const char *fstype,37623762+ int sb_flags, int mnt_flags,37633763+ const char *name, void *data)37413764{37423765 struct file_system_type *type;37433766 struct fs_context *fc;···37843805 if (!err && !mount_capable(fc))37853806 err = -EPERM;37863807 if (!err)37873787- err = vfs_get_tree(fc);37883788- if (!err)37893808 err = do_new_mount_fc(fc, path, mnt_flags);3790380937913810 put_fs_context(fc);37923811 return err;37933812}3794381337953795-int finish_automount(struct vfsmount *m, const struct path *path)38143814+static void lock_mount_exact(const struct path *path,38153815+ struct pinned_mountpoint *mp)37963816{37973817 struct dentry *dentry = path->dentry;37983798- struct pinned_mountpoint mp = {};38183818+ int err;38193819+38203820+ inode_lock(dentry->d_inode);38213821+ namespace_lock();38223822+ if (unlikely(cant_mount(dentry)))38233823+ err = -ENOENT;38243824+ else if (path_overmounted(path))38253825+ err = -EBUSY;38263826+ else38273827+ err = get_mountpoint(dentry, mp);38283828+ if (unlikely(err)) {38293829+ namespace_unlock();38303830+ inode_unlock(dentry->d_inode);38313831+ mp->parent = ERR_PTR(err);38323832+ } else {38333833+ mp->parent = real_mount(path->mnt);38343834+ }38353835+}38363836+38373837+int finish_automount(struct vfsmount *__m, const struct path *path)38383838+{38393839+ struct vfsmount *m __free(mntput) = __m;37993840 struct mount *mnt;38003841 int err;38013842···3826382738273828 mnt = real_mount(m);3828382938293829- if (m->mnt_sb == path->mnt->mnt_sb &&38303830- m->mnt_root == dentry) {38313831- err = -ELOOP;38323832- goto discard;38333833- }38303830+ if (m->mnt_root == path->dentry)38313831+ return -ELOOP;3834383238353833 /*38363836- * we don't want to use lock_mount() - in this case finding something38343834+ * we don't want to use LOCK_MOUNT() - in this case finding something38373835 * that overmounts our mountpoint to be means "quitely drop what we've38383836 * got", not "try to mount it on top".38393837 */38403840- inode_lock(dentry->d_inode);38413841- namespace_lock();38423842- if (unlikely(cant_mount(dentry))) {38433843- err = -ENOENT;38443844- goto discard_locked;38453845- }38463846- if (path_overmounted(path)) {38473847- err = 0;38483848- goto discard_locked;38493849- }38503850- err = get_mountpoint(dentry, &mp);38513851- if (err)38523852- goto discard_locked;38383838+ LOCK_MOUNT_EXACT(mp, path);38393839+ if (mp.parent == ERR_PTR(-EBUSY))38403840+ return 0;3853384138543854- err = do_add_mount(mnt, mp.mp, path,38553855- path->mnt->mnt_flags | MNT_SHRINKABLE);38563856- unlock_mount(&mp);38573857- if (unlikely(err))38583858- goto discard;38593859- return 0;38603860-38613861-discard_locked:38623862- namespace_unlock();38633863- inode_unlock(dentry->d_inode);38643864-discard:38653865- mntput(m);38423842+ err = do_add_mount(mnt, &mp, path->mnt->mnt_flags | MNT_SHRINKABLE);38433843+ if (likely(!err))38443844+ retain_and_null_ptr(m);38663845 return err;38673846}38683847···38513874 */38523875void mnt_set_expiry(struct vfsmount *mnt, struct list_head *expiry_list)38533876{38543854- read_seqlock_excl(&mount_lock);38773877+ guard(mount_locked_reader)();38553878 list_add_tail(&real_mount(mnt)->mnt_expire, expiry_list);38563856- read_sequnlock_excl(&mount_lock);38573879}38583880EXPORT_SYMBOL(mnt_set_expiry);38593881···38693893 if (list_empty(mounts))38703894 return;3871389538723872- namespace_lock();38733873- lock_mount_hash();38963896+ guard(namespace_excl)();38973897+ guard(mount_writer)();3874389838753899 /* extract from the expiration list every vfsmount that matches the38763900 * following criteria:···38923916 touch_mnt_namespace(mnt->mnt_ns);38933917 umount_tree(mnt, UMOUNT_PROPAGATE|UMOUNT_SYNC);38943918 }38953895- unlock_mount_hash();38963896- namespace_unlock();38973919}3898392038993921EXPORT_SYMBOL_GPL(mark_mounts_for_expiry);···40194045 * Therefore, if this magic number is present, it carries no information40204046 * and must be discarded.40214047 */40224022-int path_mount(const char *dev_name, struct path *path,40484048+int path_mount(const char *dev_name, const struct path *path,40234049 const char *type_page, unsigned long flags, void *data_page)40244050{40254051 unsigned int mnt_flags = 0, sb_flags;···41014127int do_mount(const char *dev_name, const char __user *dir_name,41024128 const char *type_page, unsigned long flags, void *data_page)41034129{41044104- struct path path;41304130+ struct path path __free(path_put) = {};41054131 int ret;4106413241074133 ret = user_path_at(AT_FDCWD, dir_name, LOOKUP_FOLLOW, &path);41084134 if (ret)41094135 return ret;41104110- ret = path_mount(dev_name, &path, type_page, flags, data_page);41114111- path_put(&path);41124112- return ret;41364136+ return path_mount(dev_name, &path, type_page, flags, data_page);41134137}4114413841154139static struct ucounts *inc_mnt_namespaces(struct user_namespace *ns)···41794207 struct user_namespace *user_ns, struct fs_struct *new_fs)41804208{41814209 struct mnt_namespace *new_ns;41824182- struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;42104210+ struct vfsmount *rootmnt __free(mntput) = NULL;42114211+ struct vfsmount *pwdmnt __free(mntput) = NULL;41834212 struct mount *p, *q;41844213 struct mount *old;41854214 struct mount *new;···41994226 if (IS_ERR(new_ns))42004227 return new_ns;4201422842024202- namespace_lock();42294229+ guard(namespace_excl)();42034230 /* First pass: copy the tree topology */42044231 copy_flags = CL_COPY_UNBINDABLE | CL_EXPIRE;42054232 if (user_ns != ns->user_ns)42064233 copy_flags |= CL_SLAVE;42074234 new = copy_tree(old, old->mnt.mnt_root, copy_flags);42084235 if (IS_ERR(new)) {42094209- namespace_unlock();42104210- ns_free_inum(&new_ns->ns);42114211- dec_mnt_namespaces(new_ns->ucounts);42124212- mnt_ns_release(new_ns);42364236+ emptied_ns = new_ns;42134237 return ERR_CAST(new);42144238 }42154239 if (user_ns != ns->user_ns) {42164216- lock_mount_hash();42404240+ guard(mount_writer)();42174241 lock_mnt_tree(new);42184218- unlock_mount_hash();42194242 }42204243 new_ns->root = new;42214244···42434274 while (p->mnt.mnt_root != q->mnt.mnt_root)42444275 p = next_mnt(skip_mnt_tree(p), old);42454276 }42464246- namespace_unlock();42474247-42484248- if (rootmnt)42494249- mntput(rootmnt);42504250- if (pwdmnt)42514251- mntput(pwdmnt);42524252-42534277 mnt_ns_tree_add(new_ns);42544278 return new_ns;42554279}···44674505 return ret;44684506}4469450744704470-static inline int vfs_move_mount(struct path *from_path, struct path *to_path,45084508+static inline int vfs_move_mount(const struct path *from_path,45094509+ const struct path *to_path,44714510 enum mnt_tree_flags_t mflags)44724511{44734512 int ret;···45744611/*45754612 * Return true if path is reachable from root45764613 *45774577- * namespace_sem or mount_lock is held46144614+ * locks: mount_locked_reader || namespace_shared && is_mounted(mnt)45784615 */45794616bool is_path_reachable(struct mount *mnt, struct dentry *dentry,45804617 const struct path *root)···4588462545894626bool path_is_under(const struct path *path1, const struct path *path2)45904627{45914591- bool res;45924592- read_seqlock_excl(&mount_lock);45934593- res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2);45944594- read_sequnlock_excl(&mount_lock);45954595- return res;46284628+ guard(mount_locked_reader)();46294629+ return is_path_reachable(real_mount(path1->mnt), path1->dentry, path2);45964630}45974631EXPORT_SYMBOL(path_is_under);45984632···46214661SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,46224662 const char __user *, put_old)46234663{46244624- struct path new, old, root;46644664+ struct path new __free(path_put) = {};46654665+ struct path old __free(path_put) = {};46664666+ struct path root __free(path_put) = {};46254667 struct mount *new_mnt, *root_mnt, *old_mnt, *root_parent, *ex_parent;46264626- struct pinned_mountpoint old_mp = {};46274668 int error;4628466946294670 if (!may_mount())···46334672 error = user_path_at(AT_FDCWD, new_root,46344673 LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &new);46354674 if (error)46364636- goto out0;46754675+ return error;4637467646384677 error = user_path_at(AT_FDCWD, put_old,46394678 LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &old);46404679 if (error)46414641- goto out1;46804680+ return error;4642468146434682 error = security_sb_pivotroot(&old, &new);46444683 if (error)46454645- goto out2;46844684+ return error;4646468546474686 get_fs_root(current->fs, &root);46484648- error = lock_mount(&old, &old_mp);46494649- if (error)46504650- goto out3;4651468746524652- error = -EINVAL;46884688+ LOCK_MOUNT(old_mp, &old);46894689+ old_mnt = old_mp.parent;46904690+ if (IS_ERR(old_mnt))46914691+ return PTR_ERR(old_mnt);46924692+46534693 new_mnt = real_mount(new.mnt);46544694 root_mnt = real_mount(root.mnt);46554655- old_mnt = real_mount(old.mnt);46564695 ex_parent = new_mnt->mnt_parent;46574696 root_parent = root_mnt->mnt_parent;46584697 if (IS_MNT_SHARED(old_mnt) ||46594698 IS_MNT_SHARED(ex_parent) ||46604699 IS_MNT_SHARED(root_parent))46614661- goto out4;47004700+ return -EINVAL;46624701 if (!check_mnt(root_mnt) || !check_mnt(new_mnt))46634663- goto out4;47024702+ return -EINVAL;46644703 if (new_mnt->mnt.mnt_flags & MNT_LOCKED)46654665- goto out4;46664666- error = -ENOENT;47044704+ return -EINVAL;46674705 if (d_unlinked(new.dentry))46684668- goto out4;46694669- error = -EBUSY;47064706+ return -ENOENT;46704707 if (new_mnt == root_mnt || old_mnt == root_mnt)46714671- goto out4; /* loop, on the same file system */46724672- error = -EINVAL;47084708+ return -EBUSY; /* loop, on the same file system */46734709 if (!path_mounted(&root))46744674- goto out4; /* not a mountpoint */47104710+ return -EINVAL; /* not a mountpoint */46754711 if (!mnt_has_parent(root_mnt))46764676- goto out4; /* absolute root */47124712+ return -EINVAL; /* absolute root */46774713 if (!path_mounted(&new))46784678- goto out4; /* not a mountpoint */47144714+ return -EINVAL; /* not a mountpoint */46794715 if (!mnt_has_parent(new_mnt))46804680- goto out4; /* absolute root */47164716+ return -EINVAL; /* absolute root */46814717 /* make sure we can reach put_old from new_root */46824682- if (!is_path_reachable(old_mnt, old.dentry, &new))46834683- goto out4;47184718+ if (!is_path_reachable(old_mnt, old_mp.mp->m_dentry, &new))47194719+ return -EINVAL;46844720 /* make certain new is below the root */46854721 if (!is_path_reachable(new_mnt, new.dentry, &root))46864686- goto out4;47224722+ return -EINVAL;46874723 lock_mount_hash();46884724 umount_mnt(new_mnt);46894725 if (root_mnt->mnt.mnt_flags & MNT_LOCKED) {···46994741 mnt_notify_add(root_mnt);47004742 mnt_notify_add(new_mnt);47014743 chroot_fs_refs(&root, &new);47024702- error = 0;47034703-out4:47044704- unlock_mount(&old_mp);47054705-out3:47064706- path_put(&root);47074707-out2:47084708- path_put(&old);47094709-out1:47104710- path_put(&new);47114711-out0:47124712- return error;47444744+ return 0;47134745}4714474647154747static unsigned int recalc_flags(struct mount_kattr *kattr, struct mount *mnt)···4789484147904842 if (!mnt_allow_writers(kattr, m)) {47914843 err = mnt_hold_writers(m);47924792- if (err)48444844+ if (err) {48454845+ m = next_mnt(m, mnt);47934846 break;48474847+ }47944848 }4795484947964850 if (!(kattr->kflags & MOUNT_KATTR_RECURSE))···48004850 }4801485148024852 if (err) {48034803- struct mount *p;48044804-48054805- /*48064806- * If we had to call mnt_hold_writers() MNT_WRITE_HOLD will48074807- * be set in @mnt_flags. The loop unsets MNT_WRITE_HOLD for all48084808- * mounts and needs to take care to include the first mount.48094809- */48104810- for (p = mnt; p; p = next_mnt(p, mnt)) {48114811- /* If we had to hold writers unblock them. */48124812- if (p->mnt.mnt_flags & MNT_WRITE_HOLD)48134813- mnt_unhold_writers(p);48144814-48154815- /*48164816- * We're done once the first mount we changed got48174817- * MNT_WRITE_HOLD unset.48184818- */48194819- if (p == m)48204820- break;48214821- }48534853+ /* undo all mnt_hold_writers() we'd done */48544854+ for (struct mount *p = mnt; p != m; p = next_mnt(p, mnt))48554855+ mnt_unhold_writers(p);48224856 }48234857 return err;48244858}···48334899 WRITE_ONCE(m->mnt.mnt_flags, flags);4834490048354901 /* If we had to hold writers unblock them. */48364836- if (m->mnt.mnt_flags & MNT_WRITE_HOLD)48374837- mnt_unhold_writers(m);49024902+ mnt_unhold_writers(m);4838490348394904 if (kattr->propagation)48404905 change_mnt_propagation(m, kattr->propagation);···48434910 touch_mnt_namespace(mnt->mnt_ns);48444911}4845491248464846-static int do_mount_setattr(struct path *path, struct mount_kattr *kattr)49134913+static int do_mount_setattr(const struct path *path, struct mount_kattr *kattr)48474914{48484915 struct mount *mnt = real_mount(path->mnt);48494916 int err = 0;···56415708 STATMOUNT_MNT_UIDMAP | \56425709 STATMOUNT_MNT_GIDMAP)5643571057115711+/* locks: namespace_shared */56445712static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id,56455713 struct mnt_namespace *ns)56465714{···58915957 if (ret)58925958 return ret;5893595958945894- scoped_guard(rwsem_read, &namespace_sem)59605960+ scoped_guard(namespace_shared)58955961 ret = do_statmount(ks, kreq.mnt_id, kreq.mnt_ns_id, ns);5896596258975963 if (!ret)···59025968 return ret;59035969}5904597059715971+/* locks: namespace_shared */59055972static ssize_t do_listmount(struct mnt_namespace *ns, u64 mnt_parent_id,59065973 u64 last_mnt_id, u64 *mnt_ids, size_t nr_mnt_ids,59075974 bool reverse)···60146079 * We only need to guard against mount topology changes as60156080 * listmount() doesn't care about any mount properties.60166081 */60176017- scoped_guard(rwsem_read, &namespace_sem)60826082+ scoped_guard(namespace_shared)60186083 ret = do_listmount(ns, kreq.mnt_id, last_mnt_id, kmnt_ids,60196084 nr_mnt_ids, (flags & LISTMOUNT_REVERSE));60206085 if (ret <= 0)···60976162{60986163 if (!refcount_dec_and_test(&ns->ns.count))60996164 return;61006100- namespace_lock();61656165+ guard(namespace_excl)();61016166 emptied_ns = ns;61026102- lock_mount_hash();61676167+ guard(mount_writer)();61036168 umount_tree(ns->root, 0);61046104- unlock_mount_hash();61056105- namespace_unlock();61066169}6107617061086171struct vfsmount *kern_mount(struct file_system_type *type)···61496216bool current_chrooted(void)61506217{61516218 /* Does the current process have a non-standard root */61526152- struct path ns_root;61536153- struct path fs_root;61546154- bool chrooted;61556155-61566156- /* Find the namespace root */61576157- ns_root.mnt = ¤t->nsproxy->mnt_ns->root->mnt;61586158- ns_root.dentry = ns_root.mnt->mnt_root;61596159- path_get(&ns_root);61606160- while (d_mountpoint(ns_root.dentry) && follow_down_one(&ns_root))61616161- ;62196219+ struct path fs_root __free(path_put) = {};62206220+ struct mount *root;6162622161636222 get_fs_root(current->fs, &fs_root);6164622361656165- chrooted = !path_equal(&fs_root, &ns_root);62246224+ /* Find the namespace root */6166622561676167- path_put(&fs_root);61686168- path_put(&ns_root);62266226+ guard(mount_locked_reader)();6169622761706170- return chrooted;62286228+ root = topmost_overmount(current->nsproxy->mnt_ns->root);62296229+62306230+ return fs_root.mnt != &root->mnt || !path_mounted(&fs_root);61716231}6172623261736233static bool mnt_already_visible(struct mnt_namespace *ns,···61696243{61706244 int new_flags = *new_mnt_flags;61716245 struct mount *mnt, *n;61726172- bool visible = false;6173624661746174- down_read(&namespace_sem);62476247+ guard(namespace_shared)();61756248 rbtree_postorder_for_each_entry_safe(mnt, n, &ns->mounts, mnt_node) {61766249 struct mount *child;61776250 int mnt_flags;···62176292 /* Preserve the locked attributes */62186293 *new_mnt_flags |= mnt_flags & (MNT_LOCK_READONLY | \62196294 MNT_LOCK_ATIME);62206220- visible = true;62216221- goto found;62956295+ return true;62226296 next: ;62236297 }62246224-found:62256225- up_read(&namespace_sem);62266226- return visible;62986298+ return false;62276299}6228630062296301static bool mount_too_revealing(const struct super_block *sb, int *new_mnt_flags)
+1-1
fs/nfs/localio.c
···529529}530530531531/* Factored out from fs/nfsd/vfs.h:fh_getattr() */532532-static int __vfs_getattr(struct path *p, struct kstat *stat, int version)532532+static int __vfs_getattr(const struct path *p, struct kstat *stat, int version)533533{534534 u32 request_mask = STATX_BASIC_STATS;535535
···270270 int (*commit_blocks)(struct inode *inode, struct iomap *iomaps,271271 int nr_iomaps, struct iattr *iattr);272272 int (*permission)(struct handle_to_path_ctx *ctx, unsigned int oflags);273273- struct file * (*open)(struct path *path, unsigned int oflags);273273+ struct file * (*open)(const struct path *path, unsigned int oflags);274274#define EXPORT_OP_NOWCC (0x1) /* don't collect v3 wcc data */275275#define EXPORT_OP_NOSUBTREECHK (0x2) /* no subtree checking */276276#define EXPORT_OP_CLOSE_BEFORE_UNLINK (0x4) /* close files before unlink */
+4-2
include/linux/fs.h
···13241324 struct percpu_rw_semaphore rw_sem[SB_FREEZE_LEVELS];13251325};1326132613271327+struct mount;13281328+13271329struct super_block {13281330 struct list_head s_list; /* Keep this first */13291331 dev_t s_dev; /* search index; _not_ kdev_t */···13601358 __u16 s_encoding_flags;13611359#endif13621360 struct hlist_bl_head s_roots; /* alternate root dentries for NFS */13631363- struct list_head s_mounts; /* list of mounts; _not_ for fs use */13611361+ struct mount *s_mounts; /* list of mounts; _not_ for fs use */13641362 struct block_device *s_bdev; /* can go away once we use an accessor for @s_bdev_file */13651363 struct file *s_bdev_file;13661364 struct backing_dev_info *s_bdi;···28812879 const struct cred *cred);28822880struct file *dentry_create(const struct path *path, int flags, umode_t mode,28832881 const struct cred *cred);28842884-struct path *backing_file_user_path(const struct file *f);28822882+const struct path *backing_file_user_path(const struct file *f);2885288328862884/*28872885 * When mmapping a file on a stackable filesystem (e.g., overlayfs), the file
···219219 * including the NULL termination character, stored in the supplied220220 * buffer. On error, a negative integer is returned.221221 */222222-extern int bpf_path_d_path(struct path *path, char *buf, size_t buf__sz) __ksym;222222+extern int bpf_path_d_path(const struct path *path, char *buf, size_t buf__sz) __ksym;223223224224/* This macro must be used to mark the exception callback corresponding to the225225 * main program. For example: