/* * The sys call that tells the system about a quota file. */ setquota() { register struct a { char *fblk; char *fname; } *uap = (struct a *)u.u_ap; register struct mount *mp; dev_t dev; #ifndef QUOTA u.u_error = EINVAL; return; #else u.u_error = getmdev(&dev, uap->fblk); if (u.u_error) return; for (mp = mount; mp < &mount[NMOUNT]; mp++) if (mp->m_bufp && mp->m_dev == dev) { if (uap->fname == NULL) closedq(mp); else opendq(mp, (caddr_t)uap->fname); return; } #endif }
/*ARGSUSED*/ int quotactl(struct vnode *vp, intptr_t arg, int flag, struct cred *cr) { struct quotctl quot; struct ufsvfs *ufsvfsp; int error = 0; if ((flag & DATAMODEL_MASK) == DATAMODEL_NATIVE) { if (copyin((caddr_t)arg, ", sizeof (struct quotctl))) return (EFAULT); } #ifdef _SYSCALL32_IMPL else { /* quotctl struct from ILP32 callers */ struct quotctl32 quot32; if (copyin((caddr_t)arg, "32, sizeof (struct quotctl32))) return (EFAULT); quot.op = quot32.op; quot.uid = quot32.uid; quot.addr = (caddr_t)(uintptr_t)quot32.addr; } #endif /* _SYSCALL32_IMPL */ if (quot.uid < 0) quot.uid = crgetruid(cr); if (quot.op == Q_SYNC && vp == NULL) { ufsvfsp = NULL; } else if (quot.op != Q_ALLSYNC) { ufsvfsp = (struct ufsvfs *)(vp->v_vfsp->vfs_data); } switch (quot.op) { case Q_QUOTAON: rw_enter(&dq_rwlock, RW_WRITER); if (quotas_initialized == 0) { qtinit2(); quotas_initialized = 1; } rw_exit(&dq_rwlock); error = opendq(ufsvfsp, vp, cr); break; case Q_QUOTAOFF: error = closedq(ufsvfsp, cr); if (!error) { invalidatedq(ufsvfsp); } break; case Q_SETQUOTA: case Q_SETQLIM: error = setquota(quot.op, (uid_t)quot.uid, ufsvfsp, quot.addr, cr); break; case Q_GETQUOTA: error = getquota((uid_t)quot.uid, ufsvfsp, (caddr_t)quot.addr, cr); break; case Q_SYNC: error = qsync(ufsvfsp); break; case Q_ALLSYNC: (void) qsync(NULL); break; default: error = EINVAL; break; } return (error); }