Skip to content

Commit 2ca3534

Browse files
committed
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()
2 parents 8dd5353 + 2b3c61b commit 2ca3534

File tree

3 files changed

+82
-60
lines changed

3 files changed

+82
-60
lines changed

fs/namespace.c

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -355,12 +355,13 @@ static struct mount *alloc_vfsmnt(const char *name)
355355
if (err)
356356
goto out_free_cache;
357357

358-
if (name) {
358+
if (name)
359359
mnt->mnt_devname = kstrdup_const(name,
360360
GFP_KERNEL_ACCOUNT);
361-
if (!mnt->mnt_devname)
362-
goto out_free_id;
363-
}
361+
else
362+
mnt->mnt_devname = "none";
363+
if (!mnt->mnt_devname)
364+
goto out_free_id;
364365

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

1267-
mnt = alloc_vfsmnt(fc->source ?: "none");
1268+
mnt = alloc_vfsmnt(fc->source);
12681269
if (!mnt)
12691270
return ERR_PTR(-ENOMEM);
12701271

@@ -5491,7 +5492,7 @@ static int statmount_sb_source(struct kstatmount *s, struct seq_file *seq)
54915492
seq->buf[seq->count] = '\0';
54925493
seq->count = start;
54935494
seq_commit(seq, string_unescape_inplace(seq->buf + start, UNESCAPE_OCTAL));
5494-
} else if (r->mnt_devname) {
5495+
} else {
54955496
seq_puts(seq, r->mnt_devname);
54965497
}
54975498
return 0;
@@ -5804,7 +5805,9 @@ static int grab_requested_root(struct mnt_namespace *ns, struct path *root)
58045805
STATMOUNT_SB_SOURCE | \
58055806
STATMOUNT_OPT_ARRAY | \
58065807
STATMOUNT_OPT_SEC_ARRAY | \
5807-
STATMOUNT_SUPPORTED_MASK)
5808+
STATMOUNT_SUPPORTED_MASK | \
5809+
STATMOUNT_MNT_UIDMAP | \
5810+
STATMOUNT_MNT_GIDMAP)
58085811

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

58415844
s->root = root;
5842-
s->idmap = mnt_idmap(s->mnt);
5843-
if (s->mask & STATMOUNT_SB_BASIC)
5844-
statmount_sb_basic(s);
58455845

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

5865+
if (s->mask & STATMOUNT_SB_BASIC)
5866+
statmount_sb_basic(s);
5867+
58495868
if (s->mask & STATMOUNT_PROPAGATE_FROM)
58505869
statmount_propagate_from(s);
58515870

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

6179+
/*
6180+
* We only need to guard against mount topology changes as
6181+
* listmount() doesn't care about any mount properties.
6182+
*/
61606183
scoped_guard(rwsem_read, &namespace_sem)
61616184
ret = do_listmount(ns, kreq.mnt_id, last_mnt_id, kmnt_ids,
61626185
nr_mnt_ids, (flags & LISTMOUNT_REVERSE));

fs/proc_namespace.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ static int show_vfsmnt(struct seq_file *m, struct vfsmount *mnt)
111111
if (err)
112112
goto out;
113113
} else {
114-
mangle(m, r->mnt_devname ? r->mnt_devname : "none");
114+
mangle(m, r->mnt_devname);
115115
}
116116
seq_putc(m, ' ');
117117
/* 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)
177177
if (err)
178178
goto out;
179179
} else {
180-
mangle(m, r->mnt_devname ? r->mnt_devname : "none");
180+
mangle(m, r->mnt_devname);
181181
}
182182
seq_puts(m, sb_rdonly(sb) ? " ro" : " rw");
183183
err = show_sb_opts(m, sb);
@@ -199,17 +199,13 @@ static int show_vfsstat(struct seq_file *m, struct vfsmount *mnt)
199199
int err;
200200

201201
/* device */
202+
seq_puts(m, "device ");
202203
if (sb->s_op->show_devname) {
203-
seq_puts(m, "device ");
204204
err = sb->s_op->show_devname(m, mnt_path.dentry);
205205
if (err)
206206
goto out;
207207
} else {
208-
if (r->mnt_devname) {
209-
seq_puts(m, "device ");
210-
mangle(m, r->mnt_devname);
211-
} else
212-
seq_puts(m, "no device");
208+
mangle(m, r->mnt_devname);
213209
}
214210

215211
/* mount point */

include/linux/mount.h

