Skip to content

Commit 3a2a5b2

Browse files
committed
Merge tag 'vfs-6.18-rc1.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs
Pull vfs mount updates from Christian Brauner: "This contains some work around mount api handling: - Output the warning message for mnt_too_revealing() triggered during fsmount() to the fscontext log. This makes it possible for the mount tool to output appropriate warnings on the command line. For example, with the newest fsopen()-based mount(8) from util-linux, the error messages now look like: # mount -t proc proc /tmp mount: /tmp: fsmount() failed: VFS: Mount too revealing. dmesg(1) may have more information after failed mount system call. - Do not consume fscontext log entries when returning -EMSGSIZE Userspace generally expects APIs that return -EMSGSIZE to allow for them to adjust their buffer size and retry the operation. However, the fscontext log would previously clear the message even in the -EMSGSIZE case. Given that it is very cheap for us to check whether the buffer is too small before we remove the message from the ring buffer, let's just do that instead. - Drop an unused argument from do_remount()" * tag 'vfs-6.18-rc1.mount' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs: vfs: fs/namespace.c: remove ms_flags argument from do_remount selftests/filesystems: add basic fscontext log tests fscontext: do not consume log entries when returning -EMSGSIZE vfs: output mount_too_revealing() errors to fscontext docs/vfs: Remove mentions to the old mount API helpers fscontext: add custom-prefix log helpers fs: Remove mount_bdev fs: Remove mount_nodev
2 parents 6c7ca6a + 1e5f0fb commit 3a2a5b2

9 files changed

Lines changed: 192 additions & 135 deletions

File tree

Documentation/filesystems/vfs.rst

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -209,31 +209,8 @@ method fills in is the "s_op" field. This is a pointer to a "struct
209209
super_operations" which describes the next level of the filesystem
210210
implementation.
211211

212-
Usually, a filesystem uses one of the generic mount() implementations
213-
and provides a fill_super() callback instead. The generic variants are:
214-
215-
``mount_bdev``
216-
mount a filesystem residing on a block device
217-
218-
``mount_nodev``
219-
mount a filesystem that is not backed by a device
220-
221-
``mount_single``
222-
mount a filesystem which shares the instance between all mounts
223-
224-
A fill_super() callback implementation has the following arguments:
225-
226-
``struct super_block *sb``
227-
the superblock structure. The callback must initialize this
228-
properly.
229-
230-
``void *data``
231-
arbitrary mount options, usually comes as an ASCII string (see
232-
"Mount Options" section)
233-
234-
``int silent``
235-
whether or not to be silent on error
236-
212+
For more information on mounting (and the new mount API), see
213+
Documentation/filesystems/mount_api.rst.
237214

238215
The Superblock Object
239216
=====================

fs/fsopen.c

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -18,50 +18,56 @@
1818
#include "internal.h"
1919
#include "mount.h"
2020

