Initial revision
[linux-2.6.git] / fs / 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/smp_lock.h>
15 #include <linux/security.h>
16 #include <linux/syscalls.h>
17 #include <linux/buffer_head.h>
18 #include <linux/capability.h>
19 #include <linux/quotaops.h>
20 #include <linux/major.h>
21 #include <linux/blkdev.h>
22 #include <linux/vs_base.h>
23 #include <linux/vserver/debug.h>
24
25 /* Check validity of generic quotactl commands */
26 static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
27 {
28         if (type >= MAXQUOTAS)
29                 return -EINVAL;
30         if (!sb && cmd != Q_SYNC)
31                 return -ENODEV;
32         /* Is operation supported? */
33         if (sb && !sb->s_qcop)
34                 return -ENOSYS;
35
36         switch (cmd) {
37                 case Q_GETFMT:
38                         break;
39                 case Q_QUOTAON:
40                         if (!sb->s_qcop->quota_on)
41                                 return -ENOSYS;
42                         break;
43                 case Q_QUOTAOFF:
44                         if (!sb->s_qcop->quota_off)
45                                 return -ENOSYS;
46                         break;
47                 case Q_SETINFO:
48                         if (!sb->s_qcop->set_info)
49                                 return -ENOSYS;
50                         break;
51                 case Q_GETINFO:
52                         if (!sb->s_qcop->get_info)
53                                 return -ENOSYS;
54                         break;
55                 case Q_SETQUOTA:
56                         if (!sb->s_qcop->set_dqblk)
57                                 return -ENOSYS;
58                         break;
59                 case Q_GETQUOTA:
60                         if (!sb->s_qcop->get_dqblk)
61                                 return -ENOSYS;
62                         break;
63                 case Q_SYNC:
64                         if (sb && !sb->s_qcop->quota_sync)
65                                 return -ENOSYS;
66                         break;
67                 default:
68                         return -EINVAL;
69         }
70
71         /* Is quota turned on for commands which need it? */
72         switch (cmd) {
73                 case Q_GETFMT:
74                 case Q_GETINFO:
75                 case Q_QUOTAOFF:
76                 case Q_SETINFO:
77                 case Q_SETQUOTA:
78                 case Q_GETQUOTA:
79                         /* This is just informative test so we are satisfied without a lock */
80                         if (!sb_has_quota_enabled(sb, type))
81                                 return -ESRCH;
82         }
83
84         /* Check privileges */
85         if (cmd == Q_GETQUOTA) {
86                 if (((type == USRQUOTA && current->euid != id) ||
87                      (type == GRPQUOTA && !in_egroup_p(id))) &&
88                     !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
89                         return -EPERM;
90         }
91         else if (cmd != Q_GETFMT && cmd != Q_SYNC && cmd != Q_GETINFO)
92                 if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
93                         return -EPERM;
94
95         return 0;
96 }
97
98 /* Check validity of XFS Quota Manager commands */
99 static int xqm_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
100 {
101         if (type >= XQM_MAXQUOTAS)
102                 return -EINVAL;
103         if (!sb)
104                 return -ENODEV;
105         if (!sb->s_qcop)
106                 return -ENOSYS;
107
108         switch (cmd) {
109                 case Q_XQUOTAON:
110                 case Q_XQUOTAOFF:
111                 case Q_XQUOTARM:
112                         if (!sb->s_qcop->set_xstate)
113                                 return -ENOSYS;
114                         break;
115                 case Q_XGETQSTAT:
116                         if (!sb->s_qcop->get_xstate)
117                                 return -ENOSYS;
118                         break;
119                 case Q_XSETQLIM:
120                         if (!sb->s_qcop->set_xquota)
121                                 return -ENOSYS;
122                         break;
123                 case Q_XGETQUOTA:
124                         if (!sb->s_qcop->get_xquota)
125                                 return -ENOSYS;
126                         break;
127                 case Q_XQUOTASYNC:
128                         if (!sb->s_qcop->quota_sync)
129                                 return -ENOSYS;
130                         break;
131                 default:
132                         return -EINVAL;
133         }
134
135         /* Check privileges */
136         if (cmd == Q_XGETQUOTA) {
137                 if (((type == XQM_USRQUOTA && current->euid != id) ||
138                      (type == XQM_GRPQUOTA && !in_egroup_p(id))) &&
139                      !vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
140                         return -EPERM;
141         } else if (cmd != Q_XGETQSTAT && cmd != Q_XQUOTASYNC) {
142                 if (!vx_capable(CAP_SYS_ADMIN, VXC_QUOTA_CTL))
143                         return -EPERM;
144         }
145
146         return 0;
147 }
148
149 static int check_quotactl_valid(struct super_block *sb, int type, int cmd, qid_t id)
150 {
151         int error;
152
153         if (XQM_COMMAND(cmd))
154                 error = xqm_quotactl_valid(sb, type, cmd, id);
155         else
156                 error = generic_quotactl_valid(sb, type, cmd, id);
157         if (!error)
158                 error = security_quotactl(cmd, type, id, sb);
159         return error;
160 }
161
162 static void quota_sync_sb(struct super_block *sb, int type)
163 {
164         int cnt;
165         struct inode *discard[MAXQUOTAS];
166
167         sb->s_qcop->quota_sync(sb, type);
168         /* This is not very clever (and fast) but currently I don't know about
169          * any other simple way of getting quota data to disk and we must get
170          * them there for userspace to be visible... */
171         if (sb->s_op->sync_fs)
172                 sb->s_op->sync_fs(sb, 1);
173         sync_blockdev(sb->s_bdev);
174
175         /* Now when everything is written we can discard the pagecache so
176          * that userspace sees the changes. We need i_mutex and so we could
177          * not do it inside dqonoff_mutex. Moreover we need to be carefull
178          * about races with quotaoff() (that is the reason why we have own
179          * reference to inode). */
180         mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
181         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
182                 discard[cnt] = NULL;
183                 if (type != -1 && cnt != type)
184                         continue;
185                 if (!sb_has_quota_enabled(sb, cnt))
186                         continue;
187                 discard[cnt] = igrab(sb_dqopt(sb)->files[cnt]);
188         }
189         mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
190         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
191                 if (discard[cnt]) {
192                         mutex_lock(&discard[cnt]->i_mutex);
193                         truncate_inode_pages(&discard[cnt]->i_data, 0);
194                         mutex_unlock(&discard[cnt]->i_mutex);
195                         iput(discard[cnt]);
196                 }
197         }
198 }
199
200 void sync_dquots(struct super_block *sb, int type)
201 {
202         int cnt, dirty;
203
204         if (sb) {
205                 if (sb->s_qcop->quota_sync)
206                         quota_sync_sb(sb, type);
207                 return;
208         }
209
210         spin_lock(&sb_lock);
211 restart:
212         list_for_each_entry(sb, &super_blocks, s_list) {
213                 /* This test just improves performance so it needn't be reliable... */
214                 for (cnt = 0, dirty = 0; cnt < MAXQUOTAS; cnt++)
215                         if ((type == cnt || type == -1) && sb_has_quota_enabled(sb, cnt)
216                             && info_any_dirty(&sb_dqopt(sb)->info[cnt]))
217                                 dirty = 1;
218                 if (!dirty)
219                         continue;
220                 sb->s_count++;
221                 spin_unlock(&sb_lock);
222                 down_read(&sb->s_umount);
223                 if (sb->s_root && sb->s_qcop->quota_sync)
224                         quota_sync_sb(sb, type);
225                 up_read(&sb->s_umount);
226                 spin_lock(&sb_lock);
227                 if (__put_super_and_need_restart(sb))
228                         goto restart;
229         }
230         spin_unlock(&sb_lock);
231 }
232
233 /* Copy parameters and call proper function */
234 static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void __user *addr)
235 {
236         int ret;
237
238         switch (cmd) {
239                 case Q_QUOTAON: {
240                         char *pathname;
241
242                         if (IS_ERR(pathname = getname(addr)))
243                                 return PTR_ERR(pathname);
244                         ret = sb->s_qcop->quota_on(sb, type, id, pathname);
245                         putname(pathname);
246                         return ret;
247                 }
248                 case Q_QUOTAOFF:
249                         return sb->s_qcop->quota_off(sb, type);
250
251                 case Q_GETFMT: {
252                         __u32 fmt;
253
254                         down_read(&sb_dqopt(sb)->dqptr_sem);
255                         if (!sb_has_quota_enabled(sb, type)) {
256                                 up_read(&sb_dqopt(sb)->dqptr_sem);
257                                 return -ESRCH;
258                         }
259                         fmt = sb_dqopt(sb)->info[type].dqi_format->qf_fmt_id;
260                         up_read(&sb_dqopt(sb)->dqptr_sem);
261                         if (copy_to_user(addr, &fmt, sizeof(fmt)))
262                                 return -EFAULT;
263                         return 0;
264                 }
265                 case Q_GETINFO: {
266                         struct if_dqinfo info;
267
268                         if ((ret = sb->s_qcop->get_info(sb, type, &info)))
269                                 return ret;
270                         if (copy_to_user(addr, &info, sizeof(info)))
271                                 return -EFAULT;
272                         return 0;
273                 }
274                 case Q_SETINFO: {
275                         struct if_dqinfo info;
276
277                         if (copy_from_user(&info, addr, sizeof(info)))
278                                 return -EFAULT;
279                         return sb->s_qcop->set_info(sb, type, &info);
280                 }
281                 case Q_GETQUOTA: {
282                         struct if_dqblk idq;
283
284                         if ((ret = sb->s_qcop->get_dqblk(sb, type, id, &idq)))
285                                 return ret;
286                         if (copy_to_user(addr, &idq, sizeof(idq)))
287                                 return -EFAULT;
288                         return 0;
289                 }
290                 case Q_SETQUOTA: {
291                         struct if_dqblk idq;
292
293                         if (copy_from_user(&idq, addr, sizeof(idq)))
294                                 return -EFAULT;
295                         return sb->s_qcop->set_dqblk(sb, type, id, &idq);
296                 }
297                 case Q_SYNC:
298                         sync_dquots(sb, type);
299                         return 0;
300
301                 case Q_XQUOTAON:
302                 case Q_XQUOTAOFF:
303                 case Q_XQUOTARM: {
304                         __u32 flags;
305
306                         if (copy_from_user(&flags, addr, sizeof(flags)))
307                                 return -EFAULT;
308                         return sb->s_qcop->set_xstate(sb, flags, cmd);
309                 }
310                 case Q_XGETQSTAT: {
311                         struct fs_quota_stat fqs;
312                 
313                         if ((ret = sb->s_qcop->get_xstate(sb, &fqs)))
314                                 return ret;
315                         if (copy_to_user(addr, &fqs, sizeof(fqs)))
316                                 return -EFAULT;
317                         return 0;
318                 }
319                 case Q_XSETQLIM: {
320                         struct fs_disk_quota fdq;
321
322                         if (copy_from_user(&fdq, addr, sizeof(fdq)))
323                                 return -EFAULT;
324                        return sb->s_qcop->set_xquota(sb, type, id, &fdq);
325                 }
326                 case Q_XGETQUOTA: {
327                         struct fs_disk_quota fdq;
328
329                         if ((ret = sb->s_qcop->get_xquota(sb, type, id, &fdq)))
330                                 return ret;
331                         if (copy_to_user(addr, &fdq, sizeof(fdq)))
332                                 return -EFAULT;
333                         return 0;
334                 }
335                 case Q_XQUOTASYNC:
336                         return sb->s_qcop->quota_sync(sb, type);
337                 /* We never reach here unless validity check is broken */
338                 default:
339                         BUG();
340         }
341         return 0;
342 }
343
344 #if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
345
346 #include <linux/vroot.h>
347 #include <linux/kallsyms.h>
348
349 static vroot_grb_func *vroot_get_real_bdev = NULL;
350
351 static spinlock_t vroot_grb_lock = SPIN_LOCK_UNLOCKED;
352
353 int register_vroot_grb(vroot_grb_func *func) {
354         int ret = -EBUSY;
355
356         spin_lock(&vroot_grb_lock);
357         if (!vroot_get_real_bdev) {
358                 vroot_get_real_bdev = func;
359                 ret = 0;
360         }
361         spin_unlock(&vroot_grb_lock);
362         return ret;
363 }
364 EXPORT_SYMBOL(register_vroot_grb);
365
366 int unregister_vroot_grb(vroot_grb_func *func) {
367         int ret = -EINVAL;
368
369         spin_lock(&vroot_grb_lock);
370         if (vroot_get_real_bdev) {
371                 vroot_get_real_bdev = NULL;
372                 ret = 0;
373         }
374         spin_unlock(&vroot_grb_lock);
375         return ret;
376 }
377 EXPORT_SYMBOL(unregister_vroot_grb);
378
379 #endif
380
381 /*
382  * This is the system call interface. This communicates with
383  * the user-level programs. Currently this only supports diskquota
384  * calls. Maybe we need to add the process quotas etc. in the future,
385  * but we probably should use rlimits for that.
386  */
387 asmlinkage long sys_quotactl(unsigned int cmd, const char __user *special, qid_t id, void __user *addr)
388 {
389         uint cmds, type;
390         struct super_block *sb = NULL;
391         struct block_device *bdev;
392         char *tmp;
393         int ret;
394
395         cmds = cmd >> SUBCMDSHIFT;
396         type = cmd & SUBCMDMASK;
397
398         if (cmds != Q_SYNC || special) {
399                 tmp = getname(special);
400                 if (IS_ERR(tmp))
401                         return PTR_ERR(tmp);
402                 bdev = lookup_bdev(tmp);
403                 putname(tmp);
404                 if (IS_ERR(bdev))
405                         return PTR_ERR(bdev);
406 #if defined(CONFIG_BLK_DEV_VROOT) || defined(CONFIG_BLK_DEV_VROOT_MODULE)
407                 if (bdev && bdev->bd_inode &&
408                         imajor(bdev->bd_inode) == VROOT_MAJOR) {
409                         struct block_device *bdnew = (void *)-EINVAL;
410
411                         if (vroot_get_real_bdev)
412                                 bdnew = vroot_get_real_bdev(bdev);
413                         else
414                                 vxdprintk(VXD_CBIT(misc, 0),
415                                         "vroot_get_real_bdev not set");
416
417                         bdput(bdev);
418                         if (IS_ERR(bdnew))
419                                 return PTR_ERR(bdnew);
420                         bdev = bdnew;
421                 }
422 #endif
423                 sb = get_super(bdev);
424                 bdput(bdev);
425                 if (!sb)
426                         return -ENODEV;
427         }
428
429         ret = check_quotactl_valid(sb, type, cmds, id);
430         if (ret >= 0)
431                 ret = do_quotactl(sb, type, cmds, id, addr);
432         if (sb)
433                 drop_super(sb);
434
435         return ret;
436 }