Commit 2ca35346 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'vfs-6.16-rc1.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs mount updates from Christian Brauner:
 "This contains minor mount updates for this cycle:

   - mnt->mnt_devname can never be NULL so simplify the code handling
     that case

   - Add a comment about concurrent changes during statmount() and
     listmount()

   - Update the STATMOUNT_SUPPORTED macro

   - Convert mount flags to an enum"

* tag 'vfs-6.16-rc1.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  statmount: update STATMOUNT_SUPPORTED macro
  fs: convert mount flags to enum
  ->mnt_devname is never NULL
  mount: add a comment about concurrent changes with statmount()/listmount()
parents 8dd53535 2b3c61b8
Loading
Loading
Loading
Loading
+33 −10
Original line number Diff line number Diff line
@@ -355,12 +355,13 @@ static struct mount *alloc_vfsmnt(const char *name)
		if (err)
			goto out_free_cache;

		if (name) {
		if (name)
			mnt->mnt_devname = kstrdup_const(name,
							 GFP_KERNEL_ACCOUNT);
		else
			mnt->mnt_devname = "none";
		if (!mnt->mnt_devname)
			goto out_free_id;
		}

#ifdef CONFIG_SMP
		mnt->mnt_pcp = alloc_percpu(struct mnt_pcp);
@@ -1264,7 +1265,7 @@ struct vfsmount *vfs_create_mount(struct fs_context *fc)
	if (!fc->root)
		return ERR_PTR(-EINVAL);

	mnt = alloc_vfsmnt(fc->source ?: "none");
	mnt = alloc_vfsmnt(fc->source);
	if (!mnt)
		return ERR_PTR(-ENOMEM);

@@ -5491,7 +5492,7 @@ static int statmount_sb_source(struct kstatmount *s, struct seq_file *seq)
		seq->buf[seq->count] = '\0';
		seq->count = start;
		seq_commit(seq, string_unescape_inplace(seq->buf + start, UNESCAPE_OCTAL));
	} else if (r->mnt_devname) {
	} else {
		seq_puts(seq, r->mnt_devname);
	}
	return 0;
@@ -5804,7 +5805,9 @@ static int grab_requested_root(struct mnt_namespace *ns, struct path *root)
			     STATMOUNT_SB_SOURCE | \
			     STATMOUNT_OPT_ARRAY | \
			     STATMOUNT_OPT_SEC_ARRAY | \
			     STATMOUNT_SUPPORTED_MASK)
			     STATMOUNT_SUPPORTED_MASK | \
			     STATMOUNT_MNT_UIDMAP | \
			     STATMOUNT_MNT_GIDMAP)

static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id,
			struct mnt_namespace *ns)
@@ -5839,13 +5842,29 @@ static int do_statmount(struct kstatmount *s, u64 mnt_id, u64 mnt_ns_id,
		return err;

	s->root = root;
	s->idmap = mnt_idmap(s->mnt);
	if (s->mask & STATMOUNT_SB_BASIC)
		statmount_sb_basic(s);

	/*
	 * Note that mount properties in mnt->mnt_flags, mnt->mnt_idmap
	 * can change concurrently as we only hold the read-side of the
	 * namespace semaphore and mount properties may change with only
	 * the mount lock held.
	 *
	 * We could sample the mount lock sequence counter to detect
	 * those changes and retry. But it's not worth it. Worst that
	 * happens is that the mnt->mnt_idmap pointer is already changed
	 * while mnt->mnt_flags isn't or vica versa. So what.
	 *
	 * Both mnt->mnt_flags and mnt->mnt_idmap are set and retrieved
	 * via READ_ONCE()/WRITE_ONCE() and guard against theoretical
	 * torn read/write. That's all we care about right now.
	 */
	s->idmap = mnt_idmap(s->mnt);
	if (s->mask & STATMOUNT_MNT_BASIC)
		statmount_mnt_basic(s);

	if (s->mask & STATMOUNT_SB_BASIC)
		statmount_sb_basic(s);

	if (s->mask & STATMOUNT_PROPAGATE_FROM)
		statmount_propagate_from(s);

@@ -6157,6 +6176,10 @@ SYSCALL_DEFINE4(listmount, const struct mnt_id_req __user *, req,
	    !ns_capable_noaudit(ns->user_ns, CAP_SYS_ADMIN))
		return -ENOENT;

	/*
	 * We only need to guard against mount topology changes as
	 * listmount() doesn't care about any mount properties.
	 */
	scoped_guard(rwsem_read, &namespace_sem)
		ret = do_listmount(ns, kreq.mnt_id, last_mnt_id, kmnt_ids,
				   nr_mnt_ids, (flags & LISTMOUNT_REVERSE));
+4 −8
Original line number Diff line number Diff line
@@ -111,7 +111,7 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt)
		if (err)
			goto out;
	} else {
		mangle(m, r->mnt_devname ? r->mnt_devname : "none");
		mangle(m, r->mnt_devname);
	}
	seq_putc(m, ' ');
	/* mountpoints outside of chroot jail will give SEQ_SKIP on this */
