]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/ufs/ufs/ufs_quota.c
Merge llvm 3.6.0rc1 from ^/vendor/llvm/dist, merge clang 3.6.0rc1 from
[FreeBSD/FreeBSD.git] / sys / ufs / ufs / ufs_quota.c
1 /*-
2  * Copyright (c) 1982, 1986, 1990, 1993, 1995
3  *      The Regents of the University of California.  All rights reserved.
4  *
5  * This code is derived from software contributed to Berkeley by
6  * Robert Elz at The University of Melbourne.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 4. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *      @(#)ufs_quota.c 8.5 (Berkeley) 5/20/95
33  */
34
35 #include <sys/cdefs.h>
36 __FBSDID("$FreeBSD$");
37
38 #include "opt_ffs.h"
39
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/endian.h>
43 #include <sys/fcntl.h>
44 #include <sys/kernel.h>
45 #include <sys/lock.h>
46 #include <sys/malloc.h>
47 #include <sys/mount.h>
48 #include <sys/mutex.h>
49 #include <sys/namei.h>
50 #include <sys/priv.h>
51 #include <sys/proc.h>
52 #include <sys/socket.h>
53 #include <sys/stat.h>
54 #include <sys/sysctl.h>
55 #include <sys/vnode.h>
56
57 #include <ufs/ufs/extattr.h>
58 #include <ufs/ufs/quota.h>
59 #include <ufs/ufs/inode.h>
60 #include <ufs/ufs/ufsmount.h>
61 #include <ufs/ufs/ufs_extern.h>
62
63 CTASSERT(sizeof(struct dqblk64) == sizeof(struct dqhdr64));
64
65 static int unprivileged_get_quota = 0;
66 SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_get_quota, CTLFLAG_RW,
67     &unprivileged_get_quota, 0,
68     "Unprivileged processes may retrieve quotas for other uids and gids");
69
70 static MALLOC_DEFINE(M_DQUOT, "ufs_quota", "UFS quota entries");
71
72 /*
73  * Quota name to error message mapping.
74  */
75 static char *quotatypes[] = INITQFNAMES;
76
77 static int chkdqchg(struct inode *, ufs2_daddr_t, struct ucred *, int, int *);
78 static int chkiqchg(struct inode *, int, struct ucred *, int, int *);
79 static int dqopen(struct vnode *, struct ufsmount *, int);
80 static int dqget(struct vnode *,
81         u_long, struct ufsmount *, int, struct dquot **);
82 static int dqsync(struct vnode *, struct dquot *);
83 static int dqflush(struct vnode *);
84 static int quotaoff1(struct thread *td, struct mount *mp, int type);
85 static int quotaoff_inchange(struct thread *td, struct mount *mp, int type);
86
87 /* conversion functions - from_to() */
88 static void dqb32_dq(const struct dqblk32 *, struct dquot *);
89 static void dqb64_dq(const struct dqblk64 *, struct dquot *);
90 static void dq_dqb32(const struct dquot *, struct dqblk32 *);
91 static void dq_dqb64(const struct dquot *, struct dqblk64 *);
92 static void dqb32_dqb64(const struct dqblk32 *, struct dqblk64 *);
93 static void dqb64_dqb32(const struct dqblk64 *, struct dqblk32 *);
94
95 #ifdef DIAGNOSTIC
96 static void dqref(struct dquot *);
97 static void chkdquot(struct inode *);
98 #endif
99
100 /*
101  * Set up the quotas for an inode.
102  *
103  * This routine completely defines the semantics of quotas.
104  * If other criterion want to be used to establish quotas, the
105  * MAXQUOTAS value in quota.h should be increased, and the
106  * additional dquots set up here.
107  */
108 int
109 getinoquota(struct inode *ip)
110 {
111         struct ufsmount *ump;
112         struct vnode *vp;
113         int error;
114
115         vp = ITOV(ip);
116
117         /*
118          * Disk quotas must be turned off for system files.  Currently
119          * snapshot and quota files.
120          */
121         if ((vp->v_vflag & VV_SYSTEM) != 0)
122                 return (0);
123         /*
124          * XXX: Turn off quotas for files with a negative UID or GID.
125          * This prevents the creation of 100GB+ quota files.
126          */
127         if ((int)ip->i_uid < 0 || (int)ip->i_gid < 0)
128                 return (0);
129         ump = VFSTOUFS(vp->v_mount);
130         /*
131          * Set up the user quota based on file uid.
132          * EINVAL means that quotas are not enabled.
133          */
134         if ((error =
135                 dqget(vp, ip->i_uid, ump, USRQUOTA, &ip->i_dquot[USRQUOTA])) &&
136             error != EINVAL)
137                 return (error);
138         /*
139          * Set up the group quota based on file gid.
140          * EINVAL means that quotas are not enabled.
141          */
142         if ((error =
143                 dqget(vp, ip->i_gid, ump, GRPQUOTA, &ip->i_dquot[GRPQUOTA])) &&
144             error != EINVAL)
145                 return (error);
146         return (0);
147 }
148
149 /*
150  * Update disk usage, and take corrective action.
151  */
152 int
153 chkdq(struct inode *ip, ufs2_daddr_t change, struct ucred *cred, int flags)
154 {
155         struct dquot *dq;
156         ufs2_daddr_t ncurblocks;
157         struct vnode *vp = ITOV(ip);
158         int i, error, warn, do_check;
159
160         /*
161          * Disk quotas must be turned off for system files.  Currently
162          * snapshot and quota files.
163          */
164         if ((vp->v_vflag & VV_SYSTEM) != 0)
165                 return (0);
166         /*
167          * XXX: Turn off quotas for files with a negative UID or GID.
168          * This prevents the creation of 100GB+ quota files.
169          */
170         if ((int)ip->i_uid < 0 || (int)ip->i_gid < 0)
171                 return (0);
172 #ifdef DIAGNOSTIC
173         if ((flags & CHOWN) == 0)
174                 chkdquot(ip);
175 #endif
176         if (change == 0)
177                 return (0);
178         if (change < 0) {
179                 for (i = 0; i < MAXQUOTAS; i++) {
180                         if ((dq = ip->i_dquot[i]) == NODQUOT)
181                                 continue;
182                         DQI_LOCK(dq);
183                         DQI_WAIT(dq, PINOD+1, "chkdq1");
184                         ncurblocks = dq->dq_curblocks + change;
185                         if (ncurblocks >= 0)
186                                 dq->dq_curblocks = ncurblocks;
187                         else
188                                 dq->dq_curblocks = 0;
189                         dq->dq_flags &= ~DQ_BLKS;
190                         dq->dq_flags |= DQ_MOD;
191                         DQI_UNLOCK(dq);
192                 }
193                 return (0);
194         }
195         if ((flags & FORCE) == 0 &&
196             priv_check_cred(cred, PRIV_VFS_EXCEEDQUOTA, 0))
197                 do_check = 1;
198         else
199                 do_check = 0;
200         for (i = 0; i < MAXQUOTAS; i++) {
201                 if ((dq = ip->i_dquot[i]) == NODQUOT)
202                         continue;
203                 warn = 0;
204                 DQI_LOCK(dq);
205                 DQI_WAIT(dq, PINOD+1, "chkdq2");
206                 if (do_check) {
207                         error = chkdqchg(ip, change, cred, i, &warn);
208                         if (error) {
209                                 /*
210                                  * Roll back user quota changes when
211                                  * group quota failed.
212                                  */
213                                 while (i > 0) {
214                                         --i;
215                                         dq = ip->i_dquot[i];
216                                         if (dq == NODQUOT)
217                                                 continue;
218                                         DQI_LOCK(dq);
219                                         DQI_WAIT(dq, PINOD+1, "chkdq3");
220                                         ncurblocks = dq->dq_curblocks - change;
221                                         if (ncurblocks >= 0)
222                                                 dq->dq_curblocks = ncurblocks;
223                                         else
224                                                 dq->dq_curblocks = 0;
225                                         dq->dq_flags &= ~DQ_BLKS;
226                                         dq->dq_flags |= DQ_MOD;
227                                         DQI_UNLOCK(dq);
228                                 }
229                                 return (error);
230                         }
231                 }
232                 /* Reset timer when crossing soft limit */
233                 if (dq->dq_curblocks + change >= dq->dq_bsoftlimit &&
234                     dq->dq_curblocks < dq->dq_bsoftlimit)
235                         dq->dq_btime = time_second + ip->i_ump->um_btime[i];
236                 dq->dq_curblocks += change;
237                 dq->dq_flags |= DQ_MOD;
238                 DQI_UNLOCK(dq);
239                 if (warn)
240                         uprintf("\n%s: warning, %s disk quota exceeded\n",
241                             ITOV(ip)->v_mount->mnt_stat.f_mntonname,
242                             quotatypes[i]);
243         }
244         return (0);
245 }
246
247 /*
248  * Check for a valid change to a users allocation.
249  * Issue an error message if appropriate.
250  */
251 static int
252 chkdqchg(struct inode *ip, ufs2_daddr_t change, struct ucred *cred,
253     int type, int *warn)
254 {
255         struct dquot *dq = ip->i_dquot[type];
256         ufs2_daddr_t ncurblocks = dq->dq_curblocks + change;
257
258         /*
259          * If user would exceed their hard limit, disallow space allocation.
260          */
261         if (ncurblocks >= dq->dq_bhardlimit && dq->dq_bhardlimit) {
262                 if ((dq->dq_flags & DQ_BLKS) == 0 &&
263                     ip->i_uid == cred->cr_uid) {
264                         dq->dq_flags |= DQ_BLKS;
265                         DQI_UNLOCK(dq);
266                         uprintf("\n%s: write failed, %s disk limit reached\n",
267                             ITOV(ip)->v_mount->mnt_stat.f_mntonname,
268                             quotatypes[type]);
269                         return (EDQUOT);
270                 }
271                 DQI_UNLOCK(dq);
272                 return (EDQUOT);
273         }
274         /*
275          * If user is over their soft limit for too long, disallow space
276          * allocation. Reset time limit as they cross their soft limit.
277          */
278         if (ncurblocks >= dq->dq_bsoftlimit && dq->dq_bsoftlimit) {
279                 if (dq->dq_curblocks < dq->dq_bsoftlimit) {
280                         dq->dq_btime = time_second + ip->i_ump->um_btime[type];
281                         if (ip->i_uid == cred->cr_uid)
282                                 *warn = 1;
283                         return (0);
284                 }
285                 if (time_second > dq->dq_btime) {
286                         if ((dq->dq_flags & DQ_BLKS) == 0 &&
287                             ip->i_uid == cred->cr_uid) {
288                                 dq->dq_flags |= DQ_BLKS;
289                                 DQI_UNLOCK(dq);
290                                 uprintf("\n%s: write failed, %s "
291                                     "disk quota exceeded for too long\n",
292                                     ITOV(ip)->v_mount->mnt_stat.f_mntonname,
293                                     quotatypes[type]);
294                                 return (EDQUOT);
295                         }
296                         DQI_UNLOCK(dq);
297                         return (EDQUOT);
298                 }
299         }
300         return (0);
301 }
302
303 /*
304  * Check the inode limit, applying corrective action.
305  */
306 int
307 chkiq(struct inode *ip, int change, struct ucred *cred, int flags)
308 {
309         struct dquot *dq;
310         int i, error, warn, do_check;
311
312 #ifdef DIAGNOSTIC
313         if ((flags & CHOWN) == 0)
314                 chkdquot(ip);
315 #endif
316         if (change == 0)
317                 return (0);
318         if (change < 0) {
319                 for (i = 0; i < MAXQUOTAS; i++) {
320                         if ((dq = ip->i_dquot[i]) == NODQUOT)
321                                 continue;
322                         DQI_LOCK(dq);
323                         DQI_WAIT(dq, PINOD+1, "chkiq1");
324                         if (dq->dq_curinodes >= -change)
325                                 dq->dq_curinodes += change;
326                         else
327                                 dq->dq_curinodes = 0;
328                         dq->dq_flags &= ~DQ_INODS;
329                         dq->dq_flags |= DQ_MOD;
330                         DQI_UNLOCK(dq);
331                 }
332                 return (0);
333         }
334         if ((flags & FORCE) == 0 &&
335             priv_check_cred(cred, PRIV_VFS_EXCEEDQUOTA, 0))
336                 do_check = 1;
337         else
338                 do_check = 0;
339         for (i = 0; i < MAXQUOTAS; i++) {
340                 if ((dq = ip->i_dquot[i]) == NODQUOT)
341                         continue;
342                 warn = 0;
343                 DQI_LOCK(dq);
344                 DQI_WAIT(dq, PINOD+1, "chkiq2");
345                 if (do_check) {
346                         error = chkiqchg(ip, change, cred, i, &warn);
347                         if (error) {
348                                 /*
349                                  * Roll back user quota changes when
350                                  * group quota failed.
351                                  */
352                                 while (i > 0) {
353                                         --i;
354                                         dq = ip->i_dquot[i];
355                                         if (dq == NODQUOT)
356                                                 continue;
357                                         DQI_LOCK(dq);
358                                         DQI_WAIT(dq, PINOD+1, "chkiq3");
359                                         if (dq->dq_curinodes >= change)
360                                                 dq->dq_curinodes -= change;
361                                         else
362                                                 dq->dq_curinodes = 0;
363                                         dq->dq_flags &= ~DQ_INODS;
364                                         dq->dq_flags |= DQ_MOD;
365                                         DQI_UNLOCK(dq);
366                                 }
367                                 return (error);
368                         }
369                 }
370                 /* Reset timer when crossing soft limit */
371                 if (dq->dq_curinodes + change >= dq->dq_isoftlimit &&
372                     dq->dq_curinodes < dq->dq_isoftlimit)
373                         dq->dq_itime = time_second + ip->i_ump->um_itime[i];
374                 dq->dq_curinodes += change;
375                 dq->dq_flags |= DQ_MOD;
376                 DQI_UNLOCK(dq);
377                 if (warn)
378                         uprintf("\n%s: warning, %s inode quota exceeded\n",
379                             ITOV(ip)->v_mount->mnt_stat.f_mntonname,
380                             quotatypes[i]);
381         }
382         return (0);
383 }
384
385 /*
386  * Check for a valid change to a users allocation.
387  * Issue an error message if appropriate.
388  */
389 static int
390 chkiqchg(struct inode *ip, int change, struct ucred *cred, int type, int *warn)
391 {
392         struct dquot *dq = ip->i_dquot[type];
393         ino_t ncurinodes = dq->dq_curinodes + change;
394
395         /*
396          * If user would exceed their hard limit, disallow inode allocation.
397          */
398         if (ncurinodes >= dq->dq_ihardlimit && dq->dq_ihardlimit) {
399                 if ((dq->dq_flags & DQ_INODS) == 0 &&
400                     ip->i_uid == cred->cr_uid) {
401                         dq->dq_flags |= DQ_INODS;
402                         DQI_UNLOCK(dq);
403                         uprintf("\n%s: write failed, %s inode limit reached\n",
404                             ITOV(ip)->v_mount->mnt_stat.f_mntonname,
405                             quotatypes[type]);
406                         return (EDQUOT);
407                 }
408                 DQI_UNLOCK(dq);
409                 return (EDQUOT);
410         }
411         /*
412          * If user is over their soft limit for too long, disallow inode
413          * allocation. Reset time limit as they cross their soft limit.
414          */
415         if (ncurinodes >= dq->dq_isoftlimit && dq->dq_isoftlimit) {
416                 if (dq->dq_curinodes < dq->dq_isoftlimit) {
417                         dq->dq_itime = time_second + ip->i_ump->um_itime[type];
418                         if (ip->i_uid == cred->cr_uid)
419                                 *warn = 1;
420                         return (0);
421                 }
422                 if (time_second > dq->dq_itime) {
423                         if ((dq->dq_flags & DQ_INODS) == 0 &&
424                             ip->i_uid == cred->cr_uid) {
425                                 dq->dq_flags |= DQ_INODS;
426                                 DQI_UNLOCK(dq);
427                                 uprintf("\n%s: write failed, %s "
428                                     "inode quota exceeded for too long\n",
429                                     ITOV(ip)->v_mount->mnt_stat.f_mntonname,
430                                     quotatypes[type]);
431                                 return (EDQUOT);
432                         }
433                         DQI_UNLOCK(dq);
434                         return (EDQUOT);
435                 }
436         }
437         return (0);
438 }
439
440 #ifdef DIAGNOSTIC
441 /*
442  * On filesystems with quotas enabled, it is an error for a file to change
443  * size and not to have a dquot structure associated with it.
444  */
445 static void
446 chkdquot(struct inode *ip)
447 {
448         struct ufsmount *ump = ip->i_ump;
449         struct vnode *vp = ITOV(ip);
450         int i;
451
452         /*
453          * Disk quotas must be turned off for system files.  Currently
454          * these are snapshots and quota files.
455          */
456         if ((vp->v_vflag & VV_SYSTEM) != 0)
457                 return;
458         /*
459          * XXX: Turn off quotas for files with a negative UID or GID.
460          * This prevents the creation of 100GB+ quota files.
461          */
462         if ((int)ip->i_uid < 0 || (int)ip->i_gid < 0)
463                 return;
464
465         UFS_LOCK(ump);
466         for (i = 0; i < MAXQUOTAS; i++) {
467                 if (ump->um_quotas[i] == NULLVP ||
468                     (ump->um_qflags[i] & (QTF_OPENING|QTF_CLOSING)))
469                         continue;
470                 if (ip->i_dquot[i] == NODQUOT) {
471                         UFS_UNLOCK(ump);
472                         vprint("chkdquot: missing dquot", ITOV(ip));
473                         panic("chkdquot: missing dquot");
474                 }
475         }
476         UFS_UNLOCK(ump);
477 }
478 #endif
479
480 /*
481  * Code to process quotactl commands.
482  */
483
484 /*
485  * Q_QUOTAON - set up a quota file for a particular filesystem.
486  */
487 int
488 quotaon(struct thread *td, struct mount *mp, int type, void *fname)
489 {
490         struct ufsmount *ump;
491         struct vnode *vp, **vpp;
492         struct vnode *mvp;
493         struct dquot *dq;
494         int error, flags;
495         struct nameidata nd;
496
497         error = priv_check(td, PRIV_UFS_QUOTAON);
498         if (error)
499                 return (error);
500
501         if (mp->mnt_flag & MNT_RDONLY)
502                 return (EROFS);
503
504         ump = VFSTOUFS(mp);
505         dq = NODQUOT;
506
507         NDINIT(&nd, LOOKUP, FOLLOW, UIO_USERSPACE, fname, td);
508         flags = FREAD | FWRITE;
509         vfs_ref(mp);
510         vfs_unbusy(mp);
511         error = vn_open(&nd, &flags, 0, NULL);
512         if (error != 0) {
513                 vfs_rel(mp);
514                 return (error);
515         }
516         NDFREE(&nd, NDF_ONLY_PNBUF);
517         vp = nd.ni_vp;
518         error = vfs_busy(mp, MBF_NOWAIT);
519         vfs_rel(mp);
520         if (error == 0) {
521                 if (vp->v_type != VREG) {
522                         error = EACCES;
523                         vfs_unbusy(mp);
524                 }
525         }
526         if (error != 0) {
527                 VOP_UNLOCK(vp, 0);
528                 (void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
529                 return (error);
530         }
531
532         UFS_LOCK(ump);
533         if ((ump->um_qflags[type] & (QTF_OPENING|QTF_CLOSING)) != 0) {
534                 UFS_UNLOCK(ump);
535                 VOP_UNLOCK(vp, 0);
536                 (void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
537                 vfs_unbusy(mp);
538                 return (EALREADY);
539         }
540         ump->um_qflags[type] |= QTF_OPENING|QTF_CLOSING;
541         UFS_UNLOCK(ump);
542         if ((error = dqopen(vp, ump, type)) != 0) {
543                 VOP_UNLOCK(vp, 0);
544                 UFS_LOCK(ump);
545                 ump->um_qflags[type] &= ~(QTF_OPENING|QTF_CLOSING);
546                 UFS_UNLOCK(ump);
547                 (void) vn_close(vp, FREAD|FWRITE, td->td_ucred, td);
548                 vfs_unbusy(mp);
549                 return (error);
550         }
551         VOP_UNLOCK(vp, 0);
552         MNT_ILOCK(mp);
553         mp->mnt_flag |= MNT_QUOTA;
554         MNT_IUNLOCK(mp);
555
556         vpp = &ump->um_quotas[type];
557         if (*vpp != vp)
558                 quotaoff1(td, mp, type);
559
560         /*
561          * When the directory vnode containing the quota file is
562          * inactivated, due to the shared lookup of the quota file
563          * vput()ing the dvp, the qsyncvp() call for the containing
564          * directory would try to acquire the quota lock exclusive.
565          * At the same time, lookup already locked the quota vnode
566          * shared.  Mark the quota vnode lock as allowing recursion
567          * and automatically converting shared locks to exclusive.
568          *
569          * Also mark quota vnode as system.
570          */
571         vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
572         vp->v_vflag |= VV_SYSTEM;
573         VN_LOCK_AREC(vp);
574         VN_LOCK_DSHARE(vp);
575         VOP_UNLOCK(vp, 0);
576         *vpp = vp;
577         /*
578          * Save the credential of the process that turned on quotas.
579          * Set up the time limits for this quota.
580          */
581         ump->um_cred[type] = crhold(td->td_ucred);
582         ump->um_btime[type] = MAX_DQ_TIME;
583         ump->um_itime[type] = MAX_IQ_TIME;
584         if (dqget(NULLVP, 0, ump, type, &dq) == 0) {
585                 if (dq->dq_btime > 0)
586                         ump->um_btime[type] = dq->dq_btime;
587                 if (dq->dq_itime > 0)
588                         ump->um_itime[type] = dq->dq_itime;
589                 dqrele(NULLVP, dq);
590         }
591         /*
592          * Allow the getdq from getinoquota below to read the quota
593          * from file.
594          */
595         UFS_LOCK(ump);
596         ump->um_qflags[type] &= ~QTF_CLOSING;
597         UFS_UNLOCK(ump);
598         /*
599          * Search vnodes associated with this mount point,
600          * adding references to quota file being opened.
601          * NB: only need to add dquot's for inodes being modified.
602          */
603 again:
604         MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
605                 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
606                         MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
607                         goto again;
608                 }
609                 if (vp->v_type == VNON || vp->v_writecount == 0) {
610                         VOP_UNLOCK(vp, 0);
611                         vrele(vp);
612                         continue;
613                 }
614                 error = getinoquota(VTOI(vp));
615                 VOP_UNLOCK(vp, 0);
616                 vrele(vp);
617                 if (error) {
618                         MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
619                         break;
620                 }
621         }
622
623         if (error)
624                 quotaoff_inchange(td, mp, type);
625         UFS_LOCK(ump);
626         ump->um_qflags[type] &= ~QTF_OPENING;
627         KASSERT((ump->um_qflags[type] & QTF_CLOSING) == 0,
628                 ("quotaon: leaking flags"));
629         UFS_UNLOCK(ump);
630
631         vfs_unbusy(mp);
632         return (error);
633 }
634
635 /*
636  * Main code to turn off disk quotas for a filesystem. Does not change
637  * flags.
638  */
639 static int
640 quotaoff1(struct thread *td, struct mount *mp, int type)
641 {
642         struct vnode *vp;
643         struct vnode *qvp, *mvp;
644         struct ufsmount *ump;
645         struct dquot *dq;
646         struct inode *ip;
647         struct ucred *cr;
648         int error;
649
650         ump = VFSTOUFS(mp);
651
652         UFS_LOCK(ump);
653         KASSERT((ump->um_qflags[type] & QTF_CLOSING) != 0,
654                 ("quotaoff1: flags are invalid"));
655         if ((qvp = ump->um_quotas[type]) == NULLVP) {
656                 UFS_UNLOCK(ump);
657                 return (0);
658         }
659         cr = ump->um_cred[type];
660         UFS_UNLOCK(ump);
661
662         /*
663          * Search vnodes associated with this mount point,
664          * deleting any references to quota file being closed.
665          */
666 again:
667         MNT_VNODE_FOREACH_ALL(vp, mp, mvp) {
668                 if (vp->v_type == VNON) {
669                         VI_UNLOCK(vp);
670                         continue;
671                 }
672                 if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td)) {
673                         MNT_VNODE_FOREACH_ALL_ABORT(mp, mvp);
674                         goto again;
675                 }
676                 ip = VTOI(vp);
677                 dq = ip->i_dquot[type];
678                 ip->i_dquot[type] = NODQUOT;
679                 dqrele(vp, dq);
680                 VOP_UNLOCK(vp, 0);
681                 vrele(vp);
682         }
683
684         error = dqflush(qvp);
685         if (error != 0)
686                 return (error);
687
688         /*
689          * Clear um_quotas before closing the quota vnode to prevent
690          * access to the closed vnode from dqget/dqsync
691          */
692         UFS_LOCK(ump);
693         ump->um_quotas[type] = NULLVP;
694         ump->um_cred[type] = NOCRED;
695         UFS_UNLOCK(ump);
696
697         vn_lock(qvp, LK_EXCLUSIVE | LK_RETRY);
698         qvp->v_vflag &= ~VV_SYSTEM;
699         VOP_UNLOCK(qvp, 0);
700         error = vn_close(qvp, FREAD|FWRITE, td->td_ucred, td);
701         crfree(cr);
702
703         return (error);
704 }
705
706 /*
707  * Turns off quotas, assumes that ump->um_qflags are already checked
708  * and QTF_CLOSING is set to indicate operation in progress. Fixes
709  * ump->um_qflags and mp->mnt_flag after.
710  */
711 int
712 quotaoff_inchange(struct thread *td, struct mount *mp, int type)
713 {
714         struct ufsmount *ump;
715         int i;
716         int error;
717
718         error = quotaoff1(td, mp, type);
719
720         ump = VFSTOUFS(mp);
721         UFS_LOCK(ump);
722         ump->um_qflags[type] &= ~QTF_CLOSING;
723         for (i = 0; i < MAXQUOTAS; i++)
724                 if (ump->um_quotas[i] != NULLVP)
725                         break;
726         if (i == MAXQUOTAS) {
727                 MNT_ILOCK(mp);
728                 mp->mnt_flag &= ~MNT_QUOTA;
729                 MNT_IUNLOCK(mp);
730         }
731         UFS_UNLOCK(ump);
732         return (error);
733 }
734
735 /*
736  * Q_QUOTAOFF - turn off disk quotas for a filesystem.
737  */
738 int
739 quotaoff(struct thread *td, struct mount *mp, int type)
740 {
741         struct ufsmount *ump;
742         int error;
743
744         error = priv_check(td, PRIV_UFS_QUOTAOFF);
745         if (error)
746                 return (error);
747
748         ump = VFSTOUFS(mp);
749         UFS_LOCK(ump);
750         if ((ump->um_qflags[type] & (QTF_OPENING|QTF_CLOSING)) != 0) {
751                 UFS_UNLOCK(ump);
752                 return (EALREADY);
753         }
754         ump->um_qflags[type] |= QTF_CLOSING;
755         UFS_UNLOCK(ump);
756
757         return (quotaoff_inchange(td, mp, type));
758 }
759
760 /*
761  * Q_GETQUOTA - return current values in a dqblk structure.
762  */
763 static int
764 _getquota(struct thread *td, struct mount *mp, u_long id, int type,
765     struct dqblk64 *dqb)
766 {
767         struct dquot *dq;
768         int error;
769
770         switch (type) {
771         case USRQUOTA:
772                 if ((td->td_ucred->cr_uid != id) && !unprivileged_get_quota) {
773                         error = priv_check(td, PRIV_VFS_GETQUOTA);
774                         if (error)
775                                 return (error);
776                 }
777                 break;
778
779         case GRPQUOTA:
780                 if (!groupmember(id, td->td_ucred) &&
781                     !unprivileged_get_quota) {
782                         error = priv_check(td, PRIV_VFS_GETQUOTA);
783                         if (error)
784                                 return (error);
785                 }
786                 break;
787
788         default:
789                 return (EINVAL);
790         }
791
792         dq = NODQUOT;
793         error = dqget(NULLVP, id, VFSTOUFS(mp), type, &dq);
794         if (error)
795                 return (error);
796         *dqb = dq->dq_dqb;
797         dqrele(NULLVP, dq);
798         return (error);
799 }
800
801 /*
802  * Q_SETQUOTA - assign an entire dqblk structure.
803  */
804 static int
805 _setquota(struct thread *td, struct mount *mp, u_long id, int type,
806     struct dqblk64 *dqb)
807 {
808         struct dquot *dq;
809         struct dquot *ndq;
810         struct ufsmount *ump;
811         struct dqblk64 newlim;
812         int error;
813
814         error = priv_check(td, PRIV_VFS_SETQUOTA);
815         if (error)
816                 return (error);
817
818         newlim = *dqb;
819
820         ndq = NODQUOT;
821         ump = VFSTOUFS(mp);
822
823         error = dqget(NULLVP, id, ump, type, &ndq);
824         if (error)
825                 return (error);
826         dq = ndq;
827         DQI_LOCK(dq);
828         DQI_WAIT(dq, PINOD+1, "setqta");
829         /*
830          * Copy all but the current values.
831          * Reset time limit if previously had no soft limit or were
832          * under it, but now have a soft limit and are over it.
833          */
834         newlim.dqb_curblocks = dq->dq_curblocks;
835         newlim.dqb_curinodes = dq->dq_curinodes;
836         if (dq->dq_id != 0) {
837                 newlim.dqb_btime = dq->dq_btime;
838                 newlim.dqb_itime = dq->dq_itime;
839         }
840         if (newlim.dqb_bsoftlimit &&
841             dq->dq_curblocks >= newlim.dqb_bsoftlimit &&
842             (dq->dq_bsoftlimit == 0 || dq->dq_curblocks < dq->dq_bsoftlimit))
843                 newlim.dqb_btime = time_second + ump->um_btime[type];
844         if (newlim.dqb_isoftlimit &&
845             dq->dq_curinodes >= newlim.dqb_isoftlimit &&
846             (dq->dq_isoftlimit == 0 || dq->dq_curinodes < dq->dq_isoftlimit))
847                 newlim.dqb_itime = time_second + ump->um_itime[type];
848         dq->dq_dqb = newlim;
849         if (dq->dq_curblocks < dq->dq_bsoftlimit)
850                 dq->dq_flags &= ~DQ_BLKS;
851         if (dq->dq_curinodes < dq->dq_isoftlimit)
852                 dq->dq_flags &= ~DQ_INODS;
853         if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0 &&
854             dq->dq_ihardlimit == 0 && dq->dq_bhardlimit == 0)
855                 dq->dq_flags |= DQ_FAKE;
856         else
857                 dq->dq_flags &= ~DQ_FAKE;
858         dq->dq_flags |= DQ_MOD;
859         DQI_UNLOCK(dq);
860         dqrele(NULLVP, dq);
861         return (0);
862 }
863
864 /*
865  * Q_SETUSE - set current inode and block usage.
866  */
867 static int
868 _setuse(struct thread *td, struct mount *mp, u_long id, int type,
869     struct dqblk64 *dqb)
870 {
871         struct dquot *dq;
872         struct ufsmount *ump;
873         struct dquot *ndq;
874         struct dqblk64 usage;
875         int error;
876
877         error = priv_check(td, PRIV_UFS_SETUSE);
878         if (error)
879                 return (error);
880
881         usage = *dqb;
882
883         ump = VFSTOUFS(mp);
884         ndq = NODQUOT;
885
886         error = dqget(NULLVP, id, ump, type, &ndq);
887         if (error)
888                 return (error);
889         dq = ndq;
890         DQI_LOCK(dq);
891         DQI_WAIT(dq, PINOD+1, "setuse");
892         /*
893          * Reset time limit if have a soft limit and were
894          * previously under it, but are now over it.
895          */
896         if (dq->dq_bsoftlimit && dq->dq_curblocks < dq->dq_bsoftlimit &&
897             usage.dqb_curblocks >= dq->dq_bsoftlimit)
898                 dq->dq_btime = time_second + ump->um_btime[type];
899         if (dq->dq_isoftlimit && dq->dq_curinodes < dq->dq_isoftlimit &&
900             usage.dqb_curinodes >= dq->dq_isoftlimit)
901                 dq->dq_itime = time_second + ump->um_itime[type];
902         dq->dq_curblocks = usage.dqb_curblocks;
903         dq->dq_curinodes = usage.dqb_curinodes;
904         if (dq->dq_curblocks < dq->dq_bsoftlimit)
905                 dq->dq_flags &= ~DQ_BLKS;
906         if (dq->dq_curinodes < dq->dq_isoftlimit)
907                 dq->dq_flags &= ~DQ_INODS;
908         dq->dq_flags |= DQ_MOD;
909         DQI_UNLOCK(dq);
910         dqrele(NULLVP, dq);
911         return (0);
912 }
913
914 int
915 getquota32(struct thread *td, struct mount *mp, u_long id, int type, void *addr)
916 {
917         struct dqblk32 dqb32;
918         struct dqblk64 dqb64;
919         int error;
920
921         error = _getquota(td, mp, id, type, &dqb64);
922         if (error)
923                 return (error);
924         dqb64_dqb32(&dqb64, &dqb32);
925         error = copyout(&dqb32, addr, sizeof(dqb32));
926         return (error);
927 }
928
929 int
930 setquota32(struct thread *td, struct mount *mp, u_long id, int type, void *addr)
931 {
932         struct dqblk32 dqb32;
933         struct dqblk64 dqb64;
934         int error;
935
936         error = copyin(addr, &dqb32, sizeof(dqb32));
937         if (error)
938                 return (error);
939         dqb32_dqb64(&dqb32, &dqb64);
940         error = _setquota(td, mp, id, type, &dqb64);
941         return (error);
942 }
943
944 int
945 setuse32(struct thread *td, struct mount *mp, u_long id, int type, void *addr)
946 {
947         struct dqblk32 dqb32;
948         struct dqblk64 dqb64;
949         int error;
950
951         error = copyin(addr, &dqb32, sizeof(dqb32));
952         if (error)
953                 return (error);
954         dqb32_dqb64(&dqb32, &dqb64);
955         error = _setuse(td, mp, id, type, &dqb64);
956         return (error);
957 }
958
959 int
960 getquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr)
961 {
962         struct dqblk64 dqb64;
963         int error;
964
965         error = _getquota(td, mp, id, type, &dqb64);
966         if (error)
967                 return (error);
968         error = copyout(&dqb64, addr, sizeof(dqb64));
969         return (error);
970 }
971
972 int
973 setquota(struct thread *td, struct mount *mp, u_long id, int type, void *addr)
974 {
975         struct dqblk64 dqb64;
976         int error;
977
978         error = copyin(addr, &dqb64, sizeof(dqb64));
979         if (error)
980                 return (error);
981         error = _setquota(td, mp, id, type, &dqb64);
982         return (error);
983 }
984
985 int
986 setuse(struct thread *td, struct mount *mp, u_long id, int type, void *addr)
987 {
988         struct dqblk64 dqb64;
989         int error;
990
991         error = copyin(addr, &dqb64, sizeof(dqb64));
992         if (error)
993                 return (error);
994         error = _setuse(td, mp, id, type, &dqb64);
995         return (error);
996 }
997
998 /*
999  * Q_GETQUOTASIZE - get bit-size of quota file fields
1000  */
1001 int
1002 getquotasize(struct thread *td, struct mount *mp, u_long id, int type,
1003     void *sizep)
1004 {
1005         struct ufsmount *ump = VFSTOUFS(mp);
1006         int bitsize;
1007
1008         UFS_LOCK(ump);
1009         if (ump->um_quotas[type] == NULLVP ||
1010             (ump->um_qflags[type] & QTF_CLOSING)) {
1011                 UFS_UNLOCK(ump);
1012                 return (EINVAL);
1013         }
1014         if ((ump->um_qflags[type] & QTF_64BIT) != 0)
1015                 bitsize = 64;
1016         else
1017                 bitsize = 32;
1018         UFS_UNLOCK(ump);
1019         return (copyout(&bitsize, sizep, sizeof(int)));
1020 }
1021
1022 /*
1023  * Q_SYNC - sync quota files to disk.
1024  */
1025 int
1026 qsync(struct mount *mp)
1027 {
1028         struct ufsmount *ump = VFSTOUFS(mp);
1029         struct thread *td = curthread;          /* XXX */
1030         struct vnode *vp, *mvp;
1031         struct dquot *dq;
1032         int i, error;
1033
1034         /*
1035          * Check if the mount point has any quotas.
1036          * If not, simply return.
1037          */
1038         for (i = 0; i < MAXQUOTAS; i++)
1039                 if (ump->um_quotas[i] != NULLVP)
1040                         break;
1041         if (i == MAXQUOTAS)
1042                 return (0);
1043         /*
1044          * Search vnodes associated with this mount point,
1045          * synchronizing any modified dquot structures.
1046          */
1047 again:
1048         MNT_VNODE_FOREACH_ACTIVE(vp, mp, mvp) {
1049                 if (vp->v_type == VNON) {
1050                         VI_UNLOCK(vp);
1051                         continue;
1052                 }
1053                 error = vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, td);
1054                 if (error) {
1055                         if (error == ENOENT) {
1056                                 MNT_VNODE_FOREACH_ACTIVE_ABORT(mp, mvp);
1057                                 goto again;
1058                         }
1059                         continue;
1060                 }
1061                 for (i = 0; i < MAXQUOTAS; i++) {
1062                         dq = VTOI(vp)->i_dquot[i];
1063                         if (dq != NODQUOT)
1064                                 dqsync(vp, dq);
1065                 }
1066                 vput(vp);
1067         }
1068         return (0);
1069 }
1070
1071 /*
1072  * Sync quota file for given vnode to disk.
1073  */
1074 int
1075 qsyncvp(struct vnode *vp)
1076 {
1077         struct ufsmount *ump = VFSTOUFS(vp->v_mount);
1078         struct dquot *dq;
1079         int i;
1080
1081         /*
1082          * Check if the mount point has any quotas.
1083          * If not, simply return.
1084          */
1085         for (i = 0; i < MAXQUOTAS; i++)
1086                 if (ump->um_quotas[i] != NULLVP)
1087                         break;
1088         if (i == MAXQUOTAS)
1089                 return (0);
1090         /*
1091          * Search quotas associated with this vnode
1092          * synchronizing any modified dquot structures.
1093          */
1094         for (i = 0; i < MAXQUOTAS; i++) {
1095                 dq = VTOI(vp)->i_dquot[i];
1096                 if (dq != NODQUOT)
1097                         dqsync(vp, dq);
1098         }
1099         return (0);
1100 }
1101
1102 /*
1103  * Code pertaining to management of the in-core dquot data structures.
1104  */
1105 #define DQHASH(dqvp, id) \
1106         (&dqhashtbl[((((intptr_t)(dqvp)) >> 8) + id) & dqhash])
1107 static LIST_HEAD(dqhash, dquot) *dqhashtbl;
1108 static u_long dqhash;
1109
1110 /*
1111  * Dquot free list.
1112  */
1113 #define DQUOTINC        5       /* minimum free dquots desired */
1114 static TAILQ_HEAD(dqfreelist, dquot) dqfreelist;
1115 static long numdquot, desireddquot = DQUOTINC;
1116
1117 /*
1118  * Lock to protect quota hash, dq free list and dq_cnt ref counters of
1119  * _all_ dqs.
1120  */
1121 struct mtx dqhlock;
1122
1123 #define DQH_LOCK()      mtx_lock(&dqhlock)
1124 #define DQH_UNLOCK()    mtx_unlock(&dqhlock)
1125
1126 static struct dquot *dqhashfind(struct dqhash *dqh, u_long id,
1127         struct vnode *dqvp);
1128
1129 /*
1130  * Initialize the quota system.
1131  */
1132 void
1133 dqinit(void)
1134 {
1135
1136         mtx_init(&dqhlock, "dqhlock", NULL, MTX_DEF);
1137         dqhashtbl = hashinit(desiredvnodes, M_DQUOT, &dqhash);
1138         TAILQ_INIT(&dqfreelist);
1139 }
1140
1141 /*
1142  * Shut down the quota system.
1143  */
1144 void
1145 dquninit(void)
1146 {
1147         struct dquot *dq;
1148
1149         hashdestroy(dqhashtbl, M_DQUOT, dqhash);
1150         while ((dq = TAILQ_FIRST(&dqfreelist)) != NULL) {
1151                 TAILQ_REMOVE(&dqfreelist, dq, dq_freelist);
1152                 mtx_destroy(&dq->dq_lock);
1153                 free(dq, M_DQUOT);
1154         }
1155         mtx_destroy(&dqhlock);
1156 }
1157
1158 static struct dquot *
1159 dqhashfind(struct dqhash *dqh, u_long id, struct vnode *dqvp)
1160 {
1161         struct dquot *dq;
1162
1163         mtx_assert(&dqhlock, MA_OWNED);
1164         LIST_FOREACH(dq, dqh, dq_hash) {
1165                 if (dq->dq_id != id ||
1166                     dq->dq_ump->um_quotas[dq->dq_type] != dqvp)
1167                         continue;
1168                 /*
1169                  * Cache hit with no references.  Take
1170                  * the structure off the free list.
1171                  */
1172                 if (dq->dq_cnt == 0)
1173                         TAILQ_REMOVE(&dqfreelist, dq, dq_freelist);
1174                 DQREF(dq);
1175                 return (dq);
1176         }
1177         return (NODQUOT);
1178 }
1179
1180 /*
1181  * Determine the quota file type.
1182  *
1183  * A 32-bit quota file is simply an array of struct dqblk32.
1184  *
1185  * A 64-bit quota file is a struct dqhdr64 followed by an array of struct
1186  * dqblk64.  The header contains various magic bits which allow us to be
1187  * reasonably confident that it is indeeda 64-bit quota file and not just
1188  * a 32-bit quota file that just happens to "look right".
1189  *
1190  */
1191 static int
1192 dqopen(struct vnode *vp, struct ufsmount *ump, int type)
1193 {
1194         struct dqhdr64 dqh;
1195         struct iovec aiov;
1196         struct uio auio;
1197         int error;
1198
1199         ASSERT_VOP_LOCKED(vp, "dqopen");
1200         auio.uio_iov = &aiov;
1201         auio.uio_iovcnt = 1;
1202         aiov.iov_base = &dqh;
1203         aiov.iov_len = sizeof(dqh);
1204         auio.uio_resid = sizeof(dqh);
1205         auio.uio_offset = 0;
1206         auio.uio_segflg = UIO_SYSSPACE;
1207         auio.uio_rw = UIO_READ;
1208         auio.uio_td = (struct thread *)0;
1209         error = VOP_READ(vp, &auio, 0, ump->um_cred[type]);
1210
1211         if (error != 0)
1212                 return (error);
1213         if (auio.uio_resid > 0) {
1214                 /* assume 32 bits */
1215                 return (0);
1216         }
1217
1218         UFS_LOCK(ump);
1219         if (strcmp(dqh.dqh_magic, Q_DQHDR64_MAGIC) == 0 &&
1220             be32toh(dqh.dqh_version) == Q_DQHDR64_VERSION &&
1221             be32toh(dqh.dqh_hdrlen) == (uint32_t)sizeof(struct dqhdr64) &&
1222             be32toh(dqh.dqh_reclen) == (uint32_t)sizeof(struct dqblk64)) {
1223                 /* XXX: what if the magic matches, but the sizes are wrong? */
1224                 ump->um_qflags[type] |= QTF_64BIT;
1225         } else {
1226                 ump->um_qflags[type] &= ~QTF_64BIT;
1227         }
1228         UFS_UNLOCK(ump);
1229
1230         return (0);
1231 }
1232
1233 /*
1234  * Obtain a dquot structure for the specified identifier and quota file
1235  * reading the information from the file if necessary.
1236  */
1237 static int
1238 dqget(struct vnode *vp, u_long id, struct ufsmount *ump, int type,
1239     struct dquot **dqp)
1240 {
1241         uint8_t buf[sizeof(struct dqblk64)];
1242         off_t base, recsize;
1243         struct dquot *dq, *dq1;
1244         struct dqhash *dqh;
1245         struct vnode *dqvp;
1246         struct iovec aiov;
1247         struct uio auio;
1248         int dqvplocked, error;
1249
1250 #ifdef DEBUG_VFS_LOCKS
1251         if (vp != NULLVP)
1252                 ASSERT_VOP_ELOCKED(vp, "dqget");
1253 #endif
1254
1255         if (vp != NULLVP && *dqp != NODQUOT) {
1256                 return (0);
1257         }
1258
1259         /* XXX: Disallow negative id values to prevent the
1260         * creation of 100GB+ quota data files.
1261         */
1262         if ((int)id < 0)
1263                 return (EINVAL);
1264
1265         UFS_LOCK(ump);
1266         dqvp = ump->um_quotas[type];
1267         if (dqvp == NULLVP || (ump->um_qflags[type] & QTF_CLOSING)) {
1268                 *dqp = NODQUOT;
1269                 UFS_UNLOCK(ump);
1270                 return (EINVAL);
1271         }
1272         vref(dqvp);
1273         UFS_UNLOCK(ump);
1274         error = 0;
1275         dqvplocked = 0;
1276
1277         /*
1278          * Check the cache first.
1279          */
1280         dqh = DQHASH(dqvp, id);
1281         DQH_LOCK();
1282         dq = dqhashfind(dqh, id, dqvp);
1283         if (dq != NULL) {
1284                 DQH_UNLOCK();
1285 hfound:         DQI_LOCK(dq);
1286                 DQI_WAIT(dq, PINOD+1, "dqget");
1287                 DQI_UNLOCK(dq);
1288                 if (dq->dq_ump == NULL) {
1289                         dqrele(vp, dq);
1290                         dq = NODQUOT;
1291                         error = EIO;
1292                 }
1293                 *dqp = dq;
1294                 if (dqvplocked)
1295                         vput(dqvp);
1296                 else
1297                         vrele(dqvp);
1298                 return (error);
1299         }
1300
1301         /*
1302          * Quota vnode lock is before DQ_LOCK. Acquire dqvp lock there
1303          * since new dq will appear on the hash chain DQ_LOCKed.
1304          */
1305         if (vp != dqvp) {
1306                 DQH_UNLOCK();
1307                 vn_lock(dqvp, LK_SHARED | LK_RETRY);
1308                 dqvplocked = 1;
1309                 DQH_LOCK();
1310                 /*
1311                  * Recheck the cache after sleep for quota vnode lock.
1312                  */
1313                 dq = dqhashfind(dqh, id, dqvp);
1314                 if (dq != NULL) {
1315                         DQH_UNLOCK();
1316                         goto hfound;
1317                 }
1318         }
1319
1320         /*
1321          * Not in cache, allocate a new one or take it from the
1322          * free list.
1323          */
1324         if (TAILQ_FIRST(&dqfreelist) == NODQUOT &&
1325             numdquot < MAXQUOTAS * desiredvnodes)
1326                 desireddquot += DQUOTINC;
1327         if (numdquot < desireddquot) {
1328                 numdquot++;
1329                 DQH_UNLOCK();
1330                 dq1 = malloc(sizeof *dq1, M_DQUOT, M_WAITOK | M_ZERO);
1331                 mtx_init(&dq1->dq_lock, "dqlock", NULL, MTX_DEF);
1332                 DQH_LOCK();
1333                 /*
1334                  * Recheck the cache after sleep for memory.
1335                  */
1336                 dq = dqhashfind(dqh, id, dqvp);
1337                 if (dq != NULL) {
1338                         numdquot--;
1339                         DQH_UNLOCK();
1340                         mtx_destroy(&dq1->dq_lock);
1341                         free(dq1, M_DQUOT);
1342                         goto hfound;
1343                 }
1344                 dq = dq1;
1345         } else {
1346                 if ((dq = TAILQ_FIRST(&dqfreelist)) == NULL) {
1347                         DQH_UNLOCK();
1348                         tablefull("dquot");
1349                         *dqp = NODQUOT;
1350                         if (dqvplocked)
1351                                 vput(dqvp);
1352                         else
1353                                 vrele(dqvp);
1354                         return (EUSERS);
1355                 }
1356                 if (dq->dq_cnt || (dq->dq_flags & DQ_MOD))
1357                         panic("dqget: free dquot isn't %p", dq);
1358                 TAILQ_REMOVE(&dqfreelist, dq, dq_freelist);
1359                 if (dq->dq_ump != NULL)
1360                         LIST_REMOVE(dq, dq_hash);
1361         }
1362
1363         /*
1364          * Dq is put into hash already locked to prevent parallel
1365          * usage while it is being read from file.
1366          */
1367         dq->dq_flags = DQ_LOCK;
1368         dq->dq_id = id;
1369         dq->dq_type = type;
1370         dq->dq_ump = ump;
1371         LIST_INSERT_HEAD(dqh, dq, dq_hash);
1372         DQREF(dq);
1373         DQH_UNLOCK();
1374
1375         /*
1376          * Read the requested quota record from the quota file, performing
1377          * any necessary conversions.
1378          */
1379         if (ump->um_qflags[type] & QTF_64BIT) {
1380                 recsize = sizeof(struct dqblk64);
1381                 base = sizeof(struct dqhdr64);
1382         } else {
1383                 recsize = sizeof(struct dqblk32);
1384                 base = 0;
1385         }
1386         auio.uio_iov = &aiov;
1387         auio.uio_iovcnt = 1;
1388         aiov.iov_base = buf;
1389         aiov.iov_len = recsize;
1390         auio.uio_resid = recsize;
1391         auio.uio_offset = base + id * recsize;
1392         auio.uio_segflg = UIO_SYSSPACE;
1393         auio.uio_rw = UIO_READ;
1394         auio.uio_td = (struct thread *)0;
1395
1396         error = VOP_READ(dqvp, &auio, 0, ump->um_cred[type]);
1397         if (auio.uio_resid == recsize && error == 0) {
1398                 bzero(&dq->dq_dqb, sizeof(dq->dq_dqb));
1399         } else {
1400                 if (ump->um_qflags[type] & QTF_64BIT)
1401                         dqb64_dq((struct dqblk64 *)buf, dq);
1402                 else
1403                         dqb32_dq((struct dqblk32 *)buf, dq);
1404         }
1405         if (dqvplocked)
1406                 vput(dqvp);
1407         else
1408                 vrele(dqvp);
1409         /*
1410          * I/O error in reading quota file, release
1411          * quota structure and reflect problem to caller.
1412          */
1413         if (error) {
1414                 DQH_LOCK();
1415                 dq->dq_ump = NULL;
1416                 LIST_REMOVE(dq, dq_hash);
1417                 DQH_UNLOCK();
1418                 DQI_LOCK(dq);
1419                 if (dq->dq_flags & DQ_WANT)
1420                         wakeup(dq);
1421                 dq->dq_flags = 0;
1422                 DQI_UNLOCK(dq);
1423                 dqrele(vp, dq);
1424                 *dqp = NODQUOT;
1425                 return (error);
1426         }
1427         DQI_LOCK(dq);
1428         /*
1429          * Check for no limit to enforce.
1430          * Initialize time values if necessary.
1431          */
1432         if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0 &&
1433             dq->dq_ihardlimit == 0 && dq->dq_bhardlimit == 0)
1434                 dq->dq_flags |= DQ_FAKE;
1435         if (dq->dq_id != 0) {
1436                 if (dq->dq_btime == 0) {
1437                         dq->dq_btime = time_second + ump->um_btime[type];
1438                         if (dq->dq_bsoftlimit &&
1439                             dq->dq_curblocks >= dq->dq_bsoftlimit)
1440                                 dq->dq_flags |= DQ_MOD;
1441                 }
1442                 if (dq->dq_itime == 0) {
1443                         dq->dq_itime = time_second + ump->um_itime[type];
1444                         if (dq->dq_isoftlimit &&
1445                             dq->dq_curinodes >= dq->dq_isoftlimit)
1446                                 dq->dq_flags |= DQ_MOD;
1447                 }
1448         }
1449         DQI_WAKEUP(dq);
1450         DQI_UNLOCK(dq);
1451         *dqp = dq;
1452         return (0);
1453 }
1454
1455 #ifdef DIAGNOSTIC
1456 /*
1457  * Obtain a reference to a dquot.
1458  */
1459 static void
1460 dqref(struct dquot *dq)
1461 {
1462
1463         dq->dq_cnt++;
1464 }
1465 #endif
1466
1467 /*
1468  * Release a reference to a dquot.
1469  */
1470 void
1471 dqrele(struct vnode *vp, struct dquot *dq)
1472 {
1473
1474         if (dq == NODQUOT)
1475                 return;
1476         DQH_LOCK();
1477         KASSERT(dq->dq_cnt > 0, ("Lost dq %p reference 1", dq));
1478         if (dq->dq_cnt > 1) {
1479                 dq->dq_cnt--;
1480                 DQH_UNLOCK();
1481                 return;
1482         }
1483         DQH_UNLOCK();
1484 sync:
1485         (void) dqsync(vp, dq);
1486
1487         DQH_LOCK();
1488         KASSERT(dq->dq_cnt > 0, ("Lost dq %p reference 2", dq));
1489         if (--dq->dq_cnt > 0)
1490         {
1491                 DQH_UNLOCK();
1492                 return;
1493         }
1494
1495         /*
1496          * The dq may become dirty after it is synced but before it is
1497          * put to the free list. Checking the DQ_MOD there without
1498          * locking dq should be safe since no other references to the
1499          * dq exist.
1500          */
1501         if ((dq->dq_flags & DQ_MOD) != 0) {
1502                 dq->dq_cnt++;
1503                 DQH_UNLOCK();
1504                 goto sync;
1505         }
1506         TAILQ_INSERT_TAIL(&dqfreelist, dq, dq_freelist);
1507         DQH_UNLOCK();
1508 }
1509
1510 /*
1511  * Update the disk quota in the quota file.
1512  */
1513 static int
1514 dqsync(struct vnode *vp, struct dquot *dq)
1515 {
1516         uint8_t buf[sizeof(struct dqblk64)];
1517         off_t base, recsize;
1518         struct vnode *dqvp;
1519         struct iovec aiov;
1520         struct uio auio;
1521         int error;
1522         struct mount *mp;
1523         struct ufsmount *ump;
1524
1525 #ifdef DEBUG_VFS_LOCKS
1526         if (vp != NULL)
1527                 ASSERT_VOP_ELOCKED(vp, "dqsync");
1528 #endif
1529
1530         mp = NULL;
1531         error = 0;
1532         if (dq == NODQUOT)
1533                 panic("dqsync: dquot");
1534         if ((ump = dq->dq_ump) == NULL)
1535                 return (0);
1536         UFS_LOCK(ump);
1537         if ((dqvp = ump->um_quotas[dq->dq_type]) == NULLVP)
1538                 panic("dqsync: file");
1539         vref(dqvp);
1540         UFS_UNLOCK(ump);
1541
1542         DQI_LOCK(dq);
1543         if ((dq->dq_flags & DQ_MOD) == 0) {
1544                 DQI_UNLOCK(dq);
1545                 vrele(dqvp);
1546                 return (0);
1547         }
1548         DQI_UNLOCK(dq);
1549
1550         (void) vn_start_secondary_write(dqvp, &mp, V_WAIT);
1551         if (vp != dqvp)
1552                 vn_lock(dqvp, LK_EXCLUSIVE | LK_RETRY);
1553
1554         DQI_LOCK(dq);
1555         DQI_WAIT(dq, PINOD+2, "dqsync");
1556         if ((dq->dq_flags & DQ_MOD) == 0)
1557                 goto out;
1558         dq->dq_flags |= DQ_LOCK;
1559         DQI_UNLOCK(dq);
1560
1561         /*
1562          * Write the quota record to the quota file, performing any
1563          * necessary conversions.  See dqget() for additional details.
1564          */
1565         if (ump->um_qflags[dq->dq_type] & QTF_64BIT) {
1566                 dq_dqb64(dq, (struct dqblk64 *)buf);
1567                 recsize = sizeof(struct dqblk64);
1568                 base = sizeof(struct dqhdr64);
1569         } else {
1570                 dq_dqb32(dq, (struct dqblk32 *)buf);
1571                 recsize = sizeof(struct dqblk32);
1572                 base = 0;
1573         }
1574
1575         auio.uio_iov = &aiov;
1576         auio.uio_iovcnt = 1;
1577         aiov.iov_base = buf;
1578         aiov.iov_len = recsize;
1579         auio.uio_resid = recsize;
1580         auio.uio_offset = base + dq->dq_id * recsize;
1581         auio.uio_segflg = UIO_SYSSPACE;
1582         auio.uio_rw = UIO_WRITE;
1583         auio.uio_td = (struct thread *)0;
1584         error = VOP_WRITE(dqvp, &auio, 0, dq->dq_ump->um_cred[dq->dq_type]);
1585         if (auio.uio_resid && error == 0)
1586                 error = EIO;
1587
1588         DQI_LOCK(dq);
1589         DQI_WAKEUP(dq);
1590         dq->dq_flags &= ~DQ_MOD;
1591 out:
1592         DQI_UNLOCK(dq);
1593         if (vp != dqvp)
1594                 vput(dqvp);
1595         else
1596                 vrele(dqvp);
1597         vn_finished_secondary_write(mp);
1598         return (error);
1599 }
1600
1601 /*
1602  * Flush all entries from the cache for a particular vnode.
1603  */
1604 static int
1605 dqflush(struct vnode *vp)
1606 {
1607         struct dquot *dq, *nextdq;
1608         struct dqhash *dqh;
1609         int error;
1610
1611         /*
1612          * Move all dquot's that used to refer to this quota
1613          * file off their hash chains (they will eventually
1614          * fall off the head of the free list and be re-used).
1615          */
1616         error = 0;
1617         DQH_LOCK();
1618         for (dqh = &dqhashtbl[dqhash]; dqh >= dqhashtbl; dqh--) {
1619                 for (dq = LIST_FIRST(dqh); dq; dq = nextdq) {
1620                         nextdq = LIST_NEXT(dq, dq_hash);
1621                         if (dq->dq_ump->um_quotas[dq->dq_type] != vp)
1622                                 continue;
1623                         if (dq->dq_cnt)
1624                                 error = EBUSY;
1625                         else {
1626                                 LIST_REMOVE(dq, dq_hash);
1627                                 dq->dq_ump = NULL;
1628                         }
1629                 }
1630         }
1631         DQH_UNLOCK();
1632         return (error);
1633 }
1634
1635 /*
1636  * The following three functions are provided for the adjustment of
1637  * quotas by the soft updates code.
1638  */
1639 #ifdef SOFTUPDATES
1640 /*
1641  * Acquire a reference to the quota structures associated with a vnode.
1642  * Return count of number of quota structures found.
1643  */
1644 int
1645 quotaref(vp, qrp)
1646         struct vnode *vp;
1647         struct dquot **qrp;
1648 {
1649         struct inode *ip;
1650         struct dquot *dq;
1651         int i, found;
1652
1653         for (i = 0; i < MAXQUOTAS; i++)
1654                 qrp[i] = NODQUOT;
1655         /*
1656          * Disk quotas must be turned off for system files.  Currently
1657          * snapshot and quota files.
1658          */
1659         if ((vp->v_vflag & VV_SYSTEM) != 0)
1660                 return (0);
1661         /*
1662          * Iterate through and copy active quotas.
1663          */
1664         found = 0;
1665         ip = VTOI(vp);
1666         mtx_lock(&dqhlock);
1667         for (i = 0; i < MAXQUOTAS; i++) {
1668                 if ((dq = ip->i_dquot[i]) == NODQUOT)
1669                         continue;
1670                 DQREF(dq);
1671                 qrp[i] = dq;
1672                 found++;
1673         }
1674         mtx_unlock(&dqhlock);
1675         return (found);
1676 }
1677
1678 /*
1679  * Release a set of quota structures obtained from a vnode.
1680  */
1681 void
1682 quotarele(qrp)
1683         struct dquot **qrp;
1684 {
1685         struct dquot *dq;
1686         int i;
1687
1688         for (i = 0; i < MAXQUOTAS; i++) {
1689                 if ((dq = qrp[i]) == NODQUOT)
1690                         continue;
1691                 dqrele(NULL, dq);
1692         }
1693 }
1694
1695 /*
1696  * Adjust the number of blocks associated with a quota.
1697  * Positive numbers when adding blocks; negative numbers when freeing blocks.
1698  */
1699 void
1700 quotaadj(qrp, ump, blkcount)
1701         struct dquot **qrp;
1702         struct ufsmount *ump;
1703         int64_t blkcount;
1704 {
1705         struct dquot *dq;
1706         ufs2_daddr_t ncurblocks;
1707         int i;
1708
1709         if (blkcount == 0)
1710                 return;
1711         for (i = 0; i < MAXQUOTAS; i++) {
1712                 if ((dq = qrp[i]) == NODQUOT)
1713                         continue;
1714                 DQI_LOCK(dq);
1715                 DQI_WAIT(dq, PINOD+1, "adjqta");
1716                 ncurblocks = dq->dq_curblocks + blkcount;
1717                 if (ncurblocks >= 0)
1718                         dq->dq_curblocks = ncurblocks;
1719                 else
1720                         dq->dq_curblocks = 0;
1721                 if (blkcount < 0)
1722                         dq->dq_flags &= ~DQ_BLKS;
1723                 else if (dq->dq_curblocks + blkcount >= dq->dq_bsoftlimit &&
1724                          dq->dq_curblocks < dq->dq_bsoftlimit)
1725                         dq->dq_btime = time_second + ump->um_btime[i];
1726                 dq->dq_flags |= DQ_MOD;
1727                 DQI_UNLOCK(dq);
1728         }
1729 }
1730 #endif /* SOFTUPDATES */
1731
1732 /*
1733  * 32-bit / 64-bit conversion functions.
1734  *
1735  * 32-bit quota records are stored in native byte order.  Attention must
1736  * be paid to overflow issues.
1737  *
1738  * 64-bit quota records are stored in network byte order.
1739  */
1740
1741 #define CLIP32(u64) (u64 > UINT32_MAX ? UINT32_MAX : (uint32_t)u64)
1742
1743 /*
1744  * Convert 32-bit host-order structure to dquot.
1745  */
1746 static void
1747 dqb32_dq(const struct dqblk32 *dqb32, struct dquot *dq)
1748 {
1749
1750         dq->dq_bhardlimit = dqb32->dqb_bhardlimit;
1751         dq->dq_bsoftlimit = dqb32->dqb_bsoftlimit;
1752         dq->dq_curblocks = dqb32->dqb_curblocks;
1753         dq->dq_ihardlimit = dqb32->dqb_ihardlimit;
1754         dq->dq_isoftlimit = dqb32->dqb_isoftlimit;
1755         dq->dq_curinodes = dqb32->dqb_curinodes;
1756         dq->dq_btime = dqb32->dqb_btime;
1757         dq->dq_itime = dqb32->dqb_itime;
1758 }
1759
1760 /*
1761  * Convert 64-bit network-order structure to dquot.
1762  */
1763 static void
1764 dqb64_dq(const struct dqblk64 *dqb64, struct dquot *dq)
1765 {
1766
1767         dq->dq_bhardlimit = be64toh(dqb64->dqb_bhardlimit);
1768         dq->dq_bsoftlimit = be64toh(dqb64->dqb_bsoftlimit);
1769         dq->dq_curblocks = be64toh(dqb64->dqb_curblocks);
1770         dq->dq_ihardlimit = be64toh(dqb64->dqb_ihardlimit);
1771         dq->dq_isoftlimit = be64toh(dqb64->dqb_isoftlimit);
1772         dq->dq_curinodes = be64toh(dqb64->dqb_curinodes);
1773         dq->dq_btime = be64toh(dqb64->dqb_btime);
1774         dq->dq_itime = be64toh(dqb64->dqb_itime);
1775 }
1776
1777 /*
1778  * Convert dquot to 32-bit host-order structure.
1779  */
1780 static void
1781 dq_dqb32(const struct dquot *dq, struct dqblk32 *dqb32)
1782 {
1783
1784         dqb32->dqb_bhardlimit = CLIP32(dq->dq_bhardlimit);
1785         dqb32->dqb_bsoftlimit = CLIP32(dq->dq_bsoftlimit);
1786         dqb32->dqb_curblocks = CLIP32(dq->dq_curblocks);
1787         dqb32->dqb_ihardlimit = CLIP32(dq->dq_ihardlimit);
1788         dqb32->dqb_isoftlimit = CLIP32(dq->dq_isoftlimit);
1789         dqb32->dqb_curinodes = CLIP32(dq->dq_curinodes);
1790         dqb32->dqb_btime = CLIP32(dq->dq_btime);
1791         dqb32->dqb_itime = CLIP32(dq->dq_itime);
1792 }
1793
1794 /*
1795  * Convert dquot to 64-bit network-order structure.
1796  */
1797 static void
1798 dq_dqb64(const struct dquot *dq, struct dqblk64 *dqb64)
1799 {
1800
1801         dqb64->dqb_bhardlimit = htobe64(dq->dq_bhardlimit);
1802         dqb64->dqb_bsoftlimit = htobe64(dq->dq_bsoftlimit);
1803         dqb64->dqb_curblocks = htobe64(dq->dq_curblocks);
1804         dqb64->dqb_ihardlimit = htobe64(dq->dq_ihardlimit);
1805         dqb64->dqb_isoftlimit = htobe64(dq->dq_isoftlimit);
1806         dqb64->dqb_curinodes = htobe64(dq->dq_curinodes);
1807         dqb64->dqb_btime = htobe64(dq->dq_btime);
1808         dqb64->dqb_itime = htobe64(dq->dq_itime);
1809 }
1810
1811 /*
1812  * Convert 64-bit host-order structure to 32-bit host-order structure.
1813  */
1814 static void
1815 dqb64_dqb32(const struct dqblk64 *dqb64, struct dqblk32 *dqb32)
1816 {
1817
1818         dqb32->dqb_bhardlimit = CLIP32(dqb64->dqb_bhardlimit);
1819         dqb32->dqb_bsoftlimit = CLIP32(dqb64->dqb_bsoftlimit);
1820         dqb32->dqb_curblocks = CLIP32(dqb64->dqb_curblocks);
1821         dqb32->dqb_ihardlimit = CLIP32(dqb64->dqb_ihardlimit);
1822         dqb32->dqb_isoftlimit = CLIP32(dqb64->dqb_isoftlimit);
1823         dqb32->dqb_curinodes = CLIP32(dqb64->dqb_curinodes);
1824         dqb32->dqb_btime = CLIP32(dqb64->dqb_btime);
1825         dqb32->dqb_itime = CLIP32(dqb64->dqb_itime);
1826 }
1827
1828 /*
1829  * Convert 32-bit host-order structure to 64-bit host-order structure.
1830  */
1831 static void
1832 dqb32_dqb64(const struct dqblk32 *dqb32, struct dqblk64 *dqb64)
1833 {
1834
1835         dqb64->dqb_bhardlimit = dqb32->dqb_bhardlimit;
1836         dqb64->dqb_bsoftlimit = dqb32->dqb_bsoftlimit;
1837         dqb64->dqb_curblocks = dqb32->dqb_curblocks;
1838         dqb64->dqb_ihardlimit = dqb32->dqb_ihardlimit;
1839         dqb64->dqb_isoftlimit = dqb32->dqb_isoftlimit;
1840         dqb64->dqb_curinodes = dqb32->dqb_curinodes;
1841         dqb64->dqb_btime = dqb32->dqb_btime;
1842         dqb64->dqb_itime = dqb32->dqb_itime;
1843 }