xfs_qm_syscalls.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946
  1. /*
  2. * Copyright (c) 2000-2005 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 <linux/capability.h>
  19. #include "xfs.h"
  20. #include "xfs_fs.h"
  21. #include "xfs_shared.h"
  22. #include "xfs_format.h"
  23. #include "xfs_log_format.h"
  24. #include "xfs_trans_resv.h"
  25. #include "xfs_bit.h"
  26. #include "xfs_sb.h"
  27. #include "xfs_mount.h"
  28. #include "xfs_inode.h"
  29. #include "xfs_trans.h"
  30. #include "xfs_error.h"
  31. #include "xfs_quota.h"
  32. #include "xfs_qm.h"
  33. #include "xfs_trace.h"
  34. #include "xfs_icache.h"
  35. STATIC int xfs_qm_log_quotaoff(xfs_mount_t *, xfs_qoff_logitem_t **, uint);
  36. STATIC int xfs_qm_log_quotaoff_end(xfs_mount_t *, xfs_qoff_logitem_t *,
  37. uint);
  38. STATIC uint xfs_qm_export_flags(uint);
  39. /*
  40. * Turn off quota accounting and/or enforcement for all udquots and/or
  41. * gdquots. Called only at unmount time.
  42. *
  43. * This assumes that there are no dquots of this file system cached
  44. * incore, and modifies the ondisk dquot directly. Therefore, for example,
  45. * it is an error to call this twice, without purging the cache.
  46. */
  47. int
  48. xfs_qm_scall_quotaoff(
  49. xfs_mount_t *mp,
  50. uint flags)
  51. {
  52. struct xfs_quotainfo *q = mp->m_quotainfo;
  53. uint dqtype;
  54. int error;
  55. uint inactivate_flags;
  56. xfs_qoff_logitem_t *qoffstart;
  57. /*
  58. * No file system can have quotas enabled on disk but not in core.
  59. * Note that quota utilities (like quotaoff) _expect_
  60. * errno == -EEXIST here.
  61. */
  62. if ((mp->m_qflags & flags) == 0)
  63. return -EEXIST;
  64. error = 0;
  65. flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
  66. /*
  67. * We don't want to deal with two quotaoffs messing up each other,
  68. * so we're going to serialize it. quotaoff isn't exactly a performance
  69. * critical thing.
  70. * If quotaoff, then we must be dealing with the root filesystem.
  71. */
  72. ASSERT(q);
  73. mutex_lock(&q->qi_quotaofflock);
  74. /*
  75. * If we're just turning off quota enforcement, change mp and go.
  76. */
  77. if ((flags & XFS_ALL_QUOTA_ACCT) == 0) {
  78. mp->m_qflags &= ~(flags);
  79. spin_lock(&mp->m_sb_lock);
  80. mp->m_sb.sb_qflags = mp->m_qflags;
  81. spin_unlock(&mp->m_sb_lock);
  82. mutex_unlock(&q->qi_quotaofflock);
  83. /* XXX what to do if error ? Revert back to old vals incore ? */
  84. return xfs_sync_sb(mp, false);
  85. }
  86. dqtype = 0;
  87. inactivate_flags = 0;
  88. /*
  89. * If accounting is off, we must turn enforcement off, clear the
  90. * quota 'CHKD' certificate to make it known that we have to
  91. * do a quotacheck the next time this quota is turned on.
  92. */
  93. if (flags & XFS_UQUOTA_ACCT) {
  94. dqtype |= XFS_QMOPT_UQUOTA;
  95. flags |= (XFS_UQUOTA_CHKD | XFS_UQUOTA_ENFD);
  96. inactivate_flags |= XFS_UQUOTA_ACTIVE;
  97. }
  98. if (flags & XFS_GQUOTA_ACCT) {
  99. dqtype |= XFS_QMOPT_GQUOTA;
  100. flags |= (XFS_GQUOTA_CHKD | XFS_GQUOTA_ENFD);
  101. inactivate_flags |= XFS_GQUOTA_ACTIVE;
  102. }
  103. if (flags & XFS_PQUOTA_ACCT) {
  104. dqtype |= XFS_QMOPT_PQUOTA;
  105. flags |= (XFS_PQUOTA_CHKD | XFS_PQUOTA_ENFD);
  106. inactivate_flags |= XFS_PQUOTA_ACTIVE;
  107. }
  108. /*
  109. * Nothing to do? Don't complain. This happens when we're just
  110. * turning off quota enforcement.
  111. */
  112. if ((mp->m_qflags & flags) == 0)
  113. goto out_unlock;
  114. /*
  115. * Write the LI_QUOTAOFF log record, and do SB changes atomically,
  116. * and synchronously. If we fail to write, we should abort the
  117. * operation as it cannot be recovered safely if we crash.
  118. */
  119. error = xfs_qm_log_quotaoff(mp, &qoffstart, flags);
  120. if (error)
  121. goto out_unlock;
  122. /*
  123. * Next we clear the XFS_MOUNT_*DQ_ACTIVE bit(s) in the mount struct
  124. * to take care of the race between dqget and quotaoff. We don't take
  125. * any special locks to reset these bits. All processes need to check
  126. * these bits *after* taking inode lock(s) to see if the particular
  127. * quota type is in the process of being turned off. If *ACTIVE, it is
  128. * guaranteed that all dquot structures and all quotainode ptrs will all
  129. * stay valid as long as that inode is kept locked.
  130. *
  131. * There is no turning back after this.
  132. */
  133. mp->m_qflags &= ~inactivate_flags;
  134. /*
  135. * Give back all the dquot reference(s) held by inodes.
  136. * Here we go thru every single incore inode in this file system, and
  137. * do a dqrele on the i_udquot/i_gdquot that it may have.
  138. * Essentially, as long as somebody has an inode locked, this guarantees
  139. * that quotas will not be turned off. This is handy because in a
  140. * transaction once we lock the inode(s) and check for quotaon, we can
  141. * depend on the quota inodes (and other things) being valid as long as
  142. * we keep the lock(s).
  143. */
  144. xfs_qm_dqrele_all_inodes(mp, flags);
  145. /*
  146. * Next we make the changes in the quota flag in the mount struct.
  147. * This isn't protected by a particular lock directly, because we
  148. * don't want to take a mrlock every time we depend on quotas being on.
  149. */
  150. mp->m_qflags &= ~flags;
  151. /*
  152. * Go through all the dquots of this file system and purge them,
  153. * according to what was turned off.
  154. */
  155. xfs_qm_dqpurge_all(mp, dqtype);
  156. /*
  157. * Transactions that had started before ACTIVE state bit was cleared
  158. * could have logged many dquots, so they'd have higher LSNs than
  159. * the first QUOTAOFF log record does. If we happen to crash when
  160. * the tail of the log has gone past the QUOTAOFF record, but
  161. * before the last dquot modification, those dquots __will__
  162. * recover, and that's not good.
  163. *
  164. * So, we have QUOTAOFF start and end logitems; the start
  165. * logitem won't get overwritten until the end logitem appears...
  166. */
  167. error = xfs_qm_log_quotaoff_end(mp, qoffstart, flags);
  168. if (error) {
  169. /* We're screwed now. Shutdown is the only option. */
  170. xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE);
  171. goto out_unlock;
  172. }
  173. /*
  174. * If all quotas are completely turned off, close shop.
  175. */
  176. if (mp->m_qflags == 0) {
  177. mutex_unlock(&q->qi_quotaofflock);
  178. xfs_qm_destroy_quotainfo(mp);
  179. return 0;
  180. }
  181. /*
  182. * Release our quotainode references if we don't need them anymore.
  183. */
  184. if ((dqtype & XFS_QMOPT_UQUOTA) && q->qi_uquotaip) {
  185. IRELE(q->qi_uquotaip);
  186. q->qi_uquotaip = NULL;
  187. }
  188. if ((dqtype & XFS_QMOPT_GQUOTA) && q->qi_gquotaip) {
  189. IRELE(q->qi_gquotaip);
  190. q->qi_gquotaip = NULL;
  191. }
  192. if ((dqtype & XFS_QMOPT_PQUOTA) && q->qi_pquotaip) {
  193. IRELE(q->qi_pquotaip);
  194. q->qi_pquotaip = NULL;
  195. }
  196. out_unlock:
  197. mutex_unlock(&q->qi_quotaofflock);
  198. return error;
  199. }
  200. STATIC int
  201. xfs_qm_scall_trunc_qfile(
  202. struct xfs_mount *mp,
  203. xfs_ino_t ino)
  204. {
  205. struct xfs_inode *ip;
  206. struct xfs_trans *tp;
  207. int error;
  208. if (ino == NULLFSINO)
  209. return 0;
  210. error = xfs_iget(mp, NULL, ino, 0, 0, &ip);
  211. if (error)
  212. return error;
  213. xfs_ilock(ip, XFS_IOLOCK_EXCL);
  214. tp = xfs_trans_alloc(mp, XFS_TRANS_TRUNCATE_FILE);
  215. error = xfs_trans_reserve(tp, &M_RES(mp)->tr_itruncate, 0, 0);
  216. if (error) {
  217. xfs_trans_cancel(tp, 0);
  218. xfs_iunlock(ip, XFS_IOLOCK_EXCL);
  219. goto out_put;
  220. }
  221. xfs_ilock(ip, XFS_ILOCK_EXCL);
  222. xfs_trans_ijoin(tp, ip, 0);
  223. ip->i_d.di_size = 0;
  224. xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE);
  225. error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0);
  226. if (error) {
  227. xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES |
  228. XFS_TRANS_ABORT);
  229. goto out_unlock;
  230. }
  231. ASSERT(ip->i_d.di_nextents == 0);
  232. xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG);
  233. error = xfs_trans_commit(tp, XFS_TRANS_RELEASE_LOG_RES);
  234. out_unlock:
  235. xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL);
  236. out_put:
  237. IRELE(ip);
  238. return error;
  239. }
  240. int
  241. xfs_qm_scall_trunc_qfiles(
  242. xfs_mount_t *mp,
  243. uint flags)
  244. {
  245. int error = -EINVAL;
  246. if (!xfs_sb_version_hasquota(&mp->m_sb) || flags == 0 ||
  247. (flags & ~XFS_DQ_ALLTYPES)) {
  248. xfs_debug(mp, "%s: flags=%x m_qflags=%x",
  249. __func__, flags, mp->m_qflags);
  250. return -EINVAL;
  251. }
  252. if (flags & XFS_DQ_USER) {
  253. error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_uquotino);
  254. if (error)
  255. return error;
  256. }
  257. if (flags & XFS_DQ_GROUP) {
  258. error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_gquotino);
  259. if (error)
  260. return error;
  261. }
  262. if (flags & XFS_DQ_PROJ)
  263. error = xfs_qm_scall_trunc_qfile(mp, mp->m_sb.sb_pquotino);
  264. return error;
  265. }
  266. /*
  267. * Switch on (a given) quota enforcement for a filesystem. This takes
  268. * effect immediately.
  269. * (Switching on quota accounting must be done at mount time.)
  270. */
  271. int
  272. xfs_qm_scall_quotaon(
  273. xfs_mount_t *mp,
  274. uint flags)
  275. {
  276. int error;
  277. uint qf;
  278. flags &= (XFS_ALL_QUOTA_ACCT | XFS_ALL_QUOTA_ENFD);
  279. /*
  280. * Switching on quota accounting must be done at mount time.
  281. */
  282. flags &= ~(XFS_ALL_QUOTA_ACCT);
  283. if (flags == 0) {
  284. xfs_debug(mp, "%s: zero flags, m_qflags=%x",
  285. __func__, mp->m_qflags);
  286. return -EINVAL;
  287. }
  288. /*
  289. * Can't enforce without accounting. We check the superblock
  290. * qflags here instead of m_qflags because rootfs can have
  291. * quota acct on ondisk without m_qflags' knowing.
  292. */
  293. if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 &&
  294. (flags & XFS_UQUOTA_ENFD)) ||
  295. ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 &&
  296. (flags & XFS_GQUOTA_ENFD)) ||
  297. ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 &&
  298. (flags & XFS_PQUOTA_ENFD))) {
  299. xfs_debug(mp,
  300. "%s: Can't enforce without acct, flags=%x sbflags=%x",
  301. __func__, flags, mp->m_sb.sb_qflags);
  302. return -EINVAL;
  303. }
  304. /*
  305. * If everything's up to-date incore, then don't waste time.
  306. */
  307. if ((mp->m_qflags & flags) == flags)
  308. return -EEXIST;
  309. /*
  310. * Change sb_qflags on disk but not incore mp->qflags
  311. * if this is the root filesystem.
  312. */
  313. spin_lock(&mp->m_sb_lock);
  314. qf = mp->m_sb.sb_qflags;
  315. mp->m_sb.sb_qflags = qf | flags;
  316. spin_unlock(&mp->m_sb_lock);
  317. /*
  318. * There's nothing to change if it's the same.
  319. */
  320. if ((qf & flags) == flags)
  321. return -EEXIST;
  322. error = xfs_sync_sb(mp, false);
  323. if (error)
  324. return error;
  325. /*
  326. * If we aren't trying to switch on quota enforcement, we are done.
  327. */
  328. if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) !=
  329. (mp->m_qflags & XFS_UQUOTA_ACCT)) ||
  330. ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) !=
  331. (mp->m_qflags & XFS_PQUOTA_ACCT)) ||
  332. ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) !=
  333. (mp->m_qflags & XFS_GQUOTA_ACCT)))
  334. return 0;
  335. if (! XFS_IS_QUOTA_RUNNING(mp))
  336. return -ESRCH;
  337. /*
  338. * Switch on quota enforcement in core.
  339. */
  340. mutex_lock(&mp->m_quotainfo->qi_quotaofflock);
  341. mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD);
  342. mutex_unlock(&mp->m_quotainfo->qi_quotaofflock);
  343. return 0;
  344. }
  345. /*
  346. * Return quota status information, such as uquota-off, enforcements, etc.
  347. * for Q_XGETQSTAT command.
  348. */
  349. int
  350. xfs_qm_scall_getqstat(
  351. struct xfs_mount *mp,
  352. struct fs_quota_stat *out)
  353. {
  354. struct xfs_quotainfo *q = mp->m_quotainfo;
  355. struct xfs_inode *uip = NULL;
  356. struct xfs_inode *gip = NULL;
  357. struct xfs_inode *pip = NULL;
  358. bool tempuqip = false;
  359. bool tempgqip = false;
  360. bool temppqip = false;
  361. memset(out, 0, sizeof(fs_quota_stat_t));
  362. out->qs_version = FS_QSTAT_VERSION;
  363. out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
  364. (XFS_ALL_QUOTA_ACCT|
  365. XFS_ALL_QUOTA_ENFD));
  366. uip = q->qi_uquotaip;
  367. gip = q->qi_gquotaip;
  368. pip = q->qi_pquotaip;
  369. if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
  370. if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
  371. 0, 0, &uip) == 0)
  372. tempuqip = true;
  373. }
  374. if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
  375. if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
  376. 0, 0, &gip) == 0)
  377. tempgqip = true;
  378. }
  379. /*
  380. * Q_XGETQSTAT doesn't have room for both group and project quotas.
  381. * So, allow the project quota values to be copied out only if
  382. * there is no group quota information available.
  383. */
  384. if (!gip) {
  385. if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) {
  386. if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
  387. 0, 0, &pip) == 0)
  388. temppqip = true;
  389. }
  390. } else
  391. pip = NULL;
  392. if (uip) {
  393. out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
  394. out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
  395. out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
  396. if (tempuqip)
  397. IRELE(uip);
  398. }
  399. if (gip) {
  400. out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
  401. out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks;
  402. out->qs_gquota.qfs_nextents = gip->i_d.di_nextents;
  403. if (tempgqip)
  404. IRELE(gip);
  405. }
  406. if (pip) {
  407. out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
  408. out->qs_gquota.qfs_nblks = pip->i_d.di_nblocks;
  409. out->qs_gquota.qfs_nextents = pip->i_d.di_nextents;
  410. if (temppqip)
  411. IRELE(pip);
  412. }
  413. out->qs_incoredqs = q->qi_dquots;
  414. out->qs_btimelimit = q->qi_btimelimit;
  415. out->qs_itimelimit = q->qi_itimelimit;
  416. out->qs_rtbtimelimit = q->qi_rtbtimelimit;
  417. out->qs_bwarnlimit = q->qi_bwarnlimit;
  418. out->qs_iwarnlimit = q->qi_iwarnlimit;
  419. return 0;
  420. }
  421. /*
  422. * Return quota status information, such as uquota-off, enforcements, etc.
  423. * for Q_XGETQSTATV command, to support separate project quota field.
  424. */
  425. int
  426. xfs_qm_scall_getqstatv(
  427. struct xfs_mount *mp,
  428. struct fs_quota_statv *out)
  429. {
  430. struct xfs_quotainfo *q = mp->m_quotainfo;
  431. struct xfs_inode *uip = NULL;
  432. struct xfs_inode *gip = NULL;
  433. struct xfs_inode *pip = NULL;
  434. bool tempuqip = false;
  435. bool tempgqip = false;
  436. bool temppqip = false;
  437. out->qs_flags = (__uint16_t) xfs_qm_export_flags(mp->m_qflags &
  438. (XFS_ALL_QUOTA_ACCT|
  439. XFS_ALL_QUOTA_ENFD));
  440. out->qs_uquota.qfs_ino = mp->m_sb.sb_uquotino;
  441. out->qs_gquota.qfs_ino = mp->m_sb.sb_gquotino;
  442. out->qs_pquota.qfs_ino = mp->m_sb.sb_pquotino;
  443. uip = q->qi_uquotaip;
  444. gip = q->qi_gquotaip;
  445. pip = q->qi_pquotaip;
  446. if (!uip && mp->m_sb.sb_uquotino != NULLFSINO) {
  447. if (xfs_iget(mp, NULL, mp->m_sb.sb_uquotino,
  448. 0, 0, &uip) == 0)
  449. tempuqip = true;
  450. }
  451. if (!gip && mp->m_sb.sb_gquotino != NULLFSINO) {
  452. if (xfs_iget(mp, NULL, mp->m_sb.sb_gquotino,
  453. 0, 0, &gip) == 0)
  454. tempgqip = true;
  455. }
  456. if (!pip && mp->m_sb.sb_pquotino != NULLFSINO) {
  457. if (xfs_iget(mp, NULL, mp->m_sb.sb_pquotino,
  458. 0, 0, &pip) == 0)
  459. temppqip = true;
  460. }
  461. if (uip) {
  462. out->qs_uquota.qfs_nblks = uip->i_d.di_nblocks;
  463. out->qs_uquota.qfs_nextents = uip->i_d.di_nextents;
  464. if (tempuqip)
  465. IRELE(uip);
  466. }
  467. if (gip) {
  468. out->qs_gquota.qfs_nblks = gip->i_d.di_nblocks;
  469. out->qs_gquota.qfs_nextents = gip->i_d.di_nextents;
  470. if (tempgqip)
  471. IRELE(gip);
  472. }
  473. if (pip) {
  474. out->qs_pquota.qfs_nblks = pip->i_d.di_nblocks;
  475. out->qs_pquota.qfs_nextents = pip->i_d.di_nextents;
  476. if (temppqip)
  477. IRELE(pip);
  478. }
  479. out->qs_incoredqs = q->qi_dquots;
  480. out->qs_btimelimit = q->qi_btimelimit;
  481. out->qs_itimelimit = q->qi_itimelimit;
  482. out->qs_rtbtimelimit = q->qi_rtbtimelimit;
  483. out->qs_bwarnlimit = q->qi_bwarnlimit;
  484. out->qs_iwarnlimit = q->qi_iwarnlimit;
  485. return 0;
  486. }
  487. #define XFS_QC_MASK \
  488. (QC_LIMIT_MASK | QC_TIMER_MASK | QC_WARNS_MASK)
  489. /*
  490. * Adjust quota limits, and start/stop timers accordingly.
  491. */
  492. int
  493. xfs_qm_scall_setqlim(
  494. struct xfs_mount *mp,
  495. xfs_dqid_t id,
  496. uint type,
  497. struct qc_dqblk *newlim)
  498. {
  499. struct xfs_quotainfo *q = mp->m_quotainfo;
  500. struct xfs_disk_dquot *ddq;
  501. struct xfs_dquot *dqp;
  502. struct xfs_trans *tp;
  503. int error;
  504. xfs_qcnt_t hard, soft;
  505. if (newlim->d_fieldmask & ~XFS_QC_MASK)
  506. return -EINVAL;
  507. if ((newlim->d_fieldmask & XFS_QC_MASK) == 0)
  508. return 0;
  509. /*
  510. * We don't want to race with a quotaoff so take the quotaoff lock.
  511. * We don't hold an inode lock, so there's nothing else to stop
  512. * a quotaoff from happening.
  513. */
  514. mutex_lock(&q->qi_quotaofflock);
  515. /*
  516. * Get the dquot (locked) before we start, as we need to do a
  517. * transaction to allocate it if it doesn't exist. Once we have the
  518. * dquot, unlock it so we can start the next transaction safely. We hold
  519. * a reference to the dquot, so it's safe to do this unlock/lock without
  520. * it being reclaimed in the mean time.
  521. */
  522. error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp);
  523. if (error) {
  524. ASSERT(error != -ENOENT);
  525. goto out_unlock;
  526. }
  527. xfs_dqunlock(dqp);
  528. tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
  529. error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_setqlim, 0, 0);
  530. if (error) {
  531. xfs_trans_cancel(tp, 0);
  532. goto out_rele;
  533. }
  534. xfs_dqlock(dqp);
  535. xfs_trans_dqjoin(tp, dqp);
  536. ddq = &dqp->q_core;
  537. /*
  538. * Make sure that hardlimits are >= soft limits before changing.
  539. */
  540. hard = (newlim->d_fieldmask & QC_SPC_HARD) ?
  541. (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) :
  542. be64_to_cpu(ddq->d_blk_hardlimit);
  543. soft = (newlim->d_fieldmask & QC_SPC_SOFT) ?
  544. (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) :
  545. be64_to_cpu(ddq->d_blk_softlimit);
  546. if (hard == 0 || hard >= soft) {
  547. ddq->d_blk_hardlimit = cpu_to_be64(hard);
  548. ddq->d_blk_softlimit = cpu_to_be64(soft);
  549. xfs_dquot_set_prealloc_limits(dqp);
  550. if (id == 0) {
  551. q->qi_bhardlimit = hard;
  552. q->qi_bsoftlimit = soft;
  553. }
  554. } else {
  555. xfs_debug(mp, "blkhard %Ld < blksoft %Ld", hard, soft);
  556. }
  557. hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ?
  558. (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) :
  559. be64_to_cpu(ddq->d_rtb_hardlimit);
  560. soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ?
  561. (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) :
  562. be64_to_cpu(ddq->d_rtb_softlimit);
  563. if (hard == 0 || hard >= soft) {
  564. ddq->d_rtb_hardlimit = cpu_to_be64(hard);
  565. ddq->d_rtb_softlimit = cpu_to_be64(soft);
  566. if (id == 0) {
  567. q->qi_rtbhardlimit = hard;
  568. q->qi_rtbsoftlimit = soft;
  569. }
  570. } else {
  571. xfs_debug(mp, "rtbhard %Ld < rtbsoft %Ld", hard, soft);
  572. }
  573. hard = (newlim->d_fieldmask & QC_INO_HARD) ?
  574. (xfs_qcnt_t) newlim->d_ino_hardlimit :
  575. be64_to_cpu(ddq->d_ino_hardlimit);
  576. soft = (newlim->d_fieldmask & QC_INO_SOFT) ?
  577. (xfs_qcnt_t) newlim->d_ino_softlimit :
  578. be64_to_cpu(ddq->d_ino_softlimit);
  579. if (hard == 0 || hard >= soft) {
  580. ddq->d_ino_hardlimit = cpu_to_be64(hard);
  581. ddq->d_ino_softlimit = cpu_to_be64(soft);
  582. if (id == 0) {
  583. q->qi_ihardlimit = hard;
  584. q->qi_isoftlimit = soft;
  585. }
  586. } else {
  587. xfs_debug(mp, "ihard %Ld < isoft %Ld", hard, soft);
  588. }
  589. /*
  590. * Update warnings counter(s) if requested
  591. */
  592. if (newlim->d_fieldmask & QC_SPC_WARNS)
  593. ddq->d_bwarns = cpu_to_be16(newlim->d_spc_warns);
  594. if (newlim->d_fieldmask & QC_INO_WARNS)
  595. ddq->d_iwarns = cpu_to_be16(newlim->d_ino_warns);
  596. if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
  597. ddq->d_rtbwarns = cpu_to_be16(newlim->d_rt_spc_warns);
  598. if (id == 0) {
  599. /*
  600. * Timelimits for the super user set the relative time
  601. * the other users can be over quota for this file system.
  602. * If it is zero a default is used. Ditto for the default
  603. * soft and hard limit values (already done, above), and
  604. * for warnings.
  605. */
  606. if (newlim->d_fieldmask & QC_SPC_TIMER) {
  607. q->qi_btimelimit = newlim->d_spc_timer;
  608. ddq->d_btimer = cpu_to_be32(newlim->d_spc_timer);
  609. }
  610. if (newlim->d_fieldmask & QC_INO_TIMER) {
  611. q->qi_itimelimit = newlim->d_ino_timer;
  612. ddq->d_itimer = cpu_to_be32(newlim->d_ino_timer);
  613. }
  614. if (newlim->d_fieldmask & QC_RT_SPC_TIMER) {
  615. q->qi_rtbtimelimit = newlim->d_rt_spc_timer;
  616. ddq->d_rtbtimer = cpu_to_be32(newlim->d_rt_spc_timer);
  617. }
  618. if (newlim->d_fieldmask & QC_SPC_WARNS)
  619. q->qi_bwarnlimit = newlim->d_spc_warns;
  620. if (newlim->d_fieldmask & QC_INO_WARNS)
  621. q->qi_iwarnlimit = newlim->d_ino_warns;
  622. if (newlim->d_fieldmask & QC_RT_SPC_WARNS)
  623. q->qi_rtbwarnlimit = newlim->d_rt_spc_warns;
  624. } else {
  625. /*
  626. * If the user is now over quota, start the timelimit.
  627. * The user will not be 'warned'.
  628. * Note that we keep the timers ticking, whether enforcement
  629. * is on or off. We don't really want to bother with iterating
  630. * over all ondisk dquots and turning the timers on/off.
  631. */
  632. xfs_qm_adjust_dqtimers(mp, ddq);
  633. }
  634. dqp->dq_flags |= XFS_DQ_DIRTY;
  635. xfs_trans_log_dquot(tp, dqp);
  636. error = xfs_trans_commit(tp, 0);
  637. out_rele:
  638. xfs_qm_dqrele(dqp);
  639. out_unlock:
  640. mutex_unlock(&q->qi_quotaofflock);
  641. return error;
  642. }
  643. STATIC int
  644. xfs_qm_log_quotaoff_end(
  645. xfs_mount_t *mp,
  646. xfs_qoff_logitem_t *startqoff,
  647. uint flags)
  648. {
  649. xfs_trans_t *tp;
  650. int error;
  651. xfs_qoff_logitem_t *qoffi;
  652. tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF_END);
  653. error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_equotaoff, 0, 0);
  654. if (error) {
  655. xfs_trans_cancel(tp, 0);
  656. return error;
  657. }
  658. qoffi = xfs_trans_get_qoff_item(tp, startqoff,
  659. flags & XFS_ALL_QUOTA_ACCT);
  660. xfs_trans_log_quotaoff_item(tp, qoffi);
  661. /*
  662. * We have to make sure that the transaction is secure on disk before we
  663. * return and actually stop quota accounting. So, make it synchronous.
  664. * We don't care about quotoff's performance.
  665. */
  666. xfs_trans_set_sync(tp);
  667. error = xfs_trans_commit(tp, 0);
  668. return error;
  669. }
  670. STATIC int
  671. xfs_qm_log_quotaoff(
  672. xfs_mount_t *mp,
  673. xfs_qoff_logitem_t **qoffstartp,
  674. uint flags)
  675. {
  676. xfs_trans_t *tp;
  677. int error;
  678. xfs_qoff_logitem_t *qoffi;
  679. *qoffstartp = NULL;
  680. tp = xfs_trans_alloc(mp, XFS_TRANS_QM_QUOTAOFF);
  681. error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_quotaoff, 0, 0);
  682. if (error) {
  683. xfs_trans_cancel(tp, 0);
  684. goto out;
  685. }
  686. qoffi = xfs_trans_get_qoff_item(tp, NULL, flags & XFS_ALL_QUOTA_ACCT);
  687. xfs_trans_log_quotaoff_item(tp, qoffi);
  688. spin_lock(&mp->m_sb_lock);
  689. mp->m_sb.sb_qflags = (mp->m_qflags & ~(flags)) & XFS_MOUNT_QUOTA_ALL;
  690. spin_unlock(&mp->m_sb_lock);
  691. xfs_log_sb(tp);
  692. /*
  693. * We have to make sure that the transaction is secure on disk before we
  694. * return and actually stop quota accounting. So, make it synchronous.
  695. * We don't care about quotoff's performance.
  696. */
  697. xfs_trans_set_sync(tp);
  698. error = xfs_trans_commit(tp, 0);
  699. if (error)
  700. goto out;
  701. *qoffstartp = qoffi;
  702. out:
  703. return error;
  704. }
  705. int
  706. xfs_qm_scall_getquota(
  707. struct xfs_mount *mp,
  708. xfs_dqid_t id,
  709. uint type,
  710. struct qc_dqblk *dst)
  711. {
  712. struct xfs_dquot *dqp;
  713. int error;
  714. /*
  715. * Try to get the dquot. We don't want it allocated on disk, so
  716. * we aren't passing the XFS_QMOPT_DOALLOC flag. If it doesn't
  717. * exist, we'll get ENOENT back.
  718. */
  719. error = xfs_qm_dqget(mp, NULL, id, type, 0, &dqp);
  720. if (error)
  721. return error;
  722. /*
  723. * If everything's NULL, this dquot doesn't quite exist as far as
  724. * our utility programs are concerned.
  725. */
  726. if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) {
  727. error = -ENOENT;
  728. goto out_put;
  729. }
  730. memset(dst, 0, sizeof(*dst));
  731. dst->d_spc_hardlimit =
  732. XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_hardlimit));
  733. dst->d_spc_softlimit =
  734. XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_blk_softlimit));
  735. dst->d_ino_hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
  736. dst->d_ino_softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
  737. dst->d_space = XFS_FSB_TO_B(mp, dqp->q_res_bcount);
  738. dst->d_ino_count = dqp->q_res_icount;
  739. dst->d_spc_timer = be32_to_cpu(dqp->q_core.d_btimer);
  740. dst->d_ino_timer = be32_to_cpu(dqp->q_core.d_itimer);
  741. dst->d_ino_warns = be16_to_cpu(dqp->q_core.d_iwarns);
  742. dst->d_spc_warns = be16_to_cpu(dqp->q_core.d_bwarns);
  743. dst->d_rt_spc_hardlimit =
  744. XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_hardlimit));
  745. dst->d_rt_spc_softlimit =
  746. XFS_FSB_TO_B(mp, be64_to_cpu(dqp->q_core.d_rtb_softlimit));
  747. dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_res_rtbcount);
  748. dst->d_rt_spc_timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
  749. dst->d_rt_spc_warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
  750. /*
  751. * Internally, we don't reset all the timers when quota enforcement
  752. * gets turned off. No need to confuse the user level code,
  753. * so return zeroes in that case.
  754. */
  755. if ((!XFS_IS_UQUOTA_ENFORCED(mp) &&
  756. dqp->q_core.d_flags == XFS_DQ_USER) ||
  757. (!XFS_IS_GQUOTA_ENFORCED(mp) &&
  758. dqp->q_core.d_flags == XFS_DQ_GROUP) ||
  759. (!XFS_IS_PQUOTA_ENFORCED(mp) &&
  760. dqp->q_core.d_flags == XFS_DQ_PROJ)) {
  761. dst->d_spc_timer = 0;
  762. dst->d_ino_timer = 0;
  763. dst->d_rt_spc_timer = 0;
  764. }
  765. #ifdef DEBUG
  766. if (((XFS_IS_UQUOTA_ENFORCED(mp) && type == XFS_DQ_USER) ||
  767. (XFS_IS_GQUOTA_ENFORCED(mp) && type == XFS_DQ_GROUP) ||
  768. (XFS_IS_PQUOTA_ENFORCED(mp) && type == XFS_DQ_PROJ)) &&
  769. id != 0) {
  770. if ((dst->d_space > dst->d_spc_softlimit) &&
  771. (dst->d_spc_softlimit > 0)) {
  772. ASSERT(dst->d_spc_timer != 0);
  773. }
  774. if ((dst->d_ino_count > dst->d_ino_softlimit) &&
  775. (dst->d_ino_softlimit > 0)) {
  776. ASSERT(dst->d_ino_timer != 0);
  777. }
  778. }
  779. #endif
  780. out_put:
  781. xfs_qm_dqput(dqp);
  782. return error;
  783. }
  784. STATIC uint
  785. xfs_qm_export_flags(
  786. uint flags)
  787. {
  788. uint uflags;
  789. uflags = 0;
  790. if (flags & XFS_UQUOTA_ACCT)
  791. uflags |= FS_QUOTA_UDQ_ACCT;
  792. if (flags & XFS_GQUOTA_ACCT)
  793. uflags |= FS_QUOTA_GDQ_ACCT;
  794. if (flags & XFS_PQUOTA_ACCT)
  795. uflags |= FS_QUOTA_PDQ_ACCT;
  796. if (flags & XFS_UQUOTA_ENFD)
  797. uflags |= FS_QUOTA_UDQ_ENFD;
  798. if (flags & XFS_GQUOTA_ENFD)
  799. uflags |= FS_QUOTA_GDQ_ENFD;
  800. if (flags & XFS_PQUOTA_ENFD)
  801. uflags |= FS_QUOTA_PDQ_ENFD;
  802. return uflags;
  803. }
  804. STATIC int
  805. xfs_dqrele_inode(
  806. struct xfs_inode *ip,
  807. int flags,
  808. void *args)
  809. {
  810. /* skip quota inodes */
  811. if (ip == ip->i_mount->m_quotainfo->qi_uquotaip ||
  812. ip == ip->i_mount->m_quotainfo->qi_gquotaip ||
  813. ip == ip->i_mount->m_quotainfo->qi_pquotaip) {
  814. ASSERT(ip->i_udquot == NULL);
  815. ASSERT(ip->i_gdquot == NULL);
  816. ASSERT(ip->i_pdquot == NULL);
  817. return 0;
  818. }
  819. xfs_ilock(ip, XFS_ILOCK_EXCL);
  820. if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
  821. xfs_qm_dqrele(ip->i_udquot);
  822. ip->i_udquot = NULL;
  823. }
  824. if ((flags & XFS_GQUOTA_ACCT) && ip->i_gdquot) {
  825. xfs_qm_dqrele(ip->i_gdquot);
  826. ip->i_gdquot = NULL;
  827. }
  828. if ((flags & XFS_PQUOTA_ACCT) && ip->i_pdquot) {
  829. xfs_qm_dqrele(ip->i_pdquot);
  830. ip->i_pdquot = NULL;
  831. }
  832. xfs_iunlock(ip, XFS_ILOCK_EXCL);
  833. return 0;
  834. }
  835. /*
  836. * Go thru all the inodes in the file system, releasing their dquots.
  837. *
  838. * Note that the mount structure gets modified to indicate that quotas are off
  839. * AFTER this, in the case of quotaoff.
  840. */
  841. void
  842. xfs_qm_dqrele_all_inodes(
  843. struct xfs_mount *mp,
  844. uint flags)
  845. {
  846. ASSERT(mp->m_quotainfo);
  847. xfs_inode_ag_iterator(mp, xfs_dqrele_inode, flags, NULL);
  848. }