1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 7 8 #include "xfs.h" 9 #include "xfs_fs.h" 10 #include "xfs_shared.h" 11 #include "xfs_format.h" 12 #include "xfs_log_format.h" 13 #include "xfs_trans_resv.h" 14 #include "xfs_sb.h" 15 #include "xfs_mount.h" 16 #include "xfs_inode.h" 17 #include "xfs_trans.h" 18 #include "xfs_quota.h" 19 #include "xfs_qm.h" 20 #include "xfs_icache.h" 21 22 STATIC int 23 xfs_qm_log_quotaoff( 24 struct xfs_mount *mp, 25 struct xfs_qoff_logitem **qoffstartp, 26 uint flags) 27 { 28 struct xfs_trans *tp; 29 int error; 30 struct xfs_qoff_logitem *qoffi; 31 32 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp); 33 if (error) 34 goto out; 35 36 qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); 37 xfs_trans_log_quotaoff_item(tp, qoffi); 38 39 spin_lock(&mp->m_sb_lock); 40 mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; 41 spin_unlock(&mp->m_sb_lock); 42 43 xfs_log_sb(tp); 44 45 /* 46 * We have to make sure that the transaction is secure on disk before we 47 * return and actually stop quota accounting. So, make it synchronous. 48 * We don't care about quotoff's performance. 49 */ 50 xfs_trans_set_sync(tp); 51 error = xfs_trans_commit(tp); 52 if (error) 53 goto out; 54 55 *qoffstartp = qoffi; 56 out: 57 return error; 58 } 59 60 STATIC int 61 xfs_qm_log_quotaoff_end( 62 struct xfs_mount *mp, 63 struct xfs_qoff_logitem **startqoff, 64 uint flags) 65 { 66 struct xfs_trans *tp; 67 int error; 68 struct xfs_qoff_logitem *qoffi; 69 70 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp); 71 if (error) 72 return error; 73 74 qoffi = xfs_trans_get_qoff_item(tp, *startqoff, 75 flags & XFS_ALL_QUOTA_ACCT); 76 xfs_trans_log_quotaoff_item(tp, qoffi); 77 *startqoff = NULL; 78 79 /* 80 * We have to make sure that the transaction is secure on disk before we 81 * return and actually stop quota accounting. So, make it synchronous. 82 * We don't care about quotoff's performance. 83 */ 84 xfs_trans_set_sync(tp); 85 return xfs_trans_commit(tp); 86 } 87 88 /* 89 * Turn off quota accounting and/or enforcement for all udquots and/or 90 * gdquots. Called only at unmount time. 91 * 92 * This assumes that there are no dquots of this file system cached 93 * incore, and modifies the ondisk dquot directly. Therefore, for example, 94 * it is an error to call this twice, without purging the cache. 95 */ 96 int 97 xfs_qm_scall_quotaoff( 98 xfs_mount_t *mp, 99 uint flags) 100 { 101 struct xfs_quotainfo *q = mp->m_quotainfo; 102 uint dqtype; 103 int error; 104 uint inactivate_flags; 105 struct xfs_qoff_logitem *qoffstart = NULL; 106 107 /* 108 * No file system can have quotas enabled on disk but not in core. 109 * Note that quota utilities (like quotaoff) _expect_ 110 * errno == -EEXIST here. 111 */ 112 if ((mp->m_qflags & flags) == 0) 113 return -EEXIST; 114 error = 0; 115 116 flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); 117 118 /* 119 * We don't want to deal with two quotaoffs messing up each other, 120 * so we're going to serialize it. quotaoff isn't exactly a performance 121 * critical thing. 122 * If quotaoff, then we must be dealing with the root filesystem. 123 */ 124 ASSERT(q); 125 mutex_lock(&q->qi_quotaofflock); 126 127 /* 128 * If we're just turning off quota enforcement, change mp and go. 129 */ 130 if ((flags & XFS_ALL_QUOTA_ACCT) == 0) { 131 mp->m_qflags &= ~(flags); 132 133 spin_lock(&mp->m_sb_lock); 134 mp->m_sb.sb_qflags = mp->m_qflags; 135 spin_unlock(&mp->m_sb_lock); 136 mutex_unlock(&q->qi_quotaofflock); 137 138 /* XXX what to do if error ? Revert back to old vals incore ? */ 139 return xfs_sync_sb(mp, false); 140 } 141 142 dqtype = 0; 143 inactivate_flags = 0; 144 /* 145 * If accounting is off, we must turn enforcement off, clear the 146 * quota 'CHKD' certificate to make it known that we have to 147 * do a quotacheck the next time this quota is turned on. 148 */ 149 if (flags & XFS_UQUOTA_ACCT) { 150 dqtype |= XFS_QMOPT_UQUOTA; 151 flags |= (XFS_UQUOTA_CHKD | XFS_UQUOTA_ENFD); 152 inactivate_flags |= XFS_UQUOTA_ACTIVE; 153 } 154 if (flags & XFS_GQUOTA_ACCT) { 155 dqtype |= XFS_QMOPT_GQUOTA; 156 flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD); 157 inactivate_flags |= XFS_GQUOTA_ACTIVE; 158 } 159 if (flags & XFS_PQUOTA_ACCT) { 160 dqtype |= XFS_QMOPT_PQUOTA; 161 flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD); 162 inactivate_flags |= XFS_PQUOTA_ACTIVE; 163 } 164 165 /* 166 * Nothing to do? Don't complain. This happens when we're just 167 * turning off quota enforcement. 168 */ 169 if ((mp->m_qflags & flags) == 0) 170 goto out_unlock; 171 172 /* 173 * Write the LI_QUOTAOFF log record, and do SB changes atomically, 174 * and synchronously. If we fail to write, we should abort the 175 * operation as it cannot be recovered safely if we crash. 176 */ 177 error = xfs_qm_log_quotaoff(mp, &qoffstart, flags); 178 if (error) 179 goto out_unlock; 180 181 /* 182 * Next we clear the XFS_MOUNT_*DQ_ACTIVE bit(s) in the mount struct 183 * to take care of the race between dqget and quotaoff. We don't take 184 * any special locks to reset these bits. All processes need to check 185 * these bits *after* taking inode lock(s) to see if the particular 186 * quota type is in the process of being turned off. If *ACTIVE, it is 187 * guaranteed that all dquot structures and all quotainode ptrs will all 188 * stay valid as long as that inode is kept locked. 189 * 190 * There is no turning back after this. 191 */ 192 mp->m_qflags &= ~inactivate_flags; 193 194 /* 195 * Give back all the dquot reference(s) held by inodes. 196 * Here we go thru every single incore inode in this file system, and 197 * do a dqrele on the i_udquot/i_gdquot that it may have. 198 * Essentially, as long as somebody has an inode locked, this guarantees 199 * that quotas will not be turned off. This is handy because in a 200 * transaction once we lock the inode(s) and check for quotaon, we can 201 * depend on the quota inodes (and other things) being valid as long as 202 * we keep the lock(s). 203 */ 204 xfs_qm_dqrele_all_inodes(mp, flags); 205 206 /* 207 * Next we make the changes in the quota flag in the mount struct. 208 * This isn't protected by a particular lock directly, because we 209 * don't want to take a mrlock every time we depend on quotas being on. 210 */ 211 mp->m_qflags &= ~flags; 212 213 /* 214 * Go through all the dquots of this file system and purge them, 215 * according to what was turned off. 216 */ 217 xfs_qm_dqpurge_all(mp, dqtype); 218 219 /* 220 * Transactions that had started before ACTIVE state bit was cleared 221 * could have logged many dquots, so they'd have higher LSNs than 222 * the first QUOTAOFF log record does. If we happen to crash when 223 * the tail of the log has gone past the QUOTAOFF record, but 224 * before the last dquot modification, those dquots __will__ 225 * recover, and that's not good. 226 * 227 * So, we have QUOTAOFF start and end logitems; the start 228 * logitem won't get overwritten until the end logitem appears... 229 */ 230 error = xfs_qm_log_quotaoff_end(mp, &qoffstart, flags); 231 if (error) { 232 /* We're screwed now. Shutdown is the only option. */ 233 xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); 234 goto out_unlock; 235 } 236 237 /* 238 * If all quotas are completely turned off, close shop. 239 */ 240 if (mp->m_qflags == 0) { 241 mutex_unlock(&q->qi_quotaofflock); 242 xfs_qm_destroy_quotainfo(mp); 243 return 0; 244 } 245 246 /* 247 * Release our quotainode references if we don't need them anymore. 248 */ 249 if ((dqtype & XFS_QMOPT_UQUOTA) && q->qi_uquotaip) { 250 xfs_irele(q->qi_uquotaip); 251 q->qi_uquotaip = NULL; 252 } 253 if ((dqtype & XFS_QMOPT_GQUOTA) && q->qi_gquotaip) { 254 xfs_irele(q->qi_gquotaip); 255 q->qi_gquotaip = NULL; 256 } 257 if ((dqtype & XFS_QMOPT_PQUOTA) && q->qi_pquotaip) { 258 xfs_irele(q->qi_pquotaip); 259 q->qi_pquotaip = NULL; 260 } 261 262 out_unlock: 263 if (error && qoffstart) 264 xfs_qm_qoff_logitem_relse(qoffstart); 265 mutex_unlock(&q->qi_quotaofflock); 266 return error; 267 } 268 269 STATIC int 270 xfs_qm_scall_trunc_qfile( 271 struct xfs_mount *mp, 272 xfs_ino_t ino) 273 { 274 struct xfs_inode *ip; 275 struct xfs_trans *tp; 276 int error; 277 278 if (ino == NULLFSINO) 279 return 0; 280 281 error = xfs_iget(mp, NULL, ino, 0, 0, &ip); 282 if (error) 283 return error; 284 285 xfs_ilock(ip, XFS_IOLOCK_EXCL); 286 287 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); 288 if (error) { 289 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 290 goto out_put; 291 } 292 293 xfs_ilock(ip, XFS_ILOCK_EXCL); 294 xfs_trans_ijoin(tp, ip, 0); 295 296 ip->i_d.di_size = 0; 297 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 298 299 error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); 300 if (error) { 301 xfs_trans_cancel(tp); 302 goto out_unlock; 303 } 304 305 ASSERT(ip->i_df.if_nextents == 0); 306 307 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 308 error = xfs_trans_commit(tp); 309 310 out_unlock: 311 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); 312 out_put: 313 xfs_irele(ip); 314 return error; 315 } 316 317 int 318 xfs_qm_scall_trunc_qfiles( 319 xfs_mount_t *mp, 320 uint flags) 321 { 322 int error = -EINVAL; 323 324 if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0 || 325 (flags & ~XFS_QMOPT_QUOTALL)) { 326 xfs_debug(mp, "%s: flags=%x m_qflags=%x", 327 __func__, flags, mp->m_qflags); 328 return -EINVAL; 329 } 330 331 if (flags & XFS_QMOPT_UQUOTA) { 332 error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino); 333 if (error) 334 return error; 335 } 336 if (flags & XFS_QMOPT_GQUOTA) { 337 error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino); 338 if (error) 339 return error; 340 } 341 if (flags & XFS_QMOPT_PQUOTA) 342 error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino); 343 344 return error; 345 } 346 347 /* 348 * Switch on (a given) quota enforcement for a filesystem. This takes 349 * effect immediately. 350 * (Switching on quota accounting must be done at mount time.) 351 */ 352 int 353 xfs_qm_scall_quotaon( 354 xfs_mount_t *mp, 355 uint flags) 356 { 357 int error; 358 uint qf; 359 360 /* 361 * Switching on quota accounting must be done at mount time, 362 * only consider quota enforcement stuff here. 363 */ 364 flags &= XFS_ALL_QUOTA_ENFD; 365 366 if (flags == 0) { 367 xfs_debug(mp, "%s: zero flags, m_qflags=%x", 368 __func__, mp->m_qflags); 369 return -EINVAL; 370 } 371 372 /* 373 * Can't enforce without accounting. We check the superblock 374 * qflags here instead of m_qflags because rootfs can have 375 * quota acct on ondisk without m_qflags' knowing. 376 */ 377 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && 378 (flags & XFS_UQUOTA_ENFD)) || 379 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && 380 (flags & XFS_GQUOTA_ENFD)) || 381 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 && 382 (flags & XFS_PQUOTA_ENFD))) { 383 xfs_debug(mp, 384 "%s: Can't enforce without acct, flags=%x sbflags=%x", 385 __func__, flags, mp->m_sb.sb_qflags); 386 return -EINVAL; 387 } 388 /* 389 * If everything's up to-date incore, then don't waste time. 390 */ 391 if ((mp->m_qflags & flags) == flags) 392 return -EEXIST; 393 394 /* 395 * Change sb_qflags on disk but not incore mp->qflags 396 * if this is the root filesystem. 397 */ 398 spin_lock(&mp->m_sb_lock); 399 qf = mp->m_sb.sb_qflags; 400 mp->m_sb.sb_qflags = qf | flags; 401 spin_unlock(&mp->m_sb_lock); 402 403 /* 404 * There's nothing to change if it's the same. 405 */ 406 if ((qf & flags) == flags) 407 return -EEXIST; 408 409 error = xfs_sync_sb(mp, false); 410 if (error) 411 return error; 412 /* 413 * If we aren't trying to switch on quota enforcement, we are done. 414 */ 415 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != 416 (mp->m_qflags & XFS_UQUOTA_ACCT)) || 417 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) != 418 (mp->m_qflags & XFS_PQUOTA_ACCT)) || 419 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) != 420 (mp->m_qflags & XFS_GQUOTA_ACCT))) 421 return 0; 422 423 if (! XFS_IS_QUOTA_RUNNING(mp)) 424 return -ESRCH; 425 426 /* 427 * Switch on quota enforcement in core. 428 */ 429 mutex_lock(&mp->m_quotainfo->qi_quotaofflock); 430 mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD); 431 mutex_unlock(&mp->m_quotainfo->qi_quotaofflock); 432 433 return 0; 434 } 435 436 #define XFS_QC_MASK \ 437 (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) 438 439 /* 440 * Adjust limits of this quota, and the defaults if passed in. Returns true 441 * if the new limits made sense and were applied, false otherwise. 442 */ 443 static inline bool 444 xfs_setqlim_limits( 445 struct xfs_mount *mp, 446 struct xfs_dquot_res *res, 447 struct xfs_quota_limits *qlim, 448 xfs_qcnt_t hard, 449 xfs_qcnt_t soft, 450 const char *tag) 451 { 452 /* The hard limit can't be less than the soft limit. */ 453 if (hard != 0 && hard < soft) { 454 xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag, 455 soft); 456 return false; 457 } 458 459 res->hardlimit = hard; 460 res->softlimit = soft; 461 if (qlim) { 462 qlim->hard = hard; 463 qlim->soft = soft; 464 } 465 466 return true; 467 } 468 469 static inline void 470 xfs_setqlim_warns( 471 struct xfs_dquot_res *res, 472 struct xfs_quota_limits *qlim, 473 int warns) 474 { 475 res->warnings = warns; 476 if (qlim) 477 qlim->warn = warns; 478 } 479 480 static inline void 481 xfs_setqlim_timer( 482 struct xfs_mount *mp, 483 struct xfs_dquot_res *res, 484 struct xfs_quota_limits *qlim, 485 s64 timer) 486 { 487 if (qlim) { 488 /* Set the length of the default grace period. */ 489 res->timer = xfs_dquot_set_grace_period(timer); 490 qlim->time = res->timer; 491 } else { 492 /* Set the grace period expiration on a quota. */ 493 res->timer = xfs_dquot_set_timeout(mp, timer); 494 } 495 } 496 497 /* 498 * Adjust quota limits, and start/stop timers accordingly. 499 */ 500 int 501 xfs_qm_scall_setqlim( 502 struct xfs_mount *mp, 503 xfs_dqid_t id, 504 xfs_dqtype_t type, 505 struct qc_dqblk *newlim) 506 { 507 struct xfs_quotainfo *q = mp->m_quotainfo; 508 struct xfs_dquot *dqp; 509 struct xfs_trans *tp; 510 struct xfs_def_quota *defq; 511 struct xfs_dquot_res *res; 512 struct xfs_quota_limits *qlim; 513 int error; 514 xfs_qcnt_t hard, soft; 515 516 if (newlim->d_fieldmask & ~XFS_QC_MASK) 517 return -EINVAL; 518 if ((newlim->d_fieldmask & XFS_QC_MASK) == 0) 519 return 0; 520 521 /* 522 * We don't want to race with a quotaoff so take the quotaoff lock. 523 * We don't hold an inode lock, so there's nothing else to stop 524 * a quotaoff from happening. 525 */ 526 mutex_lock(&q->qi_quotaofflock); 527 528 /* 529 * Get the dquot (locked) before we start, as we need to do a 530 * transaction to allocate it if it doesn't exist. Once we have the 531 * dquot, unlock it so we can start the next transaction safely. We hold 532 * a reference to the dquot, so it's safe to do this unlock/lock without 533 * it being reclaimed in the mean time. 534 */ 535 error = xfs_qm_dqget(mp, id, type, true, &dqp); 536 if (error) { 537 ASSERT(error != -ENOENT); 538 goto out_unlock; 539 } 540 541 defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); 542 xfs_dqunlock(dqp); 543 544 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp); 545 if (error) 546 goto out_rele; 547 548 xfs_dqlock(dqp); 549 xfs_trans_dqjoin(tp, dqp); 550 551 /* 552 * Update quota limits, warnings, and timers, and the defaults 553 * if we're touching id == 0. 554 * 555 * Make sure that hardlimits are >= soft limits before changing. 556 * 557 * Update warnings counter(s) if requested. 558 * 559 * Timelimits for the super user set the relative time the other users 560 * can be over quota for this file system. If it is zero a default is 561 * used. Ditto for the default soft and hard limit values (already 562 * done, above), and for warnings. 563 * 564 * For other IDs, userspace can bump out the grace period if over 565 * the soft limit. 566 */ 567 568 /* Blocks on the data device. */ 569 hard = (newlim->d_fieldmask & QC_SPC_HARD) ? 570 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : 571 dqp->q_blk.hardlimit; 572 soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? 573 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : 574 dqp->q_blk.softlimit; 575 res = &dqp->q_blk; 576 qlim = id == 0 ? &defq->blk : NULL; 577 578 if (xfs_setqlim_limits(mp, res, qlim, hard, soft, "blk")) 579 xfs_dquot_set_prealloc_limits(dqp); 580 if (newlim->d_fieldmask & QC_SPC_WARNS) 581 xfs_setqlim_warns(res, qlim, newlim->d_spc_warns); 582 if (newlim->d_fieldmask & QC_SPC_TIMER) 583 xfs_setqlim_timer(mp, res, qlim, newlim->d_spc_timer); 584 585 /* Blocks on the realtime device. */ 586 hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? 587 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : 588 dqp->q_rtb.hardlimit; 589 soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? 590 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : 591 dqp->q_rtb.softlimit; 592 res = &dqp->q_rtb; 593 qlim = id == 0 ? &defq->rtb : NULL; 594 595 xfs_setqlim_limits(mp, res, qlim, hard, soft, "rtb"); 596 if (newlim->d_fieldmask & QC_RT_SPC_WARNS) 597 xfs_setqlim_warns(res, qlim, newlim->d_rt_spc_warns); 598 if (newlim->d_fieldmask & QC_RT_SPC_TIMER) 599 xfs_setqlim_timer(mp, res, qlim, newlim->d_rt_spc_timer); 600 601 /* Inodes */ 602 hard = (newlim->d_fieldmask & QC_INO_HARD) ? 603 (xfs_qcnt_t) newlim->d_ino_hardlimit : 604 dqp->q_ino.hardlimit; 605 soft = (newlim->d_fieldmask & QC_INO_SOFT) ? 606 (xfs_qcnt_t) newlim->d_ino_softlimit : 607 dqp->q_ino.softlimit; 608 res = &dqp->q_ino; 609 qlim = id == 0 ? &defq->ino : NULL; 610 611 xfs_setqlim_limits(mp, res, qlim, hard, soft, "ino"); 612 if (newlim->d_fieldmask & QC_INO_WARNS) 613 xfs_setqlim_warns(res, qlim, newlim->d_ino_warns); 614 if (newlim->d_fieldmask & QC_INO_TIMER) 615 xfs_setqlim_timer(mp, res, qlim, newlim->d_ino_timer); 616 617 if (id != 0) { 618 /* 619 * If the user is now over quota, start the timelimit. 620 * The user will not be 'warned'. 621 * Note that we keep the timers ticking, whether enforcement 622 * is on or off. We don't really want to bother with iterating 623 * over all ondisk dquots and turning the timers on/off. 624 */ 625 xfs_qm_adjust_dqtimers(dqp); 626 } 627 dqp->q_flags |= XFS_DQFLAG_DIRTY; 628 xfs_trans_log_dquot(tp, dqp); 629 630 error = xfs_trans_commit(tp); 631 632 out_rele: 633 xfs_qm_dqrele(dqp); 634 out_unlock: 635 mutex_unlock(&q->qi_quotaofflock); 636 return error; 637 } 638 639 /* Fill out the quota context. */ 640 static void 641 xfs_qm_scall_getquota_fill_qc( 642 struct xfs_mount *mp, 643 xfs_dqtype_t type, 644 const struct xfs_dquot *dqp, 645 struct qc_dqblk *dst) 646 { 647 memset(dst, 0, sizeof(*dst)); 648 dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); 649 dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); 650 dst->d_ino_hardlimit = dqp->q_ino.hardlimit; 651 dst->d_ino_softlimit = dqp->q_ino.softlimit; 652 dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); 653 dst->d_ino_count = dqp->q_ino.reserved; 654 dst->d_spc_timer = dqp->q_blk.timer; 655 dst->d_ino_timer = dqp->q_ino.timer; 656 dst->d_ino_warns = dqp->q_ino.warnings; 657 dst->d_spc_warns = dqp->q_blk.warnings; 658 dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); 659 dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); 660 dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); 661 dst->d_rt_spc_timer = dqp->q_rtb.timer; 662 dst->d_rt_spc_warns = dqp->q_rtb.warnings; 663 664 /* 665 * Internally, we don't reset all the timers when quota enforcement 666 * gets turned off. No need to confuse the user level code, 667 * so return zeroes in that case. 668 */ 669 if (!xfs_dquot_is_enforced(dqp)) { 670 dst->d_spc_timer = 0; 671 dst->d_ino_timer = 0; 672 dst->d_rt_spc_timer = 0; 673 } 674 675 #ifdef DEBUG 676 if (xfs_dquot_is_enforced(dqp) && dqp->q_id != 0) { 677 if ((dst->d_space > dst->d_spc_softlimit) && 678 (dst->d_spc_softlimit > 0)) { 679 ASSERT(dst->d_spc_timer != 0); 680 } 681 if ((dst->d_ino_count > dqp->q_ino.softlimit) && 682 (dqp->q_ino.softlimit > 0)) { 683 ASSERT(dst->d_ino_timer != 0); 684 } 685 } 686 #endif 687 } 688 689 /* Return the quota information for the dquot matching id. */ 690 int 691 xfs_qm_scall_getquota( 692 struct xfs_mount *mp, 693 xfs_dqid_t id, 694 xfs_dqtype_t type, 695 struct qc_dqblk *dst) 696 { 697 struct xfs_dquot *dqp; 698 int error; 699 700 /* 701 * Try to get the dquot. We don't want it allocated on disk, so don't 702 * set doalloc. If it doesn't exist, we'll get ENOENT back. 703 */ 704 error = xfs_qm_dqget(mp, id, type, false, &dqp); 705 if (error) 706 return error; 707 708 /* 709 * If everything's NULL, this dquot doesn't quite exist as far as 710 * our utility programs are concerned. 711 */ 712 if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) { 713 error = -ENOENT; 714 goto out_put; 715 } 716 717 xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); 718 719 out_put: 720 xfs_qm_dqput(dqp); 721 return error; 722 } 723 724 /* 725 * Return the quota information for the first initialized dquot whose id 726 * is at least as high as id. 727 */ 728 int 729 xfs_qm_scall_getquota_next( 730 struct xfs_mount *mp, 731 xfs_dqid_t *id, 732 xfs_dqtype_t type, 733 struct qc_dqblk *dst) 734 { 735 struct xfs_dquot *dqp; 736 int error; 737 738 error = xfs_qm_dqget_next(mp, *id, type, &dqp); 739 if (error) 740 return error; 741 742 /* Fill in the ID we actually read from disk */ 743 *id = dqp->q_id; 744 745 xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); 746 747 xfs_qm_dqput(dqp); 748 return error; 749 } 750 751 STATIC int 752 xfs_dqrele_inode( 753 struct xfs_inode *ip, 754 void *args) 755 { 756 uint *flags = args; 757 758 /* skip quota inodes */ 759 if (ip == ip->i_mount->m_quotainfo->qi_uquotaip || 760 ip == ip->i_mount->m_quotainfo->qi_gquotaip || 761 ip == ip->i_mount->m_quotainfo->qi_pquotaip) { 762 ASSERT(ip->i_udquot == NULL); 763 ASSERT(ip->i_gdquot == NULL); 764 ASSERT(ip->i_pdquot == NULL); 765 return 0; 766 } 767 768 xfs_ilock(ip, XFS_ILOCK_EXCL); 769 if ((*flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { 770 xfs_qm_dqrele(ip->i_udquot); 771 ip->i_udquot = NULL; 772 } 773 if ((*flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { 774 xfs_qm_dqrele(ip->i_gdquot); 775 ip->i_gdquot = NULL; 776 } 777 if ((*flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) { 778 xfs_qm_dqrele(ip->i_pdquot); 779 ip->i_pdquot = NULL; 780 } 781 xfs_iunlock(ip, XFS_ILOCK_EXCL); 782 return 0; 783 } 784 785 786 /* 787 * Go thru all the inodes in the file system, releasing their dquots. 788 * 789 * Note that the mount structure gets modified to indicate that quotas are off 790 * AFTER this, in the case of quotaoff. 791 */ 792 void 793 xfs_qm_dqrele_all_inodes( 794 struct xfs_mount *mp, 795 uint flags) 796 { 797 ASSERT(mp->m_quotainfo); 798 xfs_inode_walk(mp, XFS_INODE_WALK_INEW_WAIT, xfs_dqrele_inode, 799 &flags, XFS_ICI_NO_TAG); 800 } 801