[Devel] [PATCH vz10 14/14] ve: fix remaining build errors with CONFIG_VE=n

Eva Kurchatova eva.kurchatova at virtuozzo.com
Fri Jun 26 01:08:16 MSK 2026


Fix build failures when CONFIG_VE is disabled that were not covered
by the existing fixup series (commits from Vladimir Ryabchun).

The restructuring of ve.h (moving struct ve_struct inside
#ifdef CONFIG_VE) made the type incomplete when !CONFIG_VE, exposing
unguarded dereferences and sizeof() uses in several core files.

Guard VE-specific code paths with #ifdef CONFIG_VE and provide
fallback behaviour for the !CONFIG_VE case:

 - include/linux/sysctl.h, kernel/sysctl.c: guard virtual_ptr(),
   sysctl_virtual() macro (uses sizeof(struct ve_struct)), and the
   randomize_va_space sysctl entry that references
   proc_dointvec_virtual.
 - fs/aio.c: guard ve->aio_nr, ve->aio_max_nr, ve->aio_nr_lock
   dereferences; add static fallback globals and use plain
   proc_doulongvec_minmax for !CONFIG_VE sysctl entries.
 - fs/coredump.c: guard ve->core_pattern dereferences and
   sysctl_virtual(proc_dostring_coredump) expansion; add a static
   core_pattern[] fallback.
 - fs/fcntl.c: guard ve->odirect_enable dereferences in
   may_use_odirect(); return 1 (always allow) for !CONFIG_VE.
 - fs/file.c: guard ve->is_pseudosuper dereference in
   file_close_fd_locked().
 - fs/super.c: move cred into #ifdef CONFIG_VE block in sget_fc();
   deny non-init_user_ns mounting unconditionally for !CONFIG_VE
   (the FS_VE_MOUNT exception is meaningless without VE).
 - fs/sync.c: move __ve_fsync_behavior() inside #ifdef CONFIG_VE.
 - kernel/printk/printk.c: guard time_namespace dereferences in
   ve_timens_add_boottime_ns() and ve->log_state in
   ve_log_vprintk().
 - kernel/sched/core.c: guard cgroup-internal.h include with
   CONFIG_CGROUPS (incomplete types without it).
 - fs/kernfs/file.c: guard KERNFS_GET_NS ioctl case with
   CONFIG_NET (maybe_get_net_ns is unavailable otherwise).

Signed-off-by: Eva Kurchatova <eva.kurchatova at virtuozzo.com>

https://virtuozzo.atlassian.net/browse/VSTOR-134732
Feature: fix kunit
---
 fs/aio.c               | 53 +++++++++++++++++++++++++++++++++++++-----
 fs/coredump.c          | 35 ++++++++++++++++++++++++++--
 fs/fcntl.c             |  4 ++++
 fs/file.c              |  2 ++
 fs/kernfs/file.c       |  2 ++
 fs/super.c             | 11 +++++----
 fs/sync.c              | 10 +++++++-
 include/linux/sysctl.h |  2 ++
 kernel/printk/printk.c |  5 +++-
 kernel/sched/core.c    |  2 ++
 kernel/sysctl.c        | 11 ++++++---
 11 files changed, 119 insertions(+), 18 deletions(-)

diff --git a/fs/aio.c b/fs/aio.c
index cb63416af135..6ca9731b7172 100644
--- a/fs/aio.c
+++ b/fs/aio.c
@@ -50,6 +50,12 @@
 
 #include "internal.h"
 
+#ifndef CONFIG_VE
+static DEFINE_SPINLOCK(aio_nr_lock);
+static unsigned long aio_nr;
+static unsigned long aio_max_nr = AIO_MAX_NR_DEFAULT;
+#endif
+
 #define KIOCB_KEY		0
 
 #define AIO_RING_MAGIC			0xa10a10a1
@@ -225,25 +231,31 @@ struct aio_kiocb {
 static struct ctl_table aio_sysctls[] = {
 	{
 		.procname	= "aio-nr",
-	/*
-	 * When !CONFIG_VE this doesn't matter - we take ve->aio_nr_lock,
-	 * but ve is NULL.
-	 */
 #ifdef CONFIG_VE
 		.data		= &ve0.aio_nr,
-#endif
 		.maxlen		= sizeof(unsigned long),
 		.mode		= 0444 | S_ISVTX,
 		.proc_handler	= proc_doulongvec_minmax_virtual,
+#else
+		.data		= &aio_nr,
+		.maxlen		= sizeof(aio_nr),
+		.mode		= 0444,
+		.proc_handler	= proc_doulongvec_minmax,
+#endif
 	},
 	{
 		.procname	= "aio-max-nr",
 #ifdef CONFIG_VE
 		.data		= &ve0.aio_max_nr,
-#endif
 		.maxlen		= sizeof(unsigned long),
 		.mode		= 0644 | S_ISVTX,
 		.proc_handler	= proc_doulongvec_minmax_virtual,
+#else
+		.data		= &aio_max_nr,
+		.maxlen		= sizeof(aio_max_nr),
+		.mode		= 0644,
+		.proc_handler	= proc_doulongvec_minmax,
+#endif
 	},
 };
 
@@ -727,6 +739,7 @@ static int ioctx_add_table(struct kioctx *ctx, struct mm_struct *mm)
 
 static void aio_nr_sub(struct kioctx *ctx, unsigned nr)
 {
+#ifdef CONFIG_VE
 	struct ve_struct *ve = ctx->ve;
 
 	spin_lock(&ve->aio_nr_lock);
@@ -735,6 +748,14 @@ static void aio_nr_sub(struct kioctx *ctx, unsigned nr)
 	else
 		ve->aio_nr -= nr;
 	spin_unlock(&ve->aio_nr_lock);
+#else
+	spin_lock(&aio_nr_lock);
+	if (WARN_ON(aio_nr - nr > aio_nr))
+		aio_nr = 0;
+	else
+		aio_nr -= nr;
+	spin_unlock(&aio_nr_lock);
+#endif
 }
 
 /* ioctx_alloc
@@ -744,7 +765,9 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
 {
 	struct mm_struct *mm = current->mm;
 	struct kioctx *ctx;
+#ifdef CONFIG_VE
 	struct ve_struct *ve = get_exec_env();
+#endif
 	int err = -ENOMEM;
 
 	/*
@@ -771,7 +794,11 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
 		return ERR_PTR(-EINVAL);
 	}
 
+#ifdef CONFIG_VE
 	if (!nr_events || (unsigned long)max_reqs > ve->aio_max_nr)
+#else
+	if (!nr_events || (unsigned long)max_reqs > aio_max_nr)
+#endif
 		return ERR_PTR(-EAGAIN);
 
 	ctx = kmem_cache_zalloc(kioctx_cachep, GFP_KERNEL);
@@ -779,7 +806,9 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
 		return ERR_PTR(-ENOMEM);
 
 	ctx->max_reqs = max_reqs;
+#ifdef CONFIG_VE
 	ctx->ve = get_ve(ve);
+#endif
 
 	spin_lock_init(&ctx->ctx_lock);
 	spin_lock_init(&ctx->completion_lock);
@@ -811,6 +840,7 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
 		ctx->req_batch = 1;
 
 	/* limit the number of system wide aios */
+#ifdef CONFIG_VE
 	spin_lock(&ve->aio_nr_lock);
 	if (ve->aio_nr + ctx->max_reqs > ve->aio_max_nr ||
 	    ve->aio_nr + ctx->max_reqs < ve->aio_nr) {
@@ -820,6 +850,17 @@ static struct kioctx *ioctx_alloc(unsigned nr_events)
 	}
 	ve->aio_nr += ctx->max_reqs;
 	spin_unlock(&ve->aio_nr_lock);
+#else
+	spin_lock(&aio_nr_lock);
+	if (aio_nr + ctx->max_reqs > aio_max_nr ||
+	    aio_nr + ctx->max_reqs < aio_nr) {
+		spin_unlock(&aio_nr_lock);
+		err = -EAGAIN;
+		goto err_ctx;
+	}
+	aio_nr += ctx->max_reqs;
+	spin_unlock(&aio_nr_lock);
+#endif
 
 	percpu_ref_get(&ctx->users);	/* io_setup() will drop this ref */
 	percpu_ref_get(&ctx->reqs);	/* free_ioctx_users() will drop this */
diff --git a/fs/coredump.c b/fs/coredump.c
index 3d15612e3493..605532f52038 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -75,6 +75,9 @@ static unsigned int core_pipe_limit;
 static unsigned int core_sort_vma;
 static int core_name_size = CORENAME_MAX_SIZE;
 unsigned int core_file_note_size_limit = CORE_FILE_NOTE_SIZE_DEFAULT;
+#ifndef CONFIG_VE
+static char core_pattern[CORENAME_MAX_SIZE] = "core";
+#endif
 
 enum coredump_type_t {
 	COREDUMP_FILE = 1,
@@ -223,8 +226,12 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm,
 			   size_t **argv, int *argc)
 {
 	const struct cred *cred = current_cred();
+#ifdef CONFIG_VE
 	struct ve_struct *ve = get_exec_env();
 	const char *pat_ptr = ve->core_pattern;
+#else
+	const char *pat_ptr = core_pattern;
+#endif
 	bool was_space = false;
 	int pid_in_pattern = 0;
 	int err = 0;
@@ -240,7 +247,11 @@ static int format_corename(struct core_name *cn, struct coredump_params *cprm,
 	cn->corename[0] = '\0';
 
 	if (cn->core_type == COREDUMP_PIPE) {
+#ifdef CONFIG_VE
 		int argvs = sizeof(ve->core_pattern) / 2;
+#else
+		int argvs = CORENAME_MAX_SIZE / 2;
+#endif
 		(*argv) = kmalloc_array(argvs, sizeof(**argv), GFP_KERNEL);
 		if (!(*argv))
 			return -ENOMEM;
@@ -792,9 +803,14 @@ void do_coredump(const kernel_siginfo_t *siginfo)
 						helper_argv, NULL, GFP_KERNEL,
 						umh_coredump_setup, NULL, &cprm);
 		if (sub_info)
+#ifdef CONFIG_VE
 			retval = call_usermodehelper_exec_ve(get_exec_env(),
 							     sub_info,
 							     UMH_WAIT_EXEC);
+#else
+			retval = call_usermodehelper_exec(sub_info,
+							  UMH_WAIT_EXEC);
+#endif
 
 		kfree(helper_argv);
 		if (retval) {
@@ -1043,9 +1059,14 @@ EXPORT_SYMBOL(dump_align);
 
 void validate_coredump_safety(void)
 {
+#ifdef CONFIG_VE
 	struct ve_struct *ve = get_exec_env();
 	if (suid_dumpable == SUID_DUMP_ROOT &&
 	    ve->core_pattern[0] != '/' && ve->core_pattern[0] != '|') {
+#else
+	if (suid_dumpable == SUID_DUMP_ROOT &&
+	    core_pattern[0] != '/' && core_pattern[0] != '|') {
+#endif
 
 		coredump_report_failure("Unsafe core_pattern used with fs.suid_dumpable=2: "
 			"pipe handler or fully qualified core dump path required. "
@@ -1066,7 +1087,9 @@ static int proc_dostring_coredump(const struct ctl_table *table, int write,
 static const unsigned int core_file_note_size_min = CORE_FILE_NOTE_SIZE_DEFAULT;
 static const unsigned int core_file_note_size_max = CORE_FILE_NOTE_SIZE_MAX;
 
+#ifdef CONFIG_VE
 sysctl_virtual(proc_dostring_coredump);
+#endif
 
 static struct ctl_table coredump_sysctls[] = {
 	{
@@ -1076,15 +1099,23 @@ static struct ctl_table coredump_sysctls[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec,
 	},
+#ifdef CONFIG_VE
 	{
 		.procname	= "core_pattern",
-#ifdef CONFIG_VE
 		.data		= ve0.core_pattern,
-#endif
 		.maxlen		= CORENAME_MAX_SIZE,
 		.mode		= 0644 | S_ISVTX,
 		.proc_handler	= proc_dostring_coredump_virtual,
 	},
+#else
+	{
+		.procname	= "core_pattern",
+		.data		= core_pattern,
+		.maxlen		= CORENAME_MAX_SIZE,
+		.mode		= 0644,
+		.proc_handler	= proc_dostring_coredump,
+	},
+#endif
 	{
 		.procname	= "core_pipe_limit",
 		.data		= &core_pipe_limit,
diff --git a/fs/fcntl.c b/fs/fcntl.c
index aee657baca93..832bf112c16e 100644
--- a/fs/fcntl.c
+++ b/fs/fcntl.c
@@ -49,6 +49,7 @@
  */
 int may_use_odirect(void)
 {
+#ifdef CONFIG_VE
 	int may;
 
 	if (ve_is_super(get_exec_env()))
@@ -62,6 +63,9 @@ int may_use_odirect(void)
 	}
 
 	return may;
+#else
+	return 1;
+#endif
 }
 
 static int setfl(int fd, struct file * filp, unsigned int arg)
diff --git a/fs/file.c b/fs/file.c
index 32ea42f92f71..46ed2e8d21fd 100644
--- a/fs/file.c
+++ b/fs/file.c
@@ -740,11 +740,13 @@ struct file *file_close_fd_locked(struct files_struct *files, unsigned fd)
 	}
 
 	/* Try to shrink fdt and to free memory */
+#ifdef CONFIG_VE
 	if (unlikely(fd * 2 >= fdt->max_fds &&
 		     fd > (1024 / sizeof(struct file *))) &&
 		     get_exec_env() != get_ve0() &&
 		     get_exec_env()->is_pseudosuper)
 		expand_files(files, fd, true);
+#endif
 
 	return file;
 }
diff --git a/fs/kernfs/file.c b/fs/kernfs/file.c
index 092a4dcd2ebf..e2762b8f0727 100644
--- a/fs/kernfs/file.c
+++ b/fs/kernfs/file.c
@@ -1023,11 +1023,13 @@ long kernfs_ioctl(struct file *file, unsigned int ioctl,
 	struct net *net;
 
 	switch (ioctl) {
+#ifdef CONFIG_NET
 	case KERNFS_GET_NS:
 		if (dentry->d_sb->s_magic != SYSFS_MAGIC || !ns)
 			return -ENOTTY;
 		net = (struct net *)ns;
 		return open_related_ns(&net->ns, maybe_get_net_ns);
+#endif
 	default:
 		return -ENOTTY;
 	}
diff --git a/fs/super.c b/fs/super.c
index 1adebbf35803..3b88b83c4326 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -770,11 +770,6 @@ struct super_block *sget_fc(struct fs_context *fc,
 	struct super_block *s = NULL;
 	struct super_block *old;
 	struct user_namespace *user_ns = fc->global ? &init_user_ns : fc->user_ns;
-#ifdef CONFIG_VE
-	struct cred *cred = get_exec_env()->init_cred;
-#else
-	struct cred *cred = &init_cred;
-#endif
 	int err;
 
 	/*
@@ -784,10 +779,16 @@ struct super_block *sget_fc(struct fs_context *fc,
 	 * an fs_fd opened in another user namespace.
 	 */
 	if (user_ns != &init_user_ns && !(fc->fs_type->fs_flags & FS_USERNS_MOUNT)) {
+#ifdef CONFIG_VE
+		struct cred *cred = get_exec_env()->init_cred;
 		if (!cred || !(cred->user_ns == user_ns && fc->fs_type->fs_flags & FS_VE_MOUNT)) {
 			errorfc(fc, "VFS: Mounting from non-initial user namespace is not allowed");
 			return ERR_PTR(-EPERM);
 		}
+#else
+		errorfc(fc, "VFS: Mounting from non-initial user namespace is not allowed");
+		return ERR_PTR(-EPERM);
+#endif
 	}
 
 retry:
diff --git a/fs/sync.c b/fs/sync.c
index c0114b90c3e9..532e3ca0b3f9 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -109,6 +109,7 @@ static void sync_fs_one_sb(struct super_block *sb, void *arg)
 	}
 }
 
+#ifdef CONFIG_VE
 static int __ve_fsync_behavior(struct ve_struct *ve)
 {
 	/*
@@ -124,7 +125,6 @@ static int __ve_fsync_behavior(struct ve_struct *ve)
 		return 0;
 }
 
-#ifdef CONFIG_VE
 int ve_fsync_behavior(void)
 {
 	struct ve_struct *ve;
@@ -149,10 +149,13 @@ int ve_fsync_behavior(void)
  */
 void ksys_sync(void)
 {
+#ifdef CONFIG_VE
 	struct ve_struct *ve = get_exec_env();
+#endif
 	struct sync_arg sarg;
 
 	sarg.ve = NULL;
+#ifdef CONFIG_VE
 	if (!ve_is_super(ve)) {
 		int fsb;
 		/*
@@ -171,6 +174,7 @@ void ksys_sync(void)
 		if (fsb == FSYNC_FILTERED)
 			sarg.ve = ve;
 	}
+#endif
 
 	wakeup_flusher_threads(WB_REASON_SYNC);
 
@@ -271,12 +275,15 @@ SYSCALL_DEFINE1(syncfs, int, fd)
 	struct fd f = fdget(fd);
 	struct super_block *sb;
 	int ret = 0, ret2 = 0;
+#ifdef CONFIG_VE
 	struct ve_struct *ve;
+#endif
 
 	if (!fd_file(f))
 		return -EBADF;
 	sb = fd_file(f)->f_path.dentry->d_sb;
 
+#ifdef CONFIG_VE
 	ve = get_exec_env();
 
 	if (!ve_is_super(ve)) {
@@ -298,6 +305,7 @@ SYSCALL_DEFINE1(syncfs, int, fd)
 		if ((fsb == FSYNC_FILTERED) && !is_sb_ve_accessible(ve, sb))
 			goto fdput;
 	}
+#endif
 
 	down_read(&sb->s_umount);
 	ret = sync_filesystem(sb);
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 8dbc81db769f..2cf24622fa6f 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -88,6 +88,7 @@ int proc_do_large_bitmap(const struct ctl_table *, int, void *, size_t *, loff_t
 int proc_do_static_key(const struct ctl_table *table, int write, void *buffer,
 		size_t *lenp, loff_t *ppos);
 
+#ifdef CONFIG_VE
 bool virtual_ptr(void **ptr, void *base, size_t size, void *cur);
 #define sysctl_virtual(sysctl)							\
 int sysctl ## _virtual(const struct ctl_table *table, int write,		\
@@ -106,6 +107,7 @@ extern int proc_doulongvec_minmax_virtual(const struct ctl_table *table, int wri
 		void *buffer, size_t *lenp, loff_t *ppos);
 extern int proc_dostring_coredump_virtual(const struct ctl_table *table, int write,
 		void *buffer, size_t *lenp, loff_t *ppos);
+#endif /* CONFIG_VE */
 extern int proc_dointvec_immutable(const struct ctl_table *table, int write,
 		void *buffer, size_t *lenp, loff_t *ppos);
 extern int proc_dostring_immutable(const struct ctl_table *table, int write,
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 8940b36e790b..67f9b6f66472 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -689,6 +689,7 @@ static void append_char(char **pp, char *e, char c)
 
 static inline u64 ve_timens_add_boottime_ns(u64 nsec)
 {
+#ifdef CONFIG_VE
 	struct time_namespace *ve_time_ns;
 	struct timens_offsets *ns_offsets;
 
@@ -702,7 +703,7 @@ static inline u64 ve_timens_add_boottime_ns(u64 nsec)
 	nsec += ns_offsets->boottime.tv_sec * NSEC_PER_SEC;
 	nsec += ns_offsets->boottime.tv_nsec;
 	put_time_ns(ve_time_ns);
-
+#endif
 	return nsec;
 }
 
@@ -2596,9 +2597,11 @@ static asmlinkage int ve_log_vprintk(struct ve_struct *ve, const char *fmt, va_l
 
 	if (ve_is_super(ve))
 		r = vprintk(fmt, args);
+#ifdef CONFIG_VE
 	else
 		r = vprintk_emit_log(ve->log_state, 0, LOGLEVEL_DEFAULT, NULL,
 				     fmt, args);
+#endif
 
 	return r;
 }
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 7d2214749245..61c6de281f8f 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -152,7 +152,9 @@ __read_mostly unsigned int sysctl_sched_features =
 __read_mostly int sysctl_resched_latency_warn_ms = 100;
 __read_mostly int sysctl_resched_latency_warn_once = 1;
 
+#ifdef CONFIG_CGROUPS
 #include "../cgroup/cgroup-internal.h" /* For cgroup_task_count() */
+#endif
 
 /*
  * Number of tasks to iterate in a single balance run.
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 8bb2c2de769e..1ddb89b30b7d 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1492,6 +1492,7 @@ int proc_do_large_bitmap(const struct ctl_table *table, int write,
 	return err;
 }
 
+#ifdef CONFIG_VE
 bool virtual_ptr(void **ptr, void *base, size_t size, void *cur)
 {
 	unsigned long addr = (unsigned long)*ptr;
@@ -1506,6 +1507,7 @@ bool virtual_ptr(void **ptr, void *base, size_t size, void *cur)
 
 sysctl_virtual(proc_dointvec);
 sysctl_virtual(proc_doulongvec_minmax);
+#endif
 
 static inline bool sysctl_in_container(void)
 {
@@ -1968,12 +1970,15 @@ static struct ctl_table kern_table[] = {
 		.procname	= "randomize_va_space",
 #ifdef CONFIG_VE
 		.data		= &ve0._randomize_va_space,
-#else
-		.data		= &_randomize_va_space,
-#endif
 		.maxlen		= sizeof(int),
 		.mode		= 0644 | S_ISVTX,
 		.proc_handler	= proc_dointvec_virtual,
+#else
+		.data		= &_randomize_va_space,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec,
+#endif
 	},
 #endif
 #if defined(CONFIG_S390) && defined(CONFIG_SMP)
-- 
2.54.0



More information about the Devel mailing list