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_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 93 out_unlock: 94 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); 95 out_put: 96 xfs_irele(ip); 97 return error; 98 } 99 100 int 101 xfs_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 */ 135 int 136 xfs_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 */ 225 static inline bool 226 xfs_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 251 static inline void 252 xfs_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 */ 271 int 272 xfs_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 xfs_dqunlock(dqp); 307 308 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp); 309 if (error) 310 goto out_rele; 311 312 xfs_dqlock(dqp); 313 xfs_trans_dqjoin(tp, dqp); 314 315 /* 316 * Update quota limits, warnings, and timers, and the defaults 317 * if we're touching id == 0. 318 * 319 * Make sure that hardlimits are >= soft limits before changing. 320 * 321 * Update warnings counter(s) if requested. 322 * 323 * Timelimits for the super user set the relative time the other users 324 * can be over quota for this file system. If it is zero a default is 325 * used. Ditto for the default soft and hard limit values (already 326 * done, above), and for warnings. 327 * 328 * For other IDs, userspace can bump out the grace period if over 329 * the soft limit. 330 */ 331 332 /* Blocks on the data device. */ 333 hard = (newlim->d_fieldmask & QC_SPC_HARD) ? 334 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : 335 dqp->q_blk.hardlimit; 336 soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? 337 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : 338 dqp->q_blk.softlimit; 339 res = &dqp->q_blk; 340 qlim = id == 0 ? &defq->blk : NULL; 341 342 if (xfs_setqlim_limits(mp, res, qlim, hard, soft, "blk")) 343 xfs_dquot_set_prealloc_limits(dqp); 344 if (newlim->d_fieldmask & QC_SPC_TIMER) 345 xfs_setqlim_timer(mp, res, qlim, newlim->d_spc_timer); 346 347 /* Blocks on the realtime device. */ 348 hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? 349 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : 350 dqp->q_rtb.hardlimit; 351 soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? 352 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : 353 dqp->q_rtb.softlimit; 354 res = &dqp->q_rtb; 355 qlim = id == 0 ? &defq->rtb : NULL; 356 357 xfs_setqlim_limits(mp, res, qlim, hard, soft, "rtb"); 358 if (newlim->d_fieldmask & QC_RT_SPC_TIMER) 359 xfs_setqlim_timer(mp, res, qlim, newlim->d_rt_spc_timer); 360 361 /* Inodes */ 362 hard = (newlim->d_fieldmask & QC_INO_HARD) ? 363 (xfs_qcnt_t) newlim->d_ino_hardlimit : 364 dqp->q_ino.hardlimit; 365 soft = (newlim->d_fieldmask & QC_INO_SOFT) ? 366 (xfs_qcnt_t) newlim->d_ino_softlimit : 367 dqp->q_ino.softlimit; 368 res = &dqp->q_ino; 369 qlim = id == 0 ? &defq->ino : NULL; 370 371 xfs_setqlim_limits(mp, res, qlim, hard, soft, "ino"); 372 if (newlim->d_fieldmask & QC_INO_TIMER) 373 xfs_setqlim_timer(mp, res, qlim, newlim->d_ino_timer); 374 375 if (id != 0) { 376 /* 377 * If the user is now over quota, start the timelimit. 378 * The user will not be 'warned'. 379 * Note that we keep the timers ticking, whether enforcement 380 * is on or off. We don't really want to bother with iterating 381 * over all ondisk dquots and turning the timers on/off. 382 */ 383 xfs_qm_adjust_dqtimers(dqp); 384 } 385 dqp->q_flags |= XFS_DQFLAG_DIRTY; 386 xfs_trans_log_dquot(tp, dqp); 387 388 error = xfs_trans_commit(tp); 389 390 out_rele: 391 xfs_qm_dqrele(dqp); 392 return error; 393 } 394 395 /* Fill out the quota context. */ 396 static void 397 xfs_qm_scall_getquota_fill_qc( 398 struct xfs_mount *mp, 399 xfs_dqtype_t type, 400 const struct xfs_dquot *dqp, 401 struct qc_dqblk *dst) 402 { 403 memset(dst, 0, sizeof(*dst)); 404 dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); 405 dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); 406 dst->d_ino_hardlimit = dqp->q_ino.hardlimit; 407 dst->d_ino_softlimit = dqp->q_ino.softlimit; 408 dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); 409 dst->d_ino_count = dqp->q_ino.reserved; 410 dst->d_spc_timer = dqp->q_blk.timer; 411 dst->d_ino_timer = dqp->q_ino.timer; 412 dst->d_ino_warns = 0; 413 dst->d_spc_warns = 0; 414 dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); 415 dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); 416 dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); 417 dst->d_rt_spc_timer = dqp->q_rtb.timer; 418 dst->d_rt_spc_warns = 0; 419 420 /* 421 * Internally, we don't reset all the timers when quota enforcement 422 * gets turned off. No need to confuse the user level code, 423 * so return zeroes in that case. 424 */ 425 if (!xfs_dquot_is_enforced(dqp)) { 426 dst->d_spc_timer = 0; 427 dst->d_ino_timer = 0; 428 dst->d_rt_spc_timer = 0; 429 } 430 431 #ifdef DEBUG 432 if (xfs_dquot_is_enforced(dqp) && dqp->q_id != 0) { 433 if ((dst->d_space > dst->d_spc_softlimit) && 434 (dst->d_spc_softlimit > 0)) { 435 ASSERT(dst->d_spc_timer != 0); 436 } 437 if ((dst->d_ino_count > dqp->q_ino.softlimit) && 438 (dqp->q_ino.softlimit > 0)) { 439 ASSERT(dst->d_ino_timer != 0); 440 } 441 } 442 #endif 443 } 444 445 /* Return the quota information for the dquot matching id. */ 446 int 447 xfs_qm_scall_getquota( 448 struct xfs_mount *mp, 449 xfs_dqid_t id, 450 xfs_dqtype_t type, 451 struct qc_dqblk *dst) 452 { 453 struct xfs_dquot *dqp; 454 int error; 455 456 /* 457 * Expedite pending inodegc work at the start of a quota reporting 458 * scan but don't block waiting for it to complete. 459 */ 460 if (id == 0) 461 xfs_inodegc_push(mp); 462 463 /* 464 * Try to get the dquot. We don't want it allocated on disk, so don't 465 * set doalloc. If it doesn't exist, we'll get ENOENT back. 466 */ 467 error = xfs_qm_dqget(mp, id, type, false, &dqp); 468 if (error) 469 return error; 470 471 /* 472 * If everything's NULL, this dquot doesn't quite exist as far as 473 * our utility programs are concerned. 474 */ 475 if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) { 476 error = -ENOENT; 477 goto out_put; 478 } 479 480 xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); 481 482 out_put: 483 xfs_qm_dqput(dqp); 484 return error; 485 } 486 487 /* 488 * Return the quota information for the first initialized dquot whose id 489 * is at least as high as id. 490 */ 491 int 492 xfs_qm_scall_getquota_next( 493 struct xfs_mount *mp, 494 xfs_dqid_t *id, 495 xfs_dqtype_t type, 496 struct qc_dqblk *dst) 497 { 498 struct xfs_dquot *dqp; 499 int error; 500 501 /* Flush inodegc work at the start of a quota reporting scan. */ 502 if (*id == 0) 503 xfs_inodegc_push(mp); 504 505 error = xfs_qm_dqget_next(mp, *id, type, &dqp); 506 if (error) 507 return error; 508 509 /* Fill in the ID we actually read from disk */ 510 *id = dqp->q_id; 511 512 xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); 513 514 xfs_qm_dqput(dqp); 515 return error; 516 } 517