Lines changed: 45 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -22,48 +22,51 @@ struct fs_context;
2222
struct file;
2323
struct path;
2424

25-
#define MNT_NOSUID 0x01
26-
#define MNT_NODEV 0x02
27-
#define MNT_NOEXEC 0x04
28-
#define MNT_NOATIME 0x08
29-
#define MNT_NODIRATIME 0x10
30-
#define MNT_RELATIME 0x20
31-
#define MNT_READONLY 0x40 /* does the user want this to be r/o? */
32-
#define MNT_NOSYMFOLLOW 0x80
33-
34-
#define MNT_SHRINKABLE 0x100
35-
#define MNT_WRITE_HOLD 0x200
36-
37-
#define MNT_SHARED 0x1000 /* if the vfsmount is a shared mount */
38-
#define MNT_UNBINDABLE 0x2000 /* if the vfsmount is a unbindable mount */
39-
/*
40-
* MNT_SHARED_MASK is the set of flags that should be cleared when a
41-
* mount becomes shared. Currently, this is only the flag that says a
42-
* mount cannot be bind mounted, since this is how we create a mount
43-
* that shares events with another mount. If you add a new MNT_*
44-
* flag, consider how it interacts with shared mounts.
45-
*/
46-
#define MNT_SHARED_MASK (MNT_UNBINDABLE)
47-
#define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \
48-
| MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \
49-
| MNT_READONLY | MNT_NOSYMFOLLOW)
50-
#define MNT_ATIME_MASK (MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME )
51-
52-
#define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \
53-
MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED)
54-
55-
#define MNT_INTERNAL 0x4000
56-
57-
#define MNT_LOCK_ATIME 0x040000
58-
#define MNT_LOCK_NOEXEC 0x080000
59-
#define MNT_LOCK_NOSUID 0x100000
60-
#define MNT_LOCK_NODEV 0x200000
61-
#define MNT_LOCK_READONLY 0x400000
62-
#define MNT_LOCKED 0x800000
63-
#define MNT_DOOMED 0x1000000
64-
#define MNT_SYNC_UMOUNT 0x2000000
65-
#define MNT_MARKED 0x4000000
66-
#define MNT_UMOUNT 0x8000000
25+
enum mount_flags {
26+
MNT_NOSUID = 0x01,
27+
MNT_NODEV = 0x02,
28+
MNT_NOEXEC = 0x04,
29+
MNT_NOATIME = 0x08,
30+
MNT_NODIRATIME = 0x10,
31+
MNT_RELATIME = 0x20,
32+
MNT_READONLY = 0x40, /* does the user want this to be r/o? */
33+
MNT_NOSYMFOLLOW = 0x80,
34+
35+
MNT_SHRINKABLE = 0x100,
36+
MNT_WRITE_HOLD = 0x200,
37+
38+
MNT_SHARED = 0x1000, /* if the vfsmount is a shared mount */
39+
MNT_UNBINDABLE = 0x2000, /* if the vfsmount is a unbindable mount */
40+
41+
MNT_INTERNAL = 0x4000,
42+
43+
MNT_LOCK_ATIME = 0x040000,
44+
MNT_LOCK_NOEXEC = 0x080000,
45+
MNT_LOCK_NOSUID = 0x100000,
46+
MNT_LOCK_NODEV = 0x200000,
47+
MNT_LOCK_READONLY = 0x400000,
48+
MNT_LOCKED = 0x800000,
49+
MNT_DOOMED = 0x1000000,
50+
MNT_SYNC_UMOUNT = 0x2000000,
51+
MNT_MARKED = 0x4000000,
52+
MNT_UMOUNT = 0x8000000,
53+
54+
/*
55+
* MNT_SHARED_MASK is the set of flags that should be cleared when a
56+
* mount becomes shared. Currently, this is only the flag that says a
57+
* mount cannot be bind mounted, since this is how we create a mount
58+
* that shares events with another mount. If you add a new MNT_*
59+
* flag, consider how it interacts with shared mounts.
60+
*/
61+
MNT_SHARED_MASK = MNT_UNBINDABLE,
62+
MNT_USER_SETTABLE_MASK = MNT_NOSUID | MNT_NODEV | MNT_NOEXEC
63+
| MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME
64+
| MNT_READONLY | MNT_NOSYMFOLLOW,
65+
MNT_ATIME_MASK = MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME,
66+
67+
MNT_INTERNAL_FLAGS = MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL |
68+
MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED,
69+
};
6770

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

0 commit comments

Comments
 (0)