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