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