diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/arch/ia64/ia32/ia32_entry.S linux-2.6.11.7-vs2.0-pre2.4/arch/ia64/ia32/ia32_entry.S --- linux-2.6.11.7-vs2.0-pre2.3/arch/ia64/ia32/ia32_entry.S 2005-03-02 12:38:21 +0100 +++ linux-2.6.11.7-vs2.0-pre2.4/arch/ia64/ia32/ia32_entry.S 2005-04-27 20:45:25 +0200 @@ -483,7 +483,7 @@ ia32_syscall_table: data8 sys_tgkill /* 270 */ data8 compat_sys_utimes data8 sys32_fadvise64_64 - data8 sys_ni_syscall + data8 sys32_vserver data8 sys_ni_syscall data8 sys_ni_syscall /* 275 */ data8 sys_ni_syscall diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/arch/mips/kernel/scall64-n32.S linux-2.6.11.7-vs2.0-pre2.4/arch/mips/kernel/scall64-n32.S --- linux-2.6.11.7-vs2.0-pre2.3/arch/mips/kernel/scall64-n32.S 2005-03-02 12:38:22 +0100 +++ linux-2.6.11.7-vs2.0-pre2.4/arch/mips/kernel/scall64-n32.S 2005-04-27 20:37:59 +0200 @@ -357,7 +357,7 @@ EXPORT(sysn32_call_table) PTR compat_sys_mq_timedreceive PTR compat_sys_mq_notify PTR compat_sys_mq_getsetattr - PTR sys_ni_syscall /* 6240, sys_vserver */ + PTR sys32_vserver /* 6240 */ PTR sys_waitid PTR sys_ni_syscall /* available, was setaltroot */ PTR sys_add_key diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/arch/mips/kernel/scall64-o32.S linux-2.6.11.7-vs2.0-pre2.4/arch/mips/kernel/scall64-o32.S --- linux-2.6.11.7-vs2.0-pre2.3/arch/mips/kernel/scall64-o32.S 2005-03-02 12:38:22 +0100 +++ linux-2.6.11.7-vs2.0-pre2.4/arch/mips/kernel/scall64-o32.S 2005-04-27 20:41:07 +0200 @@ -479,7 +479,7 @@ sys_call_table: PTR compat_sys_mq_timedreceive PTR compat_sys_mq_notify /* 4275 */ PTR compat_sys_mq_getsetattr - PTR sys_ni_syscall /* sys_vserver */ + PTR sys32_vserver PTR sys_waitid PTR sys_ni_syscall /* available, was setaltroot */ PTR sys_add_key /* 4280 */ diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/arch/ppc64/kernel/misc.S linux-2.6.11.7-vs2.0-pre2.4/arch/ppc64/kernel/misc.S --- linux-2.6.11.7-vs2.0-pre2.3/arch/ppc64/kernel/misc.S 2005-04-14 21:15:01 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/arch/ppc64/kernel/misc.S 2005-04-27 21:16:04 +0200 @@ -924,7 +924,7 @@ _GLOBAL(sys_call_table32) .llong .ppc32_fadvise64_64 /* 32bit only fadvise64_64 */ .llong .ppc_rtas /* 255 */ .llong .sys_ni_syscall /* 256 reserved for sys_debug_setcontext */ - .llong .sys_vserver + .llong .sys32_vserver .llong .sys_ni_syscall /* 258 reserved for new sys_remap_file_pages */ .llong .compat_sys_mbind .llong .compat_sys_get_mempolicy /* 260 */ diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/arch/s390/kernel/syscalls.S linux-2.6.11.7-vs2.0-pre2.4/arch/s390/kernel/syscalls.S --- linux-2.6.11.7-vs2.0-pre2.3/arch/s390/kernel/syscalls.S 2005-04-14 21:15:01 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/arch/s390/kernel/syscalls.S 2005-04-27 20:52:34 +0200 @@ -271,7 +271,7 @@ SYSCALL(sys_clock_settime,sys_clock_sett SYSCALL(sys_clock_gettime,sys_clock_gettime,sys32_clock_gettime_wrapper) /* 260 */ SYSCALL(sys_clock_getres,sys_clock_getres,sys32_clock_getres_wrapper) SYSCALL(sys_clock_nanosleep,sys_clock_nanosleep,sys32_clock_nanosleep_wrapper) -SYSCALL(sys_vserver,sys_vserver,sys_vserver) +SYSCALL(sys_vserver,sys_vserver,sys32_vserver) SYSCALL(s390_fadvise64_64,sys_ni_syscall,sys32_fadvise64_64_wrapper) SYSCALL(sys_statfs64,sys_statfs64,compat_sys_statfs64_wrapper) SYSCALL(sys_fstatfs64,sys_fstatfs64,compat_sys_fstatfs64_wrapper) diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/arch/sparc64/kernel/systbls.S linux-2.6.11.7-vs2.0-pre2.4/arch/sparc64/kernel/systbls.S --- linux-2.6.11.7-vs2.0-pre2.3/arch/sparc64/kernel/systbls.S 2005-04-14 21:15:01 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/arch/sparc64/kernel/systbls.S 2005-04-27 20:50:42 +0200 @@ -73,7 +73,7 @@ sys_call_table32: /*250*/ .word sys32_mremap, sys32_sysctl, sys32_getsid, sys_fdatasync, sys32_nfsservctl .word sys_ni_syscall, sys32_clock_settime, compat_sys_clock_gettime, compat_sys_clock_getres, sys32_clock_nanosleep /*260*/ .word compat_sys_sched_getaffinity, compat_sys_sched_setaffinity, sys32_timer_settime, compat_sys_timer_gettime, sys_timer_getoverrun - .word sys_timer_delete, sys32_timer_create, sys_vserver, compat_sys_io_setup, sys_io_destroy + .word sys_timer_delete, sys32_timer_create, sys32_vserver, compat_sys_io_setup, sys_io_destroy /*270*/ .word sys32_io_submit, sys_io_cancel, compat_sys_io_getevents, sys32_mq_open, sys_mq_unlink .word sys_mq_timedsend, sys_mq_timedreceive, compat_sys_mq_notify, compat_sys_mq_getsetattr, compat_sys_waitid /*280*/ .word sys_ni_syscall, sys_add_key, sys_request_key, sys_keyctl diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/arch/x86_64/ia32/ia32entry.S linux-2.6.11.7-vs2.0-pre2.4/arch/x86_64/ia32/ia32entry.S --- linux-2.6.11.7-vs2.0-pre2.3/arch/x86_64/ia32/ia32entry.S 2005-04-14 21:15:01 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/arch/x86_64/ia32/ia32entry.S 2005-04-27 20:44:05 +0200 @@ -579,7 +579,7 @@ ia32_sys_call_table: .quad sys_tgkill /* 270 */ .quad compat_sys_utimes .quad sys32_fadvise64_64 - .quad sys_vserver + .quad sys32_vserver .quad sys_mbind .quad compat_sys_get_mempolicy /* 275 */ .quad sys_set_mempolicy diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/include/linux/vserver/compat.h linux-2.6.11.7-vs2.0-pre2.4/include/linux/vserver/compat.h --- linux-2.6.11.7-vs2.0-pre2.3/include/linux/vserver/compat.h 1970-01-01 01:00:00 +0100 +++ linux-2.6.11.7-vs2.0-pre2.4/include/linux/vserver/compat.h 2005-04-28 00:49:19 +0200 @@ -0,0 +1,14 @@ +#ifndef _VX_COMPAT_H +#define _VX_COMPAT_H + +#include + +#if defined(CONFIG_IA32_EMULATION) || \ + defined(CONFIG_IA32_SUPPORT) || \ + defined(CONFIG_MIPS32_COMPAT) || \ + defined(CONFIG_SPARC32_COMPAT) + +#define VSERVER_COMPAT_X32 +#endif + +#endif /* _VX_COMPAT_H */ diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/include/linux/vserver/dlimit_cmd.h linux-2.6.11.7-vs2.0-pre2.4/include/linux/vserver/dlimit_cmd.h --- linux-2.6.11.7-vs2.0-pre2.3/include/linux/vserver/dlimit_cmd.h 2005-04-23 00:48:35 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/include/linux/vserver/dlimit_cmd.h 2005-04-27 04:32:01 +0200 @@ -27,6 +27,8 @@ struct vcmd_ctx_dlimit_v0 { #ifdef __KERNEL__ +#ifdef VSERVER_COMPAT_X32 + struct vcmd_ctx_dlimit_base_v0_x32 { uint32_t __user name_ptr; uint32_t flags; @@ -42,6 +44,8 @@ struct vcmd_ctx_dlimit_v0_x32 { uint32_t flags; }; +#endif /* VSERVER_COMPAT_X32 */ + #include extern int vc_add_dlimit(uint32_t, void __user *); @@ -50,5 +54,15 @@ extern int vc_rem_dlimit(uint32_t, void extern int vc_set_dlimit(uint32_t, void __user *); extern int vc_get_dlimit(uint32_t, void __user *); +#ifdef VSERVER_COMPAT_X32 + +extern int vc_add_dlimit_x32(uint32_t, void __user *); +extern int vc_rem_dlimit_x32(uint32_t, void __user *); + +extern int vc_set_dlimit_x32(uint32_t, void __user *); +extern int vc_get_dlimit_x32(uint32_t, void __user *); + +#endif /* VSERVER_COMPAT_X32 */ + #endif /* __KERNEL__ */ #endif /* _VX_DLIMIT_CMD_H */ diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/include/linux/vserver/inode_cmd.h linux-2.6.11.7-vs2.0-pre2.4/include/linux/vserver/inode_cmd.h --- linux-2.6.11.7-vs2.0-pre2.3/include/linux/vserver/inode_cmd.h 2005-04-23 00:48:14 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/include/linux/vserver/inode_cmd.h 2005-04-27 06:17:48 +0200 @@ -27,13 +27,17 @@ struct vcmd_ctx_iattr_v1 { #ifdef __KERNEL__ +#ifdef VSERVER_COMPAT_X32 + struct vcmd_ctx_iattr_v1_x32 { - uint32_t __user name; + uint32_t __user name_ptr; uint32_t xid; uint32_t flags; uint32_t mask; }; +#endif /* VSERVER_COMPAT_X32 */ + #include extern int vc_get_iattr_v0(uint32_t, void __user *); @@ -42,5 +46,12 @@ extern int vc_set_iattr_v0(uint32_t, voi extern int vc_get_iattr(uint32_t, void __user *); extern int vc_set_iattr(uint32_t, void __user *); +#ifdef VSERVER_COMPAT_X32 + +extern int vc_get_iattr_x32(uint32_t, void __user *); +extern int vc_set_iattr_x32(uint32_t, void __user *); + +#endif /* VSERVER_COMPAT_X32 */ + #endif /* __KERNEL__ */ #endif /* _VX_INODE_CMD_H */ diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/kernel/vserver/dlimit.c linux-2.6.11.7-vs2.0-pre2.4/kernel/vserver/dlimit.c --- linux-2.6.11.7-vs2.0-pre2.3/kernel/vserver/dlimit.c 2005-04-23 00:54:59 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/kernel/vserver/dlimit.c 2005-04-27 19:13:23 +0200 @@ -6,14 +6,15 @@ * Copyright (C) 2004-2005 Herbert Pötzl * * V0.01 initial version + * V0.02 compat32 splitup * */ -#include #include #include #include #include +#include #include #include #include @@ -179,18 +180,13 @@ void rcu_free_dl_info(struct rcu_head *h -int vc_add_dlimit(uint32_t id, void __user *data) +int do_addrem_dlimit(uint32_t id, const char __user *name, + uint32_t flags, int add) { struct nameidata nd; - struct vcmd_ctx_dlimit_base_v0 vc_data; int ret; - if (!vx_check(0, VX_ADMIN)) - return -ENOSYS; - if (copy_from_user (&vc_data, data, sizeof(vc_data))) - return -EFAULT; - - ret = user_path_walk_link(vc_data.name, &nd); + ret = user_path_walk_link(name, &nd); if (!ret) { struct super_block *sb; struct dl_info *dli; @@ -201,19 +197,28 @@ int vc_add_dlimit(uint32_t id, void __us if (!(sb = nd.dentry->d_inode->i_sb)) goto out_release; - dli = __alloc_dl_info(sb, id); - spin_lock(&dl_info_hash_lock); + if (add) { + dli = __alloc_dl_info(sb, id); + spin_lock(&dl_info_hash_lock); - ret = -EEXIST; - if (__lookup_dl_info(sb, id)) - goto out_unlock; - __hash_dl_info(dli); - dli = NULL; - ret = 0; + ret = -EEXIST; + if (__lookup_dl_info(sb, id)) + goto out_unlock; + __hash_dl_info(dli); + dli = NULL; + } else { + spin_lock(&dl_info_hash_lock); + dli = __lookup_dl_info(sb, id); + ret = -ESRCH; + if (!dli) + goto out_unlock; + __unhash_dl_info(dli); + } + ret = 0; out_unlock: spin_unlock(&dl_info_hash_lock); - if (dli) + if (add && dli) __dealloc_dl_info(dli); out_release: path_release(&nd); @@ -221,60 +226,71 @@ int vc_add_dlimit(uint32_t id, void __us return ret; } +int vc_add_dlimit(uint32_t id, void __user *data) +{ + struct vcmd_ctx_dlimit_base_v0 vc_data; + + if (!vx_check(0, VX_ADMIN)) + return -ENOSYS; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 1); +} int vc_rem_dlimit(uint32_t id, void __user *data) { - struct nameidata nd; struct vcmd_ctx_dlimit_base_v0 vc_data; - int ret; if (!vx_check(0, VX_ADMIN)) return -ENOSYS; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - ret = user_path_walk_link(vc_data.name, &nd); - if (!ret) { - struct super_block *sb; - struct dl_info *dli; - - ret = -EINVAL; - if (!nd.dentry->d_inode) - goto out_release; - if (!(sb = nd.dentry->d_inode->i_sb)) - goto out_release; + return do_addrem_dlimit(id, vc_data.name, vc_data.flags, 0); +} - spin_lock(&dl_info_hash_lock); - dli = __lookup_dl_info(sb, id); +#ifdef VSERVER_COMPAT_X32 - ret = -ESRCH; - if (!dli) - goto out_unlock; +int vc_add_dlimit_x32(uint32_t id, void __user *data) +{ + struct vcmd_ctx_dlimit_base_v0_x32 vc_data; - __unhash_dl_info(dli); - ret = 0; + if (!vx_check(0, VX_ADMIN)) + return -ENOSYS; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; - out_unlock: - spin_unlock(&dl_info_hash_lock); - out_release: - path_release(&nd); - } - return ret; + return do_addrem_dlimit(id, + (const char __user *)vc_data.name_ptr, vc_data.flags, 1); } - -int vc_set_dlimit(uint32_t id, void __user *data) +int vc_rem_dlimit_x32(uint32_t id, void __user *data) { - struct nameidata nd; - struct vcmd_ctx_dlimit_v0 vc_data; - int ret; + struct vcmd_ctx_dlimit_base_v0_x32 vc_data; if (!vx_check(0, VX_ADMIN)) return -ENOSYS; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; - ret = user_path_walk_link(vc_data.name, &nd); + return do_addrem_dlimit(id, + (const char __user *)vc_data.name_ptr, vc_data.flags, 0); +} + +#endif /* VSERVER_COMPAT_X32 */ + + +static inline +int do_set_dlimit(uint32_t id, const char __user *name, + uint32_t space_used, uint32_t space_total, + uint32_t inodes_used, uint32_t inodes_total, + uint32_t reserved, uint32_t flags) +{ + struct nameidata nd; + int ret; + + ret = user_path_walk_link(name, &nd); if (!ret) { struct super_block *sb; struct dl_info *dli; @@ -284,12 +300,12 @@ int vc_set_dlimit(uint32_t id, void __us goto out_release; if (!(sb = nd.dentry->d_inode->i_sb)) goto out_release; - if ((vc_data.reserved != (uint32_t)CDLIM_KEEP && - vc_data.reserved > 100) || - (vc_data.inodes_used != (uint32_t)CDLIM_KEEP && - vc_data.inodes_used > vc_data.inodes_total) || - (vc_data.space_used != (uint32_t)CDLIM_KEEP && - vc_data.space_used > vc_data.space_total)) + if ((reserved != (uint32_t)CDLIM_KEEP && + reserved > 100) || + (inodes_used != (uint32_t)CDLIM_KEEP && + inodes_used > inodes_total) || + (space_used != (uint32_t)CDLIM_KEEP && + space_used > space_total)) goto out_release; ret = -ESRCH; @@ -299,22 +315,22 @@ int vc_set_dlimit(uint32_t id, void __us spin_lock(&dli->dl_lock); - if (vc_data.inodes_used != (uint32_t)CDLIM_KEEP) - dli->dl_inodes_used = vc_data.inodes_used; - if (vc_data.inodes_total != (uint32_t)CDLIM_KEEP) - dli->dl_inodes_total = vc_data.inodes_total; - if (vc_data.space_used != (uint32_t)CDLIM_KEEP) { - dli->dl_space_used = vc_data.space_used; + if (inodes_used != (uint32_t)CDLIM_KEEP) + dli->dl_inodes_used = inodes_used; + if (inodes_total != (uint32_t)CDLIM_KEEP) + dli->dl_inodes_total = inodes_total; + if (space_used != (uint32_t)CDLIM_KEEP) { + dli->dl_space_used = space_used; dli->dl_space_used <<= 10; } - if (vc_data.space_total == (uint32_t)CDLIM_INFINITY) + if (space_total == (uint32_t)CDLIM_INFINITY) dli->dl_space_total = (uint64_t)CDLIM_INFINITY; - else if (vc_data.space_total != (uint32_t)CDLIM_KEEP) { - dli->dl_space_total = vc_data.space_total; + else if (space_total != (uint32_t)CDLIM_KEEP) { + dli->dl_space_total = space_total; dli->dl_space_total <<= 10; } - if (vc_data.reserved != (uint32_t)CDLIM_KEEP) - dli->dl_nrlmult = (1 << 10) * (100 - vc_data.reserved) / 100; + if (reserved != (uint32_t)CDLIM_KEEP) + dli->dl_nrlmult = (1 << 10) * (100 - reserved) / 100; spin_unlock(&dli->dl_lock); @@ -327,18 +343,51 @@ int vc_set_dlimit(uint32_t id, void __us return ret; } -int vc_get_dlimit(uint32_t id, void __user *data) +int vc_set_dlimit(uint32_t id, void __user *data) { - struct nameidata nd; struct vcmd_ctx_dlimit_v0 vc_data; - int ret; if (!vx_check(0, VX_ADMIN)) return -ENOSYS; if (copy_from_user (&vc_data, data, sizeof(vc_data))) return -EFAULT; + + return do_set_dlimit(id, vc_data.name, + vc_data.space_used, vc_data.space_total, + vc_data.inodes_used, vc_data.inodes_total, + vc_data.reserved, vc_data.flags); +} - ret = user_path_walk_link(vc_data.name, &nd); +#ifdef VSERVER_COMPAT_X32 + +int vc_set_dlimit_x32(uint32_t id, void __user *data) +{ + struct vcmd_ctx_dlimit_v0_x32 vc_data; + + if (!vx_check(0, VX_ADMIN)) + return -ENOSYS; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + return do_set_dlimit(id, (const char __user *)vc_data.name_ptr, + vc_data.space_used, vc_data.space_total, + vc_data.inodes_used, vc_data.inodes_total, + vc_data.reserved, vc_data.flags); +} + +#endif /* VSERVER_COMPAT_X32 */ + + +static inline +int do_get_dlimit(uint32_t id, const char __user *name, + uint32_t *space_used, uint32_t *space_total, + uint32_t *inodes_used, uint32_t *inodes_total, + uint32_t *reserved, uint32_t *flags) +{ + struct nameidata nd; + int ret; + + ret = user_path_walk_link(name, &nd); if (!ret) { struct super_block *sb; struct dl_info *dli; @@ -348,10 +397,6 @@ int vc_get_dlimit(uint32_t id, void __us goto out_release; if (!(sb = nd.dentry->d_inode->i_sb)) goto out_release; - if (vc_data.reserved > 100 || - vc_data.inodes_used > vc_data.inodes_total || - vc_data.space_used > vc_data.space_total) - goto out_release; ret = -ESRCH; dli = locate_dl_info(sb, id); @@ -359,21 +404,19 @@ int vc_get_dlimit(uint32_t id, void __us goto out_release; spin_lock(&dli->dl_lock); - vc_data.inodes_used = dli->dl_inodes_used; - vc_data.inodes_total = dli->dl_inodes_total; - vc_data.space_used = dli->dl_space_used >> 10; + *inodes_used = dli->dl_inodes_used; + *inodes_total = dli->dl_inodes_total; + *space_used = dli->dl_space_used >> 10; if (dli->dl_space_total == (uint64_t)CDLIM_INFINITY) - vc_data.space_total = (uint32_t)CDLIM_INFINITY; + *space_total = (uint32_t)CDLIM_INFINITY; else - vc_data.space_total = dli->dl_space_total >> 10; + *space_total = dli->dl_space_total >> 10; - vc_data.reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10); + *reserved = 100 - ((dli->dl_nrlmult * 100 + 512) >> 10); spin_unlock(&dli->dl_lock); put_dl_info(dli); ret = -EFAULT; - if (copy_to_user(data, &vc_data, sizeof(vc_data))) - goto out_release; ret = 0; out_release: @@ -383,6 +426,55 @@ int vc_get_dlimit(uint32_t id, void __us } +int vc_get_dlimit(uint32_t id, void __user *data) +{ + struct vcmd_ctx_dlimit_v0 vc_data; + int ret; + + if (!vx_check(0, VX_ADMIN)) + return -ENOSYS; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + ret = do_get_dlimit(id, vc_data.name, + &vc_data.space_used, &vc_data.space_total, + &vc_data.inodes_used, &vc_data.inodes_total, + &vc_data.reserved, &vc_data.flags); + if (ret) + return ret; + + if (copy_to_user(data, &vc_data, sizeof(vc_data))) + return -EFAULT; + return 0; +} + +#ifdef VSERVER_COMPAT_X32 + +int vc_get_dlimit_x32(uint32_t id, void __user *data) +{ + struct vcmd_ctx_dlimit_v0_x32 vc_data; + int ret; + + if (!vx_check(0, VX_ADMIN)) + return -ENOSYS; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + ret = do_get_dlimit(id, (const char __user *)vc_data.name_ptr, + &vc_data.space_used, &vc_data.space_total, + &vc_data.inodes_used, &vc_data.inodes_total, + &vc_data.reserved, &vc_data.flags); + if (ret) + return ret; + + if (copy_to_user(data, &vc_data, sizeof(vc_data))) + return -EFAULT; + return 0; +} + +#endif /* VSERVER_COMPAT_X32 */ + + void vx_vsi_statfs(struct super_block *sb, struct kstatfs *buf) { struct dl_info *dli; diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/kernel/vserver/inode.c linux-2.6.11.7-vs2.0-pre2.4/kernel/vserver/inode.c --- linux-2.6.11.7-vs2.0-pre2.3/kernel/vserver/inode.c 2005-04-14 21:19:29 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/kernel/vserver/inode.c 2005-04-27 06:19:44 +0200 @@ -9,7 +9,6 @@ * */ -#include #include #include #include @@ -17,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -87,12 +87,44 @@ int vc_get_iattr(uint32_t id, void __use &vc_data.xid, &vc_data.flags, &vc_data.mask); path_release(&nd); } + if (ret) + return ret; + + if (copy_to_user (data, &vc_data, sizeof(vc_data))) + ret = -EFAULT; + return ret; +} + +#ifdef VSERVER_COMPAT_X32 + +int vc_get_iattr_x32(uint32_t id, void __user *data) +{ + struct nameidata nd; + struct vcmd_ctx_iattr_v1_x32 vc_data = { .xid = -1 }; + int ret; + + if (!vx_check(0, VX_ADMIN)) + return -ENOSYS; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + ret = user_path_walk_link((const char __user *)vc_data.name_ptr, &nd); + if (!ret) { + ret = __vc_get_iattr(nd.dentry->d_inode, + &vc_data.xid, &vc_data.flags, &vc_data.mask); + path_release(&nd); + } + if (ret) + return ret; if (copy_to_user (data, &vc_data, sizeof(vc_data))) ret = -EFAULT; return ret; } +#endif /* VSERVER_COMPAT_X32 */ + + static int __vc_set_iattr(struct dentry *de, uint32_t *xid, uint32_t *flags, uint32_t *mask) { struct inode *in = de->d_inode; @@ -189,6 +221,32 @@ int vc_set_iattr(uint32_t id, void __use return ret; } +#ifdef VSERVER_COMPAT_X32 + +int vc_set_iattr_x32(uint32_t id, void __user *data) +{ + struct nameidata nd; + struct vcmd_ctx_iattr_v1_x32 vc_data; + int ret; + + if (!capable(CAP_SYS_ADMIN) || !capable(CAP_LINUX_IMMUTABLE)) + return -EPERM; + if (copy_from_user (&vc_data, data, sizeof(vc_data))) + return -EFAULT; + + ret = user_path_walk_link((const char __user *)vc_data.name_ptr, &nd); + if (!ret) { + ret = __vc_set_iattr(nd.dentry, + &vc_data.xid, &vc_data.flags, &vc_data.mask); + path_release(&nd); + } + + if (copy_to_user (data, &vc_data, sizeof(vc_data))) + ret = -EFAULT; + return ret; +} + +#endif /* VSERVER_COMPAT_X32 */ #ifdef CONFIG_VSERVER_LEGACY diff -NurpP --minimal linux-2.6.11.7-vs2.0-pre2.3/kernel/vserver/switch.c linux-2.6.11.7-vs2.0-pre2.4/kernel/vserver/switch.c --- linux-2.6.11.7-vs2.0-pre2.3/kernel/vserver/switch.c 2005-04-23 22:36:30 +0200 +++ linux-2.6.11.7-vs2.0-pre2.4/kernel/vserver/switch.c 2005-04-27 06:11:05 +0200 @@ -10,21 +10,22 @@ * V0.03 added rlimit functions * V0.04 added iattr, task/xid functions * V0.05 added debug/history stuff + * V0.06 added compat32 layer * */ -#include #include #include #include +#include #include #include #include -static inline int -vc_get_version(uint32_t id) +static inline +int vc_get_version(uint32_t id) { return VCI_VERSION; } @@ -45,8 +46,17 @@ vc_get_version(uint32_t id) #include -extern asmlinkage long -sys_vserver(uint32_t cmd, uint32_t id, void __user *data) +#ifdef VSERVER_COMPAT_X32 +#define __COMPAT(name, id, data, compat) \ + (compat) ? name ## _x32 (id, data) : name (id, data) +#else +#define __COMPAT(name, id, data, compat) \ + name (id, data) +#endif + + +static inline +long do_vserver(uint32_t cmd, uint32_t id, void __user *data, int compat) { vxdprintk(VXD_CBIT(switch, 0), "vc: VCMD_%02d_%d[%d], %d", @@ -153,13 +163,13 @@ sys_vserver(uint32_t cmd, uint32_t id, v return vc_set_sched(id, data); case VCMD_add_dlimit: - return vc_add_dlimit(id, data); + return __COMPAT(vc_add_dlimit, id, data, compat); case VCMD_rem_dlimit: - return vc_rem_dlimit(id, data); + return __COMPAT(vc_rem_dlimit, id, data, compat); case VCMD_set_dlimit: - return vc_set_dlimit(id, data); + return __COMPAT(vc_set_dlimit, id, data, compat); case VCMD_get_dlimit: - return vc_get_dlimit(id, data); + return __COMPAT(vc_get_dlimit, id, data, compat); } /* below here only with VX_ADMIN */ @@ -181,9 +191,9 @@ sys_vserver(uint32_t cmd, uint32_t id, v #endif case VCMD_get_iattr: - return vc_get_iattr(id, data); + return __COMPAT(vc_get_iattr, id, data, compat); case VCMD_set_iattr: - return vc_set_iattr(id, data); + return __COMPAT(vc_set_iattr, id, data, compat); case VCMD_enter_namespace: return vc_enter_namespace(id, data); @@ -208,3 +218,18 @@ sys_vserver(uint32_t cmd, uint32_t id, v return -ENOSYS; } +extern asmlinkage long +sys_vserver(uint32_t cmd, uint32_t id, void __user *data) +{ + return do_vserver(cmd, id, data, 0); +} + +#ifdef VSERVER_COMPAT_X32 + +extern asmlinkage long +sys32_vserver(uint32_t cmd, uint32_t id, void __user *data) +{ + return do_vserver(cmd, id, data, 1); +} + +#endif /* VSERVER_COMPAT_X32 */