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