21+
static inline const char *fetch_message_locked(struct fc_log *log, size_t len,
22+
bool *need_free)
23+
{
24+
const char *p;
25+
int index;
26+
27+
if (unlikely(log->head == log->tail))
28+
return ERR_PTR(-ENODATA);
29+
30+
index = log->tail & (ARRAY_SIZE(log->buffer) - 1);
31+
p = log->buffer[index];
32+
if (unlikely(strlen(p) > len))
33+
return ERR_PTR(-EMSGSIZE);
34+
35+
log->buffer[index] = NULL;
36+
*need_free = log->need_free & (1 << index);
37+
log->need_free &= ~(1 << index);
38+
log->tail++;
39+
40+
return p;
41+
}
42+
2143
/*
2244
* Allow the user to read back any error, warning or informational messages.
45+
* Only one message is returned for each read(2) call.
2346
*/
2447
static ssize_t fscontext_read(struct file *file,
2548
char __user *_buf, size_t len, loff_t *pos)
2649
{
2750
struct fs_context *fc = file->private_data;
28-
struct fc_log *log = fc->log.log;
29-
unsigned int logsize = ARRAY_SIZE(log->buffer);
30-
ssize_t ret;
31-
char *p;
51+
ssize_t err;
52+
const char *p __free(kfree) = NULL, *message;
3253
bool need_free;
33-
int index, n;
54+
int n;
3455

35-
ret = mutex_lock_interruptible(&fc->uapi_mutex);
36-
if (ret < 0)
37-
return ret;
38-
39-
if (log->head == log->tail) {
40-
mutex_unlock(&fc->uapi_mutex);
41-
return -ENODATA;
42-
}
43-
44-
index = log->tail & (logsize - 1);
45-
p = log->buffer[index];
46-
need_free = log->need_free & (1 << index);
47-
log->buffer[index] = NULL;
48-
log->need_free &= ~(1 << index);
49-
log->tail++;
56+
err = mutex_lock_interruptible(&fc->uapi_mutex);
57+
if (err < 0)
58+
return err;
59+
message = fetch_message_locked(fc->log.log, len, &need_free);
5060
mutex_unlock(&fc->uapi_mutex);
61+
if (IS_ERR(message))
62+
return PTR_ERR(message);
5163

52-
ret = -EMSGSIZE;
53-
n = strlen(p);
54-
if (n > len)
55-
goto err_free;
56-
ret = -EFAULT;
57-
if (copy_to_user(_buf, p, n) != 0)
58-
goto err_free;
59-
ret = n;
60-
61-
err_free:
6264
if (need_free)
63-
kfree(p);
64-
return ret;
65+
p = message;
66+
67+
n = strlen(message);
68+
if (copy_to_user(_buf, message, n))
69+
return -EFAULT;
70+
return n;
6571
}
6672

6773
static int fscontext_release(struct inode *inode, struct file *file)

