Deleted Added
full compact
quotacheck.c (180187) quotacheck.c (207736)
1/*
2 * Copyright (c) 1980, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Robert Elz at The University of Melbourne.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41static char sccsid[] = "@(#)quotacheck.c 8.3 (Berkeley) 1/29/94";
42#endif /* not lint */
43#endif
44#include <sys/cdefs.h>
1/*
2 * Copyright (c) 1980, 1990, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Robert Elz at The University of Melbourne.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 28 unchanged lines hidden (view full) ---

37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41static char sccsid[] = "@(#)quotacheck.c 8.3 (Berkeley) 1/29/94";
42#endif /* not lint */
43#endif
44#include <sys/cdefs.h>
45__FBSDID("$FreeBSD: head/sbin/quotacheck/quotacheck.c 180187 2008-07-02 15:51:59Z des $");
45__FBSDID("$FreeBSD: head/sbin/quotacheck/quotacheck.c 207736 2010-05-07 00:41:12Z mckusick $");
46
47/*
48 * Fix up / report on disk quotas & usage
49 */
50#include <sys/param.h>
51#include <sys/disklabel.h>
52#include <sys/mount.h>
53#include <sys/stat.h>
54
55#include <ufs/ufs/dinode.h>
56#include <ufs/ufs/quota.h>
57#include <ufs/ffs/fs.h>
58
59#include <err.h>
60#include <errno.h>
61#include <fcntl.h>
62#include <fstab.h>
63#include <grp.h>
46
47/*
48 * Fix up / report on disk quotas & usage
49 */
50#include <sys/param.h>
51#include <sys/disklabel.h>
52#include <sys/mount.h>
53#include <sys/stat.h>
54
55#include <ufs/ufs/dinode.h>
56#include <ufs/ufs/quota.h>
57#include <ufs/ffs/fs.h>
58
59#include <err.h>
60#include <errno.h>
61#include <fcntl.h>
62#include <fstab.h>
63#include <grp.h>
64#include <libutil.h>
64#include <pwd.h>
65#include <stdio.h>
66#include <stdlib.h>
67#include <string.h>
68#include <unistd.h>
69
70#include "quotacheck.h"
71

--- 32 unchanged lines hidden (view full) ---

104 u_long fu_id;
105 char fu_name[1];
106 /* actually bigger */
107};
108#define FUHASH 1024 /* must be power of two */
109struct fileusage *fuhead[MAXQUOTAS][FUHASH];
110
111int aflag; /* all file systems */
65#include <pwd.h>
66#include <stdio.h>
67#include <stdlib.h>
68#include <string.h>
69#include <unistd.h>
70
71#include "quotacheck.h"
72

--- 32 unchanged lines hidden (view full) ---

