Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  * Copyright (c) 2000-2005 Silicon Graphics, Inc.
0004  * All Rights Reserved.
0005  */
0006 #ifndef __XFS_DQUOT_H__
0007 #define __XFS_DQUOT_H__
0008 
0009 /*
0010  * Dquots are structures that hold quota information about a user or a group,
0011  * much like inodes are for files. In fact, dquots share many characteristics
0012  * with inodes. However, dquots can also be a centralized resource, relative
0013  * to a collection of inodes. In this respect, dquots share some characteristics
0014  * of the superblock.
0015  * XFS dquots exploit both those in its algorithms. They make every attempt
0016  * to not be a bottleneck when quotas are on and have minimal impact, if any,
0017  * when quotas are off.
0018  */
0019 
0020 struct xfs_mount;
0021 struct xfs_trans;
0022 
0023 enum {
0024     XFS_QLOWSP_1_PCNT = 0,
0025     XFS_QLOWSP_3_PCNT,
0026     XFS_QLOWSP_5_PCNT,
0027     XFS_QLOWSP_MAX
0028 };
0029 
0030 struct xfs_dquot_res {
0031     /* Total resources allocated and reserved. */
0032     xfs_qcnt_t      reserved;
0033 
0034     /* Total resources allocated. */
0035     xfs_qcnt_t      count;
0036 
0037     /* Absolute and preferred limits. */
0038     xfs_qcnt_t      hardlimit;
0039     xfs_qcnt_t      softlimit;
0040 
0041     /*
0042      * For root dquots, this is the default grace period, in seconds.
0043      * Otherwise, this is when the quota grace period expires,
0044      * in seconds since the Unix epoch.
0045      */
0046     time64_t        timer;
0047 };
0048 
0049 static inline bool
0050 xfs_dquot_res_over_limits(
0051     const struct xfs_dquot_res  *qres)
0052 {
0053     if ((qres->softlimit && qres->softlimit < qres->reserved) ||
0054         (qres->hardlimit && qres->hardlimit < qres->reserved))
0055         return true;
0056     return false;
0057 }
0058 
0059 /*
0060  * The incore dquot structure
0061  */
0062 struct xfs_dquot {
0063     struct list_head    q_lru;
0064     struct xfs_mount    *q_mount;
0065     xfs_dqtype_t        q_type;
0066     uint16_t        q_flags;
0067     xfs_dqid_t      q_id;
0068     uint            q_nrefs;
0069     int         q_bufoffset;
0070     xfs_daddr_t     q_blkno;
0071     xfs_fileoff_t       q_fileoffset;
0072 
0073     struct xfs_dquot_res    q_blk;  /* regular blocks */
0074     struct xfs_dquot_res    q_ino;  /* inodes */
0075     struct xfs_dquot_res    q_rtb;  /* realtime blocks */
0076 
0077     struct xfs_dq_logitem   q_logitem;
0078 
0079     xfs_qcnt_t      q_prealloc_lo_wmark;
0080     xfs_qcnt_t      q_prealloc_hi_wmark;
0081     int64_t         q_low_space[XFS_QLOWSP_MAX];
0082     struct mutex        q_qlock;
0083     struct completion   q_flush;
0084     atomic_t        q_pincount;
0085     struct wait_queue_head  q_pinwait;
0086 };
0087 
0088 /*
0089  * Lock hierarchy for q_qlock:
0090  *  XFS_QLOCK_NORMAL is the implicit default,
0091  *  XFS_QLOCK_NESTED is the dquot with the higher id in xfs_dqlock2
0092  */
0093 enum {
0094     XFS_QLOCK_NORMAL = 0,
0095     XFS_QLOCK_NESTED,
0096 };
0097 
0098 /*
0099  * Manage the q_flush completion queue embedded in the dquot. This completion
0100  * queue synchronizes processes attempting to flush the in-core dquot back to
0101  * disk.
0102  */
0103 static inline void xfs_dqflock(struct xfs_dquot *dqp)
0104 {
0105     wait_for_completion(&dqp->q_flush);
0106 }
0107 
0108 static inline bool xfs_dqflock_nowait(struct xfs_dquot *dqp)
0109 {
0110     return try_wait_for_completion(&dqp->q_flush);
0111 }
0112 
0113 static inline void xfs_dqfunlock(struct xfs_dquot *dqp)
0114 {
0115     complete(&dqp->q_flush);
0116 }
0117 
0118 static inline int xfs_dqlock_nowait(struct xfs_dquot *dqp)
0119 {
0120     return mutex_trylock(&dqp->q_qlock);
0121 }
0122 
0123 static inline void xfs_dqlock(struct xfs_dquot *dqp)
0124 {
0125     mutex_lock(&dqp->q_qlock);
0126 }
0127 
0128 static inline void xfs_dqunlock(struct xfs_dquot *dqp)
0129 {
0130     mutex_unlock(&dqp->q_qlock);
0131 }
0132 
0133 static inline int
0134 xfs_dquot_type(const struct xfs_dquot *dqp)
0135 {
0136     return dqp->q_type & XFS_DQTYPE_REC_MASK;
0137 }
0138 
0139 static inline int xfs_this_quota_on(struct xfs_mount *mp, xfs_dqtype_t type)
0140 {
0141     switch (type) {
0142     case XFS_DQTYPE_USER:
0143         return XFS_IS_UQUOTA_ON(mp);
0144     case XFS_DQTYPE_GROUP:
0145         return XFS_IS_GQUOTA_ON(mp);
0146     case XFS_DQTYPE_PROJ:
0147         return XFS_IS_PQUOTA_ON(mp);
0148     default:
0149         return 0;
0150     }
0151 }
0152 
0153 static inline struct xfs_dquot *xfs_inode_dquot(
0154     struct xfs_inode    *ip,
0155     xfs_dqtype_t        type)
0156 {
0157     switch (type) {
0158     case XFS_DQTYPE_USER:
0159         return ip->i_udquot;
0160     case XFS_DQTYPE_GROUP:
0161         return ip->i_gdquot;
0162     case XFS_DQTYPE_PROJ:
0163         return ip->i_pdquot;
0164     default:
0165         return NULL;
0166     }
0167 }
0168 
0169 /* Decide if the dquot's limits are actually being enforced. */
0170 static inline bool
0171 xfs_dquot_is_enforced(
0172     const struct xfs_dquot  *dqp)
0173 {
0174     switch (xfs_dquot_type(dqp)) {
0175     case XFS_DQTYPE_USER:
0176         return XFS_IS_UQUOTA_ENFORCED(dqp->q_mount);
0177     case XFS_DQTYPE_GROUP:
0178         return XFS_IS_GQUOTA_ENFORCED(dqp->q_mount);
0179     case XFS_DQTYPE_PROJ:
0180         return XFS_IS_PQUOTA_ENFORCED(dqp->q_mount);
0181     }
0182     ASSERT(0);
0183     return false;
0184 }
0185 
0186 /*
0187  * Check whether a dquot is under low free space conditions. We assume the quota
0188  * is enabled and enforced.
0189  */
0190 static inline bool xfs_dquot_lowsp(struct xfs_dquot *dqp)
0191 {
0192     int64_t freesp;
0193 
0194     freesp = dqp->q_blk.hardlimit - dqp->q_blk.reserved;
0195     if (freesp < dqp->q_low_space[XFS_QLOWSP_1_PCNT])
0196         return true;
0197 
0198     return false;
0199 }
0200 
0201 void xfs_dquot_to_disk(struct xfs_disk_dquot *ddqp, struct xfs_dquot *dqp);
0202 
0203 #define XFS_DQ_IS_LOCKED(dqp)   (mutex_is_locked(&((dqp)->q_qlock)))
0204 #define XFS_DQ_IS_DIRTY(dqp)    ((dqp)->q_flags & XFS_DQFLAG_DIRTY)
0205 
0206 void        xfs_qm_dqdestroy(struct xfs_dquot *dqp);
0207 int     xfs_qm_dqflush(struct xfs_dquot *dqp, struct xfs_buf **bpp);
0208 void        xfs_qm_dqunpin_wait(struct xfs_dquot *dqp);
0209 void        xfs_qm_adjust_dqtimers(struct xfs_dquot *d);
0210 void        xfs_qm_adjust_dqlimits(struct xfs_dquot *d);
0211 xfs_dqid_t  xfs_qm_id_for_quotatype(struct xfs_inode *ip,
0212                 xfs_dqtype_t type);
0213 int     xfs_qm_dqget(struct xfs_mount *mp, xfs_dqid_t id,
0214                 xfs_dqtype_t type, bool can_alloc,
0215                 struct xfs_dquot **dqpp);
0216 int     xfs_qm_dqget_inode(struct xfs_inode *ip, xfs_dqtype_t type,
0217                 bool can_alloc, struct xfs_dquot **dqpp);
0218 int     xfs_qm_dqget_next(struct xfs_mount *mp, xfs_dqid_t id,
0219                 xfs_dqtype_t type, struct xfs_dquot **dqpp);
0220 int     xfs_qm_dqget_uncached(struct xfs_mount *mp,
0221                 xfs_dqid_t id, xfs_dqtype_t type,
0222                 struct xfs_dquot **dqpp);
0223 void        xfs_qm_dqput(struct xfs_dquot *dqp);
0224 
0225 void        xfs_dqlock2(struct xfs_dquot *, struct xfs_dquot *);
0226 
0227 void        xfs_dquot_set_prealloc_limits(struct xfs_dquot *);
0228 
0229 static inline struct xfs_dquot *xfs_qm_dqhold(struct xfs_dquot *dqp)
0230 {
0231     xfs_dqlock(dqp);
0232     dqp->q_nrefs++;
0233     xfs_dqunlock(dqp);
0234     return dqp;
0235 }
0236 
0237 typedef int (*xfs_qm_dqiterate_fn)(struct xfs_dquot *dq,
0238         xfs_dqtype_t type, void *priv);
0239 int xfs_qm_dqiterate(struct xfs_mount *mp, xfs_dqtype_t type,
0240         xfs_qm_dqiterate_fn iter_fn, void *priv);
0241 
0242 time64_t xfs_dquot_set_timeout(struct xfs_mount *mp, time64_t timeout);
0243 time64_t xfs_dquot_set_grace_period(time64_t grace);
0244 
0245 #endif /* __XFS_DQUOT_H__ */