Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v6.19 289 lines 6.4 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2008, Christoph Hellwig 4 * All Rights Reserved. 5 */ 6#include "xfs.h" 7#include "xfs_shared.h" 8#include "xfs_format.h" 9#include "xfs_log_format.h" 10#include "xfs_trans_resv.h" 11#include "xfs_mount.h" 12#include "xfs_inode.h" 13#include "xfs_quota.h" 14#include "xfs_trans.h" 15#include "xfs_icache.h" 16#include "xfs_qm.h" 17 18 19static int 20xfs_qm_fill_state( 21 struct qc_type_state *tstate, 22 struct xfs_mount *mp, 23 xfs_dqtype_t type) 24{ 25 struct xfs_inode *ip; 26 struct xfs_def_quota *defq; 27 int error; 28 29 error = xfs_qm_qino_load(mp, type, &ip); 30 if (error) { 31 tstate->ino = NULLFSINO; 32 return error != -ENOENT ? error : 0; 33 } 34 35 defq = xfs_get_defquota(mp->m_quotainfo, type); 36 37 tstate->ino = ip->i_ino; 38 tstate->flags |= QCI_SYSFILE; 39 tstate->blocks = ip->i_nblocks; 40 tstate->nextents = ip->i_df.if_nextents; 41 tstate->spc_timelimit = (u32)defq->blk.time; 42 tstate->ino_timelimit = (u32)defq->ino.time; 43 tstate->rt_spc_timelimit = (u32)defq->rtb.time; 44 tstate->spc_warnlimit = 0; 45 tstate->ino_warnlimit = 0; 46 tstate->rt_spc_warnlimit = 0; 47 xfs_irele(ip); 48 49 return 0; 50} 51 52/* 53 * Return quota status information, such as enforcements, quota file inode 54 * numbers etc. 55 */ 56static int 57xfs_fs_get_quota_state( 58 struct super_block *sb, 59 struct qc_state *state) 60{ 61 struct xfs_mount *mp = XFS_M(sb); 62 struct xfs_quotainfo *q = mp->m_quotainfo; 63 int error; 64 65 memset(state, 0, sizeof(*state)); 66 if (!XFS_IS_QUOTA_ON(mp)) 67 return 0; 68 state->s_incoredqs = min_t(uint64_t, q->qi_dquots, UINT_MAX); 69 if (XFS_IS_UQUOTA_ON(mp)) 70 state->s_state[USRQUOTA].flags |= QCI_ACCT_ENABLED; 71 if (XFS_IS_UQUOTA_ENFORCED(mp)) 72 state->s_state[USRQUOTA].flags |= QCI_LIMITS_ENFORCED; 73 if (XFS_IS_GQUOTA_ON(mp)) 74 state->s_state[GRPQUOTA].flags |= QCI_ACCT_ENABLED; 75 if (XFS_IS_GQUOTA_ENFORCED(mp)) 76 state->s_state[GRPQUOTA].flags |= QCI_LIMITS_ENFORCED; 77 if (XFS_IS_PQUOTA_ON(mp)) 78 state->s_state[PRJQUOTA].flags |= QCI_ACCT_ENABLED; 79 if (XFS_IS_PQUOTA_ENFORCED(mp)) 80 state->s_state[PRJQUOTA].flags |= QCI_LIMITS_ENFORCED; 81 82 error = xfs_qm_fill_state(&state->s_state[USRQUOTA], mp, 83 XFS_DQTYPE_USER); 84 if (error) 85 return error; 86 error = xfs_qm_fill_state(&state->s_state[GRPQUOTA], mp, 87 XFS_DQTYPE_GROUP); 88 if (error) 89 return error; 90 error = xfs_qm_fill_state(&state->s_state[PRJQUOTA], mp, 91 XFS_DQTYPE_PROJ); 92 if (error) 93 return error; 94 return 0; 95} 96 97STATIC xfs_dqtype_t 98xfs_quota_type(int type) 99{ 100 switch (type) { 101 case USRQUOTA: 102 return XFS_DQTYPE_USER; 103 case GRPQUOTA: 104 return XFS_DQTYPE_GROUP; 105 default: 106 return XFS_DQTYPE_PROJ; 107 } 108} 109 110#define XFS_QC_SETINFO_MASK (QC_TIMER_MASK) 111 112/* 113 * Adjust quota timers & warnings 114 */ 115static int 116xfs_fs_set_info( 117 struct super_block *sb, 118 int type, 119 struct qc_info *info) 120{ 121 struct xfs_mount *mp = XFS_M(sb); 122 struct qc_dqblk newlim; 123 124 if (sb_rdonly(sb)) 125 return -EROFS; 126 if (!XFS_IS_QUOTA_ON(mp)) 127 return -ENOSYS; 128 if (info->i_fieldmask & ~XFS_QC_SETINFO_MASK) 129 return -EINVAL; 130 if ((info->i_fieldmask & XFS_QC_SETINFO_MASK) == 0) 131 return 0; 132 133 newlim.d_fieldmask = info->i_fieldmask; 134 newlim.d_spc_timer = info->i_spc_timelimit; 135 newlim.d_ino_timer = info->i_ino_timelimit; 136 newlim.d_rt_spc_timer = info->i_rt_spc_timelimit; 137 newlim.d_ino_warns = info->i_ino_warnlimit; 138 newlim.d_spc_warns = info->i_spc_warnlimit; 139 newlim.d_rt_spc_warns = info->i_rt_spc_warnlimit; 140 141 return xfs_qm_scall_setqlim(mp, 0, xfs_quota_type(type), &newlim); 142} 143 144static unsigned int 145xfs_quota_flags(unsigned int uflags) 146{ 147 unsigned int flags = 0; 148 149 if (uflags & FS_QUOTA_UDQ_ACCT) 150 flags |= XFS_UQUOTA_ACCT; 151 if (uflags & FS_QUOTA_PDQ_ACCT) 152 flags |= XFS_PQUOTA_ACCT; 153 if (uflags & FS_QUOTA_GDQ_ACCT) 154 flags |= XFS_GQUOTA_ACCT; 155 if (uflags & FS_QUOTA_UDQ_ENFD) 156 flags |= XFS_UQUOTA_ENFD; 157 if (uflags & FS_QUOTA_GDQ_ENFD) 158 flags |= XFS_GQUOTA_ENFD; 159 if (uflags & FS_QUOTA_PDQ_ENFD) 160 flags |= XFS_PQUOTA_ENFD; 161 162 return flags; 163} 164 165STATIC int 166xfs_quota_enable( 167 struct super_block *sb, 168 unsigned int uflags) 169{ 170 struct xfs_mount *mp = XFS_M(sb); 171 172 if (sb_rdonly(sb)) 173 return -EROFS; 174 if (!XFS_IS_QUOTA_ON(mp)) 175 return -ENOSYS; 176 177 return xfs_qm_scall_quotaon(mp, xfs_quota_flags(uflags)); 178} 179 180STATIC int 181xfs_quota_disable( 182 struct super_block *sb, 183 unsigned int uflags) 184{ 185 struct xfs_mount *mp = XFS_M(sb); 186 187 if (sb_rdonly(sb)) 188 return -EROFS; 189 if (!XFS_IS_QUOTA_ON(mp)) 190 return -ENOSYS; 191 192 return xfs_qm_scall_quotaoff(mp, xfs_quota_flags(uflags)); 193} 194 195STATIC int 196xfs_fs_rm_xquota( 197 struct super_block *sb, 198 unsigned int uflags) 199{ 200 struct xfs_mount *mp = XFS_M(sb); 201 unsigned int flags = 0; 202 203 if (sb_rdonly(sb)) 204 return -EROFS; 205 206 if (XFS_IS_QUOTA_ON(mp)) 207 return -EINVAL; 208 209 if (uflags & ~(FS_USER_QUOTA | FS_GROUP_QUOTA | FS_PROJ_QUOTA)) 210 return -EINVAL; 211 212 if (uflags & FS_USER_QUOTA) 213 flags |= XFS_QMOPT_UQUOTA; 214 if (uflags & FS_GROUP_QUOTA) 215 flags |= XFS_QMOPT_GQUOTA; 216 if (uflags & FS_PROJ_QUOTA) 217 flags |= XFS_QMOPT_PQUOTA; 218 219 return xfs_qm_scall_trunc_qfiles(mp, flags); 220} 221 222STATIC int 223xfs_fs_get_dqblk( 224 struct super_block *sb, 225 struct kqid qid, 226 struct qc_dqblk *qdq) 227{ 228 struct xfs_mount *mp = XFS_M(sb); 229 xfs_dqid_t id; 230 231 if (!XFS_IS_QUOTA_ON(mp)) 232 return -ENOSYS; 233 234 id = from_kqid(&init_user_ns, qid); 235 return xfs_qm_scall_getquota(mp, id, xfs_quota_type(qid.type), qdq); 236} 237 238/* Return quota info for active quota >= this qid */ 239STATIC int 240xfs_fs_get_nextdqblk( 241 struct super_block *sb, 242 struct kqid *qid, 243 struct qc_dqblk *qdq) 244{ 245 int ret; 246 struct xfs_mount *mp = XFS_M(sb); 247 xfs_dqid_t id; 248 249 if (!XFS_IS_QUOTA_ON(mp)) 250 return -ENOSYS; 251 252 id = from_kqid(&init_user_ns, *qid); 253 ret = xfs_qm_scall_getquota_next(mp, &id, xfs_quota_type(qid->type), 254 qdq); 255 if (ret) 256 return ret; 257 258 /* ID may be different, so convert back what we got */ 259 *qid = make_kqid(current_user_ns(), qid->type, id); 260 return 0; 261} 262 263STATIC int 264xfs_fs_set_dqblk( 265 struct super_block *sb, 266 struct kqid qid, 267 struct qc_dqblk *qdq) 268{ 269 struct xfs_mount *mp = XFS_M(sb); 270 271 if (sb_rdonly(sb)) 272 return -EROFS; 273 if (!XFS_IS_QUOTA_ON(mp)) 274 return -ENOSYS; 275 276 return xfs_qm_scall_setqlim(mp, from_kqid(&init_user_ns, qid), 277 xfs_quota_type(qid.type), qdq); 278} 279 280const struct quotactl_ops xfs_quotactl_operations = { 281 .get_state = xfs_fs_get_quota_state, 282 .set_info = xfs_fs_set_info, 283 .quota_enable = xfs_quota_enable, 284 .quota_disable = xfs_quota_disable, 285 .rm_xquota = xfs_fs_rm_xquota, 286 .get_dqblk = xfs_fs_get_dqblk, 287 .get_nextdqblk = xfs_fs_get_nextdqblk, 288 .set_dqblk = xfs_fs_set_dqblk, 289};