xfs_qm_syscalls.c (12940B)
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_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 94out_unlock: 95 xfs_iunlock(ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); 96out_put: 97 xfs_irele(ip); 98 return error; 99} 100 101int 102xfs_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 */ 136int 137xfs_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 (QC_LIMIT_MASK | QC_TIMER_MASK) 221 222/* 223 * Adjust limits of this quota, and the defaults if passed in. Returns true 224 * if the new limits made sense and were applied, false otherwise. 225 */ 226static inline bool 227xfs_setqlim_limits( 228 struct xfs_mount *mp, 229 struct xfs_dquot_res *res, 230 struct xfs_quota_limits *qlim, 231 xfs_qcnt_t hard, 232 xfs_qcnt_t soft, 233 const char *tag) 234{ 235 /* The hard limit can't be less than the soft limit. */ 236 if (hard != 0 && hard < soft) { 237 xfs_debug(mp, "%shard %lld < %ssoft %lld", tag, hard, tag, 238 soft); 239 return false; 240 } 241 242 res->hardlimit = hard; 243 res->softlimit = soft; 244 if (qlim) { 245 qlim->hard = hard; 246 qlim->soft = soft; 247 } 248 249 return true; 250} 251 252static inline void 253xfs_setqlim_timer( 254 struct xfs_mount *mp, 255 struct xfs_dquot_res *res, 256 struct xfs_quota_limits *qlim, 257 s64 timer) 258{ 259 if (qlim) { 260 /* Set the length of the default grace period. */ 261 res->timer = xfs_dquot_set_grace_period(timer); 262 qlim->time = res->timer; 263 } else { 264 /* Set the grace period expiration on a quota. */ 265 res->timer = xfs_dquot_set_timeout(mp, timer); 266 } 267} 268 269/* 270 * Adjust quota limits, and start/stop timers accordingly. 271 */ 272int 273xfs_qm_scall_setqlim( 274 struct xfs_mount *mp, 275 xfs_dqid_t id, 276 xfs_dqtype_t type, 277 struct qc_dqblk *newlim) 278{ 279 struct xfs_quotainfo *q = mp->m_quotainfo; 280 struct xfs_dquot *dqp; 281 struct xfs_trans *tp; 282 struct xfs_def_quota *defq; 283 struct xfs_dquot_res *res; 284 struct xfs_quota_limits *qlim; 285 int error; 286 xfs_qcnt_t hard, soft; 287 288 if (newlim->d_fieldmask & ~XFS_QC_MASK) 289 return -EINVAL; 290 if ((newlim->d_fieldmask & XFS_QC_MASK) == 0) 291 return 0; 292 293 /* 294 * Get the dquot (locked) before we start, as we need to do a 295 * transaction to allocate it if it doesn't exist. Once we have the 296 * dquot, unlock it so we can start the next transaction safely. We hold 297 * a reference to the dquot, so it's safe to do this unlock/lock without 298 * it being reclaimed in the mean time. 299 */ 300 error = xfs_qm_dqget(mp, id, type, true, &dqp); 301 if (error) { 302 ASSERT(error != -ENOENT); 303 return error; 304 } 305 306 defq = xfs_get_defquota(q, xfs_dquot_type(dqp)); 307 xfs_dqunlock(dqp); 308 309 error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_setqlim, 0, 0, 0, &tp); 310 if (error) 311 goto out_rele; 312 313 xfs_dqlock(dqp); 314 xfs_trans_dqjoin(tp, dqp); 315 316 /* 317 * Update quota limits, warnings, and timers, and the defaults 318 * if we're touching id == 0. 319 * 320 * Make sure that hardlimits are >= soft limits before changing. 321 * 322 * Update warnings counter(s) if requested. 323 * 324 * Timelimits for the super user set the relative time the other users 325 * can be over quota for this file system. If it is zero a default is 326 * used. Ditto for the default soft and hard limit values (already 327 * done, above), and for warnings. 328 * 329 * For other IDs, userspace can bump out the grace period if over 330 * the soft limit. 331 */ 332 333 /* Blocks on the data device. */ 334 hard = (newlim->d_fieldmask & QC_SPC_HARD) ? 335 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_hardlimit) : 336 dqp->q_blk.hardlimit; 337 soft = (newlim->d_fieldmask & QC_SPC_SOFT) ? 338 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_spc_softlimit) : 339 dqp->q_blk.softlimit; 340 res = &dqp->q_blk; 341 qlim = id == 0 ? &defq->blk : NULL; 342 343 if (xfs_setqlim_limits(mp, res, qlim, hard, soft, "blk")) 344 xfs_dquot_set_prealloc_limits(dqp); 345 if (newlim->d_fieldmask & QC_SPC_TIMER) 346 xfs_setqlim_timer(mp, res, qlim, newlim->d_spc_timer); 347 348 /* Blocks on the realtime device. */ 349 hard = (newlim->d_fieldmask & QC_RT_SPC_HARD) ? 350 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_hardlimit) : 351 dqp->q_rtb.hardlimit; 352 soft = (newlim->d_fieldmask & QC_RT_SPC_SOFT) ? 353 (xfs_qcnt_t) XFS_B_TO_FSB(mp, newlim->d_rt_spc_softlimit) : 354 dqp->q_rtb.softlimit; 355 res = &dqp->q_rtb; 356 qlim = id == 0 ? &defq->rtb : NULL; 357 358 xfs_setqlim_limits(mp, res, qlim, hard, soft, "rtb"); 359 if (newlim->d_fieldmask & QC_RT_SPC_TIMER) 360 xfs_setqlim_timer(mp, res, qlim, newlim->d_rt_spc_timer); 361 362 /* Inodes */ 363 hard = (newlim->d_fieldmask & QC_INO_HARD) ? 364 (xfs_qcnt_t) newlim->d_ino_hardlimit : 365 dqp->q_ino.hardlimit; 366 soft = (newlim->d_fieldmask & QC_INO_SOFT) ? 367 (xfs_qcnt_t) newlim->d_ino_softlimit : 368 dqp->q_ino.softlimit; 369 res = &dqp->q_ino; 370 qlim = id == 0 ? &defq->ino : NULL; 371 372 xfs_setqlim_limits(mp, res, qlim, hard, soft, "ino"); 373 if (newlim->d_fieldmask & QC_INO_TIMER) 374 xfs_setqlim_timer(mp, res, qlim, newlim->d_ino_timer); 375 376 if (id != 0) { 377 /* 378 * If the user is now over quota, start the timelimit. 379 * The user will not be 'warned'. 380 * Note that we keep the timers ticking, whether enforcement 381 * is on or off. We don't really want to bother with iterating 382 * over all ondisk dquots and turning the timers on/off. 383 */ 384 xfs_qm_adjust_dqtimers(dqp); 385 } 386 dqp->q_flags |= XFS_DQFLAG_DIRTY; 387 xfs_trans_log_dquot(tp, dqp); 388 389 error = xfs_trans_commit(tp); 390 391out_rele: 392 xfs_qm_dqrele(dqp); 393 return error; 394} 395 396/* Fill out the quota context. */ 397static void 398xfs_qm_scall_getquota_fill_qc( 399 struct xfs_mount *mp, 400 xfs_dqtype_t type, 401 const struct xfs_dquot *dqp, 402 struct qc_dqblk *dst) 403{ 404 memset(dst, 0, sizeof(*dst)); 405 dst->d_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_blk.hardlimit); 406 dst->d_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_blk.softlimit); 407 dst->d_ino_hardlimit = dqp->q_ino.hardlimit; 408 dst->d_ino_softlimit = dqp->q_ino.softlimit; 409 dst->d_space = XFS_FSB_TO_B(mp, dqp->q_blk.reserved); 410 dst->d_ino_count = dqp->q_ino.reserved; 411 dst->d_spc_timer = dqp->q_blk.timer; 412 dst->d_ino_timer = dqp->q_ino.timer; 413 dst->d_ino_warns = 0; 414 dst->d_spc_warns = 0; 415 dst->d_rt_spc_hardlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.hardlimit); 416 dst->d_rt_spc_softlimit = XFS_FSB_TO_B(mp, dqp->q_rtb.softlimit); 417 dst->d_rt_space = XFS_FSB_TO_B(mp, dqp->q_rtb.reserved); 418 dst->d_rt_spc_timer = dqp->q_rtb.timer; 419 dst->d_rt_spc_warns = 0; 420 421 /* 422 * Internally, we don't reset all the timers when quota enforcement 423 * gets turned off. No need to confuse the user level code, 424 * so return zeroes in that case. 425 */ 426 if (!xfs_dquot_is_enforced(dqp)) { 427 dst->d_spc_timer = 0; 428 dst->d_ino_timer = 0; 429 dst->d_rt_spc_timer = 0; 430 } 431 432#ifdef DEBUG 433 if (xfs_dquot_is_enforced(dqp) && dqp->q_id != 0) { 434 if ((dst->d_space > dst->d_spc_softlimit) && 435 (dst->d_spc_softlimit > 0)) { 436 ASSERT(dst->d_spc_timer != 0); 437 } 438 if ((dst->d_ino_count > dqp->q_ino.softlimit) && 439 (dqp->q_ino.softlimit > 0)) { 440 ASSERT(dst->d_ino_timer != 0); 441 } 442 } 443#endif 444} 445 446/* Return the quota information for the dquot matching id. */ 447int 448xfs_qm_scall_getquota( 449 struct xfs_mount *mp, 450 xfs_dqid_t id, 451 xfs_dqtype_t type, 452 struct qc_dqblk *dst) 453{ 454 struct xfs_dquot *dqp; 455 int error; 456 457 /* 458 * Expedite pending inodegc work at the start of a quota reporting 459 * scan but don't block waiting for it to complete. 460 */ 461 if (id == 0) 462 xfs_inodegc_push(mp); 463 464 /* 465 * Try to get the dquot. We don't want it allocated on disk, so don't 466 * set doalloc. If it doesn't exist, we'll get ENOENT back. 467 */ 468 error = xfs_qm_dqget(mp, id, type, false, &dqp); 469 if (error) 470 return error; 471 472 /* 473 * If everything's NULL, this dquot doesn't quite exist as far as 474 * our utility programs are concerned. 475 */ 476 if (XFS_IS_DQUOT_UNINITIALIZED(dqp)) { 477 error = -ENOENT; 478 goto out_put; 479 } 480 481 xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); 482 483out_put: 484 xfs_qm_dqput(dqp); 485 return error; 486} 487 488/* 489 * Return the quota information for the first initialized dquot whose id 490 * is at least as high as id. 491 */ 492int 493xfs_qm_scall_getquota_next( 494 struct xfs_mount *mp, 495 xfs_dqid_t *id, 496 xfs_dqtype_t type, 497 struct qc_dqblk *dst) 498{ 499 struct xfs_dquot *dqp; 500 int error; 501 502 /* Flush inodegc work at the start of a quota reporting scan. */ 503 if (*id == 0) 504 xfs_inodegc_push(mp); 505 506 error = xfs_qm_dqget_next(mp, *id, type, &dqp); 507 if (error) 508 return error; 509 510 /* Fill in the ID we actually read from disk */ 511 *id = dqp->q_id; 512 513 xfs_qm_scall_getquota_fill_qc(mp, type, dqp, dst); 514 515 xfs_qm_dqput(dqp); 516 return error; 517}