Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
compat.c
Go to the documentation of this file.
1 
2 #include <linux/syscalls.h>
3 #include <linux/compat.h>
4 #include <linux/quotaops.h>
5 
6 /*
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.
9  */
20 };
21 
22 /* XFS structures */
27 };
28 
41 };
42 
43 asmlinkage long sys32_quotactl(unsigned int cmd, const char __user *special,
44  qid_t id, void __user *addr)
45 {
46  unsigned int cmds;
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;
52  u16 xdata;
53  long ret;
54 
55  cmds = cmd >> SUBCMDSHIFT;
56 
57  switch (cmds) {
58  case Q_GETQUOTA:
59  dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
60  compat_dqblk = addr;
61  ret = sys_quotactl(cmd, special, id, dqblk);
62  if (ret)
63  break;
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))
67  ret = -EFAULT;
68  break;
69  case Q_SETQUOTA:
70  dqblk = compat_alloc_user_space(sizeof(struct if_dqblk));
71  compat_dqblk = addr;
72  ret = -EFAULT;
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))
76  break;
77  ret = sys_quotactl(cmd, special, id, dqblk);
78  break;
79  case Q_XGETQSTAT:
80  fsqstat = compat_alloc_user_space(sizeof(struct fs_quota_stat));
81  compat_fsqstat = addr;
82  ret = sys_quotactl(cmd, special, id, fsqstat);
83  if (ret)
84  break;
85  ret = -EFAULT;
86  /* Copying qs_version, qs_flags, qs_pad */
87  if (copy_in_user(compat_fsqstat, fsqstat,
89  break;
90  /* Copying qs_uquota */
91  if (copy_in_user(&compat_fsqstat->qs_uquota,
92  &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))
96  break;
97  /* Copying qs_gquota */
98  if (copy_in_user(&compat_fsqstat->qs_gquota,
99  &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))
103  break;
104  /* Copying the rest */
105  if (copy_in_user(&compat_fsqstat->qs_incoredqs,
106  &fsqstat->qs_incoredqs,
107  sizeof(struct compat_fs_quota_stat) -
109  get_user(xdata, &fsqstat->qs_iwarnlimit) ||
110  put_user(xdata, &compat_fsqstat->qs_iwarnlimit))
111  break;
112  ret = 0;
113  break;
114  default:
115  ret = sys_quotactl(cmd, special, id, addr);
116  }
117  return ret;
118 }