fs/namespace.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3298,7 +3298,7 @@ static int do_reconfigure_mnt(struct path *path, unsigned int mnt_flags)
32983298
* If you've mounted a non-root directory somewhere and want to do remount
32993299
* on it - tough luck.
33003300
*/
3301-
static int do_remount(struct path *path, int ms_flags, int sb_flags,
3301+
static int do_remount(struct path *path, int sb_flags,
33023302
int mnt_flags, void *data)
33033303
{
33043304
int err;
@@ -3736,8 +3736,10 @@ static int do_new_mount_fc(struct fs_context *fc, struct path *mountpoint,
37363736
int error;
37373737

37383738
error = security_sb_kern_mount(sb);
3739-
if (!error && mount_too_revealing(sb, &mnt_flags))
3739+
if (!error && mount_too_revealing(sb, &mnt_flags)) {
3740+
errorfcp(fc, "VFS", "Mount too revealing");
37403741
error = -EPERM;
3742+
}
37413743

37423744
if (unlikely(error)) {
37433745
fc_drop_locked(fc);
@@ -4121,7 +4123,7 @@ int path_mount(const char *dev_name, struct path *path,
41214123
if ((flags & (MS_REMOUNT | MS_BIND)) == (MS_REMOUNT | MS_BIND))
41224124
return do_reconfigure_mnt(path, mnt_flags);
41234125
if (flags & MS_REMOUNT)
4124-
return do_remount(path, flags, sb_flags, mnt_flags, data_page);
4126+
return do_remount(path, sb_flags, mnt_flags, data_page);
41254127
if (flags & MS_BIND)
41264128
return do_loopback(path, dev_name, flags & MS_REC);
41274129
if (flags & (MS_SHARED | MS_PRIVATE | MS_SLAVE | MS_UNBINDABLE))
@@ -4453,7 +4455,7 @@ SYSCALL_DEFINE3(fsmount, int, fs_fd, unsigned int, flags,
44534455

44544456
ret = -EPERM;
44554457
if (mount_too_revealing(fc->root->d_sb, &mnt_flags)) {
4456-
pr_warn("VFS: Mount too revealing\n");
4458+
errorfcp(fc, "VFS", "Mount too revealing");
44574459
goto err_unlock;
44584460
}
44594461

fs/super.c

Lines changed: 0 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1716,49 +1716,6 @@ int get_tree_bdev(struct fs_context *fc,
17161716
}
17171717
EXPORT_SYMBOL(get_tree_bdev);
17181718

1719-
static int test_bdev_super(struct super_block *s, void *data)
1720-
{
1721-
return !(s->s_iflags & SB_I_RETIRED) && s->s_dev == *(dev_t *)data;
1722-
}
1723-
1724-
struct dentry *mount_bdev(struct file_system_type *fs_type,
1725-
int flags, const char *dev_name, void *data,
1726-
int (*fill_super)(struct super_block *, void *, int))
1727-
{
1728-
struct super_block *s;
1729-
int error;
1730-
dev_t dev;
1731-
1732-
error = lookup_bdev(dev_name, &dev);
1733-
if (error)
1734-
return ERR_PTR(error);
1735-
1736-
flags |= SB_NOSEC;
1737-
s = sget(fs_type, test_bdev_super, set_bdev_super, flags, &dev);
1738-
if (IS_ERR(s))
1739-
return ERR_CAST(s);
1740-
1741-
if (s->s_root) {
1742-
if ((flags ^ s->s_flags) & SB_RDONLY) {
1743-
deactivate_locked_super(s);
1744-
return ERR_PTR(-EBUSY);
1745-
}
1746-
} else {
1747-
error = setup_bdev_super(s, flags, NULL);
1748-
if (!error)
1749-
error = fill_super(s, data, flags & SB_SILENT ? 1 : 0);
1750-
if (error) {
1751-
deactivate_locked_super(s);
1752-
return ERR_PTR(error);
1753-
}
1754-
1755-
s->s_flags |= SB_ACTIVE;
1756-
}
1757-
1758-
return dget(s->s_root);
1759-
}
1760-
EXPORT_SYMBOL(mount_bdev);
1761-
17621719
void kill_block_super(struct super_block *sb)
17631720
{
17641721
struct block_device *bdev = sb->s_bdev;
@@ -1773,26 +1730,6 @@ void kill_block_super(struct super_block *sb)
17731730
EXPORT_SYMBOL(kill_block_super);
17741731
#endif
17751732

1776-
struct dentry *mount_nodev(struct file_system_type *fs_type,
1777-
int flags, void *data,
1778-
int (*fill_super)(struct super_block *, void *, int))
1779-
{
1780-
int error;
1781-
struct super_block *s = sget(fs_type, NULL, set_anon_super, flags, NULL);
1782-
1783-
if (IS_ERR(s))
1784-
return ERR_CAST(s);
1785-
1786-
error = fill_super(s, data, flags & SB_SILENT ? 1 : 0);
1787-
if (error) {
1788-
deactivate_locked_super(s);
1789-
return ERR_PTR(error);
1790-
}
1791-
s->s_flags |= SB_ACTIVE;
1792-
return dget(s->s_root);
1793-
}
1794-
EXPORT_SYMBOL(mount_nodev);
1795-
17961733
/**
17971734
* vfs_get_tree - Get the mountable root
17981735
* @fc: The superblock configuration context.

include/linux/fs.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2713,12 +2713,6 @@ static inline bool is_mgtime(const struct inode *inode)
27132713
return inode->i_opflags & IOP_MGTIME;
27142714
}
27152715

2716-
extern struct dentry *mount_bdev(struct file_system_type *fs_type,
2717-
int flags, const char *dev_name, void *data,
2718-
int (*fill_super)(struct super_block *, void *, int));
2719-
extern struct dentry *mount_nodev(struct file_system_type *fs_type,
2720-
int flags, void *data,
2721-
int (*fill_super)(struct super_block *, void *, int));
27222716
extern struct dentry *mount_subtree(struct vfsmount *mnt, const char *path);
27232717
void retire_super(struct super_block *sb);
27242718
void generic_shutdown_super(struct super_block *sb);

include/linux/fs_context.h

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -186,10 +186,12 @@ struct fc_log {
186186
extern __attribute__((format(printf, 4, 5)))
187187
void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt, ...);
188188

189-
#define __logfc(fc, l, fmt, ...) logfc((fc)->log.log, NULL, \
190-
l, fmt, ## __VA_ARGS__)
191-
#define __plog(p, l, fmt, ...) logfc((p)->log, (p)->prefix, \
192-
l, fmt, ## __VA_ARGS__)
189+
#define __logfc(fc, l, fmt, ...) \
190+
logfc((fc)->log.log, NULL, (l), (fmt), ## __VA_ARGS__)
191+
#define __plogp(p, prefix, l, fmt, ...) \
192+
logfc((p)->log, (prefix), (l), (fmt), ## __VA_ARGS__)
193+
#define __plog(p, l, fmt, ...) __plogp(p, (p)->prefix, l, fmt, ## __VA_ARGS__)
194+
193195
/**
194196
* infof - Store supplementary informational message
195197
* @fc: The context in which to log the informational message
@@ -201,6 +203,8 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt,
201203
#define infof(fc, fmt, ...) __logfc(fc, 'i', fmt, ## __VA_ARGS__)
202204
#define info_plog(p, fmt, ...) __plog(p, 'i', fmt, ## __VA_ARGS__)
203205
#define infofc(fc, fmt, ...) __plog((&(fc)->log), 'i', fmt, ## __VA_ARGS__)
206+
#define infofcp(fc, prefix, fmt, ...) \
207+
__plogp((&(fc)->log), prefix, 'i', fmt, ## __VA_ARGS__)
204208

205209
/**
206210
* warnf - Store supplementary warning message
@@ -213,6 +217,8 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt,
213217
#define warnf(fc, fmt, ...) __logfc(fc, 'w', fmt, ## __VA_ARGS__)
214218
#define warn_plog(p, fmt, ...) __plog(p, 'w', fmt, ## __VA_ARGS__)
215219
#define warnfc(fc, fmt, ...) __plog((&(fc)->log), 'w', fmt, ## __VA_ARGS__)
220+
#define warnfcp(fc, prefix, fmt, ...) \
221+
__plogp((&(fc)->log), prefix, 'w', fmt, ## __VA_ARGS__)
216222

217223
/**
218224
* errorf - Store supplementary error message
@@ -225,6 +231,8 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt,
225231
#define errorf(fc, fmt, ...) __logfc(fc, 'e', fmt, ## __VA_ARGS__)
226232
#define error_plog(p, fmt, ...) __plog(p, 'e', fmt, ## __VA_ARGS__)
227233
#define errorfc(fc, fmt, ...) __plog((&(fc)->log), 'e', fmt, ## __VA_ARGS__)
234+
#define errorfcp(fc, prefix, fmt, ...) \
235+
__plogp((&(fc)->log), prefix, 'e', fmt, ## __VA_ARGS__)
228236

229237
/**
230238
* invalf - Store supplementary invalid argument error message
@@ -237,5 +245,7 @@ void logfc(struct fc_log *log, const char *prefix, char level, const char *fmt,
237245
#define invalf(fc, fmt, ...) (errorf(fc, fmt, ## __VA_ARGS__), -EINVAL)
238246
#define inval_plog(p, fmt, ...) (error_plog(p, fmt, ## __VA_ARGS__), -EINVAL)
239247
#define invalfc(fc, fmt, ...) (errorfc(fc, fmt, ## __VA_ARGS__), -EINVAL)
248+
#define invalfcp(fc, prefix, fmt, ...) \
249+
(errorfcp(fc, prefix, fmt, ## __VA_ARGS__), -EINVAL)
240250

241251
#endif /* _LINUX_FS_CONTEXT_H */
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
dnotify_test
33
devpts_pts
4+
fclog
45
file_stressor
56
anon_inode_test
67
kernfs_test
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# SPDX-License-Identifier: GPL-2.0
22

33
CFLAGS += $(KHDR_INCLUDES)
4-
TEST_GEN_PROGS := devpts_pts file_stressor anon_inode_test kernfs_test
4+
TEST_GEN_PROGS := devpts_pts file_stressor anon_inode_test kernfs_test fclog
55
TEST_GEN_PROGS_EXTENDED := dnotify_test
66

77
include ../lib.mk

0 commit comments

Comments
 (0)