@@ -177,7 +177,7 @@ static int show_mountinfo(struct seq_file *m, struct vfsmount *mnt)
		if (err)
			goto out;
	} else {
		mangle(m, r->mnt_devname ? r->mnt_devname : "none");
		mangle(m, r->mnt_devname);
	}
	seq_puts(m, sb_rdonly(sb) ? " ro" : " rw");
	err = show_sb_opts(m, sb);
@@ -199,17 +199,13 @@ static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt)
	int err;

	/* device */
	if (sb->s_op->show_devname) {
	seq_puts(m, "device ");
	if (sb->s_op->show_devname) {
		err = sb->s_op->show_devname(m, mnt_path.dentry);
		if (err)
			goto out;
	} else {
		if (r->mnt_devname) {
			seq_puts(m, "device ");
		mangle(m, r->mnt_devname);
		} else
			seq_puts(m, "no device");
	}

	/* mount point */
+45 −42
Original line number Diff line number Diff line
@@ -22,20 +22,35 @@ struct fs_context;
struct file;
struct path;

#define MNT_NOSUID	0x01
#define MNT_NODEV	0x02
#define MNT_NOEXEC	0x04
#define MNT_NOATIME	0x08
#define MNT_NODIRATIME	0x10
#define MNT_RELATIME	0x20
#define MNT_READONLY	0x40	/* does the user want this to be r/o? */
#define MNT_NOSYMFOLLOW	0x80

#define MNT_SHRINKABLE	0x100
#define MNT_WRITE_HOLD	0x200

#define MNT_SHARED	0x1000	/* if the vfsmount is a shared mount */
#define MNT_UNBINDABLE	0x2000	/* if the vfsmount is a unbindable mount */
enum mount_flags {
	MNT_NOSUID	= 0x01,
	MNT_NODEV	= 0x02,
	MNT_NOEXEC	= 0x04,
	MNT_NOATIME	= 0x08,
	MNT_NODIRATIME	= 0x10,
	MNT_RELATIME	= 0x20,
	MNT_READONLY	= 0x40, /* does the user want this to be r/o? */
	MNT_NOSYMFOLLOW	= 0x80,

	MNT_SHRINKABLE	= 0x100,
	MNT_WRITE_HOLD	= 0x200,

	MNT_SHARED	= 0x1000, /* if the vfsmount is a shared mount */
	MNT_UNBINDABLE	= 0x2000, /* if the vfsmount is a unbindable mount */

	MNT_INTERNAL	= 0x4000,

	MNT_LOCK_ATIME		= 0x040000,
	MNT_LOCK_NOEXEC		= 0x080000,
	MNT_LOCK_NOSUID		= 0x100000,
	MNT_LOCK_NODEV		= 0x200000,
	MNT_LOCK_READONLY	= 0x400000,
	MNT_LOCKED		= 0x800000,
	MNT_DOOMED		= 0x1000000,
	MNT_SYNC_UMOUNT		= 0x2000000,
	MNT_MARKED		= 0x4000000,
	MNT_UMOUNT		= 0x8000000,

	/*
	 * MNT_SHARED_MASK is the set of flags that should be cleared when a
	 * mount becomes shared.  Currently, this is only the flag that says a
@@ -43,27 +58,15 @@ struct path;
	 * that shares events with another mount.  If you add a new MNT_*
	 * flag, consider how it interacts with shared mounts.
	 */
#define MNT_SHARED_MASK	(MNT_UNBINDABLE)
#define MNT_USER_SETTABLE_MASK  (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \
				 | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \
				 | MNT_READONLY | MNT_NOSYMFOLLOW)
#define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME )

#define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \
			    MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED)

#define MNT_INTERNAL	0x4000

#define MNT_LOCK_ATIME		0x040000
#define MNT_LOCK_NOEXEC		0x080000
#define MNT_LOCK_NOSUID		0x100000
#define MNT_LOCK_NODEV		0x200000
#define MNT_LOCK_READONLY	0x400000
#define MNT_LOCKED		0x800000
#define MNT_DOOMED		0x1000000
#define MNT_SYNC_UMOUNT		0x2000000
#define MNT_MARKED		0x4000000
#define MNT_UMOUNT		0x8000000
	MNT_SHARED_MASK	= MNT_UNBINDABLE,
	MNT_USER_SETTABLE_MASK  = MNT_NOSUID | MNT_NODEV | MNT_NOEXEC
				  | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME
				  | MNT_READONLY | MNT_NOSYMFOLLOW,
	MNT_ATIME_MASK = MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME,

	MNT_INTERNAL_FLAGS = MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL |
			     MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED,
};

struct vfsmount {
	struct dentry *mnt_root;	/* root of the mounted tree */