hc
2024-05-11 297b60346df8beafee954a0fd7c2d64f33f3b9bc
kernel/fs/xfs/xfs_trans_dquot.c
....@@ -11,11 +11,12 @@
1111 #include "xfs_trans_resv.h"
1212 #include "xfs_mount.h"
1313 #include "xfs_inode.h"
14
-#include "xfs_error.h"
1514 #include "xfs_trans.h"
1615 #include "xfs_trans_priv.h"
1716 #include "xfs_quota.h"
1817 #include "xfs_qm.h"
18
+#include "xfs_trace.h"
19
+#include "xfs_error.h"
1920
2021 STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *);
2122
....@@ -26,10 +27,9 @@
2627 */
2728 void
2829 xfs_trans_dqjoin(
29
- xfs_trans_t *tp,
30
- xfs_dquot_t *dqp)
30
+ struct xfs_trans *tp,
31
+ struct xfs_dquot *dqp)
3132 {
32
- ASSERT(dqp->q_transp != tp);
3333 ASSERT(XFS_DQ_IS_LOCKED(dqp));
3434 ASSERT(dqp->q_logitem.qli_dquot == dqp);
3535
....@@ -37,14 +37,7 @@
3737 * Get a log_item_desc to point at the new item.
3838 */
3939 xfs_trans_add_item(tp, &dqp->q_logitem.qli_item);
40
-
41
- /*
42
- * Initialize d_transp so we can later determine if this dquot is
43
- * associated with this transaction.
44
- */
45
- dqp->q_transp = tp;
4640 }
47
-
4841
4942 /*
5043 * This is called to mark the dquot as needing
....@@ -58,11 +51,16 @@
5851 */
5952 void
6053 xfs_trans_log_dquot(
61
- xfs_trans_t *tp,
62
- xfs_dquot_t *dqp)
54
+ struct xfs_trans *tp,
55
+ struct xfs_dquot *dqp)
6356 {
64
- ASSERT(dqp->q_transp == tp);
6557 ASSERT(XFS_DQ_IS_LOCKED(dqp));
58
+
59
+ /* Upgrade the dquot to bigtime format if possible. */
60
+ if (dqp->q_id != 0 &&
61
+ xfs_sb_version_hasbigtime(&tp->t_mountp->m_sb) &&
62
+ !(dqp->q_type & XFS_DQTYPE_BIGTIME))
63
+ dqp->q_type |= XFS_DQTYPE_BIGTIME;
6664
6765 tp->t_flags |= XFS_TRANS_DIRTY;
6866 set_bit(XFS_LI_DIRTY, &dqp->q_logitem.qli_item.li_flags);
....@@ -74,13 +72,13 @@
7472 */
7573 void
7674 xfs_trans_dup_dqinfo(
77
- xfs_trans_t *otp,
78
- xfs_trans_t *ntp)
75
+ struct xfs_trans *otp,
76
+ struct xfs_trans *ntp)
7977 {
80
- xfs_dqtrx_t *oq, *nq;
81
- int i, j;
82
- xfs_dqtrx_t *oqa, *nqa;
83
- ulong blk_res_used;
78
+ struct xfs_dqtrx *oq, *nq;
79
+ int i, j;
80
+ struct xfs_dqtrx *oqa, *nqa;
81
+ uint64_t blk_res_used;
8482
8583 if (!otp->t_dqinfo)
8684 return;
....@@ -137,7 +135,7 @@
137135 xfs_trans_t *tp,
138136 xfs_inode_t *ip,
139137 uint field,
140
- long delta)
138
+ int64_t delta)
141139 {
142140 xfs_mount_t *mp = tp->t_mountp;
143141
....@@ -165,14 +163,19 @@
165163 int i;
166164 struct xfs_dqtrx *qa;
167165
168
- if (XFS_QM_ISUDQ(dqp))
166
+ switch (xfs_dquot_type(dqp)) {
167
+ case XFS_DQTYPE_USER:
169168 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
170
- else if (XFS_QM_ISGDQ(dqp))
169
+ break;
170
+ case XFS_DQTYPE_GROUP:
171171 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
172
- else if (XFS_QM_ISPDQ(dqp))
172
+ break;
173
+ case XFS_DQTYPE_PROJ:
173174 qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ];
174
- else
175
+ break;
176
+ default:
175177 return NULL;
178
+ }
176179
177180 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
178181 if (qa[i].qt_dquot == NULL ||
....@@ -191,12 +194,12 @@
191194 */
192195 void
193196 xfs_trans_mod_dquot(
194
- xfs_trans_t *tp,
195
- xfs_dquot_t *dqp,
196
- uint field,
197
- long delta)
197
+ struct xfs_trans *tp,
198
+ struct xfs_dquot *dqp,
199
+ uint field,
200
+ int64_t delta)
198201 {
199
- xfs_dqtrx_t *qtrx;
202
+ struct xfs_dqtrx *qtrx;
200203
201204 ASSERT(tp);
202205 ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp));
....@@ -213,69 +216,65 @@
213216 if (qtrx->qt_dquot == NULL)
214217 qtrx->qt_dquot = dqp;
215218
219
+ if (delta) {
220
+ trace_xfs_trans_mod_dquot_before(qtrx);
221
+ trace_xfs_trans_mod_dquot(tp, dqp, field, delta);
222
+ }
223
+
216224 switch (field) {
217
-
218
- /*
219
- * regular disk blk reservation
220
- */
221
- case XFS_TRANS_DQ_RES_BLKS:
222
- qtrx->qt_blk_res += (ulong)delta;
225
+ /* regular disk blk reservation */
226
+ case XFS_TRANS_DQ_RES_BLKS:
227
+ qtrx->qt_blk_res += delta;
223228 break;
224229
225
- /*
226
- * inode reservation
227
- */
228
- case XFS_TRANS_DQ_RES_INOS:
229
- qtrx->qt_ino_res += (ulong)delta;
230
+ /* inode reservation */
231
+ case XFS_TRANS_DQ_RES_INOS:
232
+ qtrx->qt_ino_res += delta;
230233 break;
231234
232
- /*
233
- * disk blocks used.
234
- */
235
- case XFS_TRANS_DQ_BCOUNT:
235
+ /* disk blocks used. */
236
+ case XFS_TRANS_DQ_BCOUNT:
236237 qtrx->qt_bcount_delta += delta;
237238 break;
238239
239
- case XFS_TRANS_DQ_DELBCOUNT:
240
+ case XFS_TRANS_DQ_DELBCOUNT:
240241 qtrx->qt_delbcnt_delta += delta;
241242 break;
242243
243
- /*
244
- * Inode Count
245
- */
246
- case XFS_TRANS_DQ_ICOUNT:
244
+ /* Inode Count */
245
+ case XFS_TRANS_DQ_ICOUNT:
247246 if (qtrx->qt_ino_res && delta > 0) {
248
- qtrx->qt_ino_res_used += (ulong)delta;
247
+ qtrx->qt_ino_res_used += delta;
249248 ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
250249 }
251250 qtrx->qt_icount_delta += delta;
252251 break;
253252
254
- /*
255
- * rtblk reservation
256
- */
257
- case XFS_TRANS_DQ_RES_RTBLKS:
258
- qtrx->qt_rtblk_res += (ulong)delta;
253
+ /* rtblk reservation */
254
+ case XFS_TRANS_DQ_RES_RTBLKS:
255
+ qtrx->qt_rtblk_res += delta;
259256 break;
260257
261
- /*
262
- * rtblk count
263
- */
264
- case XFS_TRANS_DQ_RTBCOUNT:
258
+ /* rtblk count */
259
+ case XFS_TRANS_DQ_RTBCOUNT:
265260 if (qtrx->qt_rtblk_res && delta > 0) {
266
- qtrx->qt_rtblk_res_used += (ulong)delta;
261
+ qtrx->qt_rtblk_res_used += delta;
267262 ASSERT(qtrx->qt_rtblk_res >= qtrx->qt_rtblk_res_used);
268263 }
269264 qtrx->qt_rtbcount_delta += delta;
270265 break;
271266
272
- case XFS_TRANS_DQ_DELRTBCOUNT:
267
+ case XFS_TRANS_DQ_DELRTBCOUNT:
273268 qtrx->qt_delrtb_delta += delta;
274269 break;
275270
276
- default:
271
+ default:
277272 ASSERT(0);
278273 }
274
+
275
+ if (delta)
276
+ trace_xfs_trans_mod_dquot_after(qtrx);
277
+
279278 tp->t_flags |= XFS_TRANS_DQ_DIRTY;
280279 }
281280
....@@ -288,8 +287,8 @@
288287 */
289288 STATIC void
290289 xfs_trans_dqlockedjoin(
291
- xfs_trans_t *tp,
292
- xfs_dqtrx_t *q)
290
+ struct xfs_trans *tp,
291
+ struct xfs_dqtrx *q)
293292 {
294293 ASSERT(q[0].qt_dquot != NULL);
295294 if (q[1].qt_dquot == NULL) {
....@@ -303,6 +302,37 @@
303302 }
304303 }
305304
305
+/* Apply dqtrx changes to the quota reservation counters. */
306
+static inline void
307
+xfs_apply_quota_reservation_deltas(
308
+ struct xfs_dquot_res *res,
309
+ uint64_t reserved,
310
+ int64_t res_used,
311
+ int64_t count_delta)
312
+{
313
+ if (reserved != 0) {
314
+ /*
315
+ * Subtle math here: If reserved > res_used (the normal case),
316
+ * we're simply subtracting the unused transaction quota
317
+ * reservation from the dquot reservation.
318
+ *
319
+ * If, however, res_used > reserved, then we have allocated
320
+ * more quota blocks than were reserved for the transaction.
321
+ * We must add that excess to the dquot reservation since it
322
+ * tracks (usage + resv) and by definition we didn't reserve
323
+ * that excess.
324
+ */
325
+ res->reserved -= abs(reserved - res_used);
326
+ } else if (count_delta != 0) {
327
+ /*
328
+ * These blks were never reserved, either inside a transaction
329
+ * or outside one (in a delayed allocation). Also, this isn't
330
+ * always a negative number since we sometimes deliberately
331
+ * skip quota reservations.
332
+ */
333
+ res->reserved += count_delta;
334
+ }
335
+}
306336
307337 /*
308338 * Called by xfs_trans_commit() and similar in spirit to
....@@ -319,9 +349,8 @@
319349 int i, j;
320350 struct xfs_dquot *dqp;
321351 struct xfs_dqtrx *qtrx, *qa;
322
- struct xfs_disk_dquot *d;
323
- long totalbdelta;
324
- long totalrtbdelta;
352
+ int64_t totalbdelta;
353
+ int64_t totalrtbdelta;
325354
326355 if (!(tp->t_flags & XFS_TRANS_DQ_DIRTY))
327356 return;
....@@ -338,6 +367,8 @@
338367 xfs_trans_dqlockedjoin(tp, qa);
339368
340369 for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
370
+ uint64_t blk_res_used;
371
+
341372 qtrx = &qa[i];
342373 /*
343374 * The array of dquots is filled
....@@ -347,12 +378,10 @@
347378 break;
348379
349380 ASSERT(XFS_DQ_IS_LOCKED(dqp));
350
- ASSERT(dqp->q_transp == tp);
351381
352382 /*
353383 * adjust the actual number of blocks used
354384 */
355
- d = &dqp->q_core;
356385
357386 /*
358387 * The issue here is - sometimes we don't make a blkquota
....@@ -371,38 +400,46 @@
371400 qtrx->qt_delbcnt_delta;
372401 totalrtbdelta = qtrx->qt_rtbcount_delta +
373402 qtrx->qt_delrtb_delta;
403
+
404
+ if (totalbdelta != 0 || totalrtbdelta != 0 ||
405
+ qtrx->qt_icount_delta != 0) {
406
+ trace_xfs_trans_apply_dquot_deltas_before(dqp);
407
+ trace_xfs_trans_apply_dquot_deltas(qtrx);
408
+ }
409
+
374410 #ifdef DEBUG
375411 if (totalbdelta < 0)
376
- ASSERT(be64_to_cpu(d->d_bcount) >=
377
- -totalbdelta);
412
+ ASSERT(dqp->q_blk.count >= -totalbdelta);
378413
379414 if (totalrtbdelta < 0)
380
- ASSERT(be64_to_cpu(d->d_rtbcount) >=
381
- -totalrtbdelta);
415
+ ASSERT(dqp->q_rtb.count >= -totalrtbdelta);
382416
383417 if (qtrx->qt_icount_delta < 0)
384
- ASSERT(be64_to_cpu(d->d_icount) >=
385
- -qtrx->qt_icount_delta);
418
+ ASSERT(dqp->q_ino.count >= -qtrx->qt_icount_delta);
386419 #endif
387420 if (totalbdelta)
388
- be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta);
421
+ dqp->q_blk.count += totalbdelta;
389422
390423 if (qtrx->qt_icount_delta)
391
- be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta);
424
+ dqp->q_ino.count += qtrx->qt_icount_delta;
392425
393426 if (totalrtbdelta)
394
- be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta);
427
+ dqp->q_rtb.count += totalrtbdelta;
428
+
429
+ if (totalbdelta != 0 || totalrtbdelta != 0 ||
430
+ qtrx->qt_icount_delta != 0)
431
+ trace_xfs_trans_apply_dquot_deltas_after(dqp);
395432
396433 /*
397434 * Get any default limits in use.
398435 * Start/reset the timer(s) if needed.
399436 */
400
- if (d->d_id) {
401
- xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
402
- xfs_qm_adjust_dqtimers(tp->t_mountp, d);
437
+ if (dqp->q_id) {
438
+ xfs_qm_adjust_dqlimits(dqp);
439
+ xfs_qm_adjust_dqtimers(dqp);
403440 }
404441
405
- dqp->dq_flags |= XFS_DQ_DIRTY;
442
+ dqp->q_flags |= XFS_DQFLAG_DIRTY;
406443 /*
407444 * add this to the list of items to get logged
408445 */
....@@ -412,78 +449,31 @@
412449 * In case of delayed allocations, there's no
413450 * reservation that a transaction structure knows of.
414451 */
415
- if (qtrx->qt_blk_res != 0) {
416
- ulong blk_res_used = 0;
452
+ blk_res_used = max_t(int64_t, 0, qtrx->qt_bcount_delta);
453
+ xfs_apply_quota_reservation_deltas(&dqp->q_blk,
454
+ qtrx->qt_blk_res, blk_res_used,
455
+ qtrx->qt_bcount_delta);
417456
418
- if (qtrx->qt_bcount_delta > 0)
419
- blk_res_used = qtrx->qt_bcount_delta;
420
-
421
- if (qtrx->qt_blk_res != blk_res_used) {
422
- if (qtrx->qt_blk_res > blk_res_used)
423
- dqp->q_res_bcount -= (xfs_qcnt_t)
424
- (qtrx->qt_blk_res -
425
- blk_res_used);
426
- else
427
- dqp->q_res_bcount -= (xfs_qcnt_t)
428
- (blk_res_used -
429
- qtrx->qt_blk_res);
430
- }
431
- } else {
432
- /*
433
- * These blks were never reserved, either inside
434
- * a transaction or outside one (in a delayed
435
- * allocation). Also, this isn't always a
436
- * negative number since we sometimes
437
- * deliberately skip quota reservations.
438
- */
439
- if (qtrx->qt_bcount_delta) {
440
- dqp->q_res_bcount +=
441
- (xfs_qcnt_t)qtrx->qt_bcount_delta;
442
- }
443
- }
444457 /*
445458 * Adjust the RT reservation.
446459 */
447
- if (qtrx->qt_rtblk_res != 0) {
448
- if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
449
- if (qtrx->qt_rtblk_res >
450
- qtrx->qt_rtblk_res_used)
451
- dqp->q_res_rtbcount -= (xfs_qcnt_t)
452
- (qtrx->qt_rtblk_res -
453
- qtrx->qt_rtblk_res_used);
454
- else
455
- dqp->q_res_rtbcount -= (xfs_qcnt_t)
456
- (qtrx->qt_rtblk_res_used -
457
- qtrx->qt_rtblk_res);
458
- }
459
- } else {
460
- if (qtrx->qt_rtbcount_delta)
461
- dqp->q_res_rtbcount +=
462
- (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
463
- }
460
+ xfs_apply_quota_reservation_deltas(&dqp->q_rtb,
461
+ qtrx->qt_rtblk_res,
462
+ qtrx->qt_rtblk_res_used,
463
+ qtrx->qt_rtbcount_delta);
464464
465465 /*
466466 * Adjust the inode reservation.
467467 */
468
- if (qtrx->qt_ino_res != 0) {
469
- ASSERT(qtrx->qt_ino_res >=
470
- qtrx->qt_ino_res_used);
471
- if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
472
- dqp->q_res_icount -= (xfs_qcnt_t)
473
- (qtrx->qt_ino_res -
474
- qtrx->qt_ino_res_used);
475
- } else {
476
- if (qtrx->qt_icount_delta)
477
- dqp->q_res_icount +=
478
- (xfs_qcnt_t)qtrx->qt_icount_delta;
479
- }
468
+ ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
469
+ xfs_apply_quota_reservation_deltas(&dqp->q_ino,
470
+ qtrx->qt_ino_res,
471
+ qtrx->qt_ino_res_used,
472
+ qtrx->qt_icount_delta);
480473
481
- ASSERT(dqp->q_res_bcount >=
482
- be64_to_cpu(dqp->q_core.d_bcount));
483
- ASSERT(dqp->q_res_icount >=
484
- be64_to_cpu(dqp->q_core.d_icount));
485
- ASSERT(dqp->q_res_rtbcount >=
486
- be64_to_cpu(dqp->q_core.d_rtbcount));
474
+ ASSERT(dqp->q_blk.reserved >= dqp->q_blk.count);
475
+ ASSERT(dqp->q_ino.reserved >= dqp->q_ino.count);
476
+ ASSERT(dqp->q_rtb.reserved >= dqp->q_rtb.count);
487477 }
488478 }
489479 }
....@@ -497,12 +487,12 @@
497487 */
498488 void
499489 xfs_trans_unreserve_and_mod_dquots(
500
- xfs_trans_t *tp)
490
+ struct xfs_trans *tp)
501491 {
502492 int i, j;
503
- xfs_dquot_t *dqp;
504
- xfs_dqtrx_t *qtrx, *qa;
505
- bool locked;
493
+ struct xfs_dquot *dqp;
494
+ struct xfs_dqtrx *qtrx, *qa;
495
+ bool locked;
506496
507497 if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
508498 return;
....@@ -527,7 +517,7 @@
527517 if (qtrx->qt_blk_res) {
528518 xfs_dqlock(dqp);
529519 locked = true;
530
- dqp->q_res_bcount -=
520
+ dqp->q_blk.reserved -=
531521 (xfs_qcnt_t)qtrx->qt_blk_res;
532522 }
533523 if (qtrx->qt_ino_res) {
....@@ -535,7 +525,7 @@
535525 xfs_dqlock(dqp);
536526 locked = true;
537527 }
538
- dqp->q_res_icount -=
528
+ dqp->q_ino.reserved -=
539529 (xfs_qcnt_t)qtrx->qt_ino_res;
540530 }
541531
....@@ -544,7 +534,7 @@
544534 xfs_dqlock(dqp);
545535 locked = true;
546536 }
547
- dqp->q_res_rtbcount -=
537
+ dqp->q_rtb.reserved -=
548538 (xfs_qcnt_t)qtrx->qt_rtblk_res;
549539 }
550540 if (locked)
....@@ -560,18 +550,76 @@
560550 struct xfs_dquot *dqp,
561551 int type)
562552 {
563
- enum quota_type qtype;
553
+ enum quota_type qtype;
564554
565
- if (dqp->dq_flags & XFS_DQ_PROJ)
555
+ switch (xfs_dquot_type(dqp)) {
556
+ case XFS_DQTYPE_PROJ:
566557 qtype = PRJQUOTA;
567
- else if (dqp->dq_flags & XFS_DQ_USER)
558
+ break;
559
+ case XFS_DQTYPE_USER:
568560 qtype = USRQUOTA;
569
- else
561
+ break;
562
+ case XFS_DQTYPE_GROUP:
570563 qtype = GRPQUOTA;
564
+ break;
565
+ default:
566
+ return;
567
+ }
571568
572
- quota_send_warning(make_kqid(&init_user_ns, qtype,
573
- be32_to_cpu(dqp->q_core.d_id)),
569
+ quota_send_warning(make_kqid(&init_user_ns, qtype, dqp->q_id),
574570 mp->m_super->s_dev, type);
571
+}
572
+
573
+/*
574
+ * Decide if we can make an additional reservation against a quota resource.
575
+ * Returns an inode QUOTA_NL_ warning code and whether or not it's fatal.
576
+ *
577
+ * Note that we assume that the numeric difference between the inode and block
578
+ * warning codes will always be 3 since it's userspace ABI now, and will never
579
+ * decrease the quota reservation, so the *BELOW messages are irrelevant.
580
+ */
581
+static inline int
582
+xfs_dqresv_check(
583
+ struct xfs_dquot_res *res,
584
+ struct xfs_quota_limits *qlim,
585
+ int64_t delta,
586
+ bool *fatal)
587
+{
588
+ xfs_qcnt_t hardlimit = res->hardlimit;
589
+ xfs_qcnt_t softlimit = res->softlimit;
590
+ xfs_qcnt_t total_count = res->reserved + delta;
591
+
592
+ BUILD_BUG_ON(QUOTA_NL_BHARDWARN != QUOTA_NL_IHARDWARN + 3);
593
+ BUILD_BUG_ON(QUOTA_NL_BSOFTLONGWARN != QUOTA_NL_ISOFTLONGWARN + 3);
594
+ BUILD_BUG_ON(QUOTA_NL_BSOFTWARN != QUOTA_NL_ISOFTWARN + 3);
595
+
596
+ *fatal = false;
597
+ if (delta <= 0)
598
+ return QUOTA_NL_NOWARN;
599
+
600
+ if (!hardlimit)
601
+ hardlimit = qlim->hard;
602
+ if (!softlimit)
603
+ softlimit = qlim->soft;
604
+
605
+ if (hardlimit && total_count > hardlimit) {
606
+ *fatal = true;
607
+ return QUOTA_NL_IHARDWARN;
608
+ }
609
+
610
+ if (softlimit && total_count > softlimit) {
611
+ time64_t now = ktime_get_real_seconds();
612
+
613
+ if ((res->timer != 0 && now > res->timer) ||
614
+ (res->warnings != 0 && res->warnings >= qlim->warn)) {
615
+ *fatal = true;
616
+ return QUOTA_NL_ISOFTLONGWARN;
617
+ }
618
+
619
+ return QUOTA_NL_ISOFTWARN;
620
+ }
621
+
622
+ return QUOTA_NL_NOWARN;
575623 }
576624
577625 /*
....@@ -582,115 +630,65 @@
582630 */
583631 STATIC int
584632 xfs_trans_dqresv(
585
- xfs_trans_t *tp,
586
- xfs_mount_t *mp,
587
- xfs_dquot_t *dqp,
588
- long nblks,
589
- long ninos,
590
- uint flags)
633
+ struct xfs_trans *tp,
634
+ struct xfs_mount *mp,
635
+ struct xfs_dquot *dqp,
636
+ int64_t nblks,
637
+ long ninos,
638
+ uint flags)
591639 {
592
- xfs_qcnt_t hardlimit;
593
- xfs_qcnt_t softlimit;
594
- time_t timer;
595
- xfs_qwarncnt_t warns;
596
- xfs_qwarncnt_t warnlimit;
597
- xfs_qcnt_t total_count;
598
- xfs_qcnt_t *resbcountp;
599
- xfs_quotainfo_t *q = mp->m_quotainfo;
640
+ struct xfs_quotainfo *q = mp->m_quotainfo;
600641 struct xfs_def_quota *defq;
601
-
642
+ struct xfs_dquot_res *blkres;
643
+ struct xfs_quota_limits *qlim;
602644
603645 xfs_dqlock(dqp);
604646
605
- defq = xfs_get_defquota(dqp, q);
647
+ defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
606648
607649 if (flags & XFS_TRANS_DQ_RES_BLKS) {
608
- hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
609
- if (!hardlimit)
610
- hardlimit = defq->bhardlimit;
611
- softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit);
612
- if (!softlimit)
613
- softlimit = defq->bsoftlimit;
614
- timer = be32_to_cpu(dqp->q_core.d_btimer);
615
- warns = be16_to_cpu(dqp->q_core.d_bwarns);
616
- warnlimit = dqp->q_mount->m_quotainfo->qi_bwarnlimit;
617
- resbcountp = &dqp->q_res_bcount;
650
+ blkres = &dqp->q_blk;
651
+ qlim = &defq->blk;
618652 } else {
619
- ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
620
- hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
621
- if (!hardlimit)
622
- hardlimit = defq->rtbhardlimit;
623
- softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit);
624
- if (!softlimit)
625
- softlimit = defq->rtbsoftlimit;
626
- timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
627
- warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
628
- warnlimit = dqp->q_mount->m_quotainfo->qi_rtbwarnlimit;
629
- resbcountp = &dqp->q_res_rtbcount;
653
+ blkres = &dqp->q_rtb;
654
+ qlim = &defq->rtb;
630655 }
631656
632
- if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
633
- dqp->q_core.d_id &&
634
- ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
635
- (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
636
- (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
637
- if (nblks > 0) {
657
+ if ((flags & XFS_QMOPT_FORCE_RES) == 0 && dqp->q_id &&
658
+ xfs_dquot_is_enforced(dqp)) {
659
+ int quota_nl;
660
+ bool fatal;
661
+
662
+ /*
663
+ * dquot is locked already. See if we'd go over the hardlimit
664
+ * or exceed the timelimit if we'd reserve resources.
665
+ */
666
+ quota_nl = xfs_dqresv_check(blkres, qlim, nblks, &fatal);
667
+ if (quota_nl != QUOTA_NL_NOWARN) {
638668 /*
639
- * dquot is locked already. See if we'd go over the
640
- * hardlimit or exceed the timelimit if we allocate
641
- * nblks.
669
+ * Quota block warning codes are 3 more than the inode
670
+ * codes, which we check above.
642671 */
643
- total_count = *resbcountp + nblks;
644
- if (hardlimit && total_count > hardlimit) {
645
- xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
672
+ xfs_quota_warn(mp, dqp, quota_nl + 3);
673
+ if (fatal)
646674 goto error_return;
647
- }
648
- if (softlimit && total_count > softlimit) {
649
- if ((timer != 0 && get_seconds() > timer) ||
650
- (warns != 0 && warns >= warnlimit)) {
651
- xfs_quota_warn(mp, dqp,
652
- QUOTA_NL_BSOFTLONGWARN);
653
- goto error_return;
654
- }
655
-
656
- xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN);
657
- }
658675 }
659
- if (ninos > 0) {
660
- total_count = dqp->q_res_icount + ninos;
661
- timer = be32_to_cpu(dqp->q_core.d_itimer);
662
- warns = be16_to_cpu(dqp->q_core.d_iwarns);
663
- warnlimit = dqp->q_mount->m_quotainfo->qi_iwarnlimit;
664
- hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
665
- if (!hardlimit)
666
- hardlimit = defq->ihardlimit;
667
- softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
668
- if (!softlimit)
669
- softlimit = defq->isoftlimit;
670676
671
- if (hardlimit && total_count > hardlimit) {
672
- xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
677
+ quota_nl = xfs_dqresv_check(&dqp->q_ino, &defq->ino, ninos,
678
+ &fatal);
679
+ if (quota_nl != QUOTA_NL_NOWARN) {
680
+ xfs_quota_warn(mp, dqp, quota_nl);
681
+ if (fatal)
673682 goto error_return;
674
- }
675
- if (softlimit && total_count > softlimit) {
676
- if ((timer != 0 && get_seconds() > timer) ||
677
- (warns != 0 && warns >= warnlimit)) {
678
- xfs_quota_warn(mp, dqp,
679
- QUOTA_NL_ISOFTLONGWARN);
680
- goto error_return;
681
- }
682
- xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTWARN);
683
- }
684683 }
685684 }
686685
687686 /*
688687 * Change the reservation, but not the actual usage.
689
- * Note that q_res_bcount = q_core.d_bcount + resv
688
+ * Note that q_blk.reserved = q_blk.count + resv
690689 */
691
- (*resbcountp) += (xfs_qcnt_t)nblks;
692
- if (ninos != 0)
693
- dqp->q_res_icount += (xfs_qcnt_t)ninos;
690
+ blkres->reserved += (xfs_qcnt_t)nblks;
691
+ dqp->q_ino.reserved += (xfs_qcnt_t)ninos;
694692
695693 /*
696694 * note the reservation amt in the trans struct too,
....@@ -711,18 +709,24 @@
711709 XFS_TRANS_DQ_RES_INOS,
712710 ninos);
713711 }
714
- ASSERT(dqp->q_res_bcount >= be64_to_cpu(dqp->q_core.d_bcount));
715
- ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount));
716
- ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
712
+
713
+ if (XFS_IS_CORRUPT(mp, dqp->q_blk.reserved < dqp->q_blk.count) ||
714
+ XFS_IS_CORRUPT(mp, dqp->q_rtb.reserved < dqp->q_rtb.count) ||
715
+ XFS_IS_CORRUPT(mp, dqp->q_ino.reserved < dqp->q_ino.count))
716
+ goto error_corrupt;
717717
718718 xfs_dqunlock(dqp);
719719 return 0;
720720
721721 error_return:
722722 xfs_dqunlock(dqp);
723
- if (flags & XFS_QMOPT_ENOSPC)
723
+ if (xfs_dquot_type(dqp) == XFS_DQTYPE_PROJ)
724724 return -ENOSPC;
725725 return -EDQUOT;
726
+error_corrupt:
727
+ xfs_dqunlock(dqp);
728
+ xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
729
+ return -EFSCORRUPTED;
726730 }
727731
728732
....@@ -745,7 +749,7 @@
745749 struct xfs_dquot *udqp,
746750 struct xfs_dquot *gdqp,
747751 struct xfs_dquot *pdqp,
748
- long nblks,
752
+ int64_t nblks,
749753 long ninos,
750754 uint flags)
751755 {
....@@ -760,8 +764,7 @@
760764 ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
761765
762766 if (udqp) {
763
- error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
764
- (flags & ~XFS_QMOPT_ENOSPC));
767
+ error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos, flags);
765768 if (error)
766769 return error;
767770 }
....@@ -804,7 +807,7 @@
804807 xfs_trans_reserve_quota_nblks(
805808 struct xfs_trans *tp,
806809 struct xfs_inode *ip,
807
- long nblks,
810
+ int64_t nblks,
808811 long ninos,
809812 uint flags)
810813 {
....@@ -812,16 +815,12 @@
812815
813816 if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
814817 return 0;
815
- if (XFS_IS_PQUOTA_ON(mp))
816
- flags |= XFS_QMOPT_ENOSPC;
817818
818819 ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino));
819820
820821 ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
821
- ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
822
- XFS_TRANS_DQ_RES_RTBLKS ||
823
- (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
824
- XFS_TRANS_DQ_RES_BLKS);
822
+ ASSERT((flags & ~(XFS_QMOPT_FORCE_RES)) == XFS_TRANS_DQ_RES_RTBLKS ||
823
+ (flags & ~(XFS_QMOPT_FORCE_RES)) == XFS_TRANS_DQ_RES_BLKS);
825824
826825 /*
827826 * Reserve nblks against these dquots, with trans as the mediator.
....@@ -835,13 +834,13 @@
835834 /*
836835 * This routine is called to allocate a quotaoff log item.
837836 */
838
-xfs_qoff_logitem_t *
837
+struct xfs_qoff_logitem *
839838 xfs_trans_get_qoff_item(
840
- xfs_trans_t *tp,
841
- xfs_qoff_logitem_t *startqoff,
839
+ struct xfs_trans *tp,
840
+ struct xfs_qoff_logitem *startqoff,
842841 uint flags)
843842 {
844
- xfs_qoff_logitem_t *q;
843
+ struct xfs_qoff_logitem *q;
845844
846845 ASSERT(tp != NULL);
847846
....@@ -863,8 +862,8 @@
863862 */
864863 void
865864 xfs_trans_log_quotaoff_item(
866
- xfs_trans_t *tp,
867
- xfs_qoff_logitem_t *qlp)
865
+ struct xfs_trans *tp,
866
+ struct xfs_qoff_logitem *qlp)
868867 {
869868 tp->t_flags |= XFS_TRANS_DIRTY;
870869 set_bit(XFS_LI_DIRTY, &qlp->qql_item.li_flags);
....@@ -874,7 +873,8 @@
874873 xfs_trans_alloc_dqinfo(
875874 xfs_trans_t *tp)
876875 {
877
- tp->t_dqinfo = kmem_zone_zalloc(xfs_qm_dqtrxzone, KM_SLEEP);
876
+ tp->t_dqinfo = kmem_cache_zalloc(xfs_qm_dqtrxzone,
877
+ GFP_KERNEL | __GFP_NOFAIL);
878878 }
879879
880880 void
....@@ -883,6 +883,6 @@
883883 {
884884 if (!tp->t_dqinfo)
885885 return;
886
- kmem_zone_free(xfs_qm_dqtrxzone, tp->t_dqinfo);
886
+ kmem_cache_free(xfs_qm_dqtrxzone, tp->t_dqinfo);
887887 tp->t_dqinfo = NULL;
888888 }