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