xfs_trans_dquot.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. /*
  2. * Copyright (c) 2000-2002 Silicon Graphics, Inc.
  3. * All Rights Reserved.
  4. *
  5. * This program is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU General Public License as
  7. * published by the Free Software Foundation.
  8. *
  9. * This program is distributed in the hope that it would be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write the Free Software Foundation,
  16. * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #include "xfs.h"
  19. #include "xfs_fs.h"
  20. #include "xfs_bit.h"
  21. #include "xfs_log.h"
  22. #include "xfs_trans.h"
  23. #include "xfs_sb.h"
  24. #include "xfs_ag.h"
  25. #include "xfs_alloc.h"
  26. #include "xfs_quota.h"
  27. #include "xfs_mount.h"
  28. #include "xfs_bmap_btree.h"
  29. #include "xfs_inode.h"
  30. #include "xfs_itable.h"
  31. #include "xfs_bmap.h"
  32. #include "xfs_rtalloc.h"
  33. #include "xfs_error.h"
  34. #include "xfs_attr.h"
  35. #include "xfs_buf_item.h"
  36. #include "xfs_trans_priv.h"
  37. #include "xfs_qm.h"
  38. STATIC void xfs_trans_alloc_dqinfo(xfs_trans_t *);
  39. /*
  40. * Add the locked dquot to the transaction.
  41. * The dquot must be locked, and it cannot be associated with any
  42. * transaction.
  43. */
  44. void
  45. xfs_trans_dqjoin(
  46. xfs_trans_t *tp,
  47. xfs_dquot_t *dqp)
  48. {
  49. ASSERT(dqp->q_transp != tp);
  50. ASSERT(XFS_DQ_IS_LOCKED(dqp));
  51. ASSERT(dqp->q_logitem.qli_dquot == dqp);
  52. /*
  53. * Get a log_item_desc to point at the new item.
  54. */
  55. xfs_trans_add_item(tp, &dqp->q_logitem.qli_item);
  56. /*
  57. * Initialize d_transp so we can later determine if this dquot is
  58. * associated with this transaction.
  59. */
  60. dqp->q_transp = tp;
  61. }
  62. /*
  63. * This is called to mark the dquot as needing
  64. * to be logged when the transaction is committed. The dquot must
  65. * already be associated with the given transaction.
  66. * Note that it marks the entire transaction as dirty. In the ordinary
  67. * case, this gets called via xfs_trans_commit, after the transaction
  68. * is already dirty. However, there's nothing stop this from getting
  69. * called directly, as done by xfs_qm_scall_setqlim. Hence, the TRANS_DIRTY
  70. * flag.
  71. */
  72. void
  73. xfs_trans_log_dquot(
  74. xfs_trans_t *tp,
  75. xfs_dquot_t *dqp)
  76. {
  77. ASSERT(dqp->q_transp == tp);
  78. ASSERT(XFS_DQ_IS_LOCKED(dqp));
  79. tp->t_flags |= XFS_TRANS_DIRTY;
  80. dqp->q_logitem.qli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
  81. }
  82. /*
  83. * Carry forward whatever is left of the quota blk reservation to
  84. * the spanky new transaction
  85. */
  86. void
  87. xfs_trans_dup_dqinfo(
  88. xfs_trans_t *otp,
  89. xfs_trans_t *ntp)
  90. {
  91. xfs_dqtrx_t *oq, *nq;
  92. int i,j;
  93. xfs_dqtrx_t *oqa, *nqa;
  94. if (!otp->t_dqinfo)
  95. return;
  96. xfs_trans_alloc_dqinfo(ntp);
  97. oqa = otp->t_dqinfo->dqa_usrdquots;
  98. nqa = ntp->t_dqinfo->dqa_usrdquots;
  99. /*
  100. * Because the quota blk reservation is carried forward,
  101. * it is also necessary to carry forward the DQ_DIRTY flag.
  102. */
  103. if(otp->t_flags & XFS_TRANS_DQ_DIRTY)
  104. ntp->t_flags |= XFS_TRANS_DQ_DIRTY;
  105. for (j = 0; j < 2; j++) {
  106. for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
  107. if (oqa[i].qt_dquot == NULL)
  108. break;
  109. oq = &oqa[i];
  110. nq = &nqa[i];
  111. nq->qt_dquot = oq->qt_dquot;
  112. nq->qt_bcount_delta = nq->qt_icount_delta = 0;
  113. nq->qt_rtbcount_delta = 0;
  114. /*
  115. * Transfer whatever is left of the reservations.
  116. */
  117. nq->qt_blk_res = oq->qt_blk_res - oq->qt_blk_res_used;
  118. oq->qt_blk_res = oq->qt_blk_res_used;
  119. nq->qt_rtblk_res = oq->qt_rtblk_res -
  120. oq->qt_rtblk_res_used;
  121. oq->qt_rtblk_res = oq->qt_rtblk_res_used;
  122. nq->qt_ino_res = oq->qt_ino_res - oq->qt_ino_res_used;
  123. oq->qt_ino_res = oq->qt_ino_res_used;
  124. }
  125. oqa = otp->t_dqinfo->dqa_grpdquots;
  126. nqa = ntp->t_dqinfo->dqa_grpdquots;
  127. }
  128. }
  129. /*
  130. * Wrap around mod_dquot to account for both user and group quotas.
  131. */
  132. void
  133. xfs_trans_mod_dquot_byino(
  134. xfs_trans_t *tp,
  135. xfs_inode_t *ip,
  136. uint field,
  137. long delta)
  138. {
  139. xfs_mount_t *mp = tp->t_mountp;
  140. if (!XFS_IS_QUOTA_RUNNING(mp) ||
  141. !XFS_IS_QUOTA_ON(mp) ||
  142. ip->i_ino == mp->m_sb.sb_uquotino ||
  143. ip->i_ino == mp->m_sb.sb_gquotino)
  144. return;
  145. if (tp->t_dqinfo == NULL)
  146. xfs_trans_alloc_dqinfo(tp);
  147. if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
  148. (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
  149. if (XFS_IS_OQUOTA_ON(mp) && ip->i_gdquot)
  150. (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
  151. }
  152. STATIC xfs_dqtrx_t *
  153. xfs_trans_get_dqtrx(
  154. xfs_trans_t *tp,
  155. xfs_dquot_t *dqp)
  156. {
  157. int i;
  158. xfs_dqtrx_t *qa;
  159. qa = XFS_QM_ISUDQ(dqp) ?
  160. tp->t_dqinfo->dqa_usrdquots : tp->t_dqinfo->dqa_grpdquots;
  161. for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
  162. if (qa[i].qt_dquot == NULL ||
  163. qa[i].qt_dquot == dqp)
  164. return &qa[i];
  165. }
  166. return NULL;
  167. }
  168. /*
  169. * Make the changes in the transaction structure.
  170. * The moral equivalent to xfs_trans_mod_sb().
  171. * We don't touch any fields in the dquot, so we don't care
  172. * if it's locked or not (most of the time it won't be).
  173. */
  174. void
  175. xfs_trans_mod_dquot(
  176. xfs_trans_t *tp,
  177. xfs_dquot_t *dqp,
  178. uint field,
  179. long delta)
  180. {
  181. xfs_dqtrx_t *qtrx;
  182. ASSERT(tp);
  183. ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp));
  184. qtrx = NULL;
  185. if (tp->t_dqinfo == NULL)
  186. xfs_trans_alloc_dqinfo(tp);
  187. /*
  188. * Find either the first free slot or the slot that belongs
  189. * to this dquot.
  190. */
  191. qtrx = xfs_trans_get_dqtrx(tp, dqp);
  192. ASSERT(qtrx);
  193. if (qtrx->qt_dquot == NULL)
  194. qtrx->qt_dquot = dqp;
  195. switch (field) {
  196. /*
  197. * regular disk blk reservation
  198. */
  199. case XFS_TRANS_DQ_RES_BLKS:
  200. qtrx->qt_blk_res += (ulong)delta;
  201. break;
  202. /*
  203. * inode reservation
  204. */
  205. case XFS_TRANS_DQ_RES_INOS:
  206. qtrx->qt_ino_res += (ulong)delta;
  207. break;
  208. /*
  209. * disk blocks used.
  210. */
  211. case XFS_TRANS_DQ_BCOUNT:
  212. if (qtrx->qt_blk_res && delta > 0) {
  213. qtrx->qt_blk_res_used += (ulong)delta;
  214. ASSERT(qtrx->qt_blk_res >= qtrx->qt_blk_res_used);
  215. }
  216. qtrx->qt_bcount_delta += delta;
  217. break;
  218. case XFS_TRANS_DQ_DELBCOUNT:
  219. qtrx->qt_delbcnt_delta += delta;
  220. break;
  221. /*
  222. * Inode Count
  223. */
  224. case XFS_TRANS_DQ_ICOUNT:
  225. if (qtrx->qt_ino_res && delta > 0) {
  226. qtrx->qt_ino_res_used += (ulong)delta;
  227. ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
  228. }
  229. qtrx->qt_icount_delta += delta;
  230. break;
  231. /*
  232. * rtblk reservation
  233. */
  234. case XFS_TRANS_DQ_RES_RTBLKS:
  235. qtrx->qt_rtblk_res += (ulong)delta;
  236. break;
  237. /*
  238. * rtblk count
  239. */
  240. case XFS_TRANS_DQ_RTBCOUNT:
  241. if (qtrx->qt_rtblk_res && delta > 0) {
  242. qtrx->qt_rtblk_res_used += (ulong)delta;
  243. ASSERT(qtrx->qt_rtblk_res >= qtrx->qt_rtblk_res_used);
  244. }
  245. qtrx->qt_rtbcount_delta += delta;
  246. break;
  247. case XFS_TRANS_DQ_DELRTBCOUNT:
  248. qtrx->qt_delrtb_delta += delta;
  249. break;
  250. default:
  251. ASSERT(0);
  252. }
  253. tp->t_flags |= XFS_TRANS_DQ_DIRTY;
  254. }
  255. /*
  256. * Given an array of dqtrx structures, lock all the dquots associated
  257. * and join them to the transaction, provided they have been modified.
  258. * We know that the highest number of dquots (of one type - usr OR grp),
  259. * involved in a transaction is 2 and that both usr and grp combined - 3.
  260. * So, we don't attempt to make this very generic.
  261. */
  262. STATIC void
  263. xfs_trans_dqlockedjoin(
  264. xfs_trans_t *tp,
  265. xfs_dqtrx_t *q)
  266. {
  267. ASSERT(q[0].qt_dquot != NULL);
  268. if (q[1].qt_dquot == NULL) {
  269. xfs_dqlock(q[0].qt_dquot);
  270. xfs_trans_dqjoin(tp, q[0].qt_dquot);
  271. } else {
  272. ASSERT(XFS_QM_TRANS_MAXDQS == 2);
  273. xfs_dqlock2(q[0].qt_dquot, q[1].qt_dquot);
  274. xfs_trans_dqjoin(tp, q[0].qt_dquot);
  275. xfs_trans_dqjoin(tp, q[1].qt_dquot);
  276. }
  277. }
  278. /*
  279. * Called by xfs_trans_commit() and similar in spirit to
  280. * xfs_trans_apply_sb_deltas().
  281. * Go thru all the dquots belonging to this transaction and modify the
  282. * INCORE dquot to reflect the actual usages.
  283. * Unreserve just the reservations done by this transaction.
  284. * dquot is still left locked at exit.
  285. */
  286. void
  287. xfs_trans_apply_dquot_deltas(
  288. xfs_trans_t *tp)
  289. {
  290. int i, j;
  291. xfs_dquot_t *dqp;
  292. xfs_dqtrx_t *qtrx, *qa;
  293. xfs_disk_dquot_t *d;
  294. long totalbdelta;
  295. long totalrtbdelta;
  296. if (!(tp->t_flags & XFS_TRANS_DQ_DIRTY))
  297. return;
  298. ASSERT(tp->t_dqinfo);
  299. qa = tp->t_dqinfo->dqa_usrdquots;
  300. for (j = 0; j < 2; j++) {
  301. if (qa[0].qt_dquot == NULL) {
  302. qa = tp->t_dqinfo->dqa_grpdquots;
  303. continue;
  304. }
  305. /*
  306. * Lock all of the dquots and join them to the transaction.
  307. */
  308. xfs_trans_dqlockedjoin(tp, qa);
  309. for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
  310. qtrx = &qa[i];
  311. /*
  312. * The array of dquots is filled
  313. * sequentially, not sparsely.
  314. */
  315. if ((dqp = qtrx->qt_dquot) == NULL)
  316. break;
  317. ASSERT(XFS_DQ_IS_LOCKED(dqp));
  318. ASSERT(dqp->q_transp == tp);
  319. /*
  320. * adjust the actual number of blocks used
  321. */
  322. d = &dqp->q_core;
  323. /*
  324. * The issue here is - sometimes we don't make a blkquota
  325. * reservation intentionally to be fair to users
  326. * (when the amount is small). On the other hand,
  327. * delayed allocs do make reservations, but that's
  328. * outside of a transaction, so we have no
  329. * idea how much was really reserved.
  330. * So, here we've accumulated delayed allocation blks and
  331. * non-delay blks. The assumption is that the
  332. * delayed ones are always reserved (outside of a
  333. * transaction), and the others may or may not have
  334. * quota reservations.
  335. */
  336. totalbdelta = qtrx->qt_bcount_delta +
  337. qtrx->qt_delbcnt_delta;
  338. totalrtbdelta = qtrx->qt_rtbcount_delta +
  339. qtrx->qt_delrtb_delta;
  340. #ifdef DEBUG
  341. if (totalbdelta < 0)
  342. ASSERT(be64_to_cpu(d->d_bcount) >=
  343. -totalbdelta);
  344. if (totalrtbdelta < 0)
  345. ASSERT(be64_to_cpu(d->d_rtbcount) >=
  346. -totalrtbdelta);
  347. if (qtrx->qt_icount_delta < 0)
  348. ASSERT(be64_to_cpu(d->d_icount) >=
  349. -qtrx->qt_icount_delta);
  350. #endif
  351. if (totalbdelta)
  352. be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta);
  353. if (qtrx->qt_icount_delta)
  354. be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta);
  355. if (totalrtbdelta)
  356. be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta);
  357. /*
  358. * Get any default limits in use.
  359. * Start/reset the timer(s) if needed.
  360. */
  361. if (d->d_id) {
  362. xfs_qm_adjust_dqlimits(tp->t_mountp, d);
  363. xfs_qm_adjust_dqtimers(tp->t_mountp, d);
  364. }
  365. dqp->dq_flags |= XFS_DQ_DIRTY;
  366. /*
  367. * add this to the list of items to get logged
  368. */
  369. xfs_trans_log_dquot(tp, dqp);
  370. /*
  371. * Take off what's left of the original reservation.
  372. * In case of delayed allocations, there's no
  373. * reservation that a transaction structure knows of.
  374. */
  375. if (qtrx->qt_blk_res != 0) {
  376. if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
  377. if (qtrx->qt_blk_res >
  378. qtrx->qt_blk_res_used)
  379. dqp->q_res_bcount -= (xfs_qcnt_t)
  380. (qtrx->qt_blk_res -
  381. qtrx->qt_blk_res_used);
  382. else
  383. dqp->q_res_bcount -= (xfs_qcnt_t)
  384. (qtrx->qt_blk_res_used -
  385. qtrx->qt_blk_res);
  386. }
  387. } else {
  388. /*
  389. * These blks were never reserved, either inside
  390. * a transaction or outside one (in a delayed
  391. * allocation). Also, this isn't always a
  392. * negative number since we sometimes
  393. * deliberately skip quota reservations.
  394. */
  395. if (qtrx->qt_bcount_delta) {
  396. dqp->q_res_bcount +=
  397. (xfs_qcnt_t)qtrx->qt_bcount_delta;
  398. }
  399. }
  400. /*
  401. * Adjust the RT reservation.
  402. */
  403. if (qtrx->qt_rtblk_res != 0) {
  404. if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
  405. if (qtrx->qt_rtblk_res >
  406. qtrx->qt_rtblk_res_used)
  407. dqp->q_res_rtbcount -= (xfs_qcnt_t)
  408. (qtrx->qt_rtblk_res -
  409. qtrx->qt_rtblk_res_used);
  410. else
  411. dqp->q_res_rtbcount -= (xfs_qcnt_t)
  412. (qtrx->qt_rtblk_res_used -
  413. qtrx->qt_rtblk_res);
  414. }
  415. } else {
  416. if (qtrx->qt_rtbcount_delta)
  417. dqp->q_res_rtbcount +=
  418. (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
  419. }
  420. /*
  421. * Adjust the inode reservation.
  422. */
  423. if (qtrx->qt_ino_res != 0) {
  424. ASSERT(qtrx->qt_ino_res >=
  425. qtrx->qt_ino_res_used);
  426. if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
  427. dqp->q_res_icount -= (xfs_qcnt_t)
  428. (qtrx->qt_ino_res -
  429. qtrx->qt_ino_res_used);
  430. } else {
  431. if (qtrx->qt_icount_delta)
  432. dqp->q_res_icount +=
  433. (xfs_qcnt_t)qtrx->qt_icount_delta;
  434. }
  435. ASSERT(dqp->q_res_bcount >=
  436. be64_to_cpu(dqp->q_core.d_bcount));
  437. ASSERT(dqp->q_res_icount >=
  438. be64_to_cpu(dqp->q_core.d_icount));
  439. ASSERT(dqp->q_res_rtbcount >=
  440. be64_to_cpu(dqp->q_core.d_rtbcount));
  441. }
  442. /*
  443. * Do the group quotas next
  444. */
  445. qa = tp->t_dqinfo->dqa_grpdquots;
  446. }
  447. }
  448. /*
  449. * Release the reservations, and adjust the dquots accordingly.
  450. * This is called only when the transaction is being aborted. If by
  451. * any chance we have done dquot modifications incore (ie. deltas) already,
  452. * we simply throw those away, since that's the expected behavior
  453. * when a transaction is curtailed without a commit.
  454. */
  455. void
  456. xfs_trans_unreserve_and_mod_dquots(
  457. xfs_trans_t *tp)
  458. {
  459. int i, j;
  460. xfs_dquot_t *dqp;
  461. xfs_dqtrx_t *qtrx, *qa;
  462. boolean_t locked;
  463. if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
  464. return;
  465. qa = tp->t_dqinfo->dqa_usrdquots;
  466. for (j = 0; j < 2; j++) {
  467. for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
  468. qtrx = &qa[i];
  469. /*
  470. * We assume that the array of dquots is filled
  471. * sequentially, not sparsely.
  472. */
  473. if ((dqp = qtrx->qt_dquot) == NULL)
  474. break;
  475. /*
  476. * Unreserve the original reservation. We don't care
  477. * about the number of blocks used field, or deltas.
  478. * Also we don't bother to zero the fields.
  479. */
  480. locked = B_FALSE;
  481. if (qtrx->qt_blk_res) {
  482. xfs_dqlock(dqp);
  483. locked = B_TRUE;
  484. dqp->q_res_bcount -=
  485. (xfs_qcnt_t)qtrx->qt_blk_res;
  486. }
  487. if (qtrx->qt_ino_res) {
  488. if (!locked) {
  489. xfs_dqlock(dqp);
  490. locked = B_TRUE;
  491. }
  492. dqp->q_res_icount -=
  493. (xfs_qcnt_t)qtrx->qt_ino_res;
  494. }
  495. if (qtrx->qt_rtblk_res) {
  496. if (!locked) {
  497. xfs_dqlock(dqp);
  498. locked = B_TRUE;
  499. }
  500. dqp->q_res_rtbcount -=
  501. (xfs_qcnt_t)qtrx->qt_rtblk_res;
  502. }
  503. if (locked)
  504. xfs_dqunlock(dqp);
  505. }
  506. qa = tp->t_dqinfo->dqa_grpdquots;
  507. }
  508. }
  509. STATIC void
  510. xfs_quota_warn(
  511. struct xfs_mount *mp,
  512. struct xfs_dquot *dqp,
  513. int type)
  514. {
  515. /* no warnings for project quotas - we just return ENOSPC later */
  516. if (dqp->dq_flags & XFS_DQ_PROJ)
  517. return;
  518. quota_send_warning((dqp->dq_flags & XFS_DQ_USER) ? USRQUOTA : GRPQUOTA,
  519. be32_to_cpu(dqp->q_core.d_id), mp->m_super->s_dev,
  520. type);
  521. }
  522. /*
  523. * This reserves disk blocks and inodes against a dquot.
  524. * Flags indicate if the dquot is to be locked here and also
  525. * if the blk reservation is for RT or regular blocks.
  526. * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
  527. */
  528. STATIC int
  529. xfs_trans_dqresv(
  530. xfs_trans_t *tp,
  531. xfs_mount_t *mp,
  532. xfs_dquot_t *dqp,
  533. long nblks,
  534. long ninos,
  535. uint flags)
  536. {
  537. xfs_qcnt_t hardlimit;
  538. xfs_qcnt_t softlimit;
  539. time_t timer;
  540. xfs_qwarncnt_t warns;
  541. xfs_qwarncnt_t warnlimit;
  542. xfs_qcnt_t total_count;
  543. xfs_qcnt_t *resbcountp;
  544. xfs_quotainfo_t *q = mp->m_quotainfo;
  545. xfs_dqlock(dqp);
  546. if (flags & XFS_TRANS_DQ_RES_BLKS) {
  547. hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
  548. if (!hardlimit)
  549. hardlimit = q->qi_bhardlimit;
  550. softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit);
  551. if (!softlimit)
  552. softlimit = q->qi_bsoftlimit;
  553. timer = be32_to_cpu(dqp->q_core.d_btimer);
  554. warns = be16_to_cpu(dqp->q_core.d_bwarns);
  555. warnlimit = dqp->q_mount->m_quotainfo->qi_bwarnlimit;
  556. resbcountp = &dqp->q_res_bcount;
  557. } else {
  558. ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
  559. hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
  560. if (!hardlimit)
  561. hardlimit = q->qi_rtbhardlimit;
  562. softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit);
  563. if (!softlimit)
  564. softlimit = q->qi_rtbsoftlimit;
  565. timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
  566. warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
  567. warnlimit = dqp->q_mount->m_quotainfo->qi_rtbwarnlimit;
  568. resbcountp = &dqp->q_res_rtbcount;
  569. }
  570. if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
  571. dqp->q_core.d_id &&
  572. ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
  573. (XFS_IS_OQUOTA_ENFORCED(dqp->q_mount) &&
  574. (XFS_QM_ISPDQ(dqp) || XFS_QM_ISGDQ(dqp))))) {
  575. if (nblks > 0) {
  576. /*
  577. * dquot is locked already. See if we'd go over the
  578. * hardlimit or exceed the timelimit if we allocate
  579. * nblks.
  580. */
  581. total_count = *resbcountp + nblks;
  582. if (hardlimit && total_count > hardlimit) {
  583. xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
  584. goto error_return;
  585. }
  586. if (softlimit && total_count > softlimit) {
  587. if ((timer != 0 && get_seconds() > timer) ||
  588. (warns != 0 && warns >= warnlimit)) {
  589. xfs_quota_warn(mp, dqp,
  590. QUOTA_NL_BSOFTLONGWARN);
  591. goto error_return;
  592. }
  593. xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN);
  594. }
  595. }
  596. if (ninos > 0) {
  597. total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos;
  598. timer = be32_to_cpu(dqp->q_core.d_itimer);
  599. warns = be16_to_cpu(dqp->q_core.d_iwarns);
  600. warnlimit = dqp->q_mount->m_quotainfo->qi_iwarnlimit;
  601. hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
  602. if (!hardlimit)
  603. hardlimit = q->qi_ihardlimit;
  604. softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
  605. if (!softlimit)
  606. softlimit = q->qi_isoftlimit;
  607. if (hardlimit && total_count > hardlimit) {
  608. xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
  609. goto error_return;
  610. }
  611. if (softlimit && total_count > softlimit) {
  612. if ((timer != 0 && get_seconds() > timer) ||
  613. (warns != 0 && warns >= warnlimit)) {
  614. xfs_quota_warn(mp, dqp,
  615. QUOTA_NL_ISOFTLONGWARN);
  616. goto error_return;
  617. }
  618. xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTWARN);
  619. }
  620. }
  621. }
  622. /*
  623. * Change the reservation, but not the actual usage.
  624. * Note that q_res_bcount = q_core.d_bcount + resv
  625. */
  626. (*resbcountp) += (xfs_qcnt_t)nblks;
  627. if (ninos != 0)
  628. dqp->q_res_icount += (xfs_qcnt_t)ninos;
  629. /*
  630. * note the reservation amt in the trans struct too,
  631. * so that the transaction knows how much was reserved by
  632. * it against this particular dquot.
  633. * We don't do this when we are reserving for a delayed allocation,
  634. * because we don't have the luxury of a transaction envelope then.
  635. */
  636. if (tp) {
  637. ASSERT(tp->t_dqinfo);
  638. ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
  639. if (nblks != 0)
  640. xfs_trans_mod_dquot(tp, dqp,
  641. flags & XFS_QMOPT_RESBLK_MASK,
  642. nblks);
  643. if (ninos != 0)
  644. xfs_trans_mod_dquot(tp, dqp,
  645. XFS_TRANS_DQ_RES_INOS,
  646. ninos);
  647. }
  648. ASSERT(dqp->q_res_bcount >= be64_to_cpu(dqp->q_core.d_bcount));
  649. ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount));
  650. ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
  651. xfs_dqunlock(dqp);
  652. return 0;
  653. error_return:
  654. xfs_dqunlock(dqp);
  655. if (flags & XFS_QMOPT_ENOSPC)
  656. return ENOSPC;
  657. return EDQUOT;
  658. }
  659. /*
  660. * Given dquot(s), make disk block and/or inode reservations against them.
  661. * The fact that this does the reservation against both the usr and
  662. * grp/prj quotas is important, because this follows a both-or-nothing
  663. * approach.
  664. *
  665. * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
  666. * XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT. Used by pquota.
  667. * XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
  668. * XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
  669. * dquots are unlocked on return, if they were not locked by caller.
  670. */
  671. int
  672. xfs_trans_reserve_quota_bydquots(
  673. xfs_trans_t *tp,
  674. xfs_mount_t *mp,
  675. xfs_dquot_t *udqp,
  676. xfs_dquot_t *gdqp,
  677. long nblks,
  678. long ninos,
  679. uint flags)
  680. {
  681. int resvd = 0, error;
  682. if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
  683. return 0;
  684. if (tp && tp->t_dqinfo == NULL)
  685. xfs_trans_alloc_dqinfo(tp);
  686. ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
  687. if (udqp) {
  688. error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
  689. (flags & ~XFS_QMOPT_ENOSPC));
  690. if (error)
  691. return error;
  692. resvd = 1;
  693. }
  694. if (gdqp) {
  695. error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
  696. if (error) {
  697. /*
  698. * can't do it, so backout previous reservation
  699. */
  700. if (resvd) {
  701. flags |= XFS_QMOPT_FORCE_RES;
  702. xfs_trans_dqresv(tp, mp, udqp,
  703. -nblks, -ninos, flags);
  704. }
  705. return error;
  706. }
  707. }
  708. /*
  709. * Didn't change anything critical, so, no need to log
  710. */
  711. return 0;
  712. }
  713. /*
  714. * Lock the dquot and change the reservation if we can.
  715. * This doesn't change the actual usage, just the reservation.
  716. * The inode sent in is locked.
  717. */
  718. int
  719. xfs_trans_reserve_quota_nblks(
  720. struct xfs_trans *tp,
  721. struct xfs_inode *ip,
  722. long nblks,
  723. long ninos,
  724. uint flags)
  725. {
  726. struct xfs_mount *mp = ip->i_mount;
  727. if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
  728. return 0;
  729. if (XFS_IS_PQUOTA_ON(mp))
  730. flags |= XFS_QMOPT_ENOSPC;
  731. ASSERT(ip->i_ino != mp->m_sb.sb_uquotino);
  732. ASSERT(ip->i_ino != mp->m_sb.sb_gquotino);
  733. ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
  734. ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
  735. XFS_TRANS_DQ_RES_RTBLKS ||
  736. (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
  737. XFS_TRANS_DQ_RES_BLKS);
  738. /*
  739. * Reserve nblks against these dquots, with trans as the mediator.
  740. */
  741. return xfs_trans_reserve_quota_bydquots(tp, mp,
  742. ip->i_udquot, ip->i_gdquot,
  743. nblks, ninos, flags);
  744. }
  745. /*
  746. * This routine is called to allocate a quotaoff log item.
  747. */
  748. xfs_qoff_logitem_t *
  749. xfs_trans_get_qoff_item(
  750. xfs_trans_t *tp,
  751. xfs_qoff_logitem_t *startqoff,
  752. uint flags)
  753. {
  754. xfs_qoff_logitem_t *q;
  755. ASSERT(tp != NULL);
  756. q = xfs_qm_qoff_logitem_init(tp->t_mountp, startqoff, flags);
  757. ASSERT(q != NULL);
  758. /*
  759. * Get a log_item_desc to point at the new item.
  760. */
  761. xfs_trans_add_item(tp, &q->qql_item);
  762. return q;
  763. }
  764. /*
  765. * This is called to mark the quotaoff logitem as needing
  766. * to be logged when the transaction is committed. The logitem must
  767. * already be associated with the given transaction.
  768. */
  769. void
  770. xfs_trans_log_quotaoff_item(
  771. xfs_trans_t *tp,
  772. xfs_qoff_logitem_t *qlp)
  773. {
  774. tp->t_flags |= XFS_TRANS_DIRTY;
  775. qlp->qql_item.li_desc->lid_flags |= XFS_LID_DIRTY;
  776. }
  777. STATIC void
  778. xfs_trans_alloc_dqinfo(
  779. xfs_trans_t *tp)
  780. {
  781. tp->t_dqinfo = kmem_zone_zalloc(xfs_qm_dqtrxzone, KM_SLEEP);
  782. }
  783. void
  784. xfs_trans_free_dqinfo(
  785. xfs_trans_t *tp)
  786. {
  787. if (!tp->t_dqinfo)
  788. return;
  789. kmem_zone_free(xfs_qm_dqtrxzone, tp->t_dqinfo);
  790. tp->t_dqinfo = NULL;
  791. }