xfs_trans_dquot.c 23 KB

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