linux/fs/xfs/xfs_qm_bhv.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2000-2006 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_qm.h"
  36
  37
  38STATIC void
  39xfs_fill_statvfs_from_dquot(
  40        struct kstatfs          *statp,
  41        struct xfs_dquot        *dqp)
  42{
  43        __uint64_t              limit;
  44
  45        limit = dqp->q_core.d_blk_softlimit ?
  46                be64_to_cpu(dqp->q_core.d_blk_softlimit) :
  47                be64_to_cpu(dqp->q_core.d_blk_hardlimit);
  48        if (limit && statp->f_blocks > limit) {
  49                statp->f_blocks = limit;
  50                statp->f_bfree = statp->f_bavail =
  51                        (statp->f_blocks > dqp->q_res_bcount) ?
  52                         (statp->f_blocks - dqp->q_res_bcount) : 0;
  53        }
  54
  55        limit = dqp->q_core.d_ino_softlimit ?
  56                be64_to_cpu(dqp->q_core.d_ino_softlimit) :
  57                be64_to_cpu(dqp->q_core.d_ino_hardlimit);
  58        if (limit && statp->f_files > limit) {
  59                statp->f_files = limit;
  60                statp->f_ffree =
  61                        (statp->f_files > dqp->q_res_icount) ?
  62                         (statp->f_ffree - dqp->q_res_icount) : 0;
  63        }
  64}
  65
  66
  67/*
  68 * Directory tree accounting is implemented using project quotas, where
  69 * the project identifier is inherited from parent directories.
  70 * A statvfs (df, etc.) of a directory that is using project quota should
  71 * return a statvfs of the project, not the entire filesystem.
  72 * This makes such trees appear as if they are filesystems in themselves.
  73 */
  74void
  75xfs_qm_statvfs(
  76        xfs_inode_t             *ip,
  77        struct kstatfs          *statp)
  78{
  79        xfs_mount_t             *mp = ip->i_mount;
  80        xfs_dquot_t             *dqp;
  81
  82        if (!xfs_qm_dqget(mp, NULL, xfs_get_projid(ip), XFS_DQ_PROJ, 0, &dqp)) {
  83                xfs_fill_statvfs_from_dquot(statp, dqp);
  84                xfs_qm_dqput(dqp);
  85        }
  86}
  87
  88int
  89xfs_qm_newmount(
  90        xfs_mount_t     *mp,
  91        uint            *needquotamount,
  92        uint            *quotaflags)
  93{
  94        uint            quotaondisk;
  95        uint            uquotaondisk = 0, gquotaondisk = 0, pquotaondisk = 0;
  96
  97        quotaondisk = xfs_sb_version_hasquota(&mp->m_sb) &&
  98                                (mp->m_sb.sb_qflags & XFS_ALL_QUOTA_ACCT);
  99
 100        if (quotaondisk) {
 101                uquotaondisk = mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT;
 102                pquotaondisk = mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT;
 103                gquotaondisk = mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT;
 104        }
 105
 106        /*
 107         * If the device itself is read-only, we can't allow
 108         * the user to change the state of quota on the mount -
 109         * this would generate a transaction on the ro device,
 110         * which would lead to an I/O error and shutdown
 111         */
 112
 113        if (((uquotaondisk && !XFS_IS_UQUOTA_ON(mp)) ||
 114            (!uquotaondisk &&  XFS_IS_UQUOTA_ON(mp)) ||
 115             (gquotaondisk && !XFS_IS_GQUOTA_ON(mp)) ||
 116            (!gquotaondisk &&  XFS_IS_GQUOTA_ON(mp)) ||
 117             (pquotaondisk && !XFS_IS_PQUOTA_ON(mp)) ||
 118            (!pquotaondisk &&  XFS_IS_PQUOTA_ON(mp)))  &&
 119            xfs_dev_is_read_only(mp, "changing quota state")) {
 120                xfs_warn(mp, "please mount with%s%s%s%s.",
 121                        (!quotaondisk ? "out quota" : ""),
 122                        (uquotaondisk ? " usrquota" : ""),
 123                        (gquotaondisk ? " grpquota" : ""),
 124                        (pquotaondisk ? " prjquota" : ""));
 125                return XFS_ERROR(EPERM);
 126        }
 127
 128        if (XFS_IS_QUOTA_ON(mp) || quotaondisk) {
 129                /*
 130                 * Call mount_quotas at this point only if we won't have to do
 131                 * a quotacheck.
 132                 */
 133                if (quotaondisk && !XFS_QM_NEED_QUOTACHECK(mp)) {
 134                        /*
 135                         * If an error occurred, qm_mount_quotas code
 136                         * has already disabled quotas. So, just finish
 137                         * mounting, and get on with the boring life
 138                         * without disk quotas.
 139                         */
 140                        xfs_qm_mount_quotas(mp);
 141                } else {
 142                        /*
 143                         * Clear the quota flags, but remember them. This
 144                         * is so that the quota code doesn't get invoked
 145                         * before we're ready. This can happen when an
 146                         * inode goes inactive and wants to free blocks,
 147                         * or via xfs_log_mount_finish.
 148                         */
 149                        *needquotamount = true;
 150                        *quotaflags = mp->m_qflags;
 151                        mp->m_qflags = 0;
 152                }
 153        }
 154
 155        return 0;
 156}
 157
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.