105 u_long fu_id;
106 char fu_name[1];
107 /* actually bigger */
108};
109#define FUHASH 1024 /* must be power of two */
110struct fileusage *fuhead[MAXQUOTAS][FUHASH];
111
112int aflag; /* all file systems */
113int cflag; /* convert format to 32 or 64 bit size */
112int gflag; /* check group quotas */
113int uflag; /* check user quotas */
114int vflag; /* verbose */
115int fi; /* open disk file descriptor */
116
117struct fileusage *
114int gflag; /* check group quotas */
115int uflag; /* check user quotas */
116int vflag; /* verbose */
117int fi; /* open disk file descriptor */
118
119struct fileusage *
118 addid(u_long, int, char *, char *);
119char *blockcheck(char *);
120 addid(u_long, int, char *, const char *);
120void bread(ufs2_daddr_t, char *, long);
121void freeinodebuf(void);
122union dinode *
123 getnextinode(ino_t);
124int getquotagid(void);
121void bread(ufs2_daddr_t, char *, long);
122void freeinodebuf(void);
123union dinode *
124 getnextinode(ino_t);
125int getquotagid(void);
125int hasquota(struct fstab *, int, char **);
126struct fileusage *
127 lookup(u_long, int);
126struct fileusage *
127 lookup(u_long, int);
128struct quotaname *needchk(struct fstab *);
129int oneof(char *, char*[], int);
128int oneof(char *, char*[], int);
130void printchanges(char *, int, struct dqblk *, struct fileusage *, u_long);
129void printchanges(const char *, int, struct dqblk *, struct fileusage *,
130 u_long);
131void setinodebuf(ino_t);
131void setinodebuf(ino_t);
132int update(char *, char *, int);
132int update(const char *, struct quotafile *, int);
133void usage(void);
134
135int
136main(int argc, char *argv[])
137{
138 struct fstab *fs;
139 struct passwd *pw;
140 struct group *gr;
133void usage(void);
134
135int
136main(int argc, char *argv[])
137{
138 struct fstab *fs;
139 struct passwd *pw;
140 struct group *gr;
141 struct quotaname *qnp;
141 struct quotafile *qfu, *qfg;
142 int i, argnum, maxrun, errs, ch;
143 long done = 0;
144 char *name;
145
146 errs = maxrun = 0;
142 int i, argnum, maxrun, errs, ch;
143 long done = 0;
144 char *name;
145
146 errs = maxrun = 0;
147 while ((ch = getopt(argc, argv, "aguvl:")) != -1) {
147 while ((ch = getopt(argc, argv, "ac:guvl:")) != -1) {
148 switch(ch) {
149 case 'a':
150 aflag++;
151 break;
148 switch(ch) {
149 case 'a':
150 aflag++;
151 break;
152 case 'c':
153 if (cflag)
154 usage();
155 cflag = atoi(optarg);
156 break;
152 case 'g':
153 gflag++;
154 break;
155 case 'u':
156 uflag++;
157 break;
158 case 'v':
159 vflag++;

--- 4 unchanged lines hidden (view full) ---

164 default:
165 usage();
166 }
167 }
168 argc -= optind;
169 argv += optind;
170 if ((argc == 0 && !aflag) || (argc > 0 && aflag))
171 usage();
157 case 'g':
158 gflag++;
159 break;
160 case 'u':
161 uflag++;
162 break;
163 case 'v':
164 vflag++;

--- 4 unchanged lines hidden (view full) ---

169 default:
170 usage();
171 }
172 }
173 argc -= optind;
174 argv += optind;
175 if ((argc == 0 && !aflag) || (argc > 0 && aflag))
176 usage();
177 if (cflag && cflag != 32 && cflag != 64)
178 usage();
172 if (!gflag && !uflag) {
173 gflag++;
174 uflag++;
175 }
176 if (gflag) {
177 setgrent();
178 while ((gr = getgrent()) != NULL)
179 (void) addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name,

--- 8 unchanged lines hidden (view full) ---

188 endpwent();
189 }
190 /*
191 * The maxrun (-l) option is now deprecated.
192 */
193 if (maxrun > 0)
194 warnx("the -l option is now deprecated");
195 if (aflag)
179 if (!gflag && !uflag) {
180 gflag++;
181 uflag++;
182 }
183 if (gflag) {
184 setgrent();
185 while ((gr = getgrent()) != NULL)
186 (void) addid((u_long)gr->gr_gid, GRPQUOTA, gr->gr_name,

--- 8 unchanged lines hidden (view full) ---

195 endpwent();
196 }
197 /*
198 * The maxrun (-l) option is now deprecated.
199 */
200 if (maxrun > 0)
201 warnx("the -l option is now deprecated");
202 if (aflag)
196 exit(checkfstab());
203 exit(checkfstab(uflag, gflag));
197 if (setfsent() == 0)
198 errx(1, "%s: can't open", FSTAB);
199 while ((fs = getfsent()) != NULL) {
200 if (((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
204 if (setfsent() == 0)
205 errx(1, "%s: can't open", FSTAB);
206 while ((fs = getfsent()) != NULL) {
207 if (((argnum = oneof(fs->fs_file, argv, argc)) >= 0 ||
201 (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) &&
202 (qnp = needchk(fs)) &&
208 (argnum = oneof(fs->fs_spec, argv, argc)) >= 0) &&
203 (name = blockcheck(fs->fs_spec))) {
204 done |= 1 << argnum;
209 (name = blockcheck(fs->fs_spec))) {
210 done |= 1 << argnum;
205 errs += chkquota(name, fs->fs_file, qnp);
211 qfu = NULL;
212 if (uflag)
213 qfu = quota_open(fs, USRQUOTA, O_CREAT|O_RDWR);
214 qfg = NULL;
215 if (gflag)
216 qfg = quota_open(fs, GRPQUOTA, O_CREAT|O_RDWR);
217 if (qfu == NULL && qfg == NULL)
218 continue;
219 errs += chkquota(name, qfu, qfg);
220 if (qfu)
221 quota_close(qfu);
222 if (qfg)
223 quota_close(qfg);
206 }
207 }
208 endfsent();
209 for (i = 0; i < argc; i++)
210 if ((done & (1 << i)) == 0)
211 fprintf(stderr, "%s not found in %s\n",
212 argv[i], FSTAB);
213 exit(errs);
214}
215
216void
217usage(void)
218{
219 (void)fprintf(stderr, "%s\n%s\n",
224 }
225 }
226 endfsent();
227 for (i = 0; i < argc; i++)
228 if ((done & (1 << i)) == 0)
229 fprintf(stderr, "%s not found in %s\n",
230 argv[i], FSTAB);
231 exit(errs);
232}
233
234void
235usage(void)
236{
237 (void)fprintf(stderr, "%s\n%s\n",
220 "usage: quotacheck [-guv] [-l maxrun] -a",
221 " quotacheck [-guv] filesystem ...");
238 "usage: quotacheck [-guv] [-c 32 | 64] [-l maxrun] -a",
239 " quotacheck [-guv] [-c 32 | 64] filesystem ...");
222 exit(1);
223}
224
240 exit(1);
241}
242
225struct quotaname *
226needchk(struct fstab *fs)
227{
228 struct quotaname *qnp;
229 char *qfnp;
230
231 if (strcmp(fs->fs_vfstype, "ufs") ||
232 strcmp(fs->fs_type, FSTAB_RW))
233 return (NULL);
234 if ((qnp = malloc(sizeof(*qnp))) == NULL)
235 errx(1, "malloc failed");
236 qnp->flags = 0;
237 if (gflag && hasquota(fs, GRPQUOTA, &qfnp)) {
238 strcpy(qnp->grpqfname, qfnp);
239 qnp->flags |= HASGRP;
240 }
241 if (uflag && hasquota(fs, USRQUOTA, &qfnp)) {
242 strcpy(qnp->usrqfname, qfnp);
243 qnp->flags |= HASUSR;
244 }
245 if (qnp->flags)
246 return (qnp);
247 free(qnp);
248 return (NULL);
249}
250
251/*
252 * Possible superblock locations ordered from most to least likely.
253 */
254static int sblock_try[] = SBLOCKSEARCH;
255
256/*
257 * Scan the specified file system to check quota(s) present on it.
258 */
259int
243/*
244 * Possible superblock locations ordered from most to least likely.
245 */
246static int sblock_try[] = SBLOCKSEARCH;
247
248/*
249 * Scan the specified file system to check quota(s) present on it.
250 */
251int
260chkquota(char *fsname, char *mntpt, struct quotaname *qnp)
252chkquota(char *specname, struct quotafile *qfu, struct quotafile *qfg)
261{
262 struct fileusage *fup;
263 union dinode *dp;
264 int cg, i, mode, errs = 0;
265 ino_t ino, inosused, userino = 0, groupino = 0;
266 dev_t dev, userdev = 0, groupdev = 0;
253{
254 struct fileusage *fup;
255 union dinode *dp;
256 int cg, i, mode, errs = 0;
257 ino_t ino, inosused, userino = 0, groupino = 0;
258 dev_t dev, userdev = 0, groupdev = 0;
267 char *cp;
268 struct stat sb;
259 struct stat sb;
260 const char *mntpt;
261 char *cp;
269
262
270 if (qnp == NULL)
271 err(1, "null quota information passed to chkquota()\n");
272 if ((fi = open(fsname, O_RDONLY, 0)) < 0) {
273 warn("%s", fsname);
263 if (qfu != NULL)
264 mntpt = quota_fsname(qfu);
265 else if (qfg != NULL)
266 mntpt = quota_fsname(qfg);
267 else
268 errx(1, "null quotafile information passed to chkquota()\n");
269 if (cflag) {
270 if (vflag && qfu != NULL)
271 printf("%s: convert user quota to %d bits\n",
272 mntpt, cflag);
273 if (qfu != NULL && quota_convert(qfu, cflag) < 0) {
274 if (errno == EBADF)
275 errx(1,
276 "%s: cannot convert an active quota file",
277 mntpt);
278 err(1, "user quota conversion to size %d failed",
279 cflag);
280 }
281 if (vflag && qfg != NULL)
282 printf("%s: convert group quota to %d bits\n",
283 mntpt, cflag);
284 if (qfg != NULL && quota_convert(qfg, cflag) < 0) {
285 if (errno == EBADF)
286 errx(1,
287 "%s: cannot convert an active quota file",
288 mntpt);
289 err(1, "group quota conversion to size %d failed",
290 cflag);
291 }
292 }
293 if ((fi = open(specname, O_RDONLY, 0)) < 0) {
294 warn("%s", specname);
274 return (1);
275 }
276 if ((stat(mntpt, &sb)) < 0) {
277 warn("%s", mntpt);
278 return (1);
279 }
280 dev = sb.st_dev;
281 if (vflag) {
282 (void)printf("*** Checking ");
295 return (1);
296 }
297 if ((stat(mntpt, &sb)) < 0) {
298 warn("%s", mntpt);
299 return (1);
300 }
301 dev = sb.st_dev;
302 if (vflag) {
303 (void)printf("*** Checking ");
283 if (qnp->flags & HASUSR)
284 (void)printf("%s%s", qfextension[USRQUOTA],
285 (qnp->flags & HASGRP) ? " and " : "");
286 if (qnp->flags & HASGRP)
287 (void)printf("%s", qfextension[GRPQUOTA]);
288 (void)printf(" quotas for %s (%s)\n", fsname, mntpt);
304 if (qfu)
305 (void)printf("user%s", qfg ? " and " : "");
306 if (qfg)
307 (void)printf("group");
308 (void)printf(" quotas for %s (%s)\n", specname, mntpt);
289 }
309 }
290 if (qnp->flags & HASUSR) {
291 if (stat(qnp->usrqfname, &sb) == 0) {
310 if (qfu) {
311 if (stat(quota_qfname(qfu), &sb) == 0) {
292 userino = sb.st_ino;
293 userdev = sb.st_dev;
294 }
295 }
312 userino = sb.st_ino;
313 userdev = sb.st_dev;
314 }
315 }
296 if (qnp->flags & HASGRP) {
297 if (stat(qnp->grpqfname, &sb) == 0) {
316 if (qfg) {
317 if (stat(quota_qfname(qfg), &sb) == 0) {
298 groupino = sb.st_ino;
299 groupdev = sb.st_dev;
300 }
301 }
302 sync();
303 dev_bsize = 1;
304 for (i = 0; sblock_try[i] != -1; i++) {
305 bread(sblock_try[i], (char *)&sblock, (long)SBLOCKSIZE);

--- 71 unchanged lines hidden (view full) ---

377 */
378#ifdef SF_SNAPSHOT
379 if (DIP(dp, di_flags) & SF_SNAPSHOT)
380 continue;
381#endif
382 if ((ino == userino && dev == userdev) ||
383 (ino == groupino && dev == groupdev))
384 continue;
318 groupino = sb.st_ino;
319 groupdev = sb.st_dev;
320 }
321 }
322 sync();
323 dev_bsize = 1;
324 for (i = 0; sblock_try[i] != -1; i++) {
325 bread(sblock_try[i], (char *)&sblock, (long)SBLOCKSIZE);

--- 71 unchanged lines hidden (view full) ---

397 */
398#ifdef SF_SNAPSHOT
399 if (DIP(dp, di_flags) & SF_SNAPSHOT)
400 continue;
401#endif
402 if ((ino == userino && dev == userdev) ||
403 (ino == groupino && dev == groupdev))
404 continue;
385 if (qnp->flags & HASGRP) {
405 if (qfg) {
386 fup = addid((u_long)DIP(dp, di_gid), GRPQUOTA,
387 (char *)0, mntpt);
388 fup->fu_curinodes++;
389 if (mode == IFREG || mode == IFDIR ||
390 mode == IFLNK)
391 fup->fu_curblocks += DIP(dp, di_blocks);
392 }
406 fup = addid((u_long)DIP(dp, di_gid), GRPQUOTA,
407 (char *)0, mntpt);
408 fup->fu_curinodes++;
409 if (mode == IFREG || mode == IFDIR ||
410 mode == IFLNK)
411 fup->fu_curblocks += DIP(dp, di_blocks);
412 }
393 if (qnp->flags & HASUSR) {
413 if (qfu) {
394 fup = addid((u_long)DIP(dp, di_uid), USRQUOTA,
395 (char *)0, mntpt);
396 fup->fu_curinodes++;
397 if (mode == IFREG || mode == IFDIR ||
398 mode == IFLNK)
399 fup->fu_curblocks += DIP(dp, di_blocks);
400 }
401 }
402 }
403 freeinodebuf();
414 fup = addid((u_long)DIP(dp, di_uid), USRQUOTA,
415 (char *)0, mntpt);
416 fup->fu_curinodes++;
417 if (mode == IFREG || mode == IFDIR ||
418 mode == IFLNK)
419 fup->fu_curblocks += DIP(dp, di_blocks);
420 }
421 }
422 }
423 freeinodebuf();
404 if (qnp->flags & HASUSR)
405 errs += update(mntpt, qnp->usrqfname, USRQUOTA);
406 if (qnp->flags & HASGRP)
407 errs += update(mntpt, qnp->grpqfname, GRPQUOTA);
424 if (qfu)
425 errs += update(mntpt, qfu, USRQUOTA);
426 if (qfg)
427 errs += update(mntpt, qfg, GRPQUOTA);
408 close(fi);
409 (void)fflush(stdout);
410 return (errs);
411}
412
413/*
414 * Update a specified quota file.
415 */
416int
428 close(fi);
429 (void)fflush(stdout);
430 return (errs);
431}
432
433/*
434 * Update a specified quota file.
435 */
436int
417update(char *fsname, char *quotafile, int type)
437update(const char *fsname, struct quotafile *qf, int type)
418{
419 struct fileusage *fup;
438{
439 struct fileusage *fup;
420 FILE *qfi, *qfo;
421 u_long id, lastid, highid = 0;
440 u_long id, lastid, highid = 0;
422 off_t offset;
423 int i;
424 struct dqblk dqbuf;
425 struct stat sb;
441 struct dqblk dqbuf;
442 struct stat sb;
426 static int warned = 0;
427 static struct dqblk zerodqbuf;
428 static struct fileusage zerofileusage;
429
443 static struct dqblk zerodqbuf;
444 static struct fileusage zerofileusage;
445
430 if ((qfo = fopen(quotafile, "r+")) == NULL) {
431 if (errno == ENOENT)
432 qfo = fopen(quotafile, "w+");
433 if (qfo) {
434 warnx("creating quota file %s", quotafile);
435#define MODE (S_IRUSR|S_IWUSR|S_IRGRP)
436 (void) fchown(fileno(qfo), getuid(), getquotagid());
437 (void) fchmod(fileno(qfo), MODE);
438 } else {
439 warn("%s", quotafile);
440 return (1);
441 }
442 }
443 if ((qfi = fopen(quotafile, "r")) == NULL) {
444 warn("%s", quotafile);
445 (void) fclose(qfo);
446 return (1);
447 }
448 if (quotactl(fsname, QCMD(Q_SYNC, type), (u_long)0, (caddr_t)0) < 0 &&
449 errno == EOPNOTSUPP && !warned && vflag) {
450 warned++;
451 (void)printf("*** Warning: %s\n",
452 "Quotas are not compiled into this kernel");
453 }
454 if (fstat(fileno(qfi), &sb) < 0) {
455 warn("Cannot fstat quota file %s\n", quotafile);
456 (void) fclose(qfo);
457 (void) fclose(qfi);
458 return (1);
459 }
460 if ((sb.st_size % sizeof(struct dqblk)) != 0)
461 warn("%s size is not a multiple of dqblk\n", quotafile);
462
463 /*
464 * Scan the on-disk quota file and record any usage changes.
465 */
446 /*
447 * Scan the on-disk quota file and record any usage changes.
448 */
466
467 if (sb.st_size != 0)
468 lastid = (sb.st_size / sizeof(struct dqblk)) - 1;
469 else
470 lastid = 0;
471 for (id = 0, offset = 0; id <= lastid;
472 id++, offset += sizeof(struct dqblk)) {
473 if (fread((char *)&dqbuf, sizeof(struct dqblk), 1, qfi) == 0)
449 lastid = quota_maxid(qf);
450 for (id = 0; id <= lastid; id++) {
451 if (quota_read(qf, &dqbuf, id) < 0)
474 dqbuf = zerodqbuf;
475 if ((fup = lookup(id, type)) == NULL)
476 fup = &zerofileusage;
477 if (fup->fu_curinodes || fup->fu_curblocks ||
478 dqbuf.dqb_bsoftlimit || dqbuf.dqb_bhardlimit ||
479 dqbuf.dqb_isoftlimit || dqbuf.dqb_ihardlimit)
480 highid = id;
481 if (dqbuf.dqb_curinodes == fup->fu_curinodes &&
482 dqbuf.dqb_curblocks == fup->fu_curblocks) {
483 fup->fu_curinodes = 0;
484 fup->fu_curblocks = 0;
485 continue;
486 }
487 printchanges(fsname, type, &dqbuf, fup, id);
452 dqbuf = zerodqbuf;
453 if ((fup = lookup(id, type)) == NULL)
454 fup = &zerofileusage;
455 if (fup->fu_curinodes || fup->fu_curblocks ||
456 dqbuf.dqb_bsoftlimit || dqbuf.dqb_bhardlimit ||
457 dqbuf.dqb_isoftlimit || dqbuf.dqb_ihardlimit)
458 highid = id;
459 if (dqbuf.dqb_curinodes == fup->fu_curinodes &&
460 dqbuf.dqb_curblocks == fup->fu_curblocks) {
461 fup->fu_curinodes = 0;
462 fup->fu_curblocks = 0;
463 continue;
464 }
465 printchanges(fsname, type, &dqbuf, fup, id);
488 /*
489 * Reset time limit if have a soft limit and were
490 * previously under it, but are now over it.
491 */
492 if (dqbuf.dqb_bsoftlimit && id != 0 &&
493 dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit &&
494 fup->fu_curblocks >= dqbuf.dqb_bsoftlimit)
495 dqbuf.dqb_btime = 0;
496 if (dqbuf.dqb_isoftlimit && id != 0 &&
497 dqbuf.dqb_curinodes < dqbuf.dqb_isoftlimit &&
498 fup->fu_curinodes >= dqbuf.dqb_isoftlimit)
499 dqbuf.dqb_itime = 0;
500 dqbuf.dqb_curinodes = fup->fu_curinodes;
501 dqbuf.dqb_curblocks = fup->fu_curblocks;
466 dqbuf.dqb_curinodes = fup->fu_curinodes;
467 dqbuf.dqb_curblocks = fup->fu_curblocks;
502 if (fseeko(qfo, offset, SEEK_SET) < 0) {
503 warn("%s: seek failed", quotafile);
504 return(1);
505 }
506 fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo);
507 (void) quotactl(fsname, QCMD(Q_SETUSE, type), id,
508 (caddr_t)&dqbuf);
468 (void) quota_write_usage(qf, &dqbuf, id);
509 fup->fu_curinodes = 0;
510 fup->fu_curblocks = 0;
511 }
512
513 /*
514 * Walk the hash table looking for ids with non-zero usage
515 * that are not currently recorded in the quota file. E.g.
516 * ids that are past the end of the current file.
517 */
469 fup->fu_curinodes = 0;
470 fup->fu_curblocks = 0;
471 }
472
473 /*
474 * Walk the hash table looking for ids with non-zero usage
475 * that are not currently recorded in the quota file. E.g.
476 * ids that are past the end of the current file.
477 */
518
519 for (i = 0; i < FUHASH; i++) {
520 for (fup = fuhead[type][i]; fup != NULL; fup = fup->fu_next) {
478 for (id = 0; id < FUHASH; id++) {
479 for (fup = fuhead[type][id]; fup != NULL; fup = fup->fu_next) {
521 if (fup->fu_id <= lastid)
522 continue;
523 if (fup->fu_curinodes == 0 && fup->fu_curblocks == 0)
524 continue;
525 bzero(&dqbuf, sizeof(struct dqblk));
526 if (fup->fu_id > highid)
527 highid = fup->fu_id;
480 if (fup->fu_id <= lastid)
481 continue;
482 if (fup->fu_curinodes == 0 && fup->fu_curblocks == 0)
483 continue;
484 bzero(&dqbuf, sizeof(struct dqblk));
485 if (fup->fu_id > highid)
486 highid = fup->fu_id;
528 printchanges(fsname, type, &dqbuf, fup, id);
487 printchanges(fsname, type, &dqbuf, fup, fup->fu_id);
529 dqbuf.dqb_curinodes = fup->fu_curinodes;
530 dqbuf.dqb_curblocks = fup->fu_curblocks;
488 dqbuf.dqb_curinodes = fup->fu_curinodes;
489 dqbuf.dqb_curblocks = fup->fu_curblocks;
531 offset = (off_t)fup->fu_id * sizeof(struct dqblk);
532 if (fseeko(qfo, offset, SEEK_SET) < 0) {
533 warn("%s: seek failed", quotafile);
534 return(1);
535 }
536 fwrite((char *)&dqbuf, sizeof(struct dqblk), 1, qfo);
537 (void) quotactl(fsname, QCMD(Q_SETUSE, type), id,
538 (caddr_t)&dqbuf);
490 (void) quota_write_usage(qf, &dqbuf, fup->fu_id);
539 fup->fu_curinodes = 0;
540 fup->fu_curblocks = 0;
541 }
542 }
491 fup->fu_curinodes = 0;
492 fup->fu_curblocks = 0;
493 }
494 }
543 fclose(qfi);
544 fflush(qfo);
545 ftruncate(fileno(qfo),
546 (((off_t)highid + 1) * sizeof(struct dqblk)));
547 fclose(qfo);
495 /*
496 * If this is old format file, then size may be smaller,
497 * so ensure that we only truncate when it will make things
498 * smaller, and not if it will grow an old format file.
499 */
500 if (highid < lastid &&
501 stat(quota_qfname(qf), &sb) == 0 &&
502 sb.st_size > (((off_t)highid + 2) * sizeof(struct dqblk)))
503 truncate(quota_qfname(qf),
504 (((off_t)highid + 2) * sizeof(struct dqblk)));
548 return (0);
549}
550
551/*
552 * Check to see if target appears in list of size cnt.
553 */
554int
555oneof(char *target, char *list[], int cnt)

--- 15 unchanged lines hidden (view full) ---

571 struct group *gr;
572
573 if ((gr = getgrnam(quotagroup)) != NULL)
574 return (gr->gr_gid);
575 return (-1);
576}
577
578/*
505 return (0);
506}
507
508/*
509 * Check to see if target appears in list of size cnt.
510 */
511int
512oneof(char *target, char *list[], int cnt)

