1: /*
   2:  * Copyright (c) 1982, 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)quota_sys.c	7.1 (Berkeley) 6/5/86
   7:  */
   8: 
   9: /*
  10:  * MELBOURNE QUOTAS
  11:  *
  12:  * System calls.
  13:  */
  14: #include "param.h"
  15: #include "systm.h"
  16: #include "dir.h"
  17: #include "user.h"
  18: #include "proc.h"
  19: #include "inode.h"
  20: #include "quota.h"
  21: #include "mount.h"
  22: #include "fs.h"
  23: #include "uio.h"
  24: 
  25: /*
  26:  * The sys call that tells the system about a quota file.
  27:  */
  28: setquota()
  29: {
  30:     register struct a {
  31:         char    *fblk;
  32:         char    *fname;
  33:     } *uap = (struct a *)u.u_ap;
  34:     register struct mount *mp;
  35:     dev_t dev;
  36: 
  37: #ifndef QUOTA
  38:     u.u_error = EINVAL;
  39:     return;
  40: #else
  41:     u.u_error = getmdev(&dev, uap->fblk);
  42:     if (u.u_error)
  43:         return;
  44:     for (mp = mount; mp < &mount[NMOUNT]; mp++)
  45:         if (mp->m_bufp && mp->m_dev == dev) {
  46:             if (uap->fname == NULL)
  47:                 closedq(mp);
  48:             else
  49:                 opendq(mp, (caddr_t)uap->fname);
  50:             return;
  51:         }
  52: #endif
  53: }
  54: 
  55: /*
  56:  * Sys call to allow users to find out
  57:  * their current position wrt quota's
  58:  * and to allow super users to alter it.
  59:  */
  60: qquota()
  61: {
  62:     register struct a {
  63:         int cmd;
  64:         int uid;
  65:         int arg;
  66:         caddr_t addr;
  67:     } *uap = (struct a *)u.u_ap;
  68:     register struct quota *q;
  69: 
  70: #ifndef QUOTA
  71:     u.u_error = EINVAL;
  72:     return;
  73: #else
  74:     if (uap->uid < 0)
  75:         uap->uid = u.u_ruid;
  76:     if (uap->uid != u.u_ruid && uap->uid != u.u_quota->q_uid && !suser())
  77:         return;
  78:     if (uap->cmd != Q_SYNC && uap->cmd != Q_SETUID) {
  79:         q = getquota((uid_t)uap->uid, uap->cmd == Q_DOWARN, 0);
  80:         if (q == NOQUOTA) {
  81:             u.u_error = ESRCH;
  82:             return;
  83:         }
  84:         if (u.u_error)
  85:             goto bad;
  86:     }
  87:     switch (uap->cmd) {
  88: 
  89:     case Q_SETDLIM:
  90:         u.u_error = setdlim(q, (dev_t)uap->arg, uap->addr);
  91:         break;
  92: 
  93:     case Q_GETDLIM:
  94:         u.u_error = getdlim(q, (dev_t)uap->arg, uap->addr);
  95:         break;
  96: 
  97:     case Q_SETDUSE:
  98:         u.u_error = setduse(q, (dev_t)uap->arg, uap->addr);
  99:         break;
 100: 
 101:     case Q_SETWARN:
 102:         u.u_error = setwarn(q, (dev_t)uap->arg, uap->addr);
 103:         break;
 104: 
 105:     case Q_DOWARN:
 106:         u.u_error = dowarn(q, (dev_t)uap->arg);
 107:         break;
 108: 
 109:     case Q_SYNC:
 110:         u.u_error = qsync((dev_t)uap->arg);
 111:         return;
 112: 
 113:     case Q_SETUID:
 114:         u.u_error = qsetuid((uid_t)uap->uid, uap->arg);
 115:         return;
 116: 
 117:     default:
 118:         u.u_error = EINVAL;
 119:         break;
 120:     }
 121: bad:
 122:     delquota(q);
 123: #endif
 124: }
 125: 
 126: #ifdef QUOTA
 127: /*
 128:  * Q_SETDLIM - assign an entire dqblk structure.
 129:  */
 130: setdlim(q, dev, addr)
 131:     register struct quota *q;
 132:     dev_t dev;
 133:     caddr_t addr;
 134: {
 135:     register struct inode *ip;
 136:     register struct dquot *dq, *odq;
 137:     struct dqblk newlim;
 138:     int index, error = 0;
 139: 
 140:     if (!suser())
 141:         return (u.u_error);         /* XXX */
 142:     index = getfsx(dev);
 143:     if (index < 0 || index >= NMOUNT)
 144:         return (ENODEV);
 145:     dq = dqp(q, dev);
 146:     if (dq == NODQUOT) {
 147:         dq = dqalloc(q->q_uid, dev);
 148:         if (dq == NODQUOT)
 149:             return (error);
 150:         dq->dq_cnt++;
 151:         dq->dq_own = q;
 152:         q->q_dq[index] = dq;
 153:         odq = NODQUOT;
 154:     } else
 155:         odq = dq;
 156: 
 157:     if (dq->dq_uid != q->q_uid)
 158:         panic("setdlim");
 159:     while (dq->dq_flags & DQ_LOCK) {
 160:         dq->dq_flags |= DQ_WANT;
 161:         sleep((caddr_t)dq, PINOD+1);
 162:     }
 163:     error = copyin(addr, (caddr_t)&newlim, sizeof (struct dqblk));
 164:     if (error) {
 165:         if (dq != odq) {
 166:             q->q_dq[index] = odq;
 167:             dq->dq_cnt--;
 168:         }
 169:         dqrele(dq);
 170:         return (error);
 171:     }
 172:     dq->dq_dqb = newlim;
 173:     dq->dq_flags |= DQ_MOD;
 174:     dqrele(dq);
 175:     if (dq->dq_isoftlimit == 0 && dq->dq_bsoftlimit == 0) {
 176:         q->q_dq[index] = NODQUOT;
 177:         dq->dq_own = NOQUOTA;
 178:         dqrele(dq);
 179:         if (dq->dq_cnt == 0)    /* no files open using quota */
 180:             return (error);
 181:         dq = NODQUOT;
 182:     }
 183:     if (dq == odq)
 184:         return (error);
 185:     for (ip = inode; ip < inodeNINODE; ip++)
 186:         if (ip->i_uid == q->q_uid && ip->i_dev == dev && ip->i_mode) {
 187:             if (dq == NODQUOT)
 188:                 dqrele(ip->i_dquot);
 189:             else
 190:                 dq->dq_cnt++;
 191:             ip->i_dquot = dq;
 192:         }
 193:     return (error);
 194: }
 195: 
 196: /*
 197:  * Q_GETDLIM - return current values in a dqblk structure.
 198:  */
 199: getdlim(q, dev, addr)
 200:     struct quota *q;
 201:     dev_t dev;
 202:     caddr_t addr;
 203: {
 204:     register struct dquot *dq;
 205:     int error;
 206: 
 207:     dq = dqp(q, dev);
 208:     if (dq == NODQUOT)
 209:         return (ESRCH);
 210:     error = copyout((caddr_t)&dq->dq_dqb, addr, sizeof (struct dqblk));
 211:     dqrele(dq);
 212:     return (error);
 213: }
 214: 
 215: /*
 216:  * Q_SETDUSE - set current inode and disc block totals.
 217:  * Resets warnings and associated flags.
 218:  */
 219: setduse(q, dev, addr)
 220:     register struct quota *q;
 221:     dev_t dev;
 222:     caddr_t addr;
 223: {
 224:     register struct dquot *dq;
 225:     struct dqusage usage;
 226:     int error = 0;
 227: 
 228:     if (!suser())
 229:         return (u.u_error);
 230:     dq = dqp(q, dev);
 231:     if (dq == NODQUOT)
 232:         return (ESRCH);
 233:     while (dq->dq_flags & DQ_LOCK) {
 234:         dq->dq_flags |= DQ_WANT;
 235:         sleep((caddr_t)dq, PINOD+1);
 236:     }
 237:     if (dq->dq_uid != q->q_uid)
 238:         panic("setduse");
 239:     error = copyin(addr, (caddr_t)&usage, sizeof (usage));
 240:     if (error == 0) {
 241:         dq->dq_curinodes = usage.du_curinodes;
 242:         dq->dq_curblocks = usage.du_curblocks;
 243:         if (dq->dq_curinodes < dq->dq_isoftlimit)
 244:             dq->dq_iwarn = MAX_IQ_WARN;
 245:         if (dq->dq_curblocks < dq->dq_bsoftlimit)
 246:             dq->dq_bwarn = MAX_DQ_WARN;
 247:         dq->dq_flags &= ~(DQ_INODS | DQ_BLKS);
 248:         dq->dq_flags |= DQ_MOD;
 249:     }
 250:     dqrele(dq);
 251:     return (error);
 252: }
 253: 
 254: /*
 255:  * Q_SETWARN - set warning counters.
 256:  */
 257: setwarn(q, dev, addr)
 258:     register struct quota *q;
 259:     dev_t dev;
 260:     caddr_t addr;
 261: {
 262:     register struct dquot *dq;
 263:     int error = 0;
 264:     struct dqwarn warn;
 265: 
 266:     if (!suser())
 267:         return (u.u_error);         /* XXX */
 268:     dq = dqp(q, dev);
 269:     if (dq == NODQUOT)
 270:         return (ESRCH);
 271:     while (dq->dq_flags & DQ_LOCK) {
 272:         dq->dq_flags |= DQ_WANT;
 273:         sleep((caddr_t)dq, PINOD+1);
 274:     }
 275:     if (dq->dq_uid != q->q_uid)
 276:         panic("setwarn");
 277:     error = copyin(addr, (caddr_t)&warn, sizeof (warn));
 278:     if (error == 0) {
 279:         dq->dq_iwarn = warn.dw_iwarn;
 280:         dq->dq_bwarn = warn.dw_bwarn;
 281:         dq->dq_flags &= ~(DQ_INODS | DQ_BLKS);
 282:         dq->dq_flags |= DQ_MOD;
 283:     }
 284:     dqrele(dq);
 285:     return (error);
 286: }
 287: 
 288: /*
 289:  * Q_DOWARN - force warning(s) to user(s).
 290:  */
 291: dowarn(q, dev)
 292:     register struct quota *q;
 293:     dev_t dev;
 294: {
 295:     register struct dquot *dq, **dqq;
 296: 
 297:     if (!suser() || u.u_ttyp == NULL)
 298:         return (u.u_error);         /* XXX */
 299:     if (dev != NODEV) {
 300:         dq = dqp(q, dev);
 301:         if (dq != NODQUOT) {
 302:             qwarn(dq);
 303:             dqrele(dq);
 304:         }
 305:         return (0);
 306:     }
 307:     for (dqq = q->q_dq; dqq < &q->q_dq[NMOUNT]; dqq++) {
 308:         dq = *dqq;
 309:         if (dq != NODQUOT && dq != LOSTDQUOT)
 310:             qwarn(dq);
 311:     }
 312:     return (0);
 313: }
 314: 
 315: /*
 316:  * Q_SYNC - sync quota files to disc.
 317:  */
 318: qsync(dev)
 319:     dev_t dev;
 320: {
 321:     register struct quota *q;
 322:     register struct mount *mp;
 323:     register index;
 324: 
 325:     if (!suser())
 326:         return (u.u_error);         /* XXX */
 327:     for (mp = mount, index = 0; mp < &mount[NMOUNT]; mp++, index++)
 328:         if (mp->m_bufp && mp->m_qinod &&
 329:             (dev == NODEV || dev == mp->m_dev)) {
 330:             for (q = quota; q < quotaNQUOTA; q++)
 331:                 if (q->q_cnt) {
 332:                     q->q_cnt++;
 333:                     putdq(mp, q->q_dq[index], 0);
 334:                     delquota(q);
 335:                 }
 336:         }
 337:     return (0);
 338: }
 339: 
 340: /*
 341:  * Q_SETUID - change quota to a particular uid.
 342:  */
 343: qsetuid(uid, noquota)
 344:     uid_t uid;
 345:     int noquota;
 346: {
 347:     register struct quota *q;
 348: 
 349:     if (uid == u.u_quota->q_uid)
 350:         return (0);
 351:     if (!suser())
 352:         return (u.u_error);         /* XXX */
 353:     q = getquota(uid, 0, noquota ? Q_NDQ : 0);
 354:     qclean();
 355:     qstart(q);
 356:     return (0);
 357: }
 358: #endif

Defined functions

dowarn defined in line 291; used 1 times
getdlim defined in line 199; used 1 times
  • in line 94
qquota defined in line 60; used 2 times
qsetuid defined in line 343; used 1 times
qsync defined in line 318; used 1 times
setdlim defined in line 130; used 1 times
  • in line 90
setduse defined in line 219; used 1 times
  • in line 98
setquota defined in line 28; used 2 times
setwarn defined in line 257; used 1 times

Defined struct's

a defined in line 62; used 4 times
  • in line 33(2), 67(2)
Last modified: 1986-06-05
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 960
Valid CSS Valid XHTML 1.0 Strict