at master 13 kB view raw
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * Copyright (c) 2000-2005 Silicon Graphics, Inc. 4 * All Rights Reserved. 5 */ 6 7 8#include "xfs.h" 9#include "xfs_fs.h" 10#include "xfs_shared.h" 11#include "xfs_format.h" 12#include "xfs_log_format.h" 13#include "xfs_trans_resv.h" 14#include "xfs_sb.h" 15#include "xfs_mount.h" 16#include "xfs_inode.h" 17#include "xfs_trans.h" 18#include "xfs_quota.h" 19#include "xfs_qm.h" 20#include "xfs_icache.h" 21 22int 23xfs_qm_scall_quotaoff( 24 xfs_mount_t *mp, 25 uint flags) 26{ 27 /* 28 * No file system can have quotas enabled on disk but not in core. 29 * Note that quota utilities (like quotaoff) _expect_ 30 * errno == -EEXIST here. 31 */ 32 if ((mp->m_qflags & flags) == 0) 33 return -EEXIST; 34 35 /* 36 * We do not support actually turning off quota accounting any more. 37 * Just log a warning and ignore the accounting related flags. 38 */ 39 if (flags & XFS_ALL_QUOTA_ACCT) 40 xfs_info(mp, "disabling of quota accounting not supported."); 41 42 mutex_lock(&mp->m_quotainfo->qi_quotaofflock); 43 mp->m_qflags &= ~(flags & XFS_ALL_QUOTA_ENFD); 44 spin_lock(&mp->m_sb_lock); 45 mp->m_sb.sb_qflags = mp->m_qflags; 46 spin_unlock(&mp->m_sb_lock); 47 mutex_unlock(&mp->m_quotainfo->qi_quotaofflock); 48 49 /* XXX what to do if error ? Revert back to old vals incore ? */ 50 return xfs_sync_sb(mp, false); 51} 52 53STATIC int 54xfs_qm_scall_trunc_qfile( 55 struct xfs_mount *mp, 56 xfs_dqtype_t type) 57{ 58 struct xfs_inode *ip; 59 struct xfs_trans *tp; 60 int error; 61 62 error = xfs_qm_qino_load(mp, type, &ip); 63 if (error == -ENOENT) 64 return 0; 65 if (error) 66 return error; 67 68 xfs_ilock(ip, XFS_IOLOCK_EXCL); 69 70 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_itruncate, 0, 0, 0, &tp); 71 if (error) { 72 xfs_iunlock(ip, XFS_IOLOCK_EXCL); 73 goto out_put; 74 } 75 76 xfs_ilock(ip, XFS_ILOCK_EXCL); 77 xfs_trans_ijoin(tp, ip, 0); 78 79 ip->i_disk_size = 0; 80 xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); 81 82 error = xfs_itruncate_extents(&tp, ip, XFS_DATA_FORK, 0); 83 if (error) { 84 xfs_trans_cancel(tp); 85 goto out_unlock; 86 } 87 88 ASSERT(ip->i_df.if_nextents == 0); 89 90 xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG); 91 error = xfs_trans_commit(tp); 92 93out_unlock: 94 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); 95out_put: 96 xfs_irele(ip); 97 return error; 98} 99 100int 101xfs_qm_scall_trunc_qfiles( 102 xfs_mount_t *mp, 103 uint flags) 104{ 105 int error = -EINVAL; 106 107 if (!xfs_has_quota(mp) || flags == 0 || 108 (flags & ~XFS_QMOPT_QUOTALL)) { 109 xfs_debug(mp, "%s: flags=%x m_qflags=%x", 110 __func__, flags, mp->m_qflags); 111 return -EINVAL; 112 } 113 114 if (flags & XFS_QMOPT_UQUOTA) { 115 error = xfs_qm_scall_trunc_qfile(mp, XFS_DQTYPE_USER); 116 if (error) 117 return error; 118 } 119 if (flags & XFS_QMOPT_GQUOTA) { 120 error = xfs_qm_scall_trunc_qfile(mp, XFS_DQTYPE_GROUP); 121 if (error) 122 return error; 123 } 124 if (flags & XFS_QMOPT_PQUOTA) 125 error = xfs_qm_scall_trunc_qfile(mp, XFS_DQTYPE_PROJ); 126 127 return error; 128} 129 130/* 131 * Switch on (a given) quota enforcement for a filesystem. This takes 132 * effect immediately. 133 * (Switching on quota accounting must be done at mount time.) 134 */ 135int 136xfs_qm_scall_quotaon( 137 xfs_mount_t *mp, 138 uint flags) 139{ 140 int error; 141 uint qf; 142 143 /* 144 * Switching on quota accounting must be done at mount time, 145 * only consider quota enforcement stuff here. 146 */ 147 flags &= XFS_ALL_QUOTA_ENFD; 148 149 if (flags == 0) { 150 xfs_debug(mp, "%s: zero flags, m_qflags=%x", 151 __func__, mp->m_qflags); 152 return -EINVAL; 153 } 154 155 /* 156 * Can't enforce without accounting. We check the superblock 157 * qflags here instead of m_qflags because rootfs can have 158 * quota acct on ondisk without m_qflags' knowing. 159 */ 160 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) == 0 && 161 (flags & XFS_UQUOTA_ENFD)) || 162 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) == 0 && 163 (flags & XFS_GQUOTA_ENFD)) || 164 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) == 0 && 165 (flags & XFS_PQUOTA_ENFD))) { 166 xfs_debug(mp, 167 "%s: Can't enforce without acct, flags=%x sbflags=%x", 168 __func__, flags, mp->m_sb.sb_qflags); 169 return -EINVAL; 170 } 171 /* 172 * If everything's up to-date incore, then don't waste time. 173 */ 174 if ((mp->m_qflags & flags) == flags) 175 return -EEXIST; 176 177 /* 178 * Change sb_qflags on disk but not incore mp->qflags 179 * if this is the root filesystem. 180 */ 181 spin_lock(&mp->m_sb_lock); 182 qf = mp->m_sb.sb_qflags; 183 mp->m_sb.sb_qflags = qf | flags; 184 spin_unlock(&mp->m_sb_lock); 185 186 /* 187 * There's nothing to change if it's the same. 188 */ 189 if ((qf & flags) == flags) 190 return -EEXIST; 191 192 error = xfs_sync_sb(mp, false); 193 if (error) 194 return error; 195 /* 196 * If we aren't trying to switch on quota enforcement, we are done. 197 */ 198 if (((mp->m_sb.sb_qflags & XFS_UQUOTA_ACCT) != 199 (mp->m_qflags & XFS_UQUOTA_ACCT)) || 200 ((mp->m_sb.sb_qflags & XFS_PQUOTA_ACCT) != 201 (mp->m_qflags & XFS_PQUOTA_ACCT)) || 202 ((mp->m_sb.sb_qflags & XFS_GQUOTA_ACCT) != 203 (mp->m_qflags & XFS_GQUOTA_ACCT))) 204 return 0; 205 206 if (!XFS_IS_QUOTA_ON(mp)) 207 return -ESRCH; 208 209 /* 210 * Switch on quota enforcement in core. 211 */ 212 mutex_lock(&mp->m_quotainfo->qi_quotaofflock); 213 mp->m_qflags |= (flags & XFS_ALL_QUOTA_ENFD); 214 mutex_unlock(&mp->m_quotainfo->qi_quotaofflock); 215 216 return 0; 217} 218 219#define XFS_QC_MASK (QC_LIMIT_MASK | QC_TIMER_MASK) 220 221/* 222 * Adjust limits of this quota, and the defaults if passed in. Returns true 223 * if the new limits made sense and were applied, false otherwise. 224 */ 225static inline bool 226xfs_setqlim_limits( 227 struct xfs_mount *mp, 228 struct xfs_dquot_res *res, 229 struct xfs_quota_limits *qlim, 230 xfs_qcnt_t hard, 231 xfs_qcnt_t soft, 232 const char *tag) 233{ 234 /* The hard limit can't be less than the soft limit. */ 235 if (hard != 0 && hard < soft) { 236 xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag, 237 soft); 238 return false; 239 } 240 241 res->hardlimit = hard; 242 res->softlimit = soft; 243 if (qlim) { 244 qlim->hard = hard; 245 qlim->soft = soft; 246 } 247 248 return true; 249} 250 251static inline void 252xfs_setqlim_timer( 253 struct xfs_mount *mp, 254 struct xfs_dquot_res *res, 255 struct xfs_quota_limits *qlim, 256 s64 timer) 257{ 258 if (qlim) { 259 /* Set the length of the default grace period. */ 260 res->timer = xfs_dquot_set_grace_period(timer); 261 qlim->time = res->timer; 262 } else { 263 /* Set the grace period expiration on a quota. */ 264 res->timer = xfs_dquot_set_timeout(mp, timer); 265 } 266} 267 268/* 269 * Adjust quota limits, and start/stop timers accordingly. 270 */ 271int 272xfs_qm_scall_setqlim( 273 struct xfs_mount *mp, 274 xfs_dqid_t id, 275 xfs_dqtype_t type, 276 struct qc_dqblk *newlim) 277{ 278 struct xfs_quotainfo *q = mp->m_quotainfo; 279 struct xfs_dquot *dqp; 280 struct xfs_trans *tp; 281 struct xfs_def_quota *defq; 282 struct xfs_dquot_res *res; 283 struct xfs_quota_limits *qlim; 284 int error; 285 xfs_qcnt_t hard, soft; 286 287 if (newlim->d_fieldmask & ~XFS_QC_MASK) 288 return -EINVAL; 289 if ((newlim->d_fieldmask & XFS_QC_MASK) == 0) 290 return 0; 291 292 /* 293 * Get the dquot (locked) before we start, as we need to do a 294 * transaction to allocate it if it doesn't exist. Once we have the 295 * dquot, unlock it so we can start the next transaction safely. We hold 296 * a reference to the dquot, so it's safe to do this unlock/lock without 297 * it being reclaimed in the mean time. 298 */ 299 error = xfs_qm_dqget(mp, id, type, true, &dqp); 300 if (error) { 301 ASSERT(error != -ENOENT); 302 return error; 303 } 304 305 defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); 306 307 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp); 308 if (error) 309 goto out_rele; 310 311 mutex_lock(&dqp->q_qlock); 312 xfs_trans_dqjoin(tp, dqp); 313 314 /* 315 * Update quota limits, warnings, and timers, and the defaults 316 * if we're touching id == 0. 317 * 318 * Make sure that hardlimits are >= soft limits before changing. 319 * 320 * Update warnings counter(s) if requested. 321 * 322 * Timelimits for the super user set the relative time the other users 323 * can be over quota for this file system. If it is zero a default is 324 * used. Ditto for the default soft and hard limit values (already 325 * done, above), and for warnings. 326 * 327 * For other IDs, userspace can bump out the grace period if over 328 * the soft limit. 329 */ 330 331 /* Blocks on the data device. */ 332 hard = (newlim->d_fieldmask & QC_SPC_HARD) ? 333 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : 334 dqp->q_blk.hardlimit; 335 soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? 336 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : 337 dqp->q_blk.softlimit; 338 res = &dqp->q_blk; 339 qlim = id == 0 ? &defq->blk : NULL; 340 341 if (xfs_setqlim_limits(mp, res, qlim, hard, soft, "blk")) 342 xfs_dquot_set_prealloc_limits(dqp); 343 if (newlim->d_fieldmask & QC_SPC_TIMER) 344 xfs_setqlim_timer(mp, res, qlim, newlim->d_spc_timer); 345 346 /* Blocks on the realtime device. */ 347 hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? 348 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : 349 dqp->q_rtb.hardlimit; 350 soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? 351 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : 352 dqp->q_rtb.softlimit; 353 res = &dqp->q_rtb; 354 qlim = id == 0 ? &defq->rtb : NULL; 355 356 xfs_setqlim_limits(mp, res, qlim, hard, soft, "rtb"); 357 if (newlim->d_fieldmask & QC_RT_SPC_TIMER) 358 xfs_setqlim_timer(mp, res, qlim, newlim->d_rt_spc_timer); 359 360 /* Inodes */ 361 hard = (newlim->d_fieldmask & QC_INO_HARD) ? 362 (xfs_qcnt_t) newlim->d_ino_hardlimit : 363 dqp->q_ino.hardlimit; 364 soft = (newlim->d_fieldmask & QC_INO_SOFT) ? 365 (xfs_qcnt_t) newlim->d_ino_softlimit : 366 dqp->q_ino.softlimit; 367 res = &dqp->q_ino; 368 qlim = id == 0 ? &defq->ino : NULL; 369 370 xfs_setqlim_limits(mp, res, qlim, hard, soft, "ino"); 371 if (newlim->d_fieldmask & QC_INO_TIMER) 372 xfs_setqlim_timer(mp, res, qlim, newlim->d_ino_timer); 373 374 if (id != 0) { 375 /* 376 * If the user is now over quota, start the timelimit. 377 * The user will not be 'warned'. 378 * Note that we keep the timers ticking, whether enforcement 379 * is on or off. We don't really want to bother with iterating 380 * over all ondisk dquots and turning the timers on/off. 381 */ 382 xfs_qm_adjust_dqtimers(dqp); 383 } 384 dqp->q_flags |= XFS_DQFLAG_DIRTY; 385 xfs_trans_log_dquot(tp, dqp); 386 387 error = xfs_trans_commit(tp); 388 389out_rele: 390 xfs_qm_dqrele(dqp); 391 return error; 392} 393 394/* Fill out the quota context. */ 395static void 396xfs_qm_scall_getquota_fill_qc( 397 struct xfs_mount *mp, 398 xfs_dqtype_t type, 399 const struct xfs_dquot *dqp, 400 struct qc_dqblk *dst) 401{ 402 memset(dst, 0, sizeof(*dst)); 403 dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); 404 dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); 405 dst->d_ino_hardlimit = dqp->q_ino.hardlimit; 406 dst->d_ino_softlimit = dqp->q_ino.softlimit; 407 dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); 408 dst->d_ino_count = dqp->q_ino.reserved; 409 dst->d_spc_timer = dqp->q_blk.timer; 410 dst->d_ino_timer = dqp->q_ino.timer; 411 dst->d_ino_warns = 0; 412 dst->d_spc_warns = 0; 413 dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); 414 dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); 415 dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); 416 dst->d_rt_spc_timer = dqp->q_rtb.timer; 417 dst->d_rt_spc_warns = 0; 418 419 /* 420 * Internally, we don't reset all the timers when quota enforcement 421 * gets turned off. No need to confuse the user level code, 422 * so return zeroes in that case. 423 */ 424 if (!xfs_dquot_is_enforced(dqp)) { 425 dst->d_spc_timer = 0; 426 dst->d_ino_timer = 0; 427 dst->d_rt_spc_timer = 0; 428 } 429} 430 431/* Return the quota information for the dquot matching id. */ 432int 433xfs_qm_scall_getquota( 434 struct xfs_mount *mp, 435 xfs_dqid_t id, 436 xfs_dqtype_t type, 437 struct qc_dqblk *dst) 438{ 439 struct xfs_dquot *dqp; 440 int error; 441 442 /* 443 * Expedite pending inodegc work at the start of a quota reporting 444 * scan but don't block waiting for it to complete. 445 */ 446 if (id == 0) 447 xfs_inodegc_push(mp); 448 449 /* 450 * Try to get the dquot. We don't want it allocated on disk, so don't 451 * set doalloc. If it doesn't exist, we'll get ENOENT back. 452 */ 453 error = xfs_qm_dqget(mp, id, type, false, &dqp); 454 if (error) 455 return error; 456 457 /* 458 * If everything's NULL, this dquot doesn't quite exist as far as 459 * our utility programs are concerned. 460 */ 461 mutex_lock(&dqp->q_qlock); 462 if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) { 463 error = -ENOENT; 464 goto out_put; 465 } 466 467 xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); 468 469out_put: 470 mutex_unlock(&dqp->q_qlock); 471 xfs_qm_dqrele(dqp); 472 return error; 473} 474 475/* 476 * Return the quota information for the first initialized dquot whose id 477 * is at least as high as id. 478 */ 479int 480xfs_qm_scall_getquota_next( 481 struct xfs_mount *mp, 482 xfs_dqid_t *id, 483 xfs_dqtype_t type, 484 struct qc_dqblk *dst) 485{ 486 struct xfs_dquot *dqp; 487 int error; 488 489 /* Flush inodegc work at the start of a quota reporting scan. */ 490 if (*id == 0) 491 xfs_inodegc_push(mp); 492 493 error = xfs_qm_dqget_next(mp, *id, type, &dqp); 494 if (error) 495 return error; 496 497 /* Fill in the ID we actually read from disk */ 498 *id = dqp->q_id; 499 500 xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); 501 mutex_unlock(&dqp->q_qlock); 502 503 xfs_qm_dqrele(dqp); 504 return error; 505}