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

Defined functions

dowarn defined in line 369; used 1 times
getdlim defined in line 248; used 1 times
qquota defined in line 68; used 2 times
qsetuid defined in line 425; used 1 times
qsync defined in line 396; used 2 times
setdlim defined in line 159; used 1 times
setduse defined in line 281; used 1 times
setquota defined in line 27; used 2 times
setwarn defined in line 329; used 1 times

Defined variables

dev defined in line 34; used 26 times
mp defined in line 33; used 19 times

Defined struct's

a defined in line 70; used 4 times
  • in line 32(2), 75(2)
Last modified: 1994-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3684
Valid CSS Valid XHTML 1.0 Strict