* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
@ 2007-06-15 10:03 Mikael Pettersson
2007-06-15 10:41 ` Vasily Tarasov
2007-06-15 10:43 ` Arnd Bergmann
0 siblings, 2 replies; 31+ messages in thread
From: Mikael Pettersson @ 2007-06-15 10:03 UTC (permalink / raw)
To: akpm, vtaras; +Cc: dev, devel, jack, linux-kernel, nataliep, vvs
On Fri, 15 Jun 2007 13:01:48 +0400, Vasily Tarasov wrote:
> OpenVZ Linux kernel team has discovered the problem
> with 32bit quota tools working on 64bit architectures.
> In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
> the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
> However this isn't right. Look at if_dqblk structure:
Your patch only converts ia32 on x86-64 or ia64.
What about ppc32-on-ppc64 and sparc32-on-sparc64?
And, I guess, mips32-on-mips64?
> --- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
> +++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-14 19:50:13.000000000 +0400
...
> +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
> +/*
> + * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
> + * and is necessary due to alignment problems.
> + */
The #ifdef looks way too arch-specific. And isn't there a shared
compat.c module somewhere that this should go into?
/Mikael
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-15 10:03 [PATCH] diskquota: 32bit quota tools on 64bit architectures Mikael Pettersson
@ 2007-06-15 10:41 ` Vasily Tarasov
2007-06-15 10:43 ` Arnd Bergmann
1 sibling, 0 replies; 31+ messages in thread
From: Vasily Tarasov @ 2007-06-15 10:41 UTC (permalink / raw)
To: Mikael Pettersson; +Cc: akpm, dev, devel, jack, linux-kernel, nataliep, vvs
You can find a half-year back discussions of this patch:
First attempt: http://lkml.org/lkml/2006/10/19/123
Second attempt: http://lkml.org/lkml/2006/10/25/57
I think they will answer your questions.
Thank you,
Vasily
On Fri, 2007-06-15 at 12:03 +0200, Mikael Pettersson wrote:
> On Fri, 15 Jun 2007 13:01:48 +0400, Vasily Tarasov wrote:
> > OpenVZ Linux kernel team has discovered the problem
> > with 32bit quota tools working on 64bit architectures.
> > In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
> > the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
> > However this isn't right. Look at if_dqblk structure:
>
> Your patch only converts ia32 on x86-64 or ia64.
> What about ppc32-on-ppc64 and sparc32-on-sparc64?
> And, I guess, mips32-on-mips64?
>
> > --- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
> > +++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-14 19:50:13.000000000 +0400
> ...
> > +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
> > +/*
> > + * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
> > + * and is necessary due to alignment problems.
> > + */
>
> The #ifdef looks way too arch-specific. And isn't there a shared
> compat.c module somewhere that this should go into?
>
> /Mikael
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-15 10:03 [PATCH] diskquota: 32bit quota tools on 64bit architectures Mikael Pettersson
2007-06-15 10:41 ` Vasily Tarasov
@ 2007-06-15 10:43 ` Arnd Bergmann
2007-06-15 11:00 ` Vasily Tarasov
2007-06-15 14:48 ` Vasily Tarasov
1 sibling, 2 replies; 31+ messages in thread
From: Arnd Bergmann @ 2007-06-15 10:43 UTC (permalink / raw)
To: Mikael Pettersson
Cc: akpm, vtaras, dev, devel, jack, linux-kernel, nataliep, vvs
On Friday 15 June 2007, Mikael Pettersson wrote:
> > --- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
> > +++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-14 19:50:13.000000000 +0400
> ...
> > +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
> > +/*
> > + * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
> > + * and is necessary due to alignment problems.
> > + */
>
> The #ifdef looks way too arch-specific. And isn't there a shared
> compat.c module somewhere that this should go into?
>
Only x86_64 and ia64 have this particular problem, the other architectures,
and hopefully all future 64 bit platforms with 32 bit user space use
the same alignment rules in elf32 and elf64.
Still, the patch should be converted to use the compat_u64 type and not
add an 'attribute((packed))' so that you _can_ use the same code on all
architectures. See my 'Introduce compat_u64 and compat_s64 types' patch
that I just posted in another thread.
Arnd <><
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-15 10:43 ` Arnd Bergmann
@ 2007-06-15 11:00 ` Vasily Tarasov
2007-06-15 14:48 ` Vasily Tarasov
1 sibling, 0 replies; 31+ messages in thread
From: Vasily Tarasov @ 2007-06-15 11:00 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Mikael Pettersson, akpm, dev, devel, jack, linux-kernel, nataliep, vvs
On Fri, 2007-06-15 at 12:43 +0200, Arnd Bergmann wrote:
> On Friday 15 June 2007, Mikael Pettersson wrote:
> > > --- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
> > > +++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-14 19:50:13.000000000 +0400
> > ...
> > > +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
> > > +/*
> > > + * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
> > > + * and is necessary due to alignment problems.
> > > + */
> >
> > The #ifdef looks way too arch-specific. And isn't there a shared
> > compat.c module somewhere that this should go into?
> >
>
> Only x86_64 and ia64 have this particular problem, the other architectures,
> and hopefully all future 64 bit platforms with 32 bit user space use
> the same alignment rules in elf32 and elf64.
>
> Still, the patch should be converted to use the compat_u64 type and not
> add an 'attribute((packed))' so that you _can_ use the same code on all
> architectures. See my 'Introduce compat_u64 and compat_s64 types' patch
> that I just posted in another thread.
>
> Arnd <><
>
Agree, it'll be the most clean solution.
Is it ok, if I'll send a patch against (current kernel + Arnd's patch)?
Thanks,
Vasily
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-15 10:43 ` Arnd Bergmann
2007-06-15 11:00 ` Vasily Tarasov
@ 2007-06-15 14:48 ` Vasily Tarasov
2007-06-15 15:24 ` Arnd Bergmann
1 sibling, 1 reply; 31+ messages in thread
From: Vasily Tarasov @ 2007-06-15 14:48 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Mikael Pettersson, akpm, dev, devel, jack, linux-kernel, nataliep, vvs
On Fri, 2007-06-15 at 12:43 +0200, Arnd Bergmann wrote:
> On Friday 15 June 2007, Mikael Pettersson wrote:
> > > --- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
> > > +++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-14 19:50:13.000000000 +0400
> > ...
> > > +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
> > > +/*
> > > + * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
> > > + * and is necessary due to alignment problems.
> > > + */
> >
> > The #ifdef looks way too arch-specific. And isn't there a shared
> > compat.c module somewhere that this should go into?
> >
>
> Only x86_64 and ia64 have this particular problem, the other architectures,
> and hopefully all future 64 bit platforms with 32 bit user space use
> the same alignment rules in elf32 and elf64.
>
> Still, the patch should be converted to use the compat_u64 type and not
> add an 'attribute((packed))' so that you _can_ use the same code on all
> architectures. See my 'Introduce compat_u64 and compat_s64 types' patch
> that I just posted in another thread.
>
> Arnd <><
>
Hello,
I just noticed that we can not avoid the addition of packed attribute.
Look, for example:
struct if_dqblk {
__u64 dqb_bhardlimit;
__u64 dqb_bsoftlimit;
__u64 dqb_curspace;
__u64 dqb_ihardlimit;
__u64 dqb_isoftlimit;
__u64 dqb_curinodes;
__u64 dqb_btime;
__u64 dqb_itime;
__u32 dqb_valid;
};
sizeof(if_dqblk) = 0x48
On 32 bit: 0x44
If I replace __u64/__u32 with compat equivalents - it will not help!
alligned attribute can _only_ _increase_ the size of structure, but not
decrease it.
So we should use packed or just use the array of ints: int[2].
Vasily
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-15 14:48 ` Vasily Tarasov
@ 2007-06-15 15:24 ` Arnd Bergmann
2007-06-18 7:41 ` Vasily Tarasov
0 siblings, 1 reply; 31+ messages in thread
From: Arnd Bergmann @ 2007-06-15 15:24 UTC (permalink / raw)
To: vtaras
Cc: Mikael Pettersson, akpm, dev, devel, jack, linux-kernel, nataliep, vvs
On Friday 15 June 2007, Vasily Tarasov wrote:
> I just noticed that we can not avoid the addition of packed attribute.
> Look, for example:
>
> struct if_dqblk {
> __u64 dqb_bhardlimit;
> __u64 dqb_bsoftlimit;
> __u64 dqb_curspace;
> __u64 dqb_ihardlimit;
> __u64 dqb_isoftlimit;
> __u64 dqb_curinodes;
> __u64 dqb_btime;
> __u64 dqb_itime;
> __u32 dqb_valid;
> };
>
> sizeof(if_dqblk) = 0x48
> On 32 bit: 0x44
>
> If I replace __u64/__u32 with compat equivalents - it will not help!
> alligned attribute can _only_ _increase_ the size of structure, but not
> decrease it.
No, the gcc documentation isn't quite clear there, see the discussion about
compat_u64 and compat_s64 types. It actually does the right thing when
you use 'typedef __u64 __attribute__((aligned(64))) compat_64', as my
patch does.
Arnd <><
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-15 15:24 ` Arnd Bergmann
@ 2007-06-18 7:41 ` Vasily Tarasov
0 siblings, 0 replies; 31+ messages in thread
From: Vasily Tarasov @ 2007-06-18 7:41 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Mikael Pettersson, akpm, dev, devel, jack, linux-kernel, nataliep, vvs
On Fri, 2007-06-15 at 17:24 +0200, Arnd Bergmann wrote:
> On Friday 15 June 2007, Vasily Tarasov wrote:
> > I just noticed that we can not avoid the addition of packed attribute.
> > Look, for example:
> >
> > struct if_dqblk {
> > __u64 dqb_bhardlimit;
> > __u64 dqb_bsoftlimit;
> > __u64 dqb_curspace;
> > __u64 dqb_ihardlimit;
> > __u64 dqb_isoftlimit;
> > __u64 dqb_curinodes;
> > __u64 dqb_btime;
> > __u64 dqb_itime;
> > __u32 dqb_valid;
> > };
> >
> > sizeof(if_dqblk) = 0x48
> > On 32 bit: 0x44
> >
> > If I replace __u64/__u32 with compat equivalents - it will not help!
> > alligned attribute can _only_ _increase_ the size of structure, but not
> > decrease it.
>
> No, the gcc documentation isn't quite clear there, see the discussion about
> compat_u64 and compat_s64 types. It actually does the right thing when
> you use 'typedef __u64 __attribute__((aligned(64))) compat_64', as my
> patch does.
>
> Arnd <><
>
Wow!... Thank you for the explanation.
I'll resend the patch soon.
Vasily
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-19 19:33 ` Andrew Morton
2007-06-19 20:09 ` Mikael Pettersson
@ 2007-06-19 22:34 ` David Miller
1 sibling, 0 replies; 31+ messages in thread
From: David Miller @ 2007-06-19 22:34 UTC (permalink / raw)
To: akpm; +Cc: vtaras, dev, vvs, devel, linux-kernel, nataliep, jack, linux-arch
From: Andrew Morton <akpm@linux-foundation.org>
Date: Tue, 19 Jun 2007 12:33:16 -0700
> Only x86_64 and ia64 are fixed. Would it be correct to assume that the
> other CONFIG_COMPAT architectures also need to be fixed?
Only platforms which compat to "i386" have the issue wrt.
the alignment of "u64" types, which is "4" on i386 and
"8" on the platforms that compat to them.
This has been mentioned at least 3 times in this thread.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-19 19:33 ` Andrew Morton
@ 2007-06-19 20:09 ` Mikael Pettersson
2007-06-19 22:34 ` David Miller
1 sibling, 0 replies; 31+ messages in thread
From: Mikael Pettersson @ 2007-06-19 20:09 UTC (permalink / raw)
To: Andrew Morton
Cc: Vasily Tarasov, Kirill Korotaev, Vasily Averin,
OpenVZ Developers ML, Linux Kernel ML, Natalie Protasevich,
Jan Kara, linux-arch
Andrew Morton writes:
> On Mon, 18 Jun 2007 12:21:47 +0400
> Vasily Tarasov <vtaras@openvz.org> wrote:
>
> > From: Vasily Tarasov <vtaras@openvz.org>
> >
> > This patch should be applied after Arnd Bergmann's patch,
> > that intoduces new compat types:
> > http://lkml.org/lkml/2007/6/15/98
> >
> > OpenVZ Linux kernel team has discovered the problem
> > with 32bit quota tools working on 64bit architectures.
> > In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
> > the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
> > However this isn't right. Look at if_dqblk structure:
> >
> > struct if_dqblk {
> > __u64 dqb_bhardlimit;
> > __u64 dqb_bsoftlimit;
> > __u64 dqb_curspace;
> > __u64 dqb_ihardlimit;
> > __u64 dqb_isoftlimit;
> > __u64 dqb_curinodes;
> > __u64 dqb_btime;
> > __u64 dqb_itime;
> > __u32 dqb_valid;
> > };
> >
> > For 32 bit quota tools sizeof(if_dqblk) == 0x44.
> > But for 64 bit kernel its size is 0x48, 'cause of alignment!
> > Thus we got a problem. Attached patch reintroduce sys32_quotactl() function,
> > that handles this and related situations.
> >
> > Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
> >
> > ---
> >
> > In OpenVZ technology 32 bit Virtual Environments over
> > 64 bit OS are common, hence we have customers, that complains on this bad quota
> > behaviour:
> >
> > # /usr/bin/quota
> > quota: error while getting quota from /dev/sda1 for 0: Success
> >
> > The reason is caused above.
>
> Only x86_64 and ia64 are fixed. Would it be correct to assume that the
> other CONFIG_COMPAT architectures also need to be fixed?
I complained about this very issue when a previous version of
this patch was submitted last week, and Arnd explained that
non-x86 doesn't have a problem here because alignof(u64) is the
same in 32- and 64-bit modes.
However, the fact that the patch description talks about 32-
and 64-bit machines _in_general_, while the patch clearly only
handles x86-32 on x86-64 and ia64, is itself a bug. A more
precise patch description and a better comment in the code
is in order, I think.
/Mikael
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2007-06-18 8:21 Vasily Tarasov
@ 2007-06-19 19:33 ` Andrew Morton
2007-06-19 20:09 ` Mikael Pettersson
2007-06-19 22:34 ` David Miller
0 siblings, 2 replies; 31+ messages in thread
From: Andrew Morton @ 2007-06-19 19:33 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Kirill Korotaev, Vasily Averin, OpenVZ Developers ML,
Linux Kernel ML, Natalie Protasevich, Jan Kara, linux-arch
On Mon, 18 Jun 2007 12:21:47 +0400
Vasily Tarasov <vtaras@openvz.org> wrote:
> From: Vasily Tarasov <vtaras@openvz.org>
>
> This patch should be applied after Arnd Bergmann's patch,
> that intoduces new compat types:
> http://lkml.org/lkml/2007/6/15/98
>
> OpenVZ Linux kernel team has discovered the problem
> with 32bit quota tools working on 64bit architectures.
> In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
> the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
> However this isn't right. Look at if_dqblk structure:
>
> struct if_dqblk {
> __u64 dqb_bhardlimit;
> __u64 dqb_bsoftlimit;
> __u64 dqb_curspace;
> __u64 dqb_ihardlimit;
> __u64 dqb_isoftlimit;
> __u64 dqb_curinodes;
> __u64 dqb_btime;
> __u64 dqb_itime;
> __u32 dqb_valid;
> };
>
> For 32 bit quota tools sizeof(if_dqblk) == 0x44.
> But for 64 bit kernel its size is 0x48, 'cause of alignment!
> Thus we got a problem. Attached patch reintroduce sys32_quotactl() function,
> that handles this and related situations.
>
> Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
>
> ---
>
> In OpenVZ technology 32 bit Virtual Environments over
> 64 bit OS are common, hence we have customers, that complains on this bad quota
> behaviour:
>
> # /usr/bin/quota
> quota: error while getting quota from /dev/sda1 for 0: Success
>
> The reason is caused above.
Only x86_64 and ia64 are fixed. Would it be correct to assume that the
other CONFIG_COMPAT architectures also need to be fixed?
> --- linux-2.6.22-rc4-fixed/arch/x86_64/ia32/ia32entry.S.orig 2007-06-14 15:55:24.000000000 +0400
> +++ linux-2.6.22-rc4-fixed/arch/x86_64/ia32/ia32entry.S 2007-06-14 16:22:52.000000000 +0400
> @@ -526,7 +526,7 @@ ia32_sys_call_table:
> .quad sys_init_module
> .quad sys_delete_module
> .quad quiet_ni_syscall /* 130 get_kernel_syms */
> - .quad sys_quotactl
> + .quad sys32_quotactl
> .quad sys_getpgid
> .quad sys_fchdir
> .quad quiet_ni_syscall /* bdflush */
> --- linux-2.6.22-rc4-fixed/arch/ia64/ia32/ia32_entry.S.orig 2007-06-14 15:55:24.000000000 +0400
> +++ linux-2.6.22-rc4-fixed/arch/ia64/ia32/ia32_entry.S 2007-06-14 16:22:52.000000000 +0400
> @@ -304,7 +304,7 @@ ia32_syscall_table:
> data8 sys_ni_syscall /* init_module */
> data8 sys_ni_syscall /* delete_module */
> data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */
> - data8 sys_quotactl
> + data8 sys32_quotactl
> data8 sys_getpgid
> data8 sys_fchdir
> data8 sys_ni_syscall /* sys_bdflush */
> --- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
> +++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-18 12:00:56.000000000 +0400
> @@ -10,12 +10,14 @@
> #include <linux/slab.h>
> #include <asm/current.h>
> #include <asm/uaccess.h>
> +#include <asm/compat.h>
> #include <linux/kernel.h>
> #include <linux/security.h>
> #include <linux/syscalls.h>
> #include <linux/buffer_head.h>
> #include <linux/capability.h>
> #include <linux/quotaops.h>
> +#include <linux/types.h>
>
> /* Check validity of generic quotactl commands */
> static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
> @@ -384,3 +386,119 @@ asmlinkage long sys_quotactl(unsigned in
>
> return ret;
> }
> +
> +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
> +/*
> + * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
> + * and is necessary due to alignment problems.
> + */
> +struct compat_if_dqblk {
> + compat_u64 dqb_bhardlimit;
> + compat_u64 dqb_bsoftlimit;
> + compat_u64 dqb_curspace;
> + compat_u64 dqb_ihardlimit;
> + compat_u64 dqb_isoftlimit;
> + compat_u64 dqb_curinodes;
> + compat_u64 dqb_btime;
> + compat_u64 dqb_itime;
> + compat_uint_t dqb_valid;
> +};
> +
> +/* XFS structures */
> +struct compat_fs_qfilestat {
> + compat_u64 dqb_bhardlimit;
> + compat_u64 qfs_nblks;
> + compat_uint_t qfs_nextents;
> +};
> +
> +struct compat_fs_quota_stat {
> + __s8 qs_version;
> + __u16 qs_flags;
> + __s8 qs_pad;
> + struct compat_fs_qfilestat qs_uquota;
> + struct compat_fs_qfilestat qs_gquota;
> + compat_uint_t qs_incoredqs;
> + compat_int_t qs_btimelimit;
> + compat_int_t qs_itimelimit;
> + compat_int_t qs_rtbtimelimit;
> + __u16 qs_bwarnlimit;
> + __u16 qs_iwarnlimit;
> +};
> +
> +asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
> + qid_t id, void __user *addr)
> +{
> + unsigned int cmds;
> + struct if_dqblk __user *dqblk;
> + struct compat_if_dqblk __user *compat_dqblk;
> + struct fs_quota_stat __user *fsqstat;
> + struct compat_fs_quota_stat __user *compat_fsqstat;
> + compat_uint_t data;
> + u16 xdata;
> + long ret;
> +
> + cmds = cmd >> SUBCMDSHIFT;
> +
> + switch (cmds) {
> + case Q_GETQUOTA:
> + dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
> + compat_dqblk = addr;
> + ret = sys_quotactl(cmd, special, id, dqblk);
> + if (ret)
> + break;
> + if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) ||
> + get_user(data, &dqblk->dqb_valid) ||
> + put_user(data, &compat_dqblk->dqb_valid))
> + ret = -EFAULT;
> + break;
> + case Q_SETQUOTA:
> + dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
> + compat_dqblk = addr;
> + ret = -EFAULT;
> + if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) ||
> + get_user(data, &compat_dqblk->dqb_valid) ||
> + put_user(data, &dqblk->dqb_valid))
> + break;
> + ret = sys_quotactl(cmd, special, id, dqblk);
> + break;
> + case Q_XGETQSTAT:
> + fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat));
> + compat_fsqstat = addr;
> + ret = sys_quotactl(cmd, special, id, fsqstat);
> + if (ret)
> + break;
> + ret = -EFAULT;
> + /* Copying qs_version, qs_flags, qs_pad */
> + if (copy_in_user(compat_fsqstat, fsqstat,
> + offsetof(struct compat_fs_quota_stat, qs_uquota)))
> + break;
> + /* Copying qs_uquota */
> + if (copy_in_user(&compat_fsqstat->qs_uquota,
> + &fsqstat->qs_uquota,
> + sizeof(compat_fsqstat->qs_uquota)) ||
> + get_user(data, &fsqstat->qs_uquota.qfs_nextents) ||
> + put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents))
> + break;
> + /* Copying qs_gquota */
> + if (copy_in_user(&compat_fsqstat->qs_gquota,
> + &fsqstat->qs_gquota,
> + sizeof(compat_fsqstat->qs_gquota)) ||
> + get_user(data, &fsqstat->qs_gquota.qfs_nextents) ||
> + put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents))
> + break;
> + /* Copying the rest */
> + if (copy_in_user(&compat_fsqstat->qs_incoredqs,
> + &fsqstat->qs_incoredqs,
> + sizeof(struct compat_fs_quota_stat) -
> + offsetof(struct compat_fs_quota_stat, qs_incoredqs)) ||
> + get_user(xdata, &fsqstat->qs_iwarnlimit) ||
> + put_user(xdata, &compat_fsqstat->qs_iwarnlimit))
> + break;
> + ret = 0;
> + break;
> + default:
> + ret = sys_quotactl(cmd, special, id, addr);
> + }
> + return ret;
> +}
> +#endif
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH] diskquota: 32bit quota tools on 64bit architectures
@ 2007-06-18 8:21 Vasily Tarasov
2007-06-19 19:33 ` Andrew Morton
0 siblings, 1 reply; 31+ messages in thread
From: Vasily Tarasov @ 2007-06-18 8:21 UTC (permalink / raw)
To: Andrew Morton
Cc: Kirill Korotaev, Vasily Averin, OpenVZ Developers ML,
Linux Kernel ML, Natalie Protasevich, Jan Kara
From: Vasily Tarasov <vtaras@openvz.org>
This patch should be applied after Arnd Bergmann's patch,
that intoduces new compat types:
http://lkml.org/lkml/2007/6/15/98
OpenVZ Linux kernel team has discovered the problem
with 32bit quota tools working on 64bit architectures.
In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
However this isn't right. Look at if_dqblk structure:
struct if_dqblk {
__u64 dqb_bhardlimit;
__u64 dqb_bsoftlimit;
__u64 dqb_curspace;
__u64 dqb_ihardlimit;
__u64 dqb_isoftlimit;
__u64 dqb_curinodes;
__u64 dqb_btime;
__u64 dqb_itime;
__u32 dqb_valid;
};
For 32 bit quota tools sizeof(if_dqblk) == 0x44.
But for 64 bit kernel its size is 0x48, 'cause of alignment!
Thus we got a problem. Attached patch reintroduce sys32_quotactl() function,
that handles this and related situations.
Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
---
In OpenVZ technology 32 bit Virtual Environments over
64 bit OS are common, hence we have customers, that complains on this bad quota
behaviour:
# /usr/bin/quota
quota: error while getting quota from /dev/sda1 for 0: Success
The reason is caused above.
--- linux-2.6.22-rc4-fixed/arch/x86_64/ia32/ia32entry.S.orig 2007-06-14 15:55:24.000000000 +0400
+++ linux-2.6.22-rc4-fixed/arch/x86_64/ia32/ia32entry.S 2007-06-14 16:22:52.000000000 +0400
@@ -526,7 +526,7 @@ ia32_sys_call_table:
.quad sys_init_module
.quad sys_delete_module
.quad quiet_ni_syscall /* 130 get_kernel_syms */
- .quad sys_quotactl
+ .quad sys32_quotactl
.quad sys_getpgid
.quad sys_fchdir
.quad quiet_ni_syscall /* bdflush */
--- linux-2.6.22-rc4-fixed/arch/ia64/ia32/ia32_entry.S.orig 2007-06-14 15:55:24.000000000 +0400
+++ linux-2.6.22-rc4-fixed/arch/ia64/ia32/ia32_entry.S 2007-06-14 16:22:52.000000000 +0400
@@ -304,7 +304,7 @@ ia32_syscall_table:
data8 sys_ni_syscall /* init_module */
data8 sys_ni_syscall /* delete_module */
data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */
- data8 sys_quotactl
+ data8 sys32_quotactl
data8 sys_getpgid
data8 sys_fchdir
data8 sys_ni_syscall /* sys_bdflush */
--- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
+++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-18 12:00:56.000000000 +0400
@@ -10,12 +10,14 @@
#include <linux/slab.h>
#include <asm/current.h>
#include <asm/uaccess.h>
+#include <asm/compat.h>
#include <linux/kernel.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/buffer_head.h>
#include <linux/capability.h>
#include <linux/quotaops.h>
+#include <linux/types.h>
/* Check validity of generic quotactl commands */
static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
@@ -384,3 +386,119 @@ asmlinkage long sys_quotactl(unsigned in
return ret;
}
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+/*
+ * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
+ * and is necessary due to alignment problems.
+ */
+struct compat_if_dqblk {
+ compat_u64 dqb_bhardlimit;
+ compat_u64 dqb_bsoftlimit;
+ compat_u64 dqb_curspace;
+ compat_u64 dqb_ihardlimit;
+ compat_u64 dqb_isoftlimit;
+ compat_u64 dqb_curinodes;
+ compat_u64 dqb_btime;
+ compat_u64 dqb_itime;
+ compat_uint_t dqb_valid;
+};
+
+/* XFS structures */
+struct compat_fs_qfilestat {
+ compat_u64 dqb_bhardlimit;
+ compat_u64 qfs_nblks;
+ compat_uint_t qfs_nextents;
+};
+
+struct compat_fs_quota_stat {
+ __s8 qs_version;
+ __u16 qs_flags;
+ __s8 qs_pad;
+ struct compat_fs_qfilestat qs_uquota;
+ struct compat_fs_qfilestat qs_gquota;
+ compat_uint_t qs_incoredqs;
+ compat_int_t qs_btimelimit;
+ compat_int_t qs_itimelimit;
+ compat_int_t qs_rtbtimelimit;
+ __u16 qs_bwarnlimit;
+ __u16 qs_iwarnlimit;
+};
+
+asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
+ qid_t id, void __user *addr)
+{
+ unsigned int cmds;
+ struct if_dqblk __user *dqblk;
+ struct compat_if_dqblk __user *compat_dqblk;
+ struct fs_quota_stat __user *fsqstat;
+ struct compat_fs_quota_stat __user *compat_fsqstat;
+ compat_uint_t data;
+ u16 xdata;
+ long ret;
+
+ cmds = cmd >> SUBCMDSHIFT;
+
+ switch (cmds) {
+ case Q_GETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ if (ret)
+ break;
+ if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &dqblk->dqb_valid) ||
+ put_user(data, &compat_dqblk->dqb_valid))
+ ret = -EFAULT;
+ break;
+ case Q_SETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = -EFAULT;
+ if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &compat_dqblk->dqb_valid) ||
+ put_user(data, &dqblk->dqb_valid))
+ break;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ break;
+ case Q_XGETQSTAT:
+ fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat));
+ compat_fsqstat = addr;
+ ret = sys_quotactl(cmd, special, id, fsqstat);
+ if (ret)
+ break;
+ ret = -EFAULT;
+ /* Copying qs_version, qs_flags, qs_pad */
+ if (copy_in_user(compat_fsqstat, fsqstat,
+ offsetof(struct compat_fs_quota_stat, qs_uquota)))
+ break;
+ /* Copying qs_uquota */
+ if (copy_in_user(&compat_fsqstat->qs_uquota,
+ &fsqstat->qs_uquota,
+ sizeof(compat_fsqstat->qs_uquota)) ||
+ get_user(data, &fsqstat->qs_uquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents))
+ break;
+ /* Copying qs_gquota */
+ if (copy_in_user(&compat_fsqstat->qs_gquota,
+ &fsqstat->qs_gquota,
+ sizeof(compat_fsqstat->qs_gquota)) ||
+ get_user(data, &fsqstat->qs_gquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents))
+ break;
+ /* Copying the rest */
+ if (copy_in_user(&compat_fsqstat->qs_incoredqs,
+ &fsqstat->qs_incoredqs,
+ sizeof(struct compat_fs_quota_stat) -
+ offsetof(struct compat_fs_quota_stat, qs_incoredqs)) ||
+ get_user(xdata, &fsqstat->qs_iwarnlimit) ||
+ put_user(xdata, &compat_fsqstat->qs_iwarnlimit))
+ break;
+ ret = 0;
+ break;
+ default:
+ ret = sys_quotactl(cmd, special, id, addr);
+ }
+ return ret;
+}
+#endif
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
@ 2007-06-15 11:08 Mikael Pettersson
0 siblings, 0 replies; 31+ messages in thread
From: Mikael Pettersson @ 2007-06-15 11:08 UTC (permalink / raw)
To: arnd, mikpe; +Cc: akpm, dev, devel, jack, linux-kernel, nataliep, vtaras, vvs
On Fri, 15 Jun 2007 12:43:01 +0200, Arnd Bergmann wrote:
> On Friday 15 June 2007, Mikael Pettersson wrote:
> > > --- linux-2.6.22-rc4-fixed/fs/quota.c.orig=A0=A0=A0=A02007-06-14 15:55:=
> 26.000000000 +0400
> > > +++ linux-2.6.22-rc4-fixed/fs/quota.c=A02007-06-14 19:50:13.000000000 +=
> 0400
> > ...
> > > +#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
> > > +/*
> > > + * This code works only for 32 bit quota tools over 64 bit OS (x86_64,=
> ia64)
> > > + * and is necessary due to alignment problems.
> > > + */
> >=20
> > The #ifdef looks way too arch-specific. And isn't there a shared
> > compat.c module somewhere that this should go into?
> >=20
>
> Only x86_64 and ia64 have this particular problem, the other architectures,
> and hopefully all future 64 bit platforms with 32 bit user space use
> the same alignment rules in elf32 and elf64.
Ah yes, alignof(u64) is the same in 32- and 64-bit modes on !x86,
thus they don't have a problem here.
Thanks for explaining that. I consider this is an essential
piece of information that should be included in the patch.
(In a comment in the code, not buried in some commit log.)
/Mikael
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH] diskquota: 32bit quota tools on 64bit architectures
@ 2007-06-15 9:01 Vasily Tarasov
0 siblings, 0 replies; 31+ messages in thread
From: Vasily Tarasov @ 2007-06-15 9:01 UTC (permalink / raw)
To: Andrew Morton
Cc: Kirill Korotaev, Vasily Averin, OpenVZ Developers ML,
Linux Kernel ML, Natalie Protasevich, Jan Kara
From: Vasily Tarasov <vtaras@openvz.org>
OpenVZ Linux kernel team has discovered the problem
with 32bit quota tools working on 64bit architectures.
In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
However this isn't right. Look at if_dqblk structure:
struct if_dqblk {
__u64 dqb_bhardlimit;
__u64 dqb_bsoftlimit;
__u64 dqb_curspace;
__u64 dqb_ihardlimit;
__u64 dqb_isoftlimit;
__u64 dqb_curinodes;
__u64 dqb_btime;
__u64 dqb_itime;
__u32 dqb_valid;
};
For 32 bit quota tools sizeof(if_dqblk) == 0x44.
But for 64 bit kernel its size is 0x48, 'cause of alignment!
Thus we got a problem. Attached patch reintroduce sys32_quotactl() function,
that handles this and related situations.
Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
---
In OpenVZ technology 32 bit Virtual Environments over
64 bit OS are common, hence we have customers, that complains on this bad quota
behaviour:
# /usr/bin/quota
quota: error while getting quota from /dev/sda1 for 0: Success
The reason is caused above.
--- linux-2.6.22-rc4-fixed/arch/x86_64/ia32/ia32entry.S.orig 2007-06-14 15:55:24.000000000 +0400
+++ linux-2.6.22-rc4-fixed/arch/x86_64/ia32/ia32entry.S 2007-06-14 16:22:52.000000000 +0400
@@ -526,7 +526,7 @@ ia32_sys_call_table:
.quad sys_init_module
.quad sys_delete_module
.quad quiet_ni_syscall /* 130 get_kernel_syms */
- .quad sys_quotactl
+ .quad sys32_quotactl
.quad sys_getpgid
.quad sys_fchdir
.quad quiet_ni_syscall /* bdflush */
--- linux-2.6.22-rc4-fixed/arch/ia64/ia32/ia32_entry.S.orig 2007-06-14 15:55:24.000000000 +0400
+++ linux-2.6.22-rc4-fixed/arch/ia64/ia32/ia32_entry.S 2007-06-14 16:22:52.000000000 +0400
@@ -304,7 +304,7 @@ ia32_syscall_table:
data8 sys_ni_syscall /* init_module */
data8 sys_ni_syscall /* delete_module */
data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */
- data8 sys_quotactl
+ data8 sys32_quotactl
data8 sys_getpgid
data8 sys_fchdir
data8 sys_ni_syscall /* sys_bdflush */
--- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
+++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-14 19:50:13.000000000 +0400
@@ -10,12 +10,14 @@
#include <linux/slab.h>
#include <asm/current.h>
#include <asm/uaccess.h>
+#include <asm/compat.h>
#include <linux/kernel.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/buffer_head.h>
#include <linux/capability.h>
#include <linux/quotaops.h>
+#include <linux/types.h>
/* Check validity of generic quotactl commands */
static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
@@ -384,3 +386,119 @@ asmlinkage long sys_quotactl(unsigned in
return ret;
}
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+/*
+ * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
+ * and is necessary due to alignment problems.
+ */
+struct compat_if_dqblk {
+ __u64 dqb_bhardlimit;
+ __u64 dqb_bsoftlimit;
+ __u64 dqb_curspace;
+ __u64 dqb_ihardlimit;
+ __u64 dqb_isoftlimit;
+ __u64 dqb_curinodes;
+ __u64 dqb_btime;
+ __u64 dqb_itime;
+ __u32 dqb_valid;
+} __attribute__ ((__packed__));
+
+/* XFS structures */
+struct compat_fs_qfilestat {
+ __u64 dqb_bhardlimit;
+ __u64 qfs_nblks;
+ __u32 qfs_nextents;
+} __attribute__ ((__packed__));
+
+struct compat_fs_quota_stat {
+ __s8 qs_version;
+ __u16 qs_flags;
+ __s8 qs_pad;
+ struct compat_fs_qfilestat qs_uquota;
+ struct compat_fs_qfilestat qs_gquota;
+ __u32 qs_incoredqs;
+ __s32 qs_btimelimit;
+ __s32 qs_itimelimit;
+ __s32 qs_rtbtimelimit;
+ __u16 qs_bwarnlimit;
+ __u16 qs_iwarnlimit;
+};
+
+asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
+ qid_t id, void __user *addr)
+{
+ unsigned int cmds;
+ struct if_dqblk __user *dqblk;
+ struct compat_if_dqblk __user *compat_dqblk;
+ struct fs_quota_stat __user *fsqstat;
+ struct compat_fs_quota_stat __user *compat_fsqstat;
+ u32 data;
+ u16 xdata;
+ long ret;
+
+ cmds = cmd >> SUBCMDSHIFT;
+
+ switch (cmds) {
+ case Q_GETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ if (ret)
+ break;
+ if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &dqblk->dqb_valid) ||
+ put_user(data, &compat_dqblk->dqb_valid))
+ ret = -EFAULT;
+ break;
+ case Q_SETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = -EFAULT;
+ if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &compat_dqblk->dqb_valid) ||
+ put_user(data, &dqblk->dqb_valid))
+ break;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ break;
+ case Q_XGETQSTAT:
+ fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat));
+ compat_fsqstat = addr;
+ ret = sys_quotactl(cmd, special, id, fsqstat);
+ if (ret)
+ break;
+ ret = -EFAULT;
+ /* Copying qs_version, qs_flags, qs_pad */
+ if (copy_in_user(compat_fsqstat, fsqstat,
+ offsetof(struct compat_fs_quota_stat, qs_uquota)))
+ break;
+ /* Copying qs_uquota */
+ if (copy_in_user(&compat_fsqstat->qs_uquota,
+ &fsqstat->qs_uquota,
+ sizeof(compat_fsqstat->qs_uquota)) ||
+ get_user(data, &fsqstat->qs_uquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents))
+ break;
+ /* Copying qs_gquota */
+ if (copy_in_user(&compat_fsqstat->qs_gquota,
+ &fsqstat->qs_gquota,
+ sizeof(compat_fsqstat->qs_gquota)) ||
+ get_user(data, &fsqstat->qs_gquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents))
+ break;
+ /* Copying the rest */
+ if (copy_in_user(&compat_fsqstat->qs_incoredqs,
+ &fsqstat->qs_incoredqs,
+ sizeof(struct compat_fs_quota_stat) -
+ offsetof(struct compat_fs_quota_stat, qs_incoredqs)) ||
+ get_user(xdata, &fsqstat->qs_iwarnlimit) ||
+ put_user(xdata, &compat_fsqstat->qs_iwarnlimit))
+ break;
+ ret = 0;
+ break;
+ default:
+ ret = sys_quotactl(cmd, special, id, addr);
+ }
+ return ret;
+}
+#endif
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH] diskquota: 32bit quota tools on 64bit architectures
@ 2007-06-15 8:59 Vasily Tarasov
0 siblings, 0 replies; 31+ messages in thread
From: Vasily Tarasov @ 2007-06-15 8:59 UTC (permalink / raw)
To: Andrew Morton
Cc: Kirill Korotaev, Vasily Averin, OpenVZ Developers ML,
Linux Kernel ML, Natalie Protasevich, Jan Kara
From: Vasily Tarasov <vtaras@openvz.org>
OpenVZ Linux kernel team has discovered the problem
with 32bit quota tools working on 64bit architectures.
In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
However this isn't right. Look at if_dqblk structure:
struct if_dqblk {
__u64 dqb_bhardlimit;
__u64 dqb_bsoftlimit;
__u64 dqb_curspace;
__u64 dqb_ihardlimit;
__u64 dqb_isoftlimit;
__u64 dqb_curinodes;
__u64 dqb_btime;
__u64 dqb_itime;
__u32 dqb_valid;
};
For 32 bit quota tools sizeof(if_dqblk) == 0x44.
But for 64 bit kernel its size is 0x48, 'cause of alignment!
Thus we got a problem. Attached patch reintroduce sys32_quotactl() function,
that handles this and related situations.
Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
---
In OpenVZ technology 32 bit Virtual Environments over
64 bit OS are common, hence we have customers, that complains on this bad quota
behaviour:
# /usr/bin/quota
quota: error while getting quota from /dev/sda1 for 0: Success
The reason is caused above.
--- linux-2.6.22-rc4-fixed/arch/x86_64/ia32/ia32entry.S.orig 2007-06-14 15:55:24.000000000 +0400
+++ linux-2.6.22-rc4-fixed/arch/x86_64/ia32/ia32entry.S 2007-06-14 16:22:52.000000000 +0400
@@ -526,7 +526,7 @@ ia32_sys_call_table:
.quad sys_init_module
.quad sys_delete_module
.quad quiet_ni_syscall /* 130 get_kernel_syms */
- .quad sys_quotactl
+ .quad sys32_quotactl
.quad sys_getpgid
.quad sys_fchdir
.quad quiet_ni_syscall /* bdflush */
--- linux-2.6.22-rc4-fixed/arch/ia64/ia32/ia32_entry.S.orig 2007-06-14 15:55:24.000000000 +0400
+++ linux-2.6.22-rc4-fixed/arch/ia64/ia32/ia32_entry.S 2007-06-14 16:22:52.000000000 +0400
@@ -304,7 +304,7 @@ ia32_syscall_table:
data8 sys_ni_syscall /* init_module */
data8 sys_ni_syscall /* delete_module */
data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */
- data8 sys_quotactl
+ data8 sys32_quotactl
data8 sys_getpgid
data8 sys_fchdir
data8 sys_ni_syscall /* sys_bdflush */
--- linux-2.6.22-rc4-fixed/fs/quota.c.orig 2007-06-14 15:55:26.000000000 +0400
+++ linux-2.6.22-rc4-fixed/fs/quota.c 2007-06-14 19:50:13.000000000 +0400
@@ -10,12 +10,14 @@
#include <linux/slab.h>
#include <asm/current.h>
#include <asm/uaccess.h>
+#include <asm/compat.h>
#include <linux/kernel.h>
#include <linux/security.h>
#include <linux/syscalls.h>
#include <linux/buffer_head.h>
#include <linux/capability.h>
#include <linux/quotaops.h>
+#include <linux/types.h>
/* Check validity of generic quotactl commands */
static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
@@ -384,3 +386,119 @@ asmlinkage long sys_quotactl(unsigned in
return ret;
}
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+/*
+ * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
+ * and is necessary due to alignment problems.
+ */
+struct compat_if_dqblk {
+ __u64 dqb_bhardlimit;
+ __u64 dqb_bsoftlimit;
+ __u64 dqb_curspace;
+ __u64 dqb_ihardlimit;
+ __u64 dqb_isoftlimit;
+ __u64 dqb_curinodes;
+ __u64 dqb_btime;
+ __u64 dqb_itime;
+ __u32 dqb_valid;
+} __attribute__ ((__packed__));
+
+/* XFS structures */
+struct compat_fs_qfilestat {
+ __u64 dqb_bhardlimit;
+ __u64 qfs_nblks;
+ __u32 qfs_nextents;
+} __attribute__ ((__packed__));
+
+struct compat_fs_quota_stat {
+ __s8 qs_version;
+ __u16 qs_flags;
+ __s8 qs_pad;
+ struct compat_fs_qfilestat qs_uquota;
+ struct compat_fs_qfilestat qs_gquota;
+ __u32 qs_incoredqs;
+ __s32 qs_btimelimit;
+ __s32 qs_itimelimit;
+ __s32 qs_rtbtimelimit;
+ __u16 qs_bwarnlimit;
+ __u16 qs_iwarnlimit;
+};
+
+asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
+ qid_t id, void __user *addr)
+{
+ unsigned int cmds;
+ struct if_dqblk __user *dqblk;
+ struct compat_if_dqblk __user *compat_dqblk;
+ struct fs_quota_stat __user *fsqstat;
+ struct compat_fs_quota_stat __user *compat_fsqstat;
+ u32 data;
+ u16 xdata;
+ long ret;
+
+ cmds = cmd >> SUBCMDSHIFT;
+
+ switch (cmds) {
+ case Q_GETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ if (ret)
+ break;
+ if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &dqblk->dqb_valid) ||
+ put_user(data, &compat_dqblk->dqb_valid))
+ ret = -EFAULT;
+ break;
+ case Q_SETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = -EFAULT;
+ if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &compat_dqblk->dqb_valid) ||
+ put_user(data, &dqblk->dqb_valid))
+ break;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ break;
+ case Q_XGETQSTAT:
+ fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat));
+ compat_fsqstat = addr;
+ ret = sys_quotactl(cmd, special, id, fsqstat);
+ if (ret)
+ break;
+ ret = -EFAULT;
+ /* Copying qs_version, qs_flags, qs_pad */
+ if (copy_in_user(compat_fsqstat, fsqstat,
+ offsetof(struct compat_fs_quota_stat, qs_uquota)))
+ break;
+ /* Copying qs_uquota */
+ if (copy_in_user(&compat_fsqstat->qs_uquota,
+ &fsqstat->qs_uquota,
+ sizeof(compat_fsqstat->qs_uquota)) ||
+ get_user(data, &fsqstat->qs_uquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents))
+ break;
+ /* Copying qs_gquota */
+ if (copy_in_user(&compat_fsqstat->qs_gquota,
+ &fsqstat->qs_gquota,
+ sizeof(compat_fsqstat->qs_gquota)) ||
+ get_user(data, &fsqstat->qs_gquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents))
+ break;
+ /* Copying the rest */
+ if (copy_in_user(&compat_fsqstat->qs_incoredqs,
+ &fsqstat->qs_incoredqs,
+ sizeof(struct compat_fs_quota_stat) -
+ offsetof(struct compat_fs_quota_stat, qs_incoredqs)) ||
+ get_user(xdata, &fsqstat->qs_iwarnlimit) ||
+ put_user(xdata, &compat_fsqstat->qs_iwarnlimit))
+ break;
+ ret = 0;
+ break;
+ default:
+ ret = sys_quotactl(cmd, special, id, addr);
+ }
+ return ret;
+}
+#endif
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-25 11:25 ` Vasily Tarasov
@ 2006-10-25 11:50 ` Arnd Bergmann
0 siblings, 0 replies; 31+ messages in thread
From: Arnd Bergmann @ 2006-10-25 11:50 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara, Alan Cox,
Roman Kagan, Randy Dunlap, Dmitry Mishin, Andi Kleen,
Vasily Averin, Christoph Hellwig, Kirill Korotaev,
OpenVZ Developers List
On Wednesday 25 October 2006 13:25, Vasily Tarasov wrote:
> Actually I didn't use __attribute__, 'case I'v heard, that this isn't
> encouraged now to use __attribute__((...)) in kernel. But if you think it
> is ok, and even preferable, I will definitely redo it!
You shouldn't use attributes in ABI headers, because they are
not interpreted correctly by every compiler. For stuff inside
of the kernel, I don't see a reason against it.
Arnd <><
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-25 11:03 ` Arnd Bergmann
@ 2006-10-25 11:25 ` Vasily Tarasov
2006-10-25 11:50 ` Arnd Bergmann
0 siblings, 1 reply; 31+ messages in thread
From: Vasily Tarasov @ 2006-10-25 11:25 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara, Alan Cox,
Roman Kagan, Randy Dunlap, Dmitry Mishin, Andi Kleen,
Vasily Averin, Christoph Hellwig, Kirill Korotaev,
OpenVZ Developers List
Arnd Bergmann wrote:
> > +struct compat_if_dqblk {
> > + compat_uint_t dqb_bhardlimit[2];
> > + compat_uint_t dqb_bsoftlimit[2];
> > + compat_uint_t dqb_curspace[2];
> > + compat_uint_t dqb_ihardlimit[2];
> > + compat_uint_t dqb_isoftlimit[2];
> > + compat_uint_t dqb_curinodes[2];
> > + compat_uint_t dqb_btime[2];
> > + compat_uint_t dqb_itime[2];
> > + compat_uint_t dqb_valid;
> > +};
> > +
> > +/* XFS structures */
> > +struct compat_fs_qfilestat {
> > + compat_uint_t dqb_bhardlimit[2];
> > + compat_uint_t qfs_nblks[2];
> > + compat_uint_t qfs_nextents;
> > +};
> > +
>
> The patch looks technically correct, but you have defined the structures
> in a somewhat unusual way. I'd have defined them with
> attribute((packed, aligned(4))) in the end.
>
> Or even better, we should probably add a
>
> typedef unsigned long long __attribute__((aligned(4))) compat_u64;
>
> for x86 compat and use that instead of compat_uint_t foo[2].
Actually I didn't use __attribute__, 'case I'v heard, that this isn't
encouraged now to use __attribute__((...)) in kernel. But if you think it
is ok, and even preferable, I will definitely redo it!
Thanks!
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-25 10:03 Vasily Tarasov
@ 2006-10-25 11:03 ` Arnd Bergmann
2006-10-25 11:25 ` Vasily Tarasov
0 siblings, 1 reply; 31+ messages in thread
From: Arnd Bergmann @ 2006-10-25 11:03 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara, Alan Cox,
Roman Kagan, Randy Dunlap, Dmitry Mishin, Andi Kleen,
Vasily Averin, Christoph Hellwig, Kirill Korotaev,
OpenVZ Developers List
On Wednesday 25 October 2006 12:03, Vasily Tarasov wrote:
> + * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
> + * and is necessary due to alignment problems.
> + */
> +struct compat_if_dqblk {
> + compat_uint_t dqb_bhardlimit[2];
> + compat_uint_t dqb_bsoftlimit[2];
> + compat_uint_t dqb_curspace[2];
> + compat_uint_t dqb_ihardlimit[2];
> + compat_uint_t dqb_isoftlimit[2];
> + compat_uint_t dqb_curinodes[2];
> + compat_uint_t dqb_btime[2];
> + compat_uint_t dqb_itime[2];
> + compat_uint_t dqb_valid;
> +};
> +
> +/* XFS structures */
> +struct compat_fs_qfilestat {
> + compat_uint_t dqb_bhardlimit[2];
> + compat_uint_t qfs_nblks[2];
> + compat_uint_t qfs_nextents;
> +};
> +
The patch looks technically correct, but you have defined the structures
in a somewhat unusual way. I'd have defined them with
attribute((packed, aligned(4))) in the end.
Or even better, we should probably add a
typedef unsigned long long __attribute__((aligned(4))) compat_u64;
for x86 compat and use that instead of compat_uint_t foo[2].
Arnd <><
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH] diskquota: 32bit quota tools on 64bit architectures
@ 2006-10-25 10:03 Vasily Tarasov
2006-10-25 11:03 ` Arnd Bergmann
0 siblings, 1 reply; 31+ messages in thread
From: Vasily Tarasov @ 2006-10-25 10:03 UTC (permalink / raw)
To: Linux Kernel Mailing List
Cc: Andrew Morton, Jan Kara, Alan Cox, Roman Kagan, Randy Dunlap,
Dmitry Mishin, Andi Kleen, Vasily Averin, Christoph Hellwig,
Kirill Korotaev, Arnd Bergmann, OpenVZ Developers List
OpenVZ Linux kernel team has discovered the problem
with 32bit quota tools working on 64bit architectures.
In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
However this isn't right. Look at if_dqblk structure:
struct if_dqblk {
__u64 dqb_bhardlimit;
__u64 dqb_bsoftlimit;
__u64 dqb_curspace;
__u64 dqb_ihardlimit;
__u64 dqb_isoftlimit;
__u64 dqb_curinodes;
__u64 dqb_btime;
__u64 dqb_itime;
__u32 dqb_valid;
};
For 32 bit quota tools sizeof(if_dqblk) == 0x44.
But for 64 bit kernel its size is 0x48, 'cause of alignment!
Thus we got a problem.
Also XFS quota structures fs_qfilestat and fs_quota_stat
have the same problem.
Attached patch reintroduce sys32_quotactl() function,
that handles the situation.
Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
---
In OpenVZ technology 32 bit Virtual Environments over
64 bit OS are common, hence we have customers, that complains
on this bad quota behaviour:
# /usr/bin/quota
quota: error while getting quota from /dev/sda1 for 0: Success
The reason is caused above.
--- linux-2.6.18/fs/quota.c.quota32 2006-09-20 07:42:06.000000000 +0400
+++ linux-2.6.18/fs/quota.c 2006-10-24 16:20:21.000000000 +0400
@@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <asm/current.h>
#include <asm/uaccess.h>
+#include <asm/compat.h>
#include <linux/kernel.h>
#include <linux/smp_lock.h>
#include <linux/security.h>
@@ -17,6 +18,7 @@
#include <linux/buffer_head.h>
#include <linux/capability.h>
#include <linux/quotaops.h>
+#include <linux/types.h>
/* Check validity of generic quotactl commands */
static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
@@ -376,3 +378,119 @@
return ret;
}
+
+#if defined(CONFIG_X86_64) || defined(CONFIG_IA64)
+/*
+ * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
+ * and is necessary due to alignment problems.
+ */
+struct compat_if_dqblk {
+ compat_uint_t dqb_bhardlimit[2];
+ compat_uint_t dqb_bsoftlimit[2];
+ compat_uint_t dqb_curspace[2];
+ compat_uint_t dqb_ihardlimit[2];
+ compat_uint_t dqb_isoftlimit[2];
+ compat_uint_t dqb_curinodes[2];
+ compat_uint_t dqb_btime[2];
+ compat_uint_t dqb_itime[2];
+ compat_uint_t dqb_valid;
+};
+
+/* XFS structures */
+struct compat_fs_qfilestat {
+ compat_uint_t dqb_bhardlimit[2];
+ compat_uint_t qfs_nblks[2];
+ compat_uint_t qfs_nextents;
+};
+
+struct compat_fs_quota_stat {
+ __s8 qs_version;
+ __u16 qs_flags;
+ __s8 qs_pad;
+ struct compat_fs_qfilestat qs_uquota;
+ struct compat_fs_qfilestat qs_gquota;
+ compat_uint_t qs_incoredqs;
+ compat_int_t qs_btimelimit;
+ compat_int_t qs_itimelimit;
+ compat_int_t qs_rtbtimelimit;
+ __u16 qs_bwarnlimit;
+ __u16 qs_iwarnlimit;
+};
+
+asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
+ qid_t id, void __user *addr)
+{
+ unsigned int cmds;
+ struct if_dqblk __user *dqblk;
+ struct compat_if_dqblk __user *compat_dqblk;
+ struct fs_quota_stat __user *fsqstat;
+ struct compat_fs_quota_stat __user *compat_fsqstat;
+ compat_uint_t data;
+ u16 xdata;
+ long ret;
+
+ cmds = cmd >> SUBCMDSHIFT;
+
+ switch (cmds) {
+ case Q_GETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ if (ret)
+ break;
+ if (copy_in_user(compat_dqblk, dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &dqblk->dqb_valid) ||
+ put_user(data, &compat_dqblk->dqb_valid))
+ ret = -EFAULT;
+ break;
+ case Q_SETQUOTA:
+ dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
+ compat_dqblk = addr;
+ ret = -EFAULT;
+ if (copy_in_user(dqblk, compat_dqblk, sizeof(*compat_dqblk)) ||
+ get_user(data, &compat_dqblk->dqb_valid) ||
+ put_user(data, &dqblk->dqb_valid))
+ break;
+ ret = sys_quotactl(cmd, special, id, dqblk);
+ break;
+ case Q_XGETQSTAT:
+ fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat));
+ compat_fsqstat = addr;
+ ret = sys_quotactl(cmd, special, id, fsqstat);
+ if (ret)
+ break;
+ ret = -EFAULT;
+ /* Copying qs_version, qs_flags, qs_pad */
+ if (copy_in_user(compat_fsqstat, fsqstat,
+ offsetof(struct compat_fs_quota_stat, qs_uquota)))
+ break;
+ /* Copying qs_uquota */
+ if (copy_in_user(&compat_fsqstat->qs_uquota,
+ &fsqstat->qs_uquota,
+ sizeof(compat_fsqstat->qs_uquota)) ||
+ get_user(data, &fsqstat->qs_uquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_uquota.qfs_nextents))
+ break;
+ /* Copying qs_gquota */
+ if (copy_in_user(&compat_fsqstat->qs_gquota,
+ &fsqstat->qs_gquota,
+ sizeof(compat_fsqstat->qs_gquota)) ||
+ get_user(data, &fsqstat->qs_gquota.qfs_nextents) ||
+ put_user(data, &compat_fsqstat->qs_gquota.qfs_nextents))
+ break;
+ /* Copying the rest */
+ if (copy_in_user(&compat_fsqstat->qs_incoredqs,
+ &fsqstat->qs_incoredqs,
+ sizeof(struct compat_fs_quota_stat) -
+ offsetof(struct compat_fs_quota_stat, qs_incoredqs)) ||
+ get_user(xdata, &fsqstat->qs_iwarnlimit) ||
+ put_user(xdata, &compat_fsqstat->qs_iwarnlimit))
+ break;
+ ret = 0;
+ break;
+ default:
+ ret = sys_quotactl(cmd, special, id, addr);
+ }
+ return ret;
+}
+#endif
--- linux-2.6.18/arch/ia64/ia32/ia32_entry.S.quota32 2006-09-20 07:42:06.000000000 +0400
+++ linux-2.6.18/arch/ia64/ia32/ia32_entry.S 2006-10-23 17:35:38.000000000 +0400
@@ -341,7 +341,7 @@
data8 sys_ni_syscall /* init_module */
data8 sys_ni_syscall /* delete_module */
data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */
- data8 sys_quotactl
+ data8 sys32_quotactl
data8 sys_getpgid
data8 sys_fchdir
data8 sys_ni_syscall /* sys_bdflush */
--- linux-2.6.18/arch/x86_64/ia32/ia32entry.S.quota32 2006-09-20 07:42:06.000000000 +0400
+++ linux-2.6.18/arch/x86_64/ia32/ia32entry.S 2006-10-23 17:35:38.000000000 +0400
@@ -526,7 +526,7 @@
.quad sys_init_module
.quad sys_delete_module
.quad quiet_ni_syscall /* 130 get_kernel_syms */
- .quad sys_quotactl
+ .quad sys32_quotactl
.quad sys_getpgid
.quad sys_fchdir
.quad quiet_ni_syscall /* bdflush */
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-21 16:28 ` Arnd Bergmann
2006-10-23 2:12 ` David Chinner
@ 2006-10-23 10:51 ` Vasily Tarasov
1 sibling, 0 replies; 31+ messages in thread
From: Vasily Tarasov @ 2006-10-23 10:51 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Christoph Hellwig, Linux Kernel Mailing List, Andrew Morton,
Jan Kara, Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List, David Chinner
Hello,
Arnd Bergmann wrote:
<snip>
> On a related topic, I just noticed
>
> typedef struct fs_qfilestat {
> __u64 qfs_ino; /* inode number */
> __u64 qfs_nblks; /* number of BBs 512-byte-blks */
> __u32 qfs_nextents; /* number of extents */
> } fs_qfilestat_t;
>
> typedef struct fs_quota_stat {
> __s8 qs_version; /* version number for future changes */
> __u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
> __s8 qs_pad; /* unused */
> fs_qfilestat_t qs_uquota; /* user quota storage information */
> fs_qfilestat_t qs_gquota; /* group quota storage information */
> __u32 qs_incoredqs; /* number of dquots incore */
> __s32 qs_btimelimit; /* limit for blks timer */
> __s32 qs_itimelimit; /* limit for inodes timer */
> __s32 qs_rtbtimelimit;/* limit for rt blks timer */
> __u16 qs_bwarnlimit; /* limit for num warnings */
> __u16 qs_iwarnlimit; /* limit for num warnings */
> } fs_quota_stat_t;
>
> This one seems to have a more severe problem in x86_64 compat
> mode. I haven't tried it, but isn't everything down from
> gs_gquota aligned differently on i386?
<snip>
The problem indeed exists:
ia32:
sizeof(fs_qfilestat) = 0x14
sizeof(fs_quota_stat) = 0x44
x86_64:
sizeof(fs_qfilestat) = 0x18
sizeof(fs_quota_stat) = 0x50
Note, that the difference between sizes of fs_qfilestat on ia32 and
on x86_64 doesn't equal 8 bytes, as was expected (by me :)), but equals 12 bytes:
'cause of padding at the end of fs_quota_stat structure on x86_64.
I will add support of 32-bit XFS quotactl over 64bit OS in next patch.
Thank you!
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-21 16:28 ` Arnd Bergmann
@ 2006-10-23 2:12 ` David Chinner
2006-10-23 10:51 ` Vasily Tarasov
1 sibling, 0 replies; 31+ messages in thread
From: David Chinner @ 2006-10-23 2:12 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Vasily Tarasov, Christoph Hellwig, Linux Kernel Mailing List,
Andrew Morton, Jan Kara, Dmitry Mishin, Vasily Averin,
Kirill Korotaev, OpenVZ Developers List, xfs
On Sat, Oct 21, 2006 at 06:28:32PM +0200, Arnd Bergmann wrote:
> On a related topic, I just noticed
>
> typedef struct fs_qfilestat {
> __u64 qfs_ino; /* inode number */
> __u64 qfs_nblks; /* number of BBs 512-byte-blks */
> __u32 qfs_nextents; /* number of extents */
> } fs_qfilestat_t;
>
> typedef struct fs_quota_stat {
> __s8 qs_version; /* version number for future changes */
> __u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
> __s8 qs_pad; /* unused */
> fs_qfilestat_t qs_uquota; /* user quota storage information */
> fs_qfilestat_t qs_gquota; /* group quota storage information */
> __u32 qs_incoredqs; /* number of dquots incore */
> __s32 qs_btimelimit; /* limit for blks timer */
> __s32 qs_itimelimit; /* limit for inodes timer */
> __s32 qs_rtbtimelimit;/* limit for rt blks timer */
> __u16 qs_bwarnlimit; /* limit for num warnings */
> __u16 qs_iwarnlimit; /* limit for num warnings */
> } fs_quota_stat_t;
Ah, the XFS quota structures.....
> This one seems to have a more severe problem in x86_64 compat
> mode. I haven't tried it, but isn't everything down from
> gs_gquota aligned differently on i386?
Yes - this is just one of several interfaces into XFS that need compat
handling that don't have them right now.
Cheers,
Dave.
--
Dave Chinner
Principal Engineer
SGI Australian Software Group
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-20 6:10 ` Vasily Tarasov
@ 2006-10-21 16:28 ` Arnd Bergmann
2006-10-23 2:12 ` David Chinner
2006-10-23 10:51 ` Vasily Tarasov
0 siblings, 2 replies; 31+ messages in thread
From: Arnd Bergmann @ 2006-10-21 16:28 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Christoph Hellwig, Linux Kernel Mailing List, Andrew Morton,
Jan Kara, Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
On Friday 20 October 2006 08:10, Vasily Tarasov wrote:
> Christoph Hellwig wrote:
>
> <snip>
>
> > Please allocate the structure using compat_alloc_userspace and copy
> > with copy_in_user instead of the set_fs trick.
>
> <snip>
>
> Good idea, thank you for your tip, I'll do it.
I think it would be even better to integrate this into fs/quota.c
and get rid of the extra copy entirely. The only thing you need
to do differently in case of 32 bit Q_GETQUOTA is the size
of the copy_{from,to}_user.
On a related topic, I just noticed
typedef struct fs_qfilestat {
__u64 qfs_ino; /* inode number */
__u64 qfs_nblks; /* number of BBs 512-byte-blks */
__u32 qfs_nextents; /* number of extents */
} fs_qfilestat_t;
typedef struct fs_quota_stat {
__s8 qs_version; /* version number for future changes */
__u16 qs_flags; /* XFS_QUOTA_{U,P,G}DQ_{ACCT,ENFD} */
__s8 qs_pad; /* unused */
fs_qfilestat_t qs_uquota; /* user quota storage information */
fs_qfilestat_t qs_gquota; /* group quota storage information */
__u32 qs_incoredqs; /* number of dquots incore */
__s32 qs_btimelimit; /* limit for blks timer */
__s32 qs_itimelimit; /* limit for inodes timer */
__s32 qs_rtbtimelimit;/* limit for rt blks timer */
__u16 qs_bwarnlimit; /* limit for num warnings */
__u16 qs_iwarnlimit; /* limit for num warnings */
} fs_quota_stat_t;
This one seems to have a more severe problem in x86_64 compat
mode. I haven't tried it, but isn't everything down from
gs_gquota aligned differently on i386?
Arnd <><
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-20 6:30 ` Vasily Tarasov
2006-10-20 7:12 ` Christoph Hellwig
@ 2006-10-20 12:21 ` Andi Kleen
1 sibling, 0 replies; 31+ messages in thread
From: Andi Kleen @ 2006-10-20 12:21 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara,
Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
On Friday 20 October 2006 08:30, Vasily Tarasov wrote:
> Andi Kleen wrote:
>
> <snip>
> > Thanks. But the code should be probably common somewhere in fs/*, not
> > duplicated.
> <snip>
>
> Thank you for the comment!
> I'm not sure we should do it. If we move the code in fs/quota.c for example,
> than this code will be compiled for _all_ arhitectures, not only for x86_64 and ia64.
> Of course, we can surround this code by #ifdefs <ARCH>, but I thought this is
> a bad style... Moreover looking through current kernel code, I found out that
> usually code is duplicated in such cases.
Well it doesn't hurt them even if not strictly needed and it's better to have common code for
this. BTW you have to convert over to compat_alloc_* for this as Christoph stated
because set_fs doesn't work on all architectures. Best you use the compat_* types too.
-Andi
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-20 6:30 ` Vasily Tarasov
@ 2006-10-20 7:12 ` Christoph Hellwig
2006-10-20 12:21 ` Andi Kleen
1 sibling, 0 replies; 31+ messages in thread
From: Christoph Hellwig @ 2006-10-20 7:12 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Andi Kleen, Linux Kernel Mailing List, Andrew Morton, Jan Kara,
Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
On Fri, Oct 20, 2006 at 10:30:04AM +0400, Vasily Tarasov wrote:
> Andi Kleen wrote:
>
> <snip>
> > Thanks. But the code should be probably common somewhere in fs/*, not
> > duplicated.
> <snip>
>
> Thank you for the comment!
> I'm not sure we should do it. If we move the code in fs/quota.c for example,
> than this code will be compiled for _all_ arhitectures, not only for x86_64 and ia64.
> Of course, we can surround this code by #ifdefs <ARCH>, but I thought this is
> a bad style... Moreover looking through current kernel code, I found out that
> usually code is duplicated in such cases.
>
> However, if you insist I'll modify the code! :)
I suspect a compat_x86.c file somehwere might make sense, as only x86 has
the wierd alignment rules, but we have two architectures that allow to run
x86 binaries with the compat subszstem. Now the big question: where should
we put this file?
>
> Thank you.
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
---end quoted text---
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-19 16:09 ` Andi Kleen
@ 2006-10-20 6:30 ` Vasily Tarasov
2006-10-20 7:12 ` Christoph Hellwig
2006-10-20 12:21 ` Andi Kleen
0 siblings, 2 replies; 31+ messages in thread
From: Vasily Tarasov @ 2006-10-20 6:30 UTC (permalink / raw)
To: Andi Kleen
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara,
Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
Andi Kleen wrote:
<snip>
> Thanks. But the code should be probably common somewhere in fs/*, not
> duplicated.
<snip>
Thank you for the comment!
I'm not sure we should do it. If we move the code in fs/quota.c for example,
than this code will be compiled for _all_ arhitectures, not only for x86_64 and ia64.
Of course, we can surround this code by #ifdefs <ARCH>, but I thought this is
a bad style... Moreover looking through current kernel code, I found out that
usually code is duplicated in such cases.
However, if you insist I'll modify the code! :)
Thank you.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-19 17:29 ` Christoph Hellwig
@ 2006-10-20 6:10 ` Vasily Tarasov
2006-10-21 16:28 ` Arnd Bergmann
0 siblings, 1 reply; 31+ messages in thread
From: Vasily Tarasov @ 2006-10-20 6:10 UTC (permalink / raw)
To: Christoph Hellwig
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara,
Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
Christoph Hellwig wrote:
<snip>
> Please allocate the structure using compat_alloc_userspace and copy
> with copy_in_user instead of the set_fs trick.
<snip>
Good idea, thank you for your tip, I'll do it.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
@ 2006-10-20 5:59 Vasily Tarasov
0 siblings, 0 replies; 31+ messages in thread
From: Vasily Tarasov @ 2006-10-20 5:59 UTC (permalink / raw)
To: Randy Dunlap
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara,
Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
Randy Dunlap wrote:
<snip>
> Please align the switch and case/default source lines.
> We prefer not to "double-indent" each case block inside a switch.
>
> I suppose I should try to add this to CodingStyle since it's
> not there.
>
> ---
> ~Randy
<snip>
Thank you, I'll do it!
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-19 12:32 Vasily Tarasov
` (2 preceding siblings ...)
2006-10-19 16:09 ` Andi Kleen
@ 2006-10-19 17:29 ` Christoph Hellwig
2006-10-20 6:10 ` Vasily Tarasov
3 siblings, 1 reply; 31+ messages in thread
From: Christoph Hellwig @ 2006-10-19 17:29 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara,
Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
On Thu, Oct 19, 2006 at 04:32:07PM +0400, Vasily Tarasov wrote:
> +asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
> + qid_t id, void __user *addr)
> +{
> + long ret;
> + unsigned int cmds;
> + mm_segment_t old_fs;
> + struct if_dqblk dqblk;
> + struct if32_dqblk {
> + __u32 dqb_bhardlimit[2];
> + __u32 dqb_bsoftlimit[2];
> + __u32 dqb_curspace[2];
> + __u32 dqb_ihardlimit[2];
> + __u32 dqb_isoftlimit[2];
> + __u32 dqb_curinodes[2];
> + __u32 dqb_btime[2];
> + __u32 dqb_itime[2];
> + __u32 dqb_valid;
> + } dqblk32;
> +
> + cmds = cmd >> SUBCMDSHIFT;
> +
> + switch (cmds) {
> + case Q_GETQUOTA:
> + old_fs = get_fs();
> + set_fs(KERNEL_DS);
> + ret = sys_quotactl(cmd, special, id, &dqblk);
> + set_fs(old_fs);
Please allocate the structure using compat_alloc_userspace and copy
with copy_in_user instead of the set_fs trick.
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-19 12:32 Vasily Tarasov
2006-10-19 13:06 ` Alan Cox
2006-10-19 15:22 ` Randy Dunlap
@ 2006-10-19 16:09 ` Andi Kleen
2006-10-20 6:30 ` Vasily Tarasov
2006-10-19 17:29 ` Christoph Hellwig
3 siblings, 1 reply; 31+ messages in thread
From: Andi Kleen @ 2006-10-19 16:09 UTC (permalink / raw)
To: Vasily Tarasov; +Cc: Andrew Morton, linux-kernel
Vasily Tarasov <vtaras@openvz.org> writes:
> OpenVZ Linux kernel team has discovered the problem
> with 32bit quota tools working on 64bit architectures.
> In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
> the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
> However this isn't right. Look at if_dqblk structure:
>
> struct if_dqblk {
> __u64 dqb_bhardlimit;
> __u64 dqb_bsoftlimit;
> __u64 dqb_curspace;
> __u64 dqb_ihardlimit;
> __u64 dqb_isoftlimit;
> __u64 dqb_curinodes;
> __u64 dqb_btime;
> __u64 dqb_itime;
> __u32 dqb_valid;
> };
>
> For 32 bit quota tools sizeof(if_dqblk) == 0x44.
> But for 64 bit kernel its size is 0x48, 'cause of alignment!
> Thus we got a problem.
> Attached patch reintroduce sys32_quotactl() function,
> that handles the situation.
Thanks. But the code should be probably common somewhere in fs/*, not
duplicated.
-Andi
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-19 12:32 Vasily Tarasov
2006-10-19 13:06 ` Alan Cox
@ 2006-10-19 15:22 ` Randy Dunlap
2006-10-19 16:09 ` Andi Kleen
2006-10-19 17:29 ` Christoph Hellwig
3 siblings, 0 replies; 31+ messages in thread
From: Randy Dunlap @ 2006-10-19 15:22 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara,
Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
On Thu, 19 Oct 2006 16:32:07 +0400 Vasily Tarasov wrote:
> --- linux-2.6.18/arch/ia64/ia32/sys_ia32.c.quot32 2006-09-20 07:42:06.000000000 +0400
> +++ linux-2.6.18/arch/ia64/ia32/sys_ia32.c 2006-10-19 11:17:50.000000000 +0400
> @@ -2545,6 +2545,54 @@ long sys32_fadvise64_64(int fd, __u32 of
> advice);
> }
>
> +asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
> + qid_t id, void __user *addr)
> +{
> +
> + switch (cmds) {
> + case Q_GETQUOTA:
> + old_fs = get_fs();
> + set_fs(KERNEL_DS);
> + ret = sys_quotactl(cmd, special, id, &dqblk);
> + set_fs(old_fs);
> + memcpy(&dqblk32, &dqblk, sizeof(dqblk32));
> + dqblk32.dqb_valid = dqblk.dqb_valid;
> + if (copy_to_user(addr, &dqblk32, sizeof(dqblk32)))
> + return -EFAULT;
> + break;
> + case Q_SETQUOTA:
> + if (copy_from_user(&dqblk32, addr, sizeof(dqblk32)))
> + return -EFAULT;
> + memcpy(&dqblk, &dqblk32, sizeof(dqblk32));
> + dqblk.dqb_valid = dqblk32.dqb_valid;
> + old_fs = get_fs();
> + set_fs(KERNEL_DS);
> + ret = sys_quotactl(cmd, special, id, &dqblk);
> + set_fs(old_fs);
> + break;
> + default:
> + return sys_quotactl(cmd, special, id, addr);
> + }
> + return ret;
> +}
Please align the switch and case/default source lines.
We prefer not to "double-indent" each case block inside a switch.
I suppose I should try to add this to CodingStyle since it's
not there.
> --- linux-2.6.18/arch/x86_64/ia32/sys_ia32.c.quot32 2006-09-20 07:42:06.000000000 +0400
> +++ linux-2.6.18/arch/x86_64/ia32/sys_ia32.c 2006-10-19 11:00:18.000000000 +0400
> @@ -915,3 +915,50 @@ long sys32_lookup_dcookie(u32 addr_low,
> return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len);
> }
>
> +asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
> + qid_t id, void __user *addr)
> +{
> +
> + switch (cmds) {
> + case Q_GETQUOTA:
> + old_fs = get_fs();
> + set_fs(KERNEL_DS);
> + ret = sys_quotactl(cmd, special, id, &dqblk);
> + set_fs(old_fs);
> + memcpy(&dqblk32, &dqblk, sizeof(dqblk32));
> + dqblk32.dqb_valid = dqblk.dqb_valid;
> + if (copy_to_user(addr, &dqblk32, sizeof(dqblk32)))
> + return -EFAULT;
> + break;
> + case Q_SETQUOTA:
> + if (copy_from_user(&dqblk32, addr, sizeof(dqblk32)))
> + return -EFAULT;
> + memcpy(&dqblk, &dqblk32, sizeof(dqblk32));
> + dqblk.dqb_valid = dqblk32.dqb_valid;
> + old_fs = get_fs();
> + set_fs(KERNEL_DS);
> + ret = sys_quotactl(cmd, special, id, &dqblk);
> + set_fs(old_fs);
> + break;
> + default:
> + return sys_quotactl(cmd, special, id, addr);
> + }
---
~Randy
^ permalink raw reply [flat|nested] 31+ messages in thread
* Re: [PATCH] diskquota: 32bit quota tools on 64bit architectures
2006-10-19 12:32 Vasily Tarasov
@ 2006-10-19 13:06 ` Alan Cox
2006-10-19 15:22 ` Randy Dunlap
` (2 subsequent siblings)
3 siblings, 0 replies; 31+ messages in thread
From: Alan Cox @ 2006-10-19 13:06 UTC (permalink / raw)
To: Vasily Tarasov
Cc: Linux Kernel Mailing List, Andrew Morton, Jan Kara,
Dmitry Mishin, Vasily Averin, Kirill Korotaev,
OpenVZ Developers List
Ar Iau, 2006-10-19 am 16:32 +0400, ysgrifennodd Vasily Tarasov:
> OpenVZ Linux kernel team has discovered the problem
> Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
> Acked-by: Dmitry Mishin <dim@openvz.org>
Acked-by: Alan Cox <alan@redhat.com>
^ permalink raw reply [flat|nested] 31+ messages in thread
* [PATCH] diskquota: 32bit quota tools on 64bit architectures
@ 2006-10-19 12:32 Vasily Tarasov
2006-10-19 13:06 ` Alan Cox
` (3 more replies)
0 siblings, 4 replies; 31+ messages in thread
From: Vasily Tarasov @ 2006-10-19 12:32 UTC (permalink / raw)
To: Linux Kernel Mailing List
Cc: Andrew Morton, Jan Kara, Dmitry Mishin, Vasily Averin,
Kirill Korotaev, OpenVZ Developers List
OpenVZ Linux kernel team has discovered the problem
with 32bit quota tools working on 64bit architectures.
In 2.6.10 kernel sys32_quotactl() function was replaced by sys_quotactl() with
the comment "sys_quotactl seems to be 32/64bit clean, enable it for 32bit"
However this isn't right. Look at if_dqblk structure:
struct if_dqblk {
__u64 dqb_bhardlimit;
__u64 dqb_bsoftlimit;
__u64 dqb_curspace;
__u64 dqb_ihardlimit;
__u64 dqb_isoftlimit;
__u64 dqb_curinodes;
__u64 dqb_btime;
__u64 dqb_itime;
__u32 dqb_valid;
};
For 32 bit quota tools sizeof(if_dqblk) == 0x44.
But for 64 bit kernel its size is 0x48, 'cause of alignment!
Thus we got a problem.
Attached patch reintroduce sys32_quotactl() function,
that handles the situation.
Signed-off-by: Vasily Tarasov <vtaras@openvz.org>
Acked-by: Dmitry Mishin <dim@openvz.org>
---
In OpenVZ technology 32 bit Virtual Environments over
64 bit OS are common, hence we have customers, that complains on this bad quota
behaviour:
# /usr/bin/quota
quota: error while getting quota from /dev/sda1 for 0: Success
The reason is caused above.
--- linux-2.6.18/arch/ia64/ia32/sys_ia32.c.quot32 2006-09-20 07:42:06.000000000 +0400
+++ linux-2.6.18/arch/ia64/ia32/sys_ia32.c 2006-10-19 11:17:50.000000000 +0400
@@ -2545,6 +2545,54 @@ long sys32_fadvise64_64(int fd, __u32 of
advice);
}
+asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
+ qid_t id, void __user *addr)
+{
+ long ret;
+ unsigned int cmds;
+ mm_segment_t old_fs;
+ struct if_dqblk dqblk;
+ struct if32_dqblk {
+ __u32 dqb_bhardlimit[2];
+ __u32 dqb_bsoftlimit[2];
+ __u32 dqb_curspace[2];
+ __u32 dqb_ihardlimit[2];
+ __u32 dqb_isoftlimit[2];
+ __u32 dqb_curinodes[2];
+ __u32 dqb_btime[2];
+ __u32 dqb_itime[2];
+ __u32 dqb_valid;
+ } dqblk32;
+
+ cmds = cmd >> SUBCMDSHIFT;
+
+ switch (cmds) {
+ case Q_GETQUOTA:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_quotactl(cmd, special, id, &dqblk);
+ set_fs(old_fs);
+ memcpy(&dqblk32, &dqblk, sizeof(dqblk32));
+ dqblk32.dqb_valid = dqblk.dqb_valid;
+ if (copy_to_user(addr, &dqblk32, sizeof(dqblk32)))
+ return -EFAULT;
+ break;
+ case Q_SETQUOTA:
+ if (copy_from_user(&dqblk32, addr, sizeof(dqblk32)))
+ return -EFAULT;
+ memcpy(&dqblk, &dqblk32, sizeof(dqblk32));
+ dqblk.dqb_valid = dqblk32.dqb_valid;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_quotactl(cmd, special, id, &dqblk);
+ set_fs(old_fs);
+ break;
+ default:
+ return sys_quotactl(cmd, special, id, addr);
+ }
+ return ret;
+}
+
#ifdef NOTYET /* UNTESTED FOR IA64 FROM HERE DOWN */
asmlinkage long sys32_setreuid(compat_uid_t ruid, compat_uid_t euid)
--- linux-2.6.18/arch/ia64/ia32/ia32_entry.S.quot32 2006-09-20 07:42:06.000000000 +0400
+++ linux-2.6.18/arch/ia64/ia32/ia32_entry.S 2006-10-19 11:15:52.000000000 +0400
@@ -341,7 +341,7 @@ ia32_syscall_table:
data8 sys_ni_syscall /* init_module */
data8 sys_ni_syscall /* delete_module */
data8 sys_ni_syscall /* get_kernel_syms */ /* 130 */
- data8 sys_quotactl
+ data8 sys32_quotactl
data8 sys_getpgid
data8 sys_fchdir
data8 sys_ni_syscall /* sys_bdflush */
--- linux-2.6.18/arch/x86_64/ia32/ia32entry.S.quot32 2006-09-20 07:42:06.000000000 +0400
+++ linux-2.6.18/arch/x86_64/ia32/ia32entry.S 2006-10-18 10:05:53.000000000 +0400
@@ -526,7 +526,7 @@ ia32_sys_call_table:
.quad sys_init_module
.quad sys_delete_module
.quad quiet_ni_syscall /* 130 get_kernel_syms */
- .quad sys_quotactl
+ .quad sys32_quotactl
.quad sys_getpgid
.quad sys_fchdir
.quad quiet_ni_syscall /* bdflush */
--- linux-2.6.18/arch/x86_64/ia32/sys_ia32.c.quot32 2006-09-20 07:42:06.000000000 +0400
+++ linux-2.6.18/arch/x86_64/ia32/sys_ia32.c 2006-10-19 11:00:18.000000000 +0400
@@ -915,3 +915,50 @@ long sys32_lookup_dcookie(u32 addr_low,
return sys_lookup_dcookie(((u64)addr_high << 32) | addr_low, buf, len);
}
+asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
+ qid_t id, void __user *addr)
+{
+ long ret;
+ unsigned int cmds;
+ mm_segment_t old_fs;
+ struct if_dqblk dqblk;
+ struct if32_dqblk {
+ __u32 dqb_bhardlimit[2];
+ __u32 dqb_bsoftlimit[2];
+ __u32 dqb_curspace[2];
+ __u32 dqb_ihardlimit[2];
+ __u32 dqb_isoftlimit[2];
+ __u32 dqb_curinodes[2];
+ __u32 dqb_btime[2];
+ __u32 dqb_itime[2];
+ __u32 dqb_valid;
+ } dqblk32;
+
+ cmds = cmd >> SUBCMDSHIFT;
+
+ switch (cmds) {
+ case Q_GETQUOTA:
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_quotactl(cmd, special, id, &dqblk);
+ set_fs(old_fs);
+ memcpy(&dqblk32, &dqblk, sizeof(dqblk32));
+ dqblk32.dqb_valid = dqblk.dqb_valid;
+ if (copy_to_user(addr, &dqblk32, sizeof(dqblk32)))
+ return -EFAULT;
+ break;
+ case Q_SETQUOTA:
+ if (copy_from_user(&dqblk32, addr, sizeof(dqblk32)))
+ return -EFAULT;
+ memcpy(&dqblk, &dqblk32, sizeof(dqblk32));
+ dqblk.dqb_valid = dqblk32.dqb_valid;
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+ ret = sys_quotactl(cmd, special, id, &dqblk);
+ set_fs(old_fs);
+ break;
+ default:
+ return sys_quotactl(cmd, special, id, addr);
+ }
+ return ret;
+}
^ permalink raw reply [flat|nested] 31+ messages in thread
end of thread, other threads:[~2007-06-19 22:34 UTC | newest]
Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-06-15 10:03 [PATCH] diskquota: 32bit quota tools on 64bit architectures Mikael Pettersson
2007-06-15 10:41 ` Vasily Tarasov
2007-06-15 10:43 ` Arnd Bergmann
2007-06-15 11:00 ` Vasily Tarasov
2007-06-15 14:48 ` Vasily Tarasov
2007-06-15 15:24 ` Arnd Bergmann
2007-06-18 7:41 ` Vasily Tarasov
-- strict thread matches above, loose matches on Subject: below --
2007-06-18 8:21 Vasily Tarasov
2007-06-19 19:33 ` Andrew Morton
2007-06-19 20:09 ` Mikael Pettersson
2007-06-19 22:34 ` David Miller
2007-06-15 11:08 Mikael Pettersson
2007-06-15 9:01 Vasily Tarasov
2007-06-15 8:59 Vasily Tarasov
2006-10-25 10:03 Vasily Tarasov
2006-10-25 11:03 ` Arnd Bergmann
2006-10-25 11:25 ` Vasily Tarasov
2006-10-25 11:50 ` Arnd Bergmann
2006-10-20 5:59 Vasily Tarasov
2006-10-19 12:32 Vasily Tarasov
2006-10-19 13:06 ` Alan Cox
2006-10-19 15:22 ` Randy Dunlap
2006-10-19 16:09 ` Andi Kleen
2006-10-20 6:30 ` Vasily Tarasov
2006-10-20 7:12 ` Christoph Hellwig
2006-10-20 12:21 ` Andi Kleen
2006-10-19 17:29 ` Christoph Hellwig
2006-10-20 6:10 ` Vasily Tarasov
2006-10-21 16:28 ` Arnd Bergmann
2006-10-23 2:12 ` David Chinner
2006-10-23 10:51 ` Vasily Tarasov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).