2 * Quota code necessary even when VFS quota support is not compiled
3 * into the kernel. The interesting stuff is over in dquot.c, here
4 * we have symbols for initial quotactl(2) handling, the sysctl(2)
5 * variables, etc - things needed even when quota support disabled.
9 #include <linux/namei.h>
10 #include <linux/slab.h>
11 #include <asm/current.h>
12 #include <asm/uaccess.h>
13 #include <linux/kernel.h>
14 #include <linux/smp_lock.h>
15 #include <linux/security.h>
17 /* Check validity of quotactl */
18 static int check_quotactl_valid(struct super_block
*sb
, int type
, int cmd
, qid_t id
)
20 if (type
>= MAXQUOTAS
)
22 /* Is operation supported? */
30 if (!sb
->s_qcop
->quota_on
)
34 if (!sb
->s_qcop
->quota_off
)
38 if (!sb
->s_qcop
->set_info
)
42 if (!sb
->s_qcop
->get_info
)
46 if (!sb
->s_qcop
->set_dqblk
)
50 if (!sb
->s_qcop
->get_dqblk
)
54 if (!sb
->s_qcop
->quota_sync
)
60 if (!sb
->s_qcop
->set_xstate
)
64 if (!sb
->s_qcop
->get_xstate
)
68 if (!sb
->s_qcop
->set_xquota
)
72 if (!sb
->s_qcop
->get_xquota
)
79 /* Is quota turned on for commands which need it? */
87 if (!sb_has_quota_enabled(sb
, type
))
90 /* Check privileges */
91 if (cmd
== Q_GETQUOTA
|| cmd
== Q_XGETQUOTA
) {
92 if (((type
== USRQUOTA
&& current
->euid
!= id
) ||
93 (type
== GRPQUOTA
&& !in_egroup_p(id
))) &&
94 !capable(CAP_SYS_ADMIN
))
97 else if (cmd
!= Q_GETFMT
&& cmd
!= Q_SYNC
&& cmd
!= Q_GETINFO
&& cmd
!= Q_XGETQSTAT
)
98 if (!capable(CAP_SYS_ADMIN
))
101 return security_ops
->quotactl (cmd
, type
, id
, sb
);
104 /* Resolve device pathname to superblock */
105 static struct super_block
*resolve_dev(const char *path
)
110 struct block_device
*bdev
;
111 struct super_block
*sb
;
113 ret
= user_path_walk(path
, &nd
);
117 bdev
= nd
.dentry
->d_inode
->i_bdev
;
118 mode
= nd
.dentry
->d_inode
->i_mode
;
125 sb
= get_super(bdev
);
133 /* Copy parameters and call proper function */
134 static int do_quotactl(struct super_block
*sb
, int type
, int cmd
, qid_t id
, caddr_t addr
)
142 if (IS_ERR(pathname
= getname(addr
)))
143 return PTR_ERR(pathname
);
144 ret
= sb
->s_qcop
->quota_on(sb
, type
, id
, pathname
);
149 return sb
->s_qcop
->quota_off(sb
, type
);
154 fmt
= sb_dqopt(sb
)->info
[type
].dqi_format
->qf_fmt_id
;
155 if (copy_to_user(addr
, &fmt
, sizeof(fmt
)))
160 struct if_dqinfo info
;
162 if ((ret
= sb
->s_qcop
->get_info(sb
, type
, &info
)))
164 if (copy_to_user(addr
, &info
, sizeof(info
)))
169 struct if_dqinfo info
;
171 if (copy_from_user(&info
, addr
, sizeof(info
)))
173 return sb
->s_qcop
->set_info(sb
, type
, &info
);
178 if ((ret
= sb
->s_qcop
->get_dqblk(sb
, type
, id
, &idq
)))
180 if (copy_to_user(addr
, &idq
, sizeof(idq
)))
187 if (copy_from_user(&idq
, addr
, sizeof(idq
)))
189 return sb
->s_qcop
->set_dqblk(sb
, type
, id
, &idq
);
192 return sb
->s_qcop
->quota_sync(sb
, type
);
199 if (copy_from_user(&flags
, addr
, sizeof(flags
)))
201 return sb
->s_qcop
->set_xstate(sb
, flags
, cmd
);
204 struct fs_quota_stat fqs
;
206 if ((ret
= sb
->s_qcop
->get_xstate(sb
, &fqs
)))
208 if (copy_to_user(addr
, &fqs
, sizeof(fqs
)))
213 struct fs_disk_quota fdq
;
215 if (copy_from_user(&fdq
, addr
, sizeof(fdq
)))
217 return sb
->s_qcop
->set_xquota(sb
, type
, id
, &fdq
);
220 struct fs_disk_quota fdq
;
222 if ((ret
= sb
->s_qcop
->get_xquota(sb
, type
, id
, &fdq
)))
224 if (copy_to_user(addr
, &fdq
, sizeof(fdq
)))
228 /* We never reach here unless validity check is broken */
236 * This is the system call interface. This communicates with
237 * the user-level programs. Currently this only supports diskquota
238 * calls. Maybe we need to add the process quotas etc. in the future,
239 * but we probably should use rlimits for that.
241 asmlinkage
long sys_quotactl(unsigned int cmd
, const char *special
, qid_t id
, caddr_t addr
)
244 struct super_block
*sb
= NULL
;
248 cmds
= cmd
>> SUBCMDSHIFT
;
249 type
= cmd
& SUBCMDMASK
;
251 if (IS_ERR(sb
= resolve_dev(special
))) {
256 if ((ret
= check_quotactl_valid(sb
, type
, cmds
, id
)) < 0)
258 ret
= do_quotactl(sb
, type
, cmds
, id
, addr
);