3ce1553ea7ebc557b265b70a5a4efeab07e567b3
[linux-2.6.git] / fs / quota / quota.c
1 /*
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.
6  */
7
8 #include <linux/fs.h>
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/security.h>
15 #include <linux/syscalls.h>
16 #include <linux/buffer_head.h>
17 #include <linux/capability.h>
18 #include <linux/quotaops.h>
19 #include <linux/types.h>
20 #include <linux/writeback.h>
21 #include "../internal.h"
22
23 static int check_quotactl_permission(struct super_block *sb, int type, int cmd,
24                                      qid_t id)
25 {
26         switch (cmd) {
27         /* these commands do not require any special privilegues */
28         case Q_GETFMT:
29         case Q_SYNC:
30         case Q_GETINFO:
31         case Q_XGETQSTAT:
32         case Q_XQUOTASYNC:
33                 break;
34         /* allow to query information for dquots we "own" */
35         case Q_GETQUOTA:
36         case Q_XGETQUOTA:
37                 if ((type == USRQUOTA && current_euid() == id) ||
38                     (type == GRPQUOTA && in_egroup_p(id)))
39                         break;
40                 /*FALLTHROUGH*/
41         default:
42                 if (!capable(CAP_SYS_ADMIN))
43                         return -EPERM;
44         }
45
46         return security_quotactl(cmd, type, id, sb);
47 }
48
49 static int quota_sync_all(int type)
50 {
51         struct super_block *sb, *n;
52         int ret;
53
54         if (type >= MAXQUOTAS)
55                 return -EINVAL;
56         ret = security_quotactl(Q_SYNC, type, 0, NULL);
57         if (ret)
58                 return ret;
59
60         spin_lock(&sb_lock);
61         list_for_each_entry_safe(sb, n, &super_blocks, s_list) {
62                 if (list_empty(&sb->s_instances))
63                         continue;
64                 if (!sb->s_qcop || !sb->s_qcop->quota_sync)
65                         continue;
66
67                 sb->s_count++;
68                 spin_unlock(&sb_lock);
69                 down_read(&sb->s_umount);
70                 if (sb->s_root)
71                         sb->s_qcop->quota_sync(sb, type, 1);
72                 up_read(&sb->s_umount);
73                 spin_lock(&sb_lock);
74                 __put_super(sb);
75         }
76         spin_unlock(&sb_lock);
77
78         return 0;
79 }
80
81 static int quota_quotaon(struct super_block *sb, int type, int cmd, qid_t id,
82                          void __user *addr)
83 {
84         char *pathname;
85         int ret = -ENOSYS;
86
87         pathname = getname(addr);
88         if (IS_ERR(pathname))
89                 return PTR_ERR(pathname);
90         if (sb->s_qcop->quota_on)
91                 ret = sb->s_qcop->quota_on(sb, type, id, pathname, 0);
92         putname(pathname);
93         return ret;
94 }
95
96 static int quota_getfmt(struct super_block *sb, int type, void __user *addr)
97 {
98         __u32 fmt;
99
100         down_read(&sb_dqopt(sb)->dqptr_sem);
101         if (!sb_has_quota_active(sb, type)) {
102                 up_read(&sb_dqopt(sb)->dqptr_sem);
103                 return -ESRCH;
104         }
105         fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
106         up_read(&sb_dqopt(sb)->dqptr_sem);
107         if (copy_to_user(addr, &fmt, sizeof(fmt)))
108                 return -EFAULT;
109         return 0;
110 }
111
112 static int quota_getinfo(struct super_block *sb, int type, void __user *addr)
113 {
114         struct if_dqinfo info;
115         int ret;
116
117         if (!sb->s_qcop->get_info)
118                 return -ENOSYS;
119         ret = sb->s_qcop->get_info(sb, type, &info);
120         if (!ret && copy_to_user(addr, &info, sizeof(info)))
121                 return -EFAULT;
122         return ret;
123 }
124
125 static int quota_setinfo(struct super_block *sb, int type, void __user *addr)
126 {
127         struct if_dqinfo info;
128
129         if (copy_from_user(&info, addr, sizeof(info)))
130                 return -EFAULT;
131         if (!sb->s_qcop->set_info)
132                 return -ENOSYS;
133         return sb->s_qcop->set_info(sb, type, &info);
134 }
135
136 static void copy_to_if_dqblk(struct if_dqblk *dst, struct fs_disk_quota *src)
137 {
138         dst->dqb_bhardlimit = src->d_blk_hardlimit;
139         dst->dqb_bsoftlimit = src->d_blk_softlimit;
140         dst->dqb_curspace = src->d_bcount;
141         dst->dqb_ihardlimit = src->d_ino_hardlimit;
142         dst->dqb_isoftlimit = src->d_ino_softlimit;
143         dst->dqb_curinodes = src->d_icount;
144         dst->dqb_btime = src->d_btimer;
145         dst->dqb_itime = src->d_itimer;
146         dst->dqb_valid = QIF_ALL;
147 }
148
149 static int quota_getquota(struct super_block *sb, int type, qid_t id,
150                           void __user *addr)
151 {
152         struct fs_disk_quota fdq;
153         struct if_dqblk idq;
154         int ret;
155
156         if (!sb->s_qcop->get_dqblk)
157                 return -ENOSYS;
158         ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
159         if (ret)
160                 return ret;
161         copy_to_if_dqblk(&idq, &fdq);
162         if (copy_to_user(addr, &idq, sizeof(idq)))
163                 return -EFAULT;
164         return 0;
165 }
166
167 static void copy_from_if_dqblk(struct fs_disk_quota *dst, struct if_dqblk *src)
168 {
169         dst->d_blk_hardlimit = src->dqb_bhardlimit;
170         dst->d_blk_softlimit  = src->dqb_bsoftlimit;
171         dst->d_bcount = src->dqb_curspace;
172         dst->d_ino_hardlimit = src->dqb_ihardlimit;
173         dst->d_ino_softlimit = src->dqb_isoftlimit;
174         dst->d_icount = src->dqb_curinodes;
175         dst->d_btimer = src->dqb_btime;
176         dst->d_itimer = src->dqb_itime;
177
178         dst->d_fieldmask = 0;
179         if (src->dqb_valid & QIF_BLIMITS)
180                 dst->d_fieldmask |= FS_DQ_BSOFT | FS_DQ_BHARD;
181         if (src->dqb_valid & QIF_SPACE)
182                 dst->d_fieldmask |= FS_DQ_BCOUNT;
183         if (src->dqb_valid & QIF_ILIMITS)
184                 dst->d_fieldmask |= FS_DQ_ISOFT | FS_DQ_IHARD;
185         if (src->dqb_valid & QIF_INODES)
186                 dst->d_fieldmask |= FS_DQ_ICOUNT;
187         if (src->dqb_valid & QIF_BTIME)
188                 dst->d_fieldmask |= FS_DQ_BTIMER;
189         if (src->dqb_valid & QIF_ITIME)
190                 dst->d_fieldmask |= FS_DQ_ITIMER;
191 }
192
193 static int quota_setquota(struct super_block *sb, int type, qid_t id,
194                           void __user *addr)
195 {
196         struct fs_disk_quota fdq;
197         struct if_dqblk idq;
198
199         if (copy_from_user(&idq, addr, sizeof(idq)))
200                 return -EFAULT;
201         if (!sb->s_qcop->set_dqblk)
202                 return -ENOSYS;
203         copy_from_if_dqblk(&fdq, &idq);
204         return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
205 }
206
207 static int quota_setxstate(struct super_block *sb, int cmd, void __user *addr)
208 {
209         __u32 flags;
210
211         if (copy_from_user(&flags, addr, sizeof(flags)))
212                 return -EFAULT;
213         if (!sb->s_qcop->set_xstate)
214                 return -ENOSYS;
215         return sb->s_qcop->set_xstate(sb, flags, cmd);
216 }
217
218 static int quota_getxstate(struct super_block *sb, void __user *addr)
219 {
220         struct fs_quota_stat fqs;
221         int ret;
222
223         if (!sb->s_qcop->get_xstate)
224                 return -ENOSYS;
225         ret = sb->s_qcop->get_xstate(sb, &fqs);
226         if (!ret && copy_to_user(addr, &fqs, sizeof(fqs)))
227                 return -EFAULT;
228         return ret;
229 }
230
231 static int quota_setxquota(struct super_block *sb, int type, qid_t id,
232                            void __user *addr)
233 {
234         struct fs_disk_quota fdq;
235
236         if (copy_from_user(&fdq, addr, sizeof(fdq)))
237                 return -EFAULT;
238         if (!sb->s_qcop->set_dqblk)
239                 return -ENOSYS;
240         return sb->s_qcop->set_dqblk(sb, type, id, &fdq);
241 }
242
243 static int quota_getxquota(struct super_block *sb, int type, qid_t id,
244                            void __user *addr)
245 {
246         struct fs_disk_quota fdq;
247         int ret;
248
249         if (!sb->s_qcop->get_dqblk)
250                 return -ENOSYS;
251         ret = sb->s_qcop->get_dqblk(sb, type, id, &fdq);
252         if (!ret && copy_to_user(addr, &fdq, sizeof(fdq)))
253                 return -EFAULT;
254         return ret;
255 }
256
257 /* Copy parameters and call proper function */
258 static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id,
259                        void __user *addr)
260 {
261         int ret;
262
263         if (type >= (XQM_COMMAND(cmd) ? XQM_MAXQUOTAS : MAXQUOTAS))
264                 return -EINVAL;
265         if (!sb->s_qcop)
266                 return -ENOSYS;
267
268         ret = check_quotactl_permission(sb, type, cmd, id);
269         if (ret < 0)
270                 return ret;
271
272         switch (cmd) {
273         case Q_QUOTAON:
274                 return quota_quotaon(sb, type, cmd, id, addr);
275         case Q_QUOTAOFF:
276                 if (!sb->s_qcop->quota_off)
277                         return -ENOSYS;
278                 return sb->s_qcop->quota_off(sb, type, 0);
279         case Q_GETFMT:
280                 return quota_getfmt(sb, type, addr);
281         case Q_GETINFO:
282                 return quota_getinfo(sb, type, addr);
283         case Q_SETINFO:
284                 return quota_setinfo(sb, type, addr);
285         case Q_GETQUOTA:
286                 return quota_getquota(sb, type, id, addr);
287         case Q_SETQUOTA:
288                 return quota_setquota(sb, type, id, addr);
289         case Q_SYNC:
290                 if (!sb->s_qcop->quota_sync)
291                         return -ENOSYS;
292                 return sb->s_qcop->quota_sync(sb, type, 1);
293         case Q_XQUOTAON:
294         case Q_XQUOTAOFF:
295         case Q_XQUOTARM:
296                 return quota_setxstate(sb, cmd, addr);
297         case Q_XGETQSTAT:
298                 return quota_getxstate(sb, addr);
299         case Q_XSETQLIM:
300                 return quota_setxquota(sb, type, id, addr);
301         case Q_XGETQUOTA:
302                 return quota_getxquota(sb, type, id, addr);
303         case Q_XQUOTASYNC:
304                 /* caller already holds s_umount */
305                 if (sb->s_flags & MS_RDONLY)
306                         return -EROFS;
307                 writeback_inodes_sb(sb);
308                 return 0;
309         default:
310                 return -EINVAL;
311         }
312 }
313
314 /*
315  * look up a superblock on which quota ops will be performed
316  * - use the name of a block device to find the superblock thereon
317  */
318 static struct super_block *quotactl_block(const char __user *special)
319 {
320 #ifdef CONFIG_BLOCK
321         struct block_device *bdev;
322         struct super_block *sb;
323         char *tmp = getname(special);
324
325         if (IS_ERR(tmp))
326                 return ERR_CAST(tmp);
327         bdev = lookup_bdev(tmp);
328         putname(tmp);
329         if (IS_ERR(bdev))
330                 return ERR_CAST(bdev);
331         sb = get_super(bdev);
332         bdput(bdev);
333         if (!sb)
334                 return ERR_PTR(-ENODEV);
335
336         return sb;
337 #else
338         return ERR_PTR(-ENODEV);
339 #endif
340 }
341
342 /*
343  * This is the system call interface. This communicates with
344  * the user-level programs. Currently this only supports diskquota
345  * calls. Maybe we need to add the process quotas etc. in the future,
346  * but we probably should use rlimits for that.
347  */
348 SYSCALL_DEFINE4(quotactl, unsigned int, cmd, const char __user *, special,
349                 qid_t, id, void __user *, addr)
350 {
351         uint cmds, type;
352         struct super_block *sb = NULL;
353         int ret;
354
355         cmds = cmd >> SUBCMDSHIFT;
356         type = cmd & SUBCMDMASK;
357
358         /*
359          * As a special case Q_SYNC can be called without a specific device.
360          * It will iterate all superblocks that have quota enabled and call
361          * the sync action on each of them.
362          */
363         if (!special) {
364                 if (cmds == Q_SYNC)
365                         return quota_sync_all(type);
366                 return -ENODEV;
367         }
368
369         sb = quotactl_block(special);
370         if (IS_ERR(sb))
371                 return PTR_ERR(sb);
372
373         ret = do_quotactl(sb, type, cmds, id, addr);
374
375         drop_super(sb);
376         return ret;
377 }