| .. | .. |
|---|
| 4 | 4 | * All Rights Reserved. |
|---|
| 5 | 5 | */ |
|---|
| 6 | 6 | |
|---|
| 7 | | -#include <linux/capability.h> |
|---|
| 8 | 7 | |
|---|
| 9 | 8 | #include "xfs.h" |
|---|
| 10 | 9 | #include "xfs_fs.h" |
|---|
| .. | .. |
|---|
| 12 | 11 | #include "xfs_format.h" |
|---|
| 13 | 12 | #include "xfs_log_format.h" |
|---|
| 14 | 13 | #include "xfs_trans_resv.h" |
|---|
| 15 | | -#include "xfs_bit.h" |
|---|
| 16 | 14 | #include "xfs_sb.h" |
|---|
| 17 | 15 | #include "xfs_mount.h" |
|---|
| 18 | 16 | #include "xfs_inode.h" |
|---|
| 19 | 17 | #include "xfs_trans.h" |
|---|
| 20 | | -#include "xfs_error.h" |
|---|
| 21 | 18 | #include "xfs_quota.h" |
|---|
| 22 | 19 | #include "xfs_qm.h" |
|---|
| 23 | | -#include "xfs_trace.h" |
|---|
| 24 | 20 | #include "xfs_icache.h" |
|---|
| 25 | | -#include "xfs_defer.h" |
|---|
| 26 | 21 | |
|---|
| 27 | | -STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint); |
|---|
| 28 | | -STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *, |
|---|
| 29 | | - uint); |
|---|
| 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 | +} |
|---|
| 30 | 87 | |
|---|
| 31 | 88 | /* |
|---|
| 32 | 89 | * Turn off quota accounting and/or enforcement for all udquots and/or |
|---|
| .. | .. |
|---|
| 45 | 102 | uint dqtype; |
|---|
| 46 | 103 | int error; |
|---|
| 47 | 104 | uint inactivate_flags; |
|---|
| 48 | | - xfs_qoff_logitem_t *qoffstart; |
|---|
| 105 | + struct xfs_qoff_logitem *qoffstart = NULL; |
|---|
| 49 | 106 | |
|---|
| 50 | 107 | /* |
|---|
| 51 | 108 | * No file system can have quotas enabled on disk but not in core. |
|---|
| .. | .. |
|---|
| 170 | 227 | * So, we have QUOTAOFF start and end logitems; the start |
|---|
| 171 | 228 | * logitem won't get overwritten until the end logitem appears... |
|---|
| 172 | 229 | */ |
|---|
| 173 | | - error = xfs_qm_log_quotaoff_end(mp, qoffstart, flags); |
|---|
| 230 | + error = xfs_qm_log_quotaoff_end(mp, &qoffstart, flags); |
|---|
| 174 | 231 | if (error) { |
|---|
| 175 | 232 | /* We're screwed now. Shutdown is the only option. */ |
|---|
| 176 | 233 | xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); |
|---|
| .. | .. |
|---|
| 203 | 260 | } |
|---|
| 204 | 261 | |
|---|
| 205 | 262 | out_unlock: |
|---|
| 263 | + if (error && qoffstart) |
|---|
| 264 | + xfs_qm_qoff_logitem_relse(qoffstart); |
|---|
| 206 | 265 | mutex_unlock(&q->qi_quotaofflock); |
|---|
| 207 | 266 | return error; |
|---|
| 208 | 267 | } |
|---|
| .. | .. |
|---|
| 243 | 302 | goto out_unlock; |
|---|
| 244 | 303 | } |
|---|
| 245 | 304 | |
|---|
| 246 | | - ASSERT(ip->i_d.di_nextents == 0); |
|---|
| 305 | + ASSERT(ip->i_df.if_nextents == 0); |
|---|
| 247 | 306 | |
|---|
| 248 | 307 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); |
|---|
| 249 | 308 | error = xfs_trans_commit(tp); |
|---|
| .. | .. |
|---|
| 263 | 322 | int error = -EINVAL; |
|---|
| 264 | 323 | |
|---|
| 265 | 324 | if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0 || |
|---|
| 266 | | - (flags & ~XFS_DQ_ALLTYPES)) { |
|---|
| 325 | + (flags & ~XFS_QMOPT_QUOTALL)) { |
|---|
| 267 | 326 | xfs_debug(mp, "%s: flags=%x m_qflags=%x", |
|---|
| 268 | 327 | __func__, flags, mp->m_qflags); |
|---|
| 269 | 328 | return -EINVAL; |
|---|
| 270 | 329 | } |
|---|
| 271 | 330 | |
|---|
| 272 | | - if (flags & XFS_DQ_USER) { |
|---|
| 331 | + if (flags & XFS_QMOPT_UQUOTA) { |
|---|
| 273 | 332 | error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino); |
|---|
| 274 | 333 | if (error) |
|---|
| 275 | 334 | return error; |
|---|
| 276 | 335 | } |
|---|
| 277 | | - if (flags & XFS_DQ_GROUP) { |
|---|
| 336 | + if (flags & XFS_QMOPT_GQUOTA) { |
|---|
| 278 | 337 | error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino); |
|---|
| 279 | 338 | if (error) |
|---|
| 280 | 339 | return error; |
|---|
| 281 | 340 | } |
|---|
| 282 | | - if (flags & XFS_DQ_PROJ) |
|---|
| 341 | + if (flags & XFS_QMOPT_PQUOTA) |
|---|
| 283 | 342 | error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino); |
|---|
| 284 | 343 | |
|---|
| 285 | 344 | return error; |
|---|
| .. | .. |
|---|
| 298 | 357 | int error; |
|---|
| 299 | 358 | uint qf; |
|---|
| 300 | 359 | |
|---|
| 301 | | - flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD); |
|---|
| 302 | 360 | /* |
|---|
| 303 | | - * Switching on quota accounting must be done at mount time. |
|---|
| 361 | + * Switching on quota accounting must be done at mount time, |
|---|
| 362 | + * only consider quota enforcement stuff here. |
|---|
| 304 | 363 | */ |
|---|
| 305 | | - flags &= ~(XFS_ALL_QUOTA_ACCT); |
|---|
| 364 | + flags &= XFS_ALL_QUOTA_ENFD; |
|---|
| 306 | 365 | |
|---|
| 307 | 366 | if (flags == 0) { |
|---|
| 308 | 367 | xfs_debug(mp, "%s: zero flags, m_qflags=%x", |
|---|
| .. | .. |
|---|
| 378 | 437 | (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK) |
|---|
| 379 | 438 | |
|---|
| 380 | 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 | +/* |
|---|
| 381 | 498 | * Adjust quota limits, and start/stop timers accordingly. |
|---|
| 382 | 499 | */ |
|---|
| 383 | 500 | int |
|---|
| 384 | 501 | xfs_qm_scall_setqlim( |
|---|
| 385 | 502 | struct xfs_mount *mp, |
|---|
| 386 | 503 | xfs_dqid_t id, |
|---|
| 387 | | - uint type, |
|---|
| 504 | + xfs_dqtype_t type, |
|---|
| 388 | 505 | struct qc_dqblk *newlim) |
|---|
| 389 | 506 | { |
|---|
| 390 | 507 | struct xfs_quotainfo *q = mp->m_quotainfo; |
|---|
| 391 | | - struct xfs_disk_dquot *ddq; |
|---|
| 392 | 508 | struct xfs_dquot *dqp; |
|---|
| 393 | 509 | struct xfs_trans *tp; |
|---|
| 394 | 510 | struct xfs_def_quota *defq; |
|---|
| 511 | + struct xfs_dquot_res *res; |
|---|
| 512 | + struct xfs_quota_limits *qlim; |
|---|
| 395 | 513 | int error; |
|---|
| 396 | 514 | xfs_qcnt_t hard, soft; |
|---|
| 397 | 515 | |
|---|
| .. | .. |
|---|
| 420 | 538 | goto out_unlock; |
|---|
| 421 | 539 | } |
|---|
| 422 | 540 | |
|---|
| 423 | | - defq = xfs_get_defquota(dqp, q); |
|---|
| 541 | + defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); |
|---|
| 424 | 542 | xfs_dqunlock(dqp); |
|---|
| 425 | 543 | |
|---|
| 426 | 544 | error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp); |
|---|
| .. | .. |
|---|
| 429 | 547 | |
|---|
| 430 | 548 | xfs_dqlock(dqp); |
|---|
| 431 | 549 | xfs_trans_dqjoin(tp, dqp); |
|---|
| 432 | | - ddq = &dqp->q_core; |
|---|
| 433 | 550 | |
|---|
| 434 | 551 | /* |
|---|
| 552 | + * Update quota limits, warnings, and timers, and the defaults |
|---|
| 553 | + * if we're touching id == 0. |
|---|
| 554 | + * |
|---|
| 435 | 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. |
|---|
| 436 | 566 | */ |
|---|
| 567 | + |
|---|
| 568 | + /* Blocks on the data device. */ |
|---|
| 437 | 569 | hard = (newlim->d_fieldmask & QC_SPC_HARD) ? |
|---|
| 438 | 570 | (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : |
|---|
| 439 | | - be64_to_cpu(ddq->d_blk_hardlimit); |
|---|
| 571 | + dqp->q_blk.hardlimit; |
|---|
| 440 | 572 | soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? |
|---|
| 441 | 573 | (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : |
|---|
| 442 | | - be64_to_cpu(ddq->d_blk_softlimit); |
|---|
| 443 | | - if (hard == 0 || hard >= soft) { |
|---|
| 444 | | - ddq->d_blk_hardlimit = cpu_to_be64(hard); |
|---|
| 445 | | - ddq->d_blk_softlimit = cpu_to_be64(soft); |
|---|
| 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")) |
|---|
| 446 | 579 | xfs_dquot_set_prealloc_limits(dqp); |
|---|
| 447 | | - if (id == 0) { |
|---|
| 448 | | - defq->bhardlimit = hard; |
|---|
| 449 | | - defq->bsoftlimit = soft; |
|---|
| 450 | | - } |
|---|
| 451 | | - } else { |
|---|
| 452 | | - xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft); |
|---|
| 453 | | - } |
|---|
| 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. */ |
|---|
| 454 | 586 | hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? |
|---|
| 455 | 587 | (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : |
|---|
| 456 | | - be64_to_cpu(ddq->d_rtb_hardlimit); |
|---|
| 588 | + dqp->q_rtb.hardlimit; |
|---|
| 457 | 589 | soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? |
|---|
| 458 | 590 | (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : |
|---|
| 459 | | - be64_to_cpu(ddq->d_rtb_softlimit); |
|---|
| 460 | | - if (hard == 0 || hard >= soft) { |
|---|
| 461 | | - ddq->d_rtb_hardlimit = cpu_to_be64(hard); |
|---|
| 462 | | - ddq->d_rtb_softlimit = cpu_to_be64(soft); |
|---|
| 463 | | - if (id == 0) { |
|---|
| 464 | | - defq->rtbhardlimit = hard; |
|---|
| 465 | | - defq->rtbsoftlimit = soft; |
|---|
| 466 | | - } |
|---|
| 467 | | - } else { |
|---|
| 468 | | - xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft); |
|---|
| 469 | | - } |
|---|
| 591 | + dqp->q_rtb.softlimit; |
|---|
| 592 | + res = &dqp->q_rtb; |
|---|
| 593 | + qlim = id == 0 ? &defq->rtb : NULL; |
|---|
| 470 | 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 */ |
|---|
| 471 | 602 | hard = (newlim->d_fieldmask & QC_INO_HARD) ? |
|---|
| 472 | 603 | (xfs_qcnt_t) newlim->d_ino_hardlimit : |
|---|
| 473 | | - be64_to_cpu(ddq->d_ino_hardlimit); |
|---|
| 604 | + dqp->q_ino.hardlimit; |
|---|
| 474 | 605 | soft = (newlim->d_fieldmask & QC_INO_SOFT) ? |
|---|
| 475 | 606 | (xfs_qcnt_t) newlim->d_ino_softlimit : |
|---|
| 476 | | - be64_to_cpu(ddq->d_ino_softlimit); |
|---|
| 477 | | - if (hard == 0 || hard >= soft) { |
|---|
| 478 | | - ddq->d_ino_hardlimit = cpu_to_be64(hard); |
|---|
| 479 | | - ddq->d_ino_softlimit = cpu_to_be64(soft); |
|---|
| 480 | | - if (id == 0) { |
|---|
| 481 | | - defq->ihardlimit = hard; |
|---|
| 482 | | - defq->isoftlimit = soft; |
|---|
| 483 | | - } |
|---|
| 484 | | - } else { |
|---|
| 485 | | - xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft); |
|---|
| 486 | | - } |
|---|
| 607 | + dqp->q_ino.softlimit; |
|---|
| 608 | + res = &dqp->q_ino; |
|---|
| 609 | + qlim = id == 0 ? &defq->ino : NULL; |
|---|
| 487 | 610 | |
|---|
| 488 | | - /* |
|---|
| 489 | | - * Update warnings counter(s) if requested |
|---|
| 490 | | - */ |
|---|
| 491 | | - if (newlim->d_fieldmask & QC_SPC_WARNS) |
|---|
| 492 | | - ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns); |
|---|
| 611 | + xfs_setqlim_limits(mp, res, qlim, hard, soft, "ino"); |
|---|
| 493 | 612 | if (newlim->d_fieldmask & QC_INO_WARNS) |
|---|
| 494 | | - ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns); |
|---|
| 495 | | - if (newlim->d_fieldmask & QC_RT_SPC_WARNS) |
|---|
| 496 | | - ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_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); |
|---|
| 497 | 616 | |
|---|
| 498 | | - if (id == 0) { |
|---|
| 499 | | - /* |
|---|
| 500 | | - * Timelimits for the super user set the relative time |
|---|
| 501 | | - * the other users can be over quota for this file system. |
|---|
| 502 | | - * If it is zero a default is used. Ditto for the default |
|---|
| 503 | | - * soft and hard limit values (already done, above), and |
|---|
| 504 | | - * for warnings. |
|---|
| 505 | | - */ |
|---|
| 506 | | - if (newlim->d_fieldmask & QC_SPC_TIMER) { |
|---|
| 507 | | - q->qi_btimelimit = newlim->d_spc_timer; |
|---|
| 508 | | - ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer); |
|---|
| 509 | | - } |
|---|
| 510 | | - if (newlim->d_fieldmask & QC_INO_TIMER) { |
|---|
| 511 | | - q->qi_itimelimit = newlim->d_ino_timer; |
|---|
| 512 | | - ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer); |
|---|
| 513 | | - } |
|---|
| 514 | | - if (newlim->d_fieldmask & QC_RT_SPC_TIMER) { |
|---|
| 515 | | - q->qi_rtbtimelimit = newlim->d_rt_spc_timer; |
|---|
| 516 | | - ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer); |
|---|
| 517 | | - } |
|---|
| 518 | | - if (newlim->d_fieldmask & QC_SPC_WARNS) |
|---|
| 519 | | - q->qi_bwarnlimit = newlim->d_spc_warns; |
|---|
| 520 | | - if (newlim->d_fieldmask & QC_INO_WARNS) |
|---|
| 521 | | - q->qi_iwarnlimit = newlim->d_ino_warns; |
|---|
| 522 | | - if (newlim->d_fieldmask & QC_RT_SPC_WARNS) |
|---|
| 523 | | - q->qi_rtbwarnlimit = newlim->d_rt_spc_warns; |
|---|
| 524 | | - } else { |
|---|
| 617 | + if (id != 0) { |
|---|
| 525 | 618 | /* |
|---|
| 526 | 619 | * If the user is now over quota, start the timelimit. |
|---|
| 527 | 620 | * The user will not be 'warned'. |
|---|
| .. | .. |
|---|
| 529 | 622 | * is on or off. We don't really want to bother with iterating |
|---|
| 530 | 623 | * over all ondisk dquots and turning the timers on/off. |
|---|
| 531 | 624 | */ |
|---|
| 532 | | - xfs_qm_adjust_dqtimers(mp, ddq); |
|---|
| 625 | + xfs_qm_adjust_dqtimers(dqp); |
|---|
| 533 | 626 | } |
|---|
| 534 | | - dqp->dq_flags |= XFS_DQ_DIRTY; |
|---|
| 627 | + dqp->q_flags |= XFS_DQFLAG_DIRTY; |
|---|
| 535 | 628 | xfs_trans_log_dquot(tp, dqp); |
|---|
| 536 | 629 | |
|---|
| 537 | 630 | error = xfs_trans_commit(tp); |
|---|
| .. | .. |
|---|
| 543 | 636 | return error; |
|---|
| 544 | 637 | } |
|---|
| 545 | 638 | |
|---|
| 546 | | -STATIC int |
|---|
| 547 | | -xfs_qm_log_quotaoff_end( |
|---|
| 548 | | - xfs_mount_t *mp, |
|---|
| 549 | | - xfs_qoff_logitem_t *startqoff, |
|---|
| 550 | | - uint flags) |
|---|
| 551 | | -{ |
|---|
| 552 | | - xfs_trans_t *tp; |
|---|
| 553 | | - int error; |
|---|
| 554 | | - xfs_qoff_logitem_t *qoffi; |
|---|
| 555 | | - |
|---|
| 556 | | - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp); |
|---|
| 557 | | - if (error) |
|---|
| 558 | | - return error; |
|---|
| 559 | | - |
|---|
| 560 | | - qoffi = xfs_trans_get_qoff_item(tp, startqoff, |
|---|
| 561 | | - flags & XFS_ALL_QUOTA_ACCT); |
|---|
| 562 | | - xfs_trans_log_quotaoff_item(tp, qoffi); |
|---|
| 563 | | - |
|---|
| 564 | | - /* |
|---|
| 565 | | - * We have to make sure that the transaction is secure on disk before we |
|---|
| 566 | | - * return and actually stop quota accounting. So, make it synchronous. |
|---|
| 567 | | - * We don't care about quotoff's performance. |
|---|
| 568 | | - */ |
|---|
| 569 | | - xfs_trans_set_sync(tp); |
|---|
| 570 | | - return xfs_trans_commit(tp); |
|---|
| 571 | | -} |
|---|
| 572 | | - |
|---|
| 573 | | - |
|---|
| 574 | | -STATIC int |
|---|
| 575 | | -xfs_qm_log_quotaoff( |
|---|
| 576 | | - xfs_mount_t *mp, |
|---|
| 577 | | - xfs_qoff_logitem_t **qoffstartp, |
|---|
| 578 | | - uint flags) |
|---|
| 579 | | -{ |
|---|
| 580 | | - xfs_trans_t *tp; |
|---|
| 581 | | - int error; |
|---|
| 582 | | - xfs_qoff_logitem_t *qoffi; |
|---|
| 583 | | - |
|---|
| 584 | | - *qoffstartp = NULL; |
|---|
| 585 | | - |
|---|
| 586 | | - error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp); |
|---|
| 587 | | - if (error) |
|---|
| 588 | | - goto out; |
|---|
| 589 | | - |
|---|
| 590 | | - qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT); |
|---|
| 591 | | - xfs_trans_log_quotaoff_item(tp, qoffi); |
|---|
| 592 | | - |
|---|
| 593 | | - spin_lock(&mp->m_sb_lock); |
|---|
| 594 | | - mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL; |
|---|
| 595 | | - spin_unlock(&mp->m_sb_lock); |
|---|
| 596 | | - |
|---|
| 597 | | - xfs_log_sb(tp); |
|---|
| 598 | | - |
|---|
| 599 | | - /* |
|---|
| 600 | | - * We have to make sure that the transaction is secure on disk before we |
|---|
| 601 | | - * return and actually stop quota accounting. So, make it synchronous. |
|---|
| 602 | | - * We don't care about quotoff's performance. |
|---|
| 603 | | - */ |
|---|
| 604 | | - xfs_trans_set_sync(tp); |
|---|
| 605 | | - error = xfs_trans_commit(tp); |
|---|
| 606 | | - if (error) |
|---|
| 607 | | - goto out; |
|---|
| 608 | | - |
|---|
| 609 | | - *qoffstartp = qoffi; |
|---|
| 610 | | -out: |
|---|
| 611 | | - return error; |
|---|
| 612 | | -} |
|---|
| 613 | | - |
|---|
| 614 | 639 | /* Fill out the quota context. */ |
|---|
| 615 | 640 | static void |
|---|
| 616 | 641 | xfs_qm_scall_getquota_fill_qc( |
|---|
| 617 | 642 | struct xfs_mount *mp, |
|---|
| 618 | | - uint type, |
|---|
| 643 | + xfs_dqtype_t type, |
|---|
| 619 | 644 | const struct xfs_dquot *dqp, |
|---|
| 620 | 645 | struct qc_dqblk *dst) |
|---|
| 621 | 646 | { |
|---|
| 622 | 647 | memset(dst, 0, sizeof(*dst)); |
|---|
| 623 | | - dst->d_spc_hardlimit = |
|---|
| 624 | | - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit)); |
|---|
| 625 | | - dst->d_spc_softlimit = |
|---|
| 626 | | - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit)); |
|---|
| 627 | | - dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit); |
|---|
| 628 | | - dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit); |
|---|
| 629 | | - dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount); |
|---|
| 630 | | - dst->d_ino_count = dqp->q_res_icount; |
|---|
| 631 | | - dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer); |
|---|
| 632 | | - dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer); |
|---|
| 633 | | - dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns); |
|---|
| 634 | | - dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns); |
|---|
| 635 | | - dst->d_rt_spc_hardlimit = |
|---|
| 636 | | - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit)); |
|---|
| 637 | | - dst->d_rt_spc_softlimit = |
|---|
| 638 | | - XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit)); |
|---|
| 639 | | - dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount); |
|---|
| 640 | | - dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer); |
|---|
| 641 | | - dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns); |
|---|
| 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; |
|---|
| 642 | 663 | |
|---|
| 643 | 664 | /* |
|---|
| 644 | 665 | * Internally, we don't reset all the timers when quota enforcement |
|---|
| 645 | 666 | * gets turned off. No need to confuse the user level code, |
|---|
| 646 | 667 | * so return zeroes in that case. |
|---|
| 647 | 668 | */ |
|---|
| 648 | | - if ((!XFS_IS_UQUOTA_ENFORCED(mp) && |
|---|
| 649 | | - dqp->q_core.d_flags == XFS_DQ_USER) || |
|---|
| 650 | | - (!XFS_IS_GQUOTA_ENFORCED(mp) && |
|---|
| 651 | | - dqp->q_core.d_flags == XFS_DQ_GROUP) || |
|---|
| 652 | | - (!XFS_IS_PQUOTA_ENFORCED(mp) && |
|---|
| 653 | | - dqp->q_core.d_flags == XFS_DQ_PROJ)) { |
|---|
| 669 | + if (!xfs_dquot_is_enforced(dqp)) { |
|---|
| 654 | 670 | dst->d_spc_timer = 0; |
|---|
| 655 | 671 | dst->d_ino_timer = 0; |
|---|
| 656 | 672 | dst->d_rt_spc_timer = 0; |
|---|
| 657 | 673 | } |
|---|
| 658 | 674 | |
|---|
| 659 | 675 | #ifdef DEBUG |
|---|
| 660 | | - if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) || |
|---|
| 661 | | - (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) || |
|---|
| 662 | | - (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) && |
|---|
| 663 | | - dqp->q_core.d_id != 0) { |
|---|
| 676 | + if (xfs_dquot_is_enforced(dqp) && dqp->q_id != 0) { |
|---|
| 664 | 677 | if ((dst->d_space > dst->d_spc_softlimit) && |
|---|
| 665 | 678 | (dst->d_spc_softlimit > 0)) { |
|---|
| 666 | 679 | ASSERT(dst->d_spc_timer != 0); |
|---|
| 667 | 680 | } |
|---|
| 668 | | - if ((dst->d_ino_count > dst->d_ino_softlimit) && |
|---|
| 669 | | - (dst->d_ino_softlimit > 0)) { |
|---|
| 681 | + if ((dst->d_ino_count > dqp->q_ino.softlimit) && |
|---|
| 682 | + (dqp->q_ino.softlimit > 0)) { |
|---|
| 670 | 683 | ASSERT(dst->d_ino_timer != 0); |
|---|
| 671 | 684 | } |
|---|
| 672 | 685 | } |
|---|
| .. | .. |
|---|
| 678 | 691 | xfs_qm_scall_getquota( |
|---|
| 679 | 692 | struct xfs_mount *mp, |
|---|
| 680 | 693 | xfs_dqid_t id, |
|---|
| 681 | | - uint type, |
|---|
| 694 | + xfs_dqtype_t type, |
|---|
| 682 | 695 | struct qc_dqblk *dst) |
|---|
| 683 | 696 | { |
|---|
| 684 | 697 | struct xfs_dquot *dqp; |
|---|
| .. | .. |
|---|
| 716 | 729 | xfs_qm_scall_getquota_next( |
|---|
| 717 | 730 | struct xfs_mount *mp, |
|---|
| 718 | 731 | xfs_dqid_t *id, |
|---|
| 719 | | - uint type, |
|---|
| 732 | + xfs_dqtype_t type, |
|---|
| 720 | 733 | struct qc_dqblk *dst) |
|---|
| 721 | 734 | { |
|---|
| 722 | 735 | struct xfs_dquot *dqp; |
|---|
| .. | .. |
|---|
| 727 | 740 | return error; |
|---|
| 728 | 741 | |
|---|
| 729 | 742 | /* Fill in the ID we actually read from disk */ |
|---|
| 730 | | - *id = be32_to_cpu(dqp->q_core.d_id); |
|---|
| 743 | + *id = dqp->q_id; |
|---|
| 731 | 744 | |
|---|
| 732 | 745 | xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); |
|---|
| 733 | 746 | |
|---|
| .. | .. |
|---|
| 738 | 751 | STATIC int |
|---|
| 739 | 752 | xfs_dqrele_inode( |
|---|
| 740 | 753 | struct xfs_inode *ip, |
|---|
| 741 | | - int flags, |
|---|
| 742 | 754 | void *args) |
|---|
| 743 | 755 | { |
|---|
| 756 | + uint *flags = args; |
|---|
| 757 | + |
|---|
| 744 | 758 | /* skip quota inodes */ |
|---|
| 745 | 759 | if (ip == ip->i_mount->m_quotainfo->qi_uquotaip || |
|---|
| 746 | 760 | ip == ip->i_mount->m_quotainfo->qi_gquotaip || |
|---|
| .. | .. |
|---|
| 752 | 766 | } |
|---|
| 753 | 767 | |
|---|
| 754 | 768 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
|---|
| 755 | | - if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { |
|---|
| 769 | + if ((*flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { |
|---|
| 756 | 770 | xfs_qm_dqrele(ip->i_udquot); |
|---|
| 757 | 771 | ip->i_udquot = NULL; |
|---|
| 758 | 772 | } |
|---|
| 759 | | - if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { |
|---|
| 773 | + if ((*flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) { |
|---|
| 760 | 774 | xfs_qm_dqrele(ip->i_gdquot); |
|---|
| 761 | 775 | ip->i_gdquot = NULL; |
|---|
| 762 | 776 | } |
|---|
| 763 | | - if ((flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) { |
|---|
| 777 | + if ((*flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) { |
|---|
| 764 | 778 | xfs_qm_dqrele(ip->i_pdquot); |
|---|
| 765 | 779 | ip->i_pdquot = NULL; |
|---|
| 766 | 780 | } |
|---|
| .. | .. |
|---|
| 777 | 791 | */ |
|---|
| 778 | 792 | void |
|---|
| 779 | 793 | xfs_qm_dqrele_all_inodes( |
|---|
| 780 | | - struct xfs_mount *mp, |
|---|
| 781 | | - uint flags) |
|---|
| 794 | + struct xfs_mount *mp, |
|---|
| 795 | + uint flags) |
|---|
| 782 | 796 | { |
|---|
| 783 | 797 | ASSERT(mp->m_quotainfo); |
|---|
| 784 | | - xfs_inode_ag_iterator_flags(mp, xfs_dqrele_inode, flags, NULL, |
|---|
| 785 | | - XFS_AGITER_INEW_WAIT); |
|---|
| 798 | + xfs_inode_walk(mp, XFS_INODE_WALK_INEW_WAIT, xfs_dqrele_inode, |
|---|
| 799 | + &flags, XFS_ICI_NO_TAG); |
|---|
| 786 | 800 | } |
|---|