xfs_qm_syscalls.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Copyright (c) 2000-2005 Silicon Graphics, Inc.
  4. * All Rights Reserved.
  5. */
  6. #include "xfs.h"
  7. #include "xfs_fs.h"
  8. #include "xfs_shared.h"
  9. #include "xfs_format.h"
  10. #include "xfs_log_format.h"
  11. #include "xfs_trans_resv.h"
  12. #include "xfs_sb.h"
  13. #include "xfs_mount.h"
  14. #include "xfs_inode.h"
  15. #include "xfs_trans.h"
  16. #include "xfs_quota.h"
  17. #include "xfs_qm.h"
  18. #include "xfs_icache.h"
  19. STATIC int
  20. xfs_qm_log_quotaoff(
  21. struct xfs_mount *mp,
  22. struct xfs_qoff_logitem **qoffstartp,
  23. uint flags)
  24. {
  25. struct xfs_trans *tp;
  26. int error;
  27. struct xfs_qoff_logitem *qoffi;
  28. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_quotaoff, 0, 0, 0, &tp);
  29. if (error)
  30. goto out;
  31. qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);
  32. xfs_trans_log_quotaoff_item(tp, qoffi);
  33. spin_lock(&mp->m_sb_lock);
  34. mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
  35. spin_unlock(&mp->m_sb_lock);
  36. xfs_log_sb(tp);
  37. /*
  38. * We have to make sure that the transaction is secure on disk before we
  39. * return and actually stop quota accounting. So, make it synchronous.
  40. * We don't care about quotoff's performance.
  41. */
  42. xfs_trans_set_sync(tp);
  43. error = xfs_trans_commit(tp);
  44. if (error)
  45. goto out;
  46. *qoffstartp = qoffi;
  47. out:
  48. return error;
  49. }
  50. STATIC int
  51. xfs_qm_log_quotaoff_end(
  52. struct xfs_mount *mp,
  53. struct xfs_qoff_logitem **startqoff,
  54. uint flags)
  55. {
  56. struct xfs_trans *tp;
  57. int error;
  58. struct xfs_qoff_logitem *qoffi;
  59. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_equotaoff, 0, 0, 0, &tp);
  60. if (error)
  61. return error;
  62. qoffi = xfs_trans_get_qoff_item(tp, *startqoff,
  63. flags & XFS_ALL_QUOTA_ACCT);
  64. xfs_trans_log_quotaoff_item(tp, qoffi);
  65. *startqoff = NULL;
  66. /*
  67. * We have to make sure that the transaction is secure on disk before we
  68. * return and actually stop quota accounting. So, make it synchronous.
  69. * We don't care about quotoff's performance.
  70. */
  71. xfs_trans_set_sync(tp);
  72. return xfs_trans_commit(tp);
  73. }
  74. /*
  75. * Turn off quota accounting and/or enforcement for all udquots and/or
  76. * gdquots. Called only at unmount time.
  77. *
  78. * This assumes that there are no dquots of this file system cached
  79. * incore, and modifies the ondisk dquot directly. Therefore, for example,
  80. * it is an error to call this twice, without purging the cache.
  81. */
  82. int
  83. xfs_qm_scall_quotaoff(
  84. xfs_mount_t *mp,
  85. uint flags)
  86. {
  87. struct xfs_quotainfo *q = mp->m_quotainfo;
  88. uint dqtype;
  89. int error;
  90. uint inactivate_flags;
  91. struct xfs_qoff_logitem *qoffstart = NULL;
  92. /*
  93. * No file system can have quotas enabled on disk but not in core.
  94. * Note that quota utilities (like quotaoff) _expect_
  95. * errno == -EEXIST here.
  96. */
  97. if ((mp->m_qflags & flags) == 0)
  98. return -EEXIST;
  99. error = 0;
  100. flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
  101. /*
  102. * We don't want to deal with two quotaoffs messing up each other,
  103. * so we're going to serialize it. quotaoff isn't exactly a performance
  104. * critical thing.
  105. * If quotaoff, then we must be dealing with the root filesystem.
  106. */
  107. ASSERT(q);
  108. mutex_lock(&q->qi_quotaofflock);
  109. /*
  110. * If we're just turning off quota enforcement, change mp and go.
  111. */
  112. if ((flags & XFS_ALL_QUOTA_ACCT) == 0) {
  113. mp->m_qflags &= ~(flags);
  114. spin_lock(&mp->m_sb_lock);
  115. mp->m_sb.sb_qflags = mp->m_qflags;
  116. spin_unlock(&mp->m_sb_lock);
  117. mutex_unlock(&q->qi_quotaofflock);
  118. /* XXX what to do if error ? Revert back to old vals incore ? */
  119. return xfs_sync_sb(mp, false);
  120. }
  121. dqtype = 0;
  122. inactivate_flags = 0;
  123. /*
  124. * If accounting is off, we must turn enforcement off, clear the
  125. * quota 'CHKD' certificate to make it known that we have to
  126. * do a quotacheck the next time this quota is turned on.
  127. */
  128. if (flags & XFS_UQUOTA_ACCT) {
  129. dqtype |= XFS_QMOPT_UQUOTA;
  130. flags |= (XFS_UQUOTA_CHKD | XFS_UQUOTA_ENFD);
  131. inactivate_flags |= XFS_UQUOTA_ACTIVE;
  132. }
  133. if (flags & XFS_GQUOTA_ACCT) {
  134. dqtype |= XFS_QMOPT_GQUOTA;
  135. flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
  136. inactivate_flags |= XFS_GQUOTA_ACTIVE;
  137. }
  138. if (flags & XFS_PQUOTA_ACCT) {
  139. dqtype |= XFS_QMOPT_PQUOTA;
  140. flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD);
  141. inactivate_flags |= XFS_PQUOTA_ACTIVE;
  142. }
  143. /*
  144. * Nothing to do? Don't complain. This happens when we're just
  145. * turning off quota enforcement.
  146. */
  147. if ((mp->m_qflags & flags) == 0)
  148. goto out_unlock;
  149. /*
  150. * Write the LI_QUOTAOFF log record, and do SB changes atomically,
  151. * and synchronously. If we fail to write, we should abort the
  152. * operation as it cannot be recovered safely if we crash.
  153. */
  154. error = xfs_qm_log_quotaoff(mp, &qoffstart, flags);
  155. if (error)
  156. goto out_unlock;
  157. /*
  158. * Next we clear the XFS_MOUNT_*DQ_ACTIVE bit(s) in the mount struct
  159. * to take care of the race between dqget and quotaoff. We don't take
  160. * any special locks to reset these bits. All processes need to check
  161. * these bits *after* taking inode lock(s) to see if the particular
  162. * quota type is in the process of being turned off. If *ACTIVE, it is
  163. * guaranteed that all dquot structures and all quotainode ptrs will all
  164. * stay valid as long as that inode is kept locked.
  165. *
  166. * There is no turning back after this.
  167. */
  168. mp->m_qflags &= ~inactivate_flags;
  169. /*
  170. * Give back all the dquot reference(s) held by inodes.
  171. * Here we go thru every single incore inode in this file system, and
  172. * do a dqrele on the i_udquot/i_gdquot that it may have.
  173. * Essentially, as long as somebody has an inode locked, this guarantees
  174. * that quotas will not be turned off. This is handy because in a
  175. * transaction once we lock the inode(s) and check for quotaon, we can
  176. * depend on the quota inodes (and other things) being valid as long as
  177. * we keep the lock(s).
  178. */
  179. xfs_qm_dqrele_all_inodes(mp, flags);
  180. /*
  181. * Next we make the changes in the quota flag in the mount struct.
  182. * This isn't protected by a particular lock directly, because we
  183. * don't want to take a mrlock every time we depend on quotas being on.
  184. */
  185. mp->m_qflags &= ~flags;
  186. /*
  187. * Go through all the dquots of this file system and purge them,
  188. * according to what was turned off.
  189. */
  190. xfs_qm_dqpurge_all(mp, dqtype);
  191. /*
  192. * Transactions that had started before ACTIVE state bit was cleared
  193. * could have logged many dquots, so they'd have higher LSNs than
  194. * the first QUOTAOFF log record does. If we happen to crash when
  195. * the tail of the log has gone past the QUOTAOFF record, but
  196. * before the last dquot modification, those dquots __will__
  197. * recover, and that's not good.
  198. *
  199. * So, we have QUOTAOFF start and end logitems; the start
  200. * logitem won't get overwritten until the end logitem appears...
  201. */
  202. error = xfs_qm_log_quotaoff_end(mp, &qoffstart, flags);
  203. if (error) {
  204. /* We're screwed now. Shutdown is the only option. */
  205. xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
  206. goto out_unlock;
  207. }
  208. /*
  209. * If all quotas are completely turned off, close shop.
  210. */
  211. if (mp->m_qflags == 0) {
  212. mutex_unlock(&q->qi_quotaofflock);
  213. xfs_qm_destroy_quotainfo(mp);
  214. return 0;
  215. }
  216. /*
  217. * Release our quotainode references if we don't need them anymore.
  218. */
  219. if ((dqtype & XFS_QMOPT_UQUOTA) && q->qi_uquotaip) {
  220. xfs_irele(q->qi_uquotaip);
  221. q->qi_uquotaip = NULL;
  222. }
  223. if ((dqtype & XFS_QMOPT_GQUOTA) && q->qi_gquotaip) {
  224. xfs_irele(q->qi_gquotaip);
  225. q->qi_gquotaip = NULL;
  226. }
  227. if ((dqtype & XFS_QMOPT_PQUOTA) && q->qi_pquotaip) {
  228. xfs_irele(q->qi_pquotaip);
  229. q->qi_pquotaip = NULL;
  230. }
  231. out_unlock:
  232. if (error && qoffstart)
  233. xfs_qm_qoff_logitem_relse(qoffstart);
  234. mutex_unlock(&q->qi_quotaofflock);
  235. return error;
  236. }
  237. STATIC int
  238. xfs_qm_scall_trunc_qfile(
  239. struct xfs_mount *mp,
  240. xfs_ino_t ino)
  241. {
  242. struct xfs_inode *ip;
  243. struct xfs_trans *tp;
  244. int error;
  245. if (ino == NULLFSINO)
  246. return 0;
  247. error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
  248. if (error)
  249. return error;
  250. xfs_ilock(ip, XFS_IOLOCK_EXCL);
  251. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp);
  252. if (error) {
  253. xfs_iunlock(ip, XFS_IOLOCK_EXCL);
  254. goto out_put;
  255. }
  256. xfs_ilock(ip, XFS_ILOCK_EXCL);
  257. xfs_trans_ijoin(tp, ip, 0);
  258. ip->i_d.di_size = 0;
  259. xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
  260. error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0);
  261. if (error) {
  262. xfs_trans_cancel(tp);
  263. goto out_unlock;
  264. }
  265. ASSERT(ip->i_df.if_nextents == 0);
  266. xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
  267. error = xfs_trans_commit(tp);
  268. out_unlock:
  269. xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
  270. out_put:
  271. xfs_irele(ip);
  272. return error;
  273. }
  274. int
  275. xfs_qm_scall_trunc_qfiles(
  276. xfs_mount_t *mp,
  277. uint flags)
  278. {
  279. int error = -EINVAL;
  280. if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0 ||
  281. (flags & ~XFS_QMOPT_QUOTALL)) {
  282. xfs_debug(mp, "%s: flags=%x m_qflags=%x",
  283. __func__, flags, mp->m_qflags);
  284. return -EINVAL;
  285. }
  286. if (flags & XFS_QMOPT_UQUOTA) {
  287. error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino);
  288. if (error)
  289. return error;
  290. }
  291. if (flags & XFS_QMOPT_GQUOTA) {
  292. error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino);
  293. if (error)
  294. return error;
  295. }
  296. if (flags & XFS_QMOPT_PQUOTA)
  297. error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino);
  298. return error;
  299. }
  300. /*
  301. * Switch on (a given) quota enforcement for a filesystem. This takes
  302. * effect immediately.
  303. * (Switching on quota accounting must be done at mount time.)
  304. */
  305. int
  306. xfs_qm_scall_quotaon(
  307. xfs_mount_t *mp,
  308. uint flags)
  309. {
  310. int error;
  311. uint qf;
  312. /*
  313. * Switching on quota accounting must be done at mount time,
  314. * only consider quota enforcement stuff here.
  315. */
  316. flags &= XFS_ALL_QUOTA_ENFD;
  317. if (flags == 0) {
  318. xfs_debug(mp, "%s: zero flags, m_qflags=%x",
  319. __func__, mp->m_qflags);
  320. return -EINVAL;
  321. }
  322. /*
  323. * Can't enforce without accounting. We check the superblock
  324. * qflags here instead of m_qflags because rootfs can have
  325. * quota acct on ondisk without m_qflags' knowing.
  326. */
  327. if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
  328. (flags & XFS_UQUOTA_ENFD)) ||
  329. ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
  330. (flags & XFS_GQUOTA_ENFD)) ||
  331. ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
  332. (flags & XFS_PQUOTA_ENFD))) {
  333. xfs_debug(mp,
  334. "%s: Can't enforce without acct, flags=%x sbflags=%x",
  335. __func__, flags, mp->m_sb.sb_qflags);
  336. return -EINVAL;
  337. }
  338. /*
  339. * If everything's up to-date incore, then don't waste time.
  340. */
  341. if ((mp->m_qflags & flags) == flags)
  342. return -EEXIST;
  343. /*
  344. * Change sb_qflags on disk but not incore mp->qflags
  345. * if this is the root filesystem.
  346. */
  347. spin_lock(&mp->m_sb_lock);
  348. qf = mp->m_sb.sb_qflags;
  349. mp->m_sb.sb_qflags = qf | flags;
  350. spin_unlock(&mp->m_sb_lock);
  351. /*
  352. * There's nothing to change if it's the same.
  353. */
  354. if ((qf & flags) == flags)
  355. return -EEXIST;
  356. error = xfs_sync_sb(mp, false);
  357. if (error)
  358. return error;
  359. /*
  360. * If we aren't trying to switch on quota enforcement, we are done.
  361. */
  362. if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
  363. (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
  364. ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
  365. (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
  366. ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
  367. (mp->m_qflags & XFS_GQUOTA_ACCT)))
  368. return 0;
  369. if (! XFS_IS_QUOTA_RUNNING(mp))
  370. return -ESRCH;
  371. /*
  372. * Switch on quota enforcement in core.
  373. */
  374. mutex_lock(&mp->m_quotainfo->qi_quotaofflock);
  375. mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);
  376. mutex_unlock(&mp->m_quotainfo->qi_quotaofflock);
  377. return 0;
  378. }
  379. #define XFS_QC_MASK \
  380. (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
  381. /*
  382. * Adjust limits of this quota, and the defaults if passed in. Returns true
  383. * if the new limits made sense and were applied, false otherwise.
  384. */
  385. static inline bool
  386. xfs_setqlim_limits(
  387. struct xfs_mount *mp,
  388. struct xfs_dquot_res *res,
  389. struct xfs_quota_limits *qlim,
  390. xfs_qcnt_t hard,
  391. xfs_qcnt_t soft,
  392. const char *tag)
  393. {
  394. /* The hard limit can't be less than the soft limit. */
  395. if (hard != 0 && hard < soft) {
  396. xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag,
  397. soft);
  398. return false;
  399. }
  400. res->hardlimit = hard;
  401. res->softlimit = soft;
  402. if (qlim) {
  403. qlim->hard = hard;
  404. qlim->soft = soft;
  405. }
  406. return true;
  407. }
  408. static inline void
  409. xfs_setqlim_warns(
  410. struct xfs_dquot_res *res,
  411. struct xfs_quota_limits *qlim,
  412. int warns)
  413. {
  414. res->warnings = warns;
  415. if (qlim)
  416. qlim->warn = warns;
  417. }
  418. static inline void
  419. xfs_setqlim_timer(
  420. struct xfs_mount *mp,
  421. struct xfs_dquot_res *res,
  422. struct xfs_quota_limits *qlim,
  423. s64 timer)
  424. {
  425. if (qlim) {
  426. /* Set the length of the default grace period. */
  427. res->timer = xfs_dquot_set_grace_period(timer);
  428. qlim->time = res->timer;
  429. } else {
  430. /* Set the grace period expiration on a quota. */
  431. res->timer = xfs_dquot_set_timeout(mp, timer);
  432. }
  433. }
  434. /*
  435. * Adjust quota limits, and start/stop timers accordingly.
  436. */
  437. int
  438. xfs_qm_scall_setqlim(
  439. struct xfs_mount *mp,
  440. xfs_dqid_t id,
  441. xfs_dqtype_t type,
  442. struct qc_dqblk *newlim)
  443. {
  444. struct xfs_quotainfo *q = mp->m_quotainfo;
  445. struct xfs_dquot *dqp;
  446. struct xfs_trans *tp;
  447. struct xfs_def_quota *defq;
  448. struct xfs_dquot_res *res;
  449. struct xfs_quota_limits *qlim;
  450. int error;
  451. xfs_qcnt_t hard, soft;
  452. if (newlim->d_fieldmask & ~XFS_QC_MASK)
  453. return -EINVAL;
  454. if ((newlim->d_fieldmask & XFS_QC_MASK) == 0)
  455. return 0;
  456. /*
  457. * We don't want to race with a quotaoff so take the quotaoff lock.
  458. * We don't hold an inode lock, so there's nothing else to stop
  459. * a quotaoff from happening.
  460. */
  461. mutex_lock(&q->qi_quotaofflock);
  462. /*
  463. * Get the dquot (locked) before we start, as we need to do a
  464. * transaction to allocate it if it doesn't exist. Once we have the
  465. * dquot, unlock it so we can start the next transaction safely. We hold
  466. * a reference to the dquot, so it's safe to do this unlock/lock without
  467. * it being reclaimed in the mean time.
  468. */
  469. error = xfs_qm_dqget(mp, id, type, true, &dqp);
  470. if (error) {
  471. ASSERT(error != -ENOENT);
  472. goto out_unlock;
  473. }
  474. defq = xfs_get_defquota(q, xfs_dquot_type(dqp));
  475. xfs_dqunlock(dqp);
  476. error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp);
  477. if (error)
  478. goto out_rele;
  479. xfs_dqlock(dqp);
  480. xfs_trans_dqjoin(tp, dqp);
  481. /*
  482. * Update quota limits, warnings, and timers, and the defaults
  483. * if we're touching id == 0.
  484. *
  485. * Make sure that hardlimits are >= soft limits before changing.
  486. *
  487. * Update warnings counter(s) if requested.
  488. *
  489. * Timelimits for the super user set the relative time the other users
  490. * can be over quota for this file system. If it is zero a default is
  491. * used. Ditto for the default soft and hard limit values (already
  492. * done, above), and for warnings.
  493. *
  494. * For other IDs, userspace can bump out the grace period if over
  495. * the soft limit.
  496. */
  497. /* Blocks on the data device. */
  498. hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
  499. (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
  500. dqp->q_blk.hardlimit;
  501. soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
  502. (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
  503. dqp->q_blk.softlimit;
  504. res = &dqp->q_blk;
  505. qlim = id == 0 ? &defq->blk : NULL;
  506. if (xfs_setqlim_limits(mp, res, qlim, hard, soft, "blk"))
  507. xfs_dquot_set_prealloc_limits(dqp);
  508. if (newlim->d_fieldmask & QC_SPC_WARNS)
  509. xfs_setqlim_warns(res, qlim, newlim->d_spc_warns);
  510. if (newlim->d_fieldmask & QC_SPC_TIMER)
  511. xfs_setqlim_timer(mp, res, qlim, newlim->d_spc_timer);
  512. /* Blocks on the realtime device. */
  513. hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
  514. (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
  515. dqp->q_rtb.hardlimit;
  516. soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
  517. (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
  518. dqp->q_rtb.softlimit;
  519. res = &dqp->q_rtb;
  520. qlim = id == 0 ? &defq->rtb : NULL;
  521. xfs_setqlim_limits(mp, res, qlim, hard, soft, "rtb");
  522. if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
  523. xfs_setqlim_warns(res, qlim, newlim->d_rt_spc_warns);
  524. if (newlim->d_fieldmask & QC_RT_SPC_TIMER)
  525. xfs_setqlim_timer(mp, res, qlim, newlim->d_rt_spc_timer);
  526. /* Inodes */
  527. hard = (newlim->d_fieldmask & QC_INO_HARD) ?
  528. (xfs_qcnt_t) newlim->d_ino_hardlimit :
  529. dqp->q_ino.hardlimit;
  530. soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
  531. (xfs_qcnt_t) newlim->d_ino_softlimit :
  532. dqp->q_ino.softlimit;
  533. res = &dqp->q_ino;
  534. qlim = id == 0 ? &defq->ino : NULL;
  535. xfs_setqlim_limits(mp, res, qlim, hard, soft, "ino");
  536. if (newlim->d_fieldmask & QC_INO_WARNS)
  537. xfs_setqlim_warns(res, qlim, newlim->d_ino_warns);
  538. if (newlim->d_fieldmask & QC_INO_TIMER)
  539. xfs_setqlim_timer(mp, res, qlim, newlim->d_ino_timer);
  540. if (id != 0) {
  541. /*
  542. * If the user is now over quota, start the timelimit.
  543. * The user will not be 'warned'.
  544. * Note that we keep the timers ticking, whether enforcement
  545. * is on or off. We don't really want to bother with iterating
  546. * over all ondisk dquots and turning the timers on/off.
  547. */
  548. xfs_qm_adjust_dqtimers(dqp);
  549. }
  550. dqp->q_flags |= XFS_DQFLAG_DIRTY;
  551. xfs_trans_log_dquot(tp, dqp);
  552. error = xfs_trans_commit(tp);
  553. out_rele:
  554. xfs_qm_dqrele(dqp);
  555. out_unlock:
  556. mutex_unlock(&q->qi_quotaofflock);
  557. return error;
  558. }
  559. /* Fill out the quota context. */
  560. static void
  561. xfs_qm_scall_getquota_fill_qc(
  562. struct xfs_mount *mp,
  563. xfs_dqtype_t type,
  564. const struct xfs_dquot *dqp,
  565. struct qc_dqblk *dst)
  566. {
  567. memset(dst, 0, sizeof(*dst));
  568. dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit);
  569. dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit);
  570. dst->d_ino_hardlimit = dqp->q_ino.hardlimit;
  571. dst->d_ino_softlimit = dqp->q_ino.softlimit;
  572. dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved);
  573. dst->d_ino_count = dqp->q_ino.reserved;
  574. dst->d_spc_timer = dqp->q_blk.timer;
  575. dst->d_ino_timer = dqp->q_ino.timer;
  576. dst->d_ino_warns = dqp->q_ino.warnings;
  577. dst->d_spc_warns = dqp->q_blk.warnings;
  578. dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit);
  579. dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit);
  580. dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved);
  581. dst->d_rt_spc_timer = dqp->q_rtb.timer;
  582. dst->d_rt_spc_warns = dqp->q_rtb.warnings;
  583. /*
  584. * Internally, we don't reset all the timers when quota enforcement
  585. * gets turned off. No need to confuse the user level code,
  586. * so return zeroes in that case.
  587. */
  588. if (!xfs_dquot_is_enforced(dqp)) {
  589. dst->d_spc_timer = 0;
  590. dst->d_ino_timer = 0;
  591. dst->d_rt_spc_timer = 0;
  592. }
  593. #ifdef DEBUG
  594. if (xfs_dquot_is_enforced(dqp) && dqp->q_id != 0) {
  595. if ((dst->d_space > dst->d_spc_softlimit) &&
  596. (dst->d_spc_softlimit > 0)) {
  597. ASSERT(dst->d_spc_timer != 0);
  598. }
  599. if ((dst->d_ino_count > dqp->q_ino.softlimit) &&
  600. (dqp->q_ino.softlimit > 0)) {
  601. ASSERT(dst->d_ino_timer != 0);
  602. }
  603. }
  604. #endif
  605. }
  606. /* Return the quota information for the dquot matching id. */
  607. int
  608. xfs_qm_scall_getquota(
  609. struct xfs_mount *mp,
  610. xfs_dqid_t id,
  611. xfs_dqtype_t type,
  612. struct qc_dqblk *dst)
  613. {
  614. struct xfs_dquot *dqp;
  615. int error;
  616. /*
  617. * Try to get the dquot. We don't want it allocated on disk, so don't
  618. * set doalloc. If it doesn't exist, we'll get ENOENT back.
  619. */
  620. error = xfs_qm_dqget(mp, id, type, false, &dqp);
  621. if (error)
  622. return error;
  623. /*
  624. * If everything's NULL, this dquot doesn't quite exist as far as
  625. * our utility programs are concerned.
  626. */
  627. if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) {
  628. error = -ENOENT;
  629. goto out_put;
  630. }
  631. xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst);
  632. out_put:
  633. xfs_qm_dqput(dqp);
  634. return error;
  635. }
  636. /*
  637. * Return the quota information for the first initialized dquot whose id
  638. * is at least as high as id.
  639. */
  640. int
  641. xfs_qm_scall_getquota_next(
  642. struct xfs_mount *mp,
  643. xfs_dqid_t *id,
  644. xfs_dqtype_t type,
  645. struct qc_dqblk *dst)
  646. {
  647. struct xfs_dquot *dqp;
  648. int error;
  649. error = xfs_qm_dqget_next(mp, *id, type, &dqp);
  650. if (error)
  651. return error;
  652. /* Fill in the ID we actually read from disk */
  653. *id = dqp->q_id;
  654. xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst);
  655. xfs_qm_dqput(dqp);
  656. return error;
  657. }
  658. STATIC int
  659. xfs_dqrele_inode(
  660. struct xfs_inode *ip,
  661. void *args)
  662. {
  663. uint *flags = args;
  664. /* skip quota inodes */
  665. if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
  666. ip == ip->i_mount->m_quotainfo->qi_gquotaip ||
  667. ip == ip->i_mount->m_quotainfo->qi_pquotaip) {
  668. ASSERT(ip->i_udquot == NULL);
  669. ASSERT(ip->i_gdquot == NULL);
  670. ASSERT(ip->i_pdquot == NULL);
  671. return 0;
  672. }
  673. xfs_ilock(ip, XFS_ILOCK_EXCL);
  674. if ((*flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
  675. xfs_qm_dqrele(ip->i_udquot);
  676. ip->i_udquot = NULL;
  677. }
  678. if ((*flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) {
  679. xfs_qm_dqrele(ip->i_gdquot);
  680. ip->i_gdquot = NULL;
  681. }
  682. if ((*flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) {
  683. xfs_qm_dqrele(ip->i_pdquot);
  684. ip->i_pdquot = NULL;
  685. }
  686. xfs_iunlock(ip, XFS_ILOCK_EXCL);
  687. return 0;
  688. }
  689. /*
  690. * Go thru all the inodes in the file system, releasing their dquots.
  691. *
  692. * Note that the mount structure gets modified to indicate that quotas are off
  693. * AFTER this, in the case of quotaoff.
  694. */
  695. void
  696. xfs_qm_dqrele_all_inodes(
  697. struct xfs_mount *mp,
  698. uint flags)
  699. {
  700. ASSERT(mp->m_quotainfo);
  701. xfs_inode_walk(mp, XFS_INODE_WALK_INEW_WAIT, xfs_dqrele_inode,
  702. &flags, XFS_ICI_NO_TAG);
  703. }