2 #include <linux/syscalls.h>
3 #include <linux/compat.h>
4 #include <linux/quotaops.h>
7 * This code works only for 32 bit quota tools over 64 bit OS (x86_64, ia64)
8 * and is necessary due to alignment problems.
10 struct compat_if_dqblk
{
11 compat_u64 dqb_bhardlimit
;
12 compat_u64 dqb_bsoftlimit
;
13 compat_u64 dqb_curspace
;
14 compat_u64 dqb_ihardlimit
;
15 compat_u64 dqb_isoftlimit
;
16 compat_u64 dqb_curinodes
;
19 compat_uint_t dqb_valid
;
23 struct compat_fs_qfilestat
{
24 compat_u64 dqb_bhardlimit
;
26 compat_uint_t qfs_nextents
;
29 struct compat_fs_quota_stat
{
33 struct compat_fs_qfilestat qs_uquota
;
34 struct compat_fs_qfilestat qs_gquota
;
35 compat_uint_t qs_incoredqs
;
36 compat_int_t qs_btimelimit
;
37 compat_int_t qs_itimelimit
;
38 compat_int_t qs_rtbtimelimit
;
43 asmlinkage
long sys32_quotactl(unsigned int cmd
, const char __user
*special
,
44 qid_t id
, void __user
*addr
)
47 struct if_dqblk __user
*dqblk
;
48 struct compat_if_dqblk __user
*compat_dqblk
;
49 struct fs_quota_stat __user
*fsqstat
;
50 struct compat_fs_quota_stat __user
*compat_fsqstat
;
55 cmds
= cmd
>> SUBCMDSHIFT
;
59 dqblk
= compat_alloc_user_space(sizeof(struct if_dqblk
));
61 ret
= sys_quotactl(cmd
, special
, id
, dqblk
);
64 if (copy_in_user(compat_dqblk
, dqblk
, sizeof(*compat_dqblk
)) ||
65 get_user(data
, &dqblk
->dqb_valid
) ||
66 put_user(data
, &compat_dqblk
->dqb_valid
))
70 dqblk
= compat_alloc_user_space(sizeof(struct if_dqblk
));
73 if (copy_in_user(dqblk
, compat_dqblk
, sizeof(*compat_dqblk
)) ||
74 get_user(data
, &compat_dqblk
->dqb_valid
) ||
75 put_user(data
, &dqblk
->dqb_valid
))
77 ret
= sys_quotactl(cmd
, special
, id
, dqblk
);
80 fsqstat
= compat_alloc_user_space(sizeof(struct fs_quota_stat
));
81 compat_fsqstat
= addr
;
82 ret
= sys_quotactl(cmd
, special
, id
, fsqstat
);
86 /* Copying qs_version, qs_flags, qs_pad */
87 if (copy_in_user(compat_fsqstat
, fsqstat
,
88 offsetof(struct compat_fs_quota_stat
, qs_uquota
)))
90 /* Copying qs_uquota */
91 if (copy_in_user(&compat_fsqstat
->qs_uquota
,
93 sizeof(compat_fsqstat
->qs_uquota
)) ||
94 get_user(data
, &fsqstat
->qs_uquota
.qfs_nextents
) ||
95 put_user(data
, &compat_fsqstat
->qs_uquota
.qfs_nextents
))
97 /* Copying qs_gquota */
98 if (copy_in_user(&compat_fsqstat
->qs_gquota
,
100 sizeof(compat_fsqstat
->qs_gquota
)) ||
101 get_user(data
, &fsqstat
->qs_gquota
.qfs_nextents
) ||
102 put_user(data
, &compat_fsqstat
->qs_gquota
.qfs_nextents
))
104 /* Copying the rest */
105 if (copy_in_user(&compat_fsqstat
->qs_incoredqs
,
106 &fsqstat
->qs_incoredqs
,
107 sizeof(struct compat_fs_quota_stat
) -
108 offsetof(struct compat_fs_quota_stat
, qs_incoredqs
)) ||
109 get_user(xdata
, &fsqstat
->qs_iwarnlimit
) ||
110 put_user(xdata
, &compat_fsqstat
->qs_iwarnlimit
))
115 ret
= sys_quotactl(cmd
, special
, id
, addr
);