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 --- |