linux/fs/xfs/xfs_trans_dquot.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000-2002 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 "xfs.h"
  19#include "xfs_fs.h"
  20#include "xfs_log.h"
  21#include "xfs_trans.h"
  22#include "xfs_sb.h"
  23#include "xfs_ag.h"
  24#include "xfs_alloc.h"
  25#include "xfs_quota.h"
  26#include "xfs_mount.h"
  27#include "xfs_bmap_btree.h"
  28#include "xfs_inode.h"
  29#include "xfs_itable.h"
  30#include "xfs_bmap.h"
  31#include "xfs_rtalloc.h"
  32#include "xfs_error.h"
  33#include "xfs_attr.h"
  34#include "xfs_buf_item.h"
  35#include "xfs_trans_priv.h"
  36#include "xfs_qm.h"
  37
  38STATIC void     xfs_trans_alloc_dqinfo(xfs_trans_t *);
  39
  40/*
  41 * Add the locked dquot to the transaction.
  42 * The dquot must be locked, and it cannot be associated with any
  43 * transaction.
  44 */
  45void
  46xfs_trans_dqjoin(
  47        xfs_trans_t     *tp,
  48        xfs_dquot_t     *dqp)
  49{
  50        ASSERT(dqp->q_transp != tp);
  51        ASSERT(XFS_DQ_IS_LOCKED(dqp));
  52        ASSERT(dqp->q_logitem.qli_dquot == dqp);
  53
  54        /*
  55         * Get a log_item_desc to point at the new item.
  56         */
  57        xfs_trans_add_item(tp, &dqp->q_logitem.qli_item);
  58
  59        /*
  60         * Initialize d_transp so we can later determine if this dquot is
  61         * associated with this transaction.
  62         */
  63        dqp->q_transp = tp;
  64}
  65
  66
  67/*
  68 * This is called to mark the dquot as needing
  69 * to be logged when the transaction is committed.  The dquot must
  70 * already be associated with the given transaction.
  71 * Note that it marks the entire transaction as dirty. In the ordinary
  72 * case, this gets called via xfs_trans_commit, after the transaction
  73 * is already dirty. However, there's nothing stop this from getting
  74 * called directly, as done by xfs_qm_scall_setqlim. Hence, the TRANS_DIRTY
  75 * flag.
  76 */
  77void
  78xfs_trans_log_dquot(
  79        xfs_trans_t     *tp,
  80        xfs_dquot_t     *dqp)
  81{
  82        ASSERT(dqp->q_transp == tp);
  83        ASSERT(XFS_DQ_IS_LOCKED(dqp));
  84
  85        tp->t_flags |= XFS_TRANS_DIRTY;
  86        dqp->q_logitem.qli_item.li_desc->lid_flags |= XFS_LID_DIRTY;
  87}
  88
  89/*
  90 * Carry forward whatever is left of the quota blk reservation to
  91 * the spanky new transaction
  92 */
  93void
  94xfs_trans_dup_dqinfo(
  95        xfs_trans_t     *otp,
  96        xfs_trans_t     *ntp)
  97{
  98        xfs_dqtrx_t     *oq, *nq;
  99        int             i,j;
 100        xfs_dqtrx_t     *oqa, *nqa;
 101
 102        if (!otp->t_dqinfo)
 103                return;
 104
 105        xfs_trans_alloc_dqinfo(ntp);
 106
 107        /*
 108         * Because the quota blk reservation is carried forward,
 109         * it is also necessary to carry forward the DQ_DIRTY flag.
 110         */
 111        if(otp->t_flags & XFS_TRANS_DQ_DIRTY)
 112                ntp->t_flags |= XFS_TRANS_DQ_DIRTY;
 113
 114        for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
 115                oqa = otp->t_dqinfo->dqs[j];
 116                nqa = ntp->t_dqinfo->dqs[j];
 117                for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
 118                        if (oqa[i].qt_dquot == NULL)
 119                                break;
 120                        oq = &oqa[i];
 121                        nq = &nqa[i];
 122
 123                        nq->qt_dquot = oq->qt_dquot;
 124                        nq->qt_bcount_delta = nq->qt_icount_delta = 0;
 125                        nq->qt_rtbcount_delta = 0;
 126
 127                        /*
 128                         * Transfer whatever is left of the reservations.
 129                         */
 130                        nq->qt_blk_res = oq->qt_blk_res - oq->qt_blk_res_used;
 131                        oq->qt_blk_res = oq->qt_blk_res_used;
 132
 133                        nq->qt_rtblk_res = oq->qt_rtblk_res -
 134                                oq->qt_rtblk_res_used;
 135                        oq->qt_rtblk_res = oq->qt_rtblk_res_used;
 136
 137                        nq->qt_ino_res = oq->qt_ino_res - oq->qt_ino_res_used;
 138                        oq->qt_ino_res = oq->qt_ino_res_used;
 139
 140                }
 141        }
 142}
 143
 144/*
 145 * Wrap around mod_dquot to account for both user and group quotas.
 146 */
 147void
 148xfs_trans_mod_dquot_byino(
 149        xfs_trans_t     *tp,
 150        xfs_inode_t     *ip,
 151        uint            field,
 152        long            delta)
 153{
 154        xfs_mount_t     *mp = tp->t_mountp;
 155
 156        if (!XFS_IS_QUOTA_RUNNING(mp) ||
 157            !XFS_IS_QUOTA_ON(mp) ||
 158            xfs_is_quota_inode(&mp->m_sb, ip->i_ino))
 159                return;
 160
 161        if (tp->t_dqinfo == NULL)
 162                xfs_trans_alloc_dqinfo(tp);
 163
 164        if (XFS_IS_UQUOTA_ON(mp) && ip->i_udquot)
 165                (void) xfs_trans_mod_dquot(tp, ip->i_udquot, field, delta);
 166        if (XFS_IS_GQUOTA_ON(mp) && ip->i_gdquot)
 167                (void) xfs_trans_mod_dquot(tp, ip->i_gdquot, field, delta);
 168        if (XFS_IS_PQUOTA_ON(mp) && ip->i_pdquot)
 169                (void) xfs_trans_mod_dquot(tp, ip->i_pdquot, field, delta);
 170}
 171
 172STATIC struct xfs_dqtrx *
 173xfs_trans_get_dqtrx(
 174        struct xfs_trans        *tp,
 175        struct xfs_dquot        *dqp)
 176{
 177        int                     i;
 178        struct xfs_dqtrx        *qa;
 179
 180        if (XFS_QM_ISUDQ(dqp))
 181                qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_USR];
 182        else if (XFS_QM_ISGDQ(dqp))
 183                qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_GRP];
 184        else if (XFS_QM_ISPDQ(dqp))
 185                qa = tp->t_dqinfo->dqs[XFS_QM_TRANS_PRJ];
 186        else
 187                return NULL;
 188
 189        for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
 190                if (qa[i].qt_dquot == NULL ||
 191                    qa[i].qt_dquot == dqp)
 192                        return &qa[i];
 193        }
 194
 195        return NULL;
 196}
 197
 198/*
 199 * Make the changes in the transaction structure.
 200 * The moral equivalent to xfs_trans_mod_sb().
 201 * We don't touch any fields in the dquot, so we don't care
 202 * if it's locked or not (most of the time it won't be).
 203 */
 204void
 205xfs_trans_mod_dquot(
 206        xfs_trans_t     *tp,
 207        xfs_dquot_t     *dqp,
 208        uint            field,
 209        long            delta)
 210{
 211        xfs_dqtrx_t     *qtrx;
 212
 213        ASSERT(tp);
 214        ASSERT(XFS_IS_QUOTA_RUNNING(tp->t_mountp));
 215        qtrx = NULL;
 216
 217        if (tp->t_dqinfo == NULL)
 218                xfs_trans_alloc_dqinfo(tp);
 219        /*
 220         * Find either the first free slot or the slot that belongs
 221         * to this dquot.
 222         */
 223        qtrx = xfs_trans_get_dqtrx(tp, dqp);
 224        ASSERT(qtrx);
 225        if (qtrx->qt_dquot == NULL)
 226                qtrx->qt_dquot = dqp;
 227
 228        switch (field) {
 229
 230                /*
 231                 * regular disk blk reservation
 232                 */
 233              case XFS_TRANS_DQ_RES_BLKS:
 234                qtrx->qt_blk_res += (ulong)delta;
 235                break;
 236
 237                /*
 238                 * inode reservation
 239                 */
 240              case XFS_TRANS_DQ_RES_INOS:
 241                qtrx->qt_ino_res += (ulong)delta;
 242                break;
 243
 244                /*
 245                 * disk blocks used.
 246                 */
 247              case XFS_TRANS_DQ_BCOUNT:
 248                if (qtrx->qt_blk_res && delta > 0) {
 249                        qtrx->qt_blk_res_used += (ulong)delta;
 250                        ASSERT(qtrx->qt_blk_res >= qtrx->qt_blk_res_used);
 251                }
 252                qtrx->qt_bcount_delta += delta;
 253                break;
 254
 255              case XFS_TRANS_DQ_DELBCOUNT:
 256                qtrx->qt_delbcnt_delta += delta;
 257                break;
 258
 259                /*
 260                 * Inode Count
 261                 */
 262              case XFS_TRANS_DQ_ICOUNT:
 263                if (qtrx->qt_ino_res && delta > 0) {
 264                        qtrx->qt_ino_res_used += (ulong)delta;
 265                        ASSERT(qtrx->qt_ino_res >= qtrx->qt_ino_res_used);
 266                }
 267                qtrx->qt_icount_delta += delta;
 268                break;
 269
 270                /*
 271                 * rtblk reservation
 272                 */
 273              case XFS_TRANS_DQ_RES_RTBLKS:
 274                qtrx->qt_rtblk_res += (ulong)delta;
 275                break;
 276
 277                /*
 278                 * rtblk count
 279                 */
 280              case XFS_TRANS_DQ_RTBCOUNT:
 281                if (qtrx->qt_rtblk_res && delta > 0) {
 282                        qtrx->qt_rtblk_res_used += (ulong)delta;
 283                        ASSERT(qtrx->qt_rtblk_res >= qtrx->qt_rtblk_res_used);
 284                }
 285                qtrx->qt_rtbcount_delta += delta;
 286                break;
 287
 288              case XFS_TRANS_DQ_DELRTBCOUNT:
 289                qtrx->qt_delrtb_delta += delta;
 290                break;
 291
 292              default:
 293                ASSERT(0);
 294        }
 295        tp->t_flags |= XFS_TRANS_DQ_DIRTY;
 296}
 297
 298
 299/*
 300 * Given an array of dqtrx structures, lock all the dquots associated and join
 301 * them to the transaction, provided they have been modified.  We know that the
 302 * highest number of dquots of one type - usr, grp OR prj - involved in a
 303 * transaction is 2 so we don't need to make this very generic.
 304 */
 305STATIC void
 306xfs_trans_dqlockedjoin(
 307        xfs_trans_t     *tp,
 308        xfs_dqtrx_t     *q)
 309{
 310        ASSERT(q[0].qt_dquot != NULL);
 311        if (q[1].qt_dquot == NULL) {
 312                xfs_dqlock(q[0].qt_dquot);
 313                xfs_trans_dqjoin(tp, q[0].qt_dquot);
 314        } else {
 315                ASSERT(XFS_QM_TRANS_MAXDQS == 2);
 316                xfs_dqlock2(q[0].qt_dquot, q[1].qt_dquot);
 317                xfs_trans_dqjoin(tp, q[0].qt_dquot);
 318                xfs_trans_dqjoin(tp, q[1].qt_dquot);
 319        }
 320}
 321
 322
 323/*
 324 * Called by xfs_trans_commit() and similar in spirit to
 325 * xfs_trans_apply_sb_deltas().
 326 * Go thru all the dquots belonging to this transaction and modify the
 327 * INCORE dquot to reflect the actual usages.
 328 * Unreserve just the reservations done by this transaction.
 329 * dquot is still left locked at exit.
 330 */
 331void
 332xfs_trans_apply_dquot_deltas(
 333        struct xfs_trans        *tp)
 334{
 335        int                     i, j;
 336        struct xfs_dquot        *dqp;
 337        struct xfs_dqtrx        *qtrx, *qa;
 338        struct xfs_disk_dquot   *d;
 339        long                    totalbdelta;
 340        long                    totalrtbdelta;
 341
 342        if (!(tp->t_flags & XFS_TRANS_DQ_DIRTY))
 343                return;
 344
 345        ASSERT(tp->t_dqinfo);
 346        for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
 347                qa = tp->t_dqinfo->dqs[j];
 348                if (qa[0].qt_dquot == NULL)
 349                        continue;
 350
 351                /*
 352                 * Lock all of the dquots and join them to the transaction.
 353                 */
 354                xfs_trans_dqlockedjoin(tp, qa);
 355
 356                for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
 357                        qtrx = &qa[i];
 358                        /*
 359                         * The array of dquots is filled
 360                         * sequentially, not sparsely.
 361                         */
 362                        if ((dqp = qtrx->qt_dquot) == NULL)
 363                                break;
 364
 365                        ASSERT(XFS_DQ_IS_LOCKED(dqp));
 366                        ASSERT(dqp->q_transp == tp);
 367
 368                        /*
 369                         * adjust the actual number of blocks used
 370                         */
 371                        d = &dqp->q_core;
 372
 373                        /*
 374                         * The issue here is - sometimes we don't make a blkquota
 375                         * reservation intentionally to be fair to users
 376                         * (when the amount is small). On the other hand,
 377                         * delayed allocs do make reservations, but that's
 378                         * outside of a transaction, so we have no
 379                         * idea how much was really reserved.
 380                         * So, here we've accumulated delayed allocation blks and
 381                         * non-delay blks. The assumption is that the
 382                         * delayed ones are always reserved (outside of a
 383                         * transaction), and the others may or may not have
 384                         * quota reservations.
 385                         */
 386                        totalbdelta = qtrx->qt_bcount_delta +
 387                                qtrx->qt_delbcnt_delta;
 388                        totalrtbdelta = qtrx->qt_rtbcount_delta +
 389                                qtrx->qt_delrtb_delta;
 390#ifdef DEBUG
 391                        if (totalbdelta < 0)
 392                                ASSERT(be64_to_cpu(d->d_bcount) >=
 393                                       -totalbdelta);
 394
 395                        if (totalrtbdelta < 0)
 396                                ASSERT(be64_to_cpu(d->d_rtbcount) >=
 397                                       -totalrtbdelta);
 398
 399                        if (qtrx->qt_icount_delta < 0)
 400                                ASSERT(be64_to_cpu(d->d_icount) >=
 401                                       -qtrx->qt_icount_delta);
 402#endif
 403                        if (totalbdelta)
 404                                be64_add_cpu(&d->d_bcount, (xfs_qcnt_t)totalbdelta);
 405
 406                        if (qtrx->qt_icount_delta)
 407                                be64_add_cpu(&d->d_icount, (xfs_qcnt_t)qtrx->qt_icount_delta);
 408
 409                        if (totalrtbdelta)
 410                                be64_add_cpu(&d->d_rtbcount, (xfs_qcnt_t)totalrtbdelta);
 411
 412                        /*
 413                         * Get any default limits in use.
 414                         * Start/reset the timer(s) if needed.
 415                         */
 416                        if (d->d_id) {
 417                                xfs_qm_adjust_dqlimits(tp->t_mountp, dqp);
 418                                xfs_qm_adjust_dqtimers(tp->t_mountp, d);
 419                        }
 420
 421                        dqp->dq_flags |= XFS_DQ_DIRTY;
 422                        /*
 423                         * add this to the list of items to get logged
 424                         */
 425                        xfs_trans_log_dquot(tp, dqp);
 426                        /*
 427                         * Take off what's left of the original reservation.
 428                         * In case of delayed allocations, there's no
 429                         * reservation that a transaction structure knows of.
 430                         */
 431                        if (qtrx->qt_blk_res != 0) {
 432                                if (qtrx->qt_blk_res != qtrx->qt_blk_res_used) {
 433                                        if (qtrx->qt_blk_res >
 434                                            qtrx->qt_blk_res_used)
 435                                                dqp->q_res_bcount -= (xfs_qcnt_t)
 436                                                        (qtrx->qt_blk_res -
 437                                                         qtrx->qt_blk_res_used);
 438                                        else
 439                                                dqp->q_res_bcount -= (xfs_qcnt_t)
 440                                                        (qtrx->qt_blk_res_used -
 441                                                         qtrx->qt_blk_res);
 442                                }
 443                        } else {
 444                                /*
 445                                 * These blks were never reserved, either inside
 446                                 * a transaction or outside one (in a delayed
 447                                 * allocation). Also, this isn't always a
 448                                 * negative number since we sometimes
 449                                 * deliberately skip quota reservations.
 450                                 */
 451                                if (qtrx->qt_bcount_delta) {
 452                                        dqp->q_res_bcount +=
 453                                              (xfs_qcnt_t)qtrx->qt_bcount_delta;
 454                                }
 455                        }
 456                        /*
 457                         * Adjust the RT reservation.
 458                         */
 459                        if (qtrx->qt_rtblk_res != 0) {
 460                                if (qtrx->qt_rtblk_res != qtrx->qt_rtblk_res_used) {
 461                                        if (qtrx->qt_rtblk_res >
 462                                            qtrx->qt_rtblk_res_used)
 463                                               dqp->q_res_rtbcount -= (xfs_qcnt_t)
 464                                                       (qtrx->qt_rtblk_res -
 465                                                        qtrx->qt_rtblk_res_used);
 466                                        else
 467                                               dqp->q_res_rtbcount -= (xfs_qcnt_t)
 468                                                       (qtrx->qt_rtblk_res_used -
 469                                                        qtrx->qt_rtblk_res);
 470                                }
 471                        } else {
 472                                if (qtrx->qt_rtbcount_delta)
 473                                        dqp->q_res_rtbcount +=
 474                                            (xfs_qcnt_t)qtrx->qt_rtbcount_delta;
 475                        }
 476
 477                        /*
 478                         * Adjust the inode reservation.
 479                         */
 480                        if (qtrx->qt_ino_res != 0) {
 481                                ASSERT(qtrx->qt_ino_res >=
 482                                       qtrx->qt_ino_res_used);
 483                                if (qtrx->qt_ino_res > qtrx->qt_ino_res_used)
 484                                        dqp->q_res_icount -= (xfs_qcnt_t)
 485                                                (qtrx->qt_ino_res -
 486                                                 qtrx->qt_ino_res_used);
 487                        } else {
 488                                if (qtrx->qt_icount_delta)
 489                                        dqp->q_res_icount +=
 490                                            (xfs_qcnt_t)qtrx->qt_icount_delta;
 491                        }
 492
 493                        ASSERT(dqp->q_res_bcount >=
 494                                be64_to_cpu(dqp->q_core.d_bcount));
 495                        ASSERT(dqp->q_res_icount >=
 496                                be64_to_cpu(dqp->q_core.d_icount));
 497                        ASSERT(dqp->q_res_rtbcount >=
 498                                be64_to_cpu(dqp->q_core.d_rtbcount));
 499                }
 500        }
 501}
 502
 503/*
 504 * Release the reservations, and adjust the dquots accordingly.
 505 * This is called only when the transaction is being aborted. If by
 506 * any chance we have done dquot modifications incore (ie. deltas) already,
 507 * we simply throw those away, since that's the expected behavior
 508 * when a transaction is curtailed without a commit.
 509 */
 510void
 511xfs_trans_unreserve_and_mod_dquots(
 512        xfs_trans_t             *tp)
 513{
 514        int                     i, j;
 515        xfs_dquot_t             *dqp;
 516        xfs_dqtrx_t             *qtrx, *qa;
 517        bool                    locked;
 518
 519        if (!tp->t_dqinfo || !(tp->t_flags & XFS_TRANS_DQ_DIRTY))
 520                return;
 521
 522        for (j = 0; j < XFS_QM_TRANS_DQTYPES; j++) {
 523                qa = tp->t_dqinfo->dqs[j];
 524
 525                for (i = 0; i < XFS_QM_TRANS_MAXDQS; i++) {
 526                        qtrx = &qa[i];
 527                        /*
 528                         * We assume that the array of dquots is filled
 529                         * sequentially, not sparsely.
 530                         */
 531                        if ((dqp = qtrx->qt_dquot) == NULL)
 532                                break;
 533                        /*
 534                         * Unreserve the original reservation. We don't care
 535                         * about the number of blocks used field, or deltas.
 536                         * Also we don't bother to zero the fields.
 537                         */
 538                        locked = false;
 539                        if (qtrx->qt_blk_res) {
 540                                xfs_dqlock(dqp);
 541                                locked = true;
 542                                dqp->q_res_bcount -=
 543                                        (xfs_qcnt_t)qtrx->qt_blk_res;
 544                        }
 545                        if (qtrx->qt_ino_res) {
 546                                if (!locked) {
 547                                        xfs_dqlock(dqp);
 548                                        locked = true;
 549                                }
 550                                dqp->q_res_icount -=
 551                                        (xfs_qcnt_t)qtrx->qt_ino_res;
 552                        }
 553
 554                        if (qtrx->qt_rtblk_res) {
 555                                if (!locked) {
 556                                        xfs_dqlock(dqp);
 557                                        locked = true;
 558                                }
 559                                dqp->q_res_rtbcount -=
 560                                        (xfs_qcnt_t)qtrx->qt_rtblk_res;
 561                        }
 562                        if (locked)
 563                                xfs_dqunlock(dqp);
 564
 565                }
 566        }
 567}
 568
 569STATIC void
 570xfs_quota_warn(
 571        struct xfs_mount        *mp,
 572        struct xfs_dquot        *dqp,
 573        int                     type)
 574{
 575        /* no warnings for project quotas - we just return ENOSPC later */
 576        if (dqp->dq_flags & XFS_DQ_PROJ)
 577                return;
 578        quota_send_warning(make_kqid(&init_user_ns,
 579                                     (dqp->dq_flags & XFS_DQ_USER) ?
 580                                     USRQUOTA : GRPQUOTA,
 581                                     be32_to_cpu(dqp->q_core.d_id)),
 582                           mp->m_super->s_dev, type);
 583}
 584
 585/*
 586 * This reserves disk blocks and inodes against a dquot.
 587 * Flags indicate if the dquot is to be locked here and also
 588 * if the blk reservation is for RT or regular blocks.
 589 * Sending in XFS_QMOPT_FORCE_RES flag skips the quota check.
 590 */
 591STATIC int
 592xfs_trans_dqresv(
 593        xfs_trans_t     *tp,
 594        xfs_mount_t     *mp,
 595        xfs_dquot_t     *dqp,
 596        long            nblks,
 597        long            ninos,
 598        uint            flags)
 599{
 600        xfs_qcnt_t      hardlimit;
 601        xfs_qcnt_t      softlimit;
 602        time_t          timer;
 603        xfs_qwarncnt_t  warns;
 604        xfs_qwarncnt_t  warnlimit;
 605        xfs_qcnt_t      total_count;
 606        xfs_qcnt_t      *resbcountp;
 607        xfs_quotainfo_t *q = mp->m_quotainfo;
 608
 609
 610        xfs_dqlock(dqp);
 611
 612        if (flags & XFS_TRANS_DQ_RES_BLKS) {
 613                hardlimit = be64_to_cpu(dqp->q_core.d_blk_hardlimit);
 614                if (!hardlimit)
 615                        hardlimit = q->qi_bhardlimit;
 616                softlimit = be64_to_cpu(dqp->q_core.d_blk_softlimit);
 617                if (!softlimit)
 618                        softlimit = q->qi_bsoftlimit;
 619                timer = be32_to_cpu(dqp->q_core.d_btimer);
 620                warns = be16_to_cpu(dqp->q_core.d_bwarns);
 621                warnlimit = dqp->q_mount->m_quotainfo->qi_bwarnlimit;
 622                resbcountp = &dqp->q_res_bcount;
 623        } else {
 624                ASSERT(flags & XFS_TRANS_DQ_RES_RTBLKS);
 625                hardlimit = be64_to_cpu(dqp->q_core.d_rtb_hardlimit);
 626                if (!hardlimit)
 627                        hardlimit = q->qi_rtbhardlimit;
 628                softlimit = be64_to_cpu(dqp->q_core.d_rtb_softlimit);
 629                if (!softlimit)
 630                        softlimit = q->qi_rtbsoftlimit;
 631                timer = be32_to_cpu(dqp->q_core.d_rtbtimer);
 632                warns = be16_to_cpu(dqp->q_core.d_rtbwarns);
 633                warnlimit = dqp->q_mount->m_quotainfo->qi_rtbwarnlimit;
 634                resbcountp = &dqp->q_res_rtbcount;
 635        }
 636
 637        if ((flags & XFS_QMOPT_FORCE_RES) == 0 &&
 638            dqp->q_core.d_id &&
 639            ((XFS_IS_UQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISUDQ(dqp)) ||
 640             (XFS_IS_GQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISGDQ(dqp)) ||
 641             (XFS_IS_PQUOTA_ENFORCED(dqp->q_mount) && XFS_QM_ISPDQ(dqp)))) {
 642                if (nblks > 0) {
 643                        /*
 644                         * dquot is locked already. See if we'd go over the
 645                         * hardlimit or exceed the timelimit if we allocate
 646                         * nblks.
 647                         */
 648                        total_count = *resbcountp + nblks;
 649                        if (hardlimit && total_count > hardlimit) {
 650                                xfs_quota_warn(mp, dqp, QUOTA_NL_BHARDWARN);
 651                                goto error_return;
 652                        }
 653                        if (softlimit && total_count > softlimit) {
 654                                if ((timer != 0 && get_seconds() > timer) ||
 655                                    (warns != 0 && warns >= warnlimit)) {
 656                                        xfs_quota_warn(mp, dqp,
 657                                                       QUOTA_NL_BSOFTLONGWARN);
 658                                        goto error_return;
 659                                }
 660
 661                                xfs_quota_warn(mp, dqp, QUOTA_NL_BSOFTWARN);
 662                        }
 663                }
 664                if (ninos > 0) {
 665                        total_count = be64_to_cpu(dqp->q_core.d_icount) + ninos;
 666                        timer = be32_to_cpu(dqp->q_core.d_itimer);
 667                        warns = be16_to_cpu(dqp->q_core.d_iwarns);
 668                        warnlimit = dqp->q_mount->m_quotainfo->qi_iwarnlimit;
 669                        hardlimit = be64_to_cpu(dqp->q_core.d_ino_hardlimit);
 670                        if (!hardlimit)
 671                                hardlimit = q->qi_ihardlimit;
 672                        softlimit = be64_to_cpu(dqp->q_core.d_ino_softlimit);
 673                        if (!softlimit)
 674                                softlimit = q->qi_isoftlimit;
 675
 676                        if (hardlimit && total_count > hardlimit) {
 677                                xfs_quota_warn(mp, dqp, QUOTA_NL_IHARDWARN);
 678                                goto error_return;
 679                        }
 680                        if (softlimit && total_count > softlimit) {
 681                                if  ((timer != 0 && get_seconds() > timer) ||
 682                                     (warns != 0 && warns >= warnlimit)) {
 683                                        xfs_quota_warn(mp, dqp,
 684                                                       QUOTA_NL_ISOFTLONGWARN);
 685                                        goto error_return;
 686                                }
 687                                xfs_quota_warn(mp, dqp, QUOTA_NL_ISOFTWARN);
 688                        }
 689                }
 690        }
 691
 692        /*
 693         * Change the reservation, but not the actual usage.
 694         * Note that q_res_bcount = q_core.d_bcount + resv
 695         */
 696        (*resbcountp) += (xfs_qcnt_t)nblks;
 697        if (ninos != 0)
 698                dqp->q_res_icount += (xfs_qcnt_t)ninos;
 699
 700        /*
 701         * note the reservation amt in the trans struct too,
 702         * so that the transaction knows how much was reserved by
 703         * it against this particular dquot.
 704         * We don't do this when we are reserving for a delayed allocation,
 705         * because we don't have the luxury of a transaction envelope then.
 706         */
 707        if (tp) {
 708                ASSERT(tp->t_dqinfo);
 709                ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
 710                if (nblks != 0)
 711                        xfs_trans_mod_dquot(tp, dqp,
 712                                            flags & XFS_QMOPT_RESBLK_MASK,
 713                                            nblks);
 714                if (ninos != 0)
 715                        xfs_trans_mod_dquot(tp, dqp,
 716                                            XFS_TRANS_DQ_RES_INOS,
 717                                            ninos);
 718        }
 719        ASSERT(dqp->q_res_bcount >= be64_to_cpu(dqp->q_core.d_bcount));
 720        ASSERT(dqp->q_res_rtbcount >= be64_to_cpu(dqp->q_core.d_rtbcount));
 721        ASSERT(dqp->q_res_icount >= be64_to_cpu(dqp->q_core.d_icount));
 722
 723        xfs_dqunlock(dqp);
 724        return 0;
 725
 726error_return:
 727        xfs_dqunlock(dqp);
 728        if (flags & XFS_QMOPT_ENOSPC)
 729                return ENOSPC;
 730        return EDQUOT;
 731}
 732
 733
 734/*
 735 * Given dquot(s), make disk block and/or inode reservations against them.
 736 * The fact that this does the reservation against user, group and
 737 * project quotas is important, because this follows a all-or-nothing
 738 * approach.
 739 *
 740 * flags = XFS_QMOPT_FORCE_RES evades limit enforcement. Used by chown.
 741 *         XFS_QMOPT_ENOSPC returns ENOSPC not EDQUOT.  Used by pquota.
 742 *         XFS_TRANS_DQ_RES_BLKS reserves regular disk blocks
 743 *         XFS_TRANS_DQ_RES_RTBLKS reserves realtime disk blocks
 744 * dquots are unlocked on return, if they were not locked by caller.
 745 */
 746int
 747xfs_trans_reserve_quota_bydquots(
 748        struct xfs_trans        *tp,
 749        struct xfs_mount        *mp,
 750        struct xfs_dquot        *udqp,
 751        struct xfs_dquot        *gdqp,
 752        struct xfs_dquot        *pdqp,
 753        long                    nblks,
 754        long                    ninos,
 755        uint                    flags)
 756{
 757        int             error;
 758
 759        if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
 760                return 0;
 761
 762        if (tp && tp->t_dqinfo == NULL)
 763                xfs_trans_alloc_dqinfo(tp);
 764
 765        ASSERT(flags & XFS_QMOPT_RESBLK_MASK);
 766
 767        if (udqp) {
 768                error = xfs_trans_dqresv(tp, mp, udqp, nblks, ninos,
 769                                        (flags & ~XFS_QMOPT_ENOSPC));
 770                if (error)
 771                        return error;
 772        }
 773
 774        if (gdqp) {
 775                error = xfs_trans_dqresv(tp, mp, gdqp, nblks, ninos, flags);
 776                if (error)
 777                        goto unwind_usr;
 778        }
 779
 780        if (pdqp) {
 781                error = xfs_trans_dqresv(tp, mp, pdqp, nblks, ninos, flags);
 782                if (error)
 783                        goto unwind_grp;
 784        }
 785
 786        /*
 787         * Didn't change anything critical, so, no need to log
 788         */
 789        return 0;
 790
 791unwind_grp:
 792        flags |= XFS_QMOPT_FORCE_RES;
 793        if (gdqp)
 794                xfs_trans_dqresv(tp, mp, gdqp, -nblks, -ninos, flags);
 795unwind_usr:
 796        flags |= XFS_QMOPT_FORCE_RES;
 797        if (udqp)
 798                xfs_trans_dqresv(tp, mp, udqp, -nblks, -ninos, flags);
 799        return error;
 800}
 801
 802
 803/*
 804 * Lock the dquot and change the reservation if we can.
 805 * This doesn't change the actual usage, just the reservation.
 806 * The inode sent in is locked.
 807 */
 808int
 809xfs_trans_reserve_quota_nblks(
 810        struct xfs_trans        *tp,
 811        struct xfs_inode        *ip,
 812        long                    nblks,
 813        long                    ninos,
 814        uint                    flags)
 815{
 816        struct xfs_mount        *mp = ip->i_mount;
 817
 818        if (!XFS_IS_QUOTA_RUNNING(mp) || !XFS_IS_QUOTA_ON(mp))
 819                return 0;
 820        if (XFS_IS_PQUOTA_ON(mp))
 821                flags |= XFS_QMOPT_ENOSPC;
 822
 823        ASSERT(!xfs_is_quota_inode(&mp->m_sb, ip->i_ino));
 824
 825        ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL));
 826        ASSERT((flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
 827                                XFS_TRANS_DQ_RES_RTBLKS ||
 828               (flags & ~(XFS_QMOPT_FORCE_RES | XFS_QMOPT_ENOSPC)) ==
 829                                XFS_TRANS_DQ_RES_BLKS);
 830
 831        /*
 832         * Reserve nblks against these dquots, with trans as the mediator.
 833         */
 834        return xfs_trans_reserve_quota_bydquots(tp, mp,
 835                                                ip->i_udquot, ip->i_gdquot,
 836                                                ip->i_pdquot,
 837                                                nblks, ninos, flags);
 838}
 839
 840/*
 841 * This routine is called to allocate a quotaoff log item.
 842 */
 843xfs_qoff_logitem_t *
 844xfs_trans_get_qoff_item(
 845        xfs_trans_t             *tp,
 846        xfs_qoff_logitem_t      *startqoff,
 847        uint                    flags)
 848{
 849        xfs_qoff_logitem_t      *q;
 850
 851        ASSERT(tp != NULL);
 852
 853        q = xfs_qm_qoff_logitem_init(tp->t_mountp, startqoff, flags);
 854        ASSERT(q != NULL);
 855
 856        /*
 857         * Get a log_item_desc to point at the new item.
 858         */
 859        xfs_trans_add_item(tp, &q->qql_item);
 860        return q;
 861}
 862
 863
 864/*
 865 * This is called to mark the quotaoff logitem as needing
 866 * to be logged when the transaction is committed.  The logitem must
 867 * already be associated with the given transaction.
 868 */
 869void
 870xfs_trans_log_quotaoff_item(
 871        xfs_trans_t             *tp,
 872        xfs_qoff_logitem_t      *qlp)
 873{
 874        tp->t_flags |= XFS_TRANS_DIRTY;
 875        qlp->qql_item.li_desc->lid_flags |= XFS_LID_DIRTY;
 876}
 877
 878STATIC void
 879xfs_trans_alloc_dqinfo(
 880        xfs_trans_t     *tp)
 881{
 882        tp->t_dqinfo = kmem_zone_zalloc(xfs_qm_dqtrxzone, KM_SLEEP);
 883}
 884
 885void
 886xfs_trans_free_dqinfo(
 887        xfs_trans_t     *tp)
 888{
 889        if (!tp->t_dqinfo)
 890                return;
 891        kmem_zone_free(xfs_qm_dqtrxzone, tp->t_dqinfo);
 892        tp->t_dqinfo = NULL;
 893}
 894
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.