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