Commit 0f70f5b0 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull automount updates from Al Viro:
 "Automount wart removal

  A bunch of odd boilerplate gone from instances - the reason for
  those was the need to protect the yet-to-be-attched mount from
  mark_mounts_for_expiry() deciding to take it out.

  But that's easy to detect and take care of in mark_mounts_for_expiry()
  itself; no need to have every instance simulate mount being busy by
  grabbing an extra reference to it, with finish_automount() undoing
  that once it attaches that mount.

  Should've done it that way from the very beginning... This is a
  flagday change, thankfully there are very few instances.

  vfs_submount() is gone - its sole remaining user (trace_automount)
  had been switched to saner primitives"

* tag 'pull-automount' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  kill vfs_submount()
  saner calling conventions for ->d_automount()
parents edb94482 2dbf6e0d
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -1243,3 +1243,9 @@ arguments in the opposite order but is otherwise identical.

Using try_lookup_noperm() will require linux/namei.h to be included.

---

**mandatory**

Calling conventions for ->d_automount() have changed; we should *not* grab
an extra reference to new mount - it should be returned with refcount 1.
+1 −3
Original line number Diff line number Diff line
@@ -1390,9 +1390,7 @@ defined:

	If a vfsmount is returned, the caller will attempt to mount it
	on the mountpoint and will remove the vfsmount from its
	expiration list in the case of failure.  The vfsmount should be
	returned with 2 refs on it to prevent automatic expiration - the
	caller will clean up the additional ref.
	expiration list in the case of failure.

	This function is only used if DCACHE_NEED_AUTOMOUNT is set on
	the dentry.  This is set by __d_instantiate() if S_AUTOMOUNT is
+0 −1
Original line number Diff line number Diff line
@@ -189,7 +189,6 @@ struct vfsmount *afs_d_automount(struct path *path)
	if (IS_ERR(newmnt))
		return newmnt;

	mntget(newmnt); /* prevent immediate expiration */
	mnt_set_expiry(newmnt, &afs_vfsmounts);
	queue_delayed_work(afs_wq, &afs_mntpt_expiry_timer,
			   afs_mntpt_expiry_timeout * HZ);
+0 −3
Original line number Diff line number Diff line
@@ -319,9 +319,6 @@ static struct vfsmount *fuse_dentry_automount(struct path *path)

	/* Create the submount */
	mnt = fc_mount(fsc);
	if (!IS_ERR(mnt))
		mntget(mnt);

	put_fs_context(fsc);
	return mnt;
}
+3 −21
Original line number Diff line number Diff line
@@ -1326,21 +1326,6 @@ struct vfsmount *vfs_kern_mount(struct file_system_type *type,
}
EXPORT_SYMBOL_GPL(vfs_kern_mount);

struct vfsmount *
vfs_submount(const struct dentry *mountpoint, struct file_system_type *type,
	     const char *name, void *data)
{
	/* Until it is worked out how to pass the user namespace
	 * through from the parent mount to the submount don't support
	 * unprivileged mounts with submounts.
	 */
	if (mountpoint->d_sb->s_user_ns != &init_user_ns)
		return ERR_PTR(-EPERM);

	return vfs_kern_mount(type, SB_SUBMOUNT, name, data);
}
EXPORT_SYMBOL_GPL(vfs_submount);

static struct mount *clone_mnt(struct mount *old, struct dentry *root,
					int flag)
{
@@ -3889,10 +3874,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
		return PTR_ERR(m);

	mnt = real_mount(m);
	/* The new mount record should have at least 2 refs to prevent it being
	 * expired before we get a chance to add it
	 */
	BUG_ON(mnt_get_count(mnt) < 2);

	if (m->mnt_sb == path->mnt->mnt_sb &&
	    m->mnt_root == dentry) {
@@ -3925,7 +3906,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
	unlock_mount(mp);
	if (unlikely(err))
		goto discard;
	mntput(m);
	return 0;

discard_locked:
@@ -3939,7 +3919,6 @@ int finish_automount(struct vfsmount *m, const struct path *path)
		namespace_unlock();
	}
	mntput(m);
	mntput(m);
	return err;
}

@@ -3976,11 +3955,14 @@ void mark_mounts_for_expiry(struct list_head *mounts)

	/* extract from the expiration list every vfsmount that matches the
	 * following criteria:
	 * - already mounted
	 * - only referenced by its parent vfsmount
	 * - still marked for expiry (marked on the last call here; marks are
	 *   cleared by mntput())
	 */
	list_for_each_entry_safe(mnt, next, mounts, mnt_expire) {
		if (!is_mounted(&mnt->mnt))
			continue;
		if (!xchg(&mnt->mnt_expiry_mark, 1) ||
			propagate_mount_busy(mnt, 1))
			continue;
Loading