xfs_qm_syscalls.c 27 KB

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