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_ufs.c 7.1.1 (2.11BSD GTE) 12/31/93
7: */
8:
9: /*
10: * MELBOURNE QUOTAS
11: *
12: * Routines used in checking limits on file system usage.
13: */
14: #include "param.h"
15: #ifdef QUOTA
16: #include "systm.h"
17: #include "user.h"
18: #include "proc.h"
19: #include "inode.h"
20: #include "quota.h"
21: #include "fs.h"
22: #include "mount.h"
23: #include "uio.h"
24:
25: /*
26: * Find the dquot structure that should
27: * be used in checking i/o on inode ip.
28: */
29: struct dquot *
30: inoquota(ip)
31: register struct inode *ip;
32: {
33: register struct quota *q;
34: register struct dquot **dqq;
35: register struct mount *mp;
36: int index;
37:
38: top:
39: q = qfind(ip->i_uid);
40: if (q == NOQUOTA) {
41: for (mp = mount; mp < &mount[NMOUNT]; mp++)
42: #ifdef pdp11
43: if (mp->m_inodp && mp->m_dev == ip->i_dev)
44: #else
45: if (mp->m_bufp && mp->m_dev == ip->i_dev)
46: #endif
47: return (discquota(ip->i_uid, mp->m_qinod));
48: panic("inoquota");
49: }
50:
51: /*
52: * We have a quota struct in core (most likely our own) that
53: * belongs to the same user as the inode
54: */
55: if (q->q_flags & Q_NDQ)
56: return (NODQUOT);
57: if (q->q_flags & Q_LOCK) {
58: q->q_flags |= Q_WANT;
59: #ifdef pdp11
60: QUOTAUNMAP();
61: sleep((caddr_t)q, PINOD+1);
62: QUOTAMAP();
63: #else
64: sleep((caddr_t)q, PINOD+1);
65: #endif
66: goto top; /* might just have been freed */
67: }
68: index = getfsx(ip->i_dev);
69: dqq = &q->q_dq[index];
70: if (*dqq == LOSTDQUOT) {
71: q->q_flags |= Q_LOCK;
72: *dqq = discquota(q->q_uid, mount[index].m_qinod);
73: if (*dqq != NODQUOT)
74: (*dqq)->dq_own = q;
75: if (q->q_flags & Q_WANT)
76: wakeup((caddr_t)q);
77: q->q_flags &= ~(Q_LOCK | Q_WANT);
78: }
79: if (*dqq != NODQUOT)
80: (*dqq)->dq_cnt++;
81: return (*dqq);
82: }
83:
84: /*
85: * Update disc usage, and take corrective action.
86: */
87: chkdq(ip, change, force)
88: register struct inode *ip;
89: long change;
90: int force;
91: {
92: register struct dquot *dq;
93:
94: if (change == 0)
95: return (0);
96: #ifdef pdp11
97: dq = ix_dquot[ip - inode];
98: #else
99: dq = ip->i_dquot;
100: #endif
101: if (dq == NODQUOT)
102: return (0);
103: if (dq->dq_bsoftlimit == 0)
104: return (0);
105: dq->dq_flags |= DQ_MOD;
106: /*
107: * reset warnings if below disk quota.
108: */
109: if (dq->dq_bwarn == 0 && dq->dq_bsoftlimit &&
110: (dq->dq_curblocks + change) < dq->dq_bsoftlimit) {
111: dq->dq_bwarn = MAX_DQ_WARN;
112: if (dq->dq_own == u.u_quota) {
113: uprintf("\nUNDER DISC QUOTA: (%s) by %d Kbytes\n",
114: ip->i_fs->fs_fsmnt,
115: #ifdef pdp11
116: (dq->dq_bsoftlimit + 1023L - (dq->dq_curblocks
117: + change)) / 1024);
118: #else
119: dbtob(dq->dq_bsoftlimit -
120: (dq->dq_curblocks + change)) / 1024);
121: #endif
122: }
123: }
124: if (change < 0) {
125: if (dq->dq_curblocks + change >= 0)
126: dq->dq_curblocks += change;
127: else
128: dq->dq_curblocks = 0;
129: dq->dq_flags &= ~DQ_BLKS;
130: return (0);
131: }
132:
133: /*
134: * If user is over quota, or has run out of warnings, then
135: * disallow space allocation (except su's are never stopped).
136: */
137: if (u.u_uid == 0)
138: force = 1;
139: if (!force && dq->dq_bwarn == 0) {
140: if ((dq->dq_flags & DQ_BLKS) == 0 && dq->dq_own == u.u_quota) {
141: uprintf("\nOVER DISC QUOTA: (%s) NO MORE DISC SPACE\n",
142: ip->i_fs->fs_fsmnt);
143: dq->dq_flags |= DQ_BLKS;
144: }
145: return (EDQUOT);
146: }
147: if (dq->dq_curblocks < dq->dq_bsoftlimit) {
148: dq->dq_curblocks += change;
149: if (dq->dq_curblocks < dq->dq_bsoftlimit)
150: return (0);
151: if (dq->dq_own == u.u_quota)
152: uprintf("\nWARNING: disc quota (%s) exceeded\n",
153: ip->i_fs->fs_fsmnt);
154: return (0);
155: }
156: if (!force && dq->dq_bhardlimit &&
157: dq->dq_curblocks + change >= dq->dq_bhardlimit) {
158: if ((dq->dq_flags & DQ_BLKS) == 0 && dq->dq_own == u.u_quota) {
159: uprintf("\nDISC LIMIT REACHED (%s) - WRITE FAILED\n",
160: ip->i_fs->fs_fsmnt);
161: dq->dq_flags |= DQ_BLKS;
162: }
163: return (EDQUOT);
164: }
165: /*
166: * User is over quota, but not over limit
167: * or is over limit, but we have been told
168: * there is nothing we can do.
169: */
170: dq->dq_curblocks += change;
171: return (0);
172: }
173:
174: /*
175: * Check the inode limit, applying corrective action.
176: */
177: chkiq(dev, ip, uid, force)
178: dev_t dev;
179: uid_t uid;
180: register struct inode *ip;
181: int force;
182: {
183: register struct dquot *dq;
184: register struct quota *q;
185:
186: if (ip == NULL) { /* allocation */
187: q = qfind(uid);
188: if (q != NOQUOTA)
189: dq = dqp(q, dev);
190: else
191: dq = discquota(uid, mount[getfsx(dev)].m_qinod);
192: } else { /* free */
193: #ifdef pdp11
194: dq = ix_dquot[ip - inode];
195: #else
196: dq = ip->i_dquot;
197: #endif
198: if (dq != NODQUOT)
199: dq->dq_cnt++;
200: }
201: if (dq == NODQUOT)
202: return (0);
203: if (dq->dq_isoftlimit == 0) {
204: dqrele(dq);
205: return (0);
206: }
207: dq->dq_flags |= DQ_MOD;
208: if (ip) { /* a free */
209: if (dq->dq_curinodes)
210: dq->dq_curinodes--;
211: dq->dq_flags &= ~DQ_INODS;
212: dqrele(dq);
213: return (0);
214: }
215:
216: /*
217: * The following shouldn't be necessary, as if u.u_uid == 0
218: * then dq == NODQUOT & we wouldn't get here at all, but
219: * then again, its not going to harm anything ...
220: */
221: if (u.u_uid == 0) /* su's musn't be stopped */
222: force = 1;
223: if (!force && dq->dq_iwarn == 0) {
224: if ((dq->dq_flags & DQ_INODS) == 0 && dq->dq_own == u.u_quota) {
225: uprintf("\nOVER FILE QUOTA - NO MORE FILES (%s)\n",
226: getfs(dq->dq_dev)->fs_fsmnt);
227: dq->dq_flags |= DQ_INODS;
228: }
229: dqrele(dq);
230: return (EDQUOT);
231: }
232: if (dq->dq_curinodes < dq->dq_isoftlimit) {
233: if (++dq->dq_curinodes >= dq->dq_isoftlimit &&
234: dq->dq_own == u.u_quota)
235: uprintf("\nWARNING - too many files (%s)\n",
236: getfs(dq->dq_dev)->fs_fsmnt);
237: dqrele(dq);
238: return (0);
239: }
240: if (!force && dq->dq_ihardlimit &&
241: dq->dq_curinodes + 1 >= dq->dq_ihardlimit) {
242: if ((dq->dq_flags & DQ_INODS) == 0 && dq->dq_own == u.u_quota) {
243: uprintf("\nFILE LIMIT REACHED - CREATE FAILED (%s)\n",
244: getfs(dq->dq_dev)->fs_fsmnt);
245: dq->dq_flags |= DQ_INODS;
246: }
247: dqrele(dq);
248: return (EDQUOT);
249: }
250: /*
251: * Over quota but not at limit;
252: * or over limit, but we aren't
253: * allowed to stop it.
254: */
255: dq->dq_curinodes++;
256: dqrele(dq);
257: return (0);
258: }
259: #endif
Defined functions
chkdq
defined in line
87; used 4 times