.. | .. |
---|
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 | } |
---|