--- 15 unchanged lines hidden (view full) ---

528 struct group *gr;
529
530 if ((gr = getgrnam(quotagroup)) != NULL)
531 return (gr->gr_gid);
532 return (-1);
533}
534
535/*
579 * Check to see if a particular quota is to be enabled.
580 */
581int
582hasquota(struct fstab *fs, int type, char **qfnamep)
583{
584 char *opt;
585 char *cp;
586 struct statfs sfb;
587 static char initname, usrname[100], grpname[100];
588 static char buf[BUFSIZ];
589
590 if (!initname) {
591 (void)snprintf(usrname, sizeof(usrname), "%s%s",
592 qfextension[USRQUOTA], qfname);
593 (void)snprintf(grpname, sizeof(grpname), "%s%s",
594 qfextension[GRPQUOTA], qfname);
595 initname = 1;
596 }
597 strcpy(buf, fs->fs_mntops);
598 for (opt = strtok(buf, ","); opt; opt = strtok(NULL, ",")) {
599 if ((cp = index(opt, '=')) != NULL)
600 *cp++ = '\0';
601 if (type == USRQUOTA && strcmp(opt, usrname) == 0)
602 break;
603 if (type == GRPQUOTA && strcmp(opt, grpname) == 0)
604 break;
605 }
606 if (!opt)
607 return (0);
608 if (cp)
609 *qfnamep = cp;
610 else {
611 (void)snprintf(buf, sizeof(buf), "%s/%s.%s", fs->fs_file,
612 qfname, qfextension[type]);
613 *qfnamep = buf;
614 }
615 if (statfs(fs->fs_file, &sfb) != 0) {
616 warn("cannot statfs mount point %s", fs->fs_file);
617 return (0);
618 }
619 if (strcmp(fs->fs_file, sfb.f_mntonname)) {
620 warnx("%s not mounted for %s quotas", fs->fs_file,
621 type == USRQUOTA ? "user" : "group");
622 return (0);
623 }
624 return (1);
625}
626
627/*
628 * Routines to manage the file usage table.
629 *
630 * Lookup an id of a specific type.
631 */
632struct fileusage *
633lookup(u_long id, int type)
634{
635 struct fileusage *fup;
636
637 for (fup = fuhead[type][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next)
638 if (fup->fu_id == id)
639 return (fup);
640 return (NULL);
641}
642
643/*
644 * Add a new file usage id if it does not already exist.
645 */
646struct fileusage *
536 * Routines to manage the file usage table.
537 *
538 * Lookup an id of a specific type.
539 */
540struct fileusage *
541lookup(u_long id, int type)
542{
543 struct fileusage *fup;
544
545 for (fup = fuhead[type][id & (FUHASH-1)]; fup != 0; fup = fup->fu_next)
546 if (fup->fu_id == id)
547 return (fup);
548 return (NULL);
549}
550
551/*
552 * Add a new file usage id if it does not already exist.
553 */
554struct fileusage *
647addid(u_long id, int type, char *name, char *fsname)
555addid(u_long id, int type, char *name, const char *fsname)
648{
649 struct fileusage *fup, **fhp;
650 int len;
651
652 if ((fup = lookup(id, type)) != NULL)
653 return (fup);
654 if (name)
655 len = strlen(name);

--- 118 unchanged lines hidden (view full) ---

774 read(fi, buf, cnt) != cnt)
775 errx(1, "bread failed on block %ld", (long)bno);
776}
777
778/*
779 * Display updated block and i-node counts.
780 */
781void
556{
557 struct fileusage *fup, **fhp;
558 int len;
559
560 if ((fup = lookup(id, type)) != NULL)
561 return (fup);
562 if (name)
563 len = strlen(name);

--- 118 unchanged lines hidden (view full) ---

682 read(fi, buf, cnt) != cnt)
683 errx(1, "bread failed on block %ld", (long)bno);
684}
685
686/*
687 * Display updated block and i-node counts.
688 */
689void
782printchanges(char *fsname, int type, struct dqblk *dp,
690printchanges(const char *fsname, int type, struct dqblk *dp,
783 struct fileusage *fup, u_long id)
784{
785 if (!vflag)
786 return;
787 if (aflag)
788 (void)printf("%s: ", fsname);
789 if (fup->fu_name[0] == '\0')
790 (void)printf("%-8lu fixed ", id);

--- 25 unchanged lines hidden ---
691 struct fileusage *fup, u_long id)
692{
693 if (!vflag)
694 return;
695 if (aflag)
696 (void)printf("%s: ", fsname);
697 if (fup->fu_name[0] == '\0')
698 (void)printf("%-8lu fixed ", id);

--- 25 unchanged lines hidden ---