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