mirror of
https://github.com/freebsd/freebsd-src
synced 2024-10-15 12:54:27 +00:00
If quotas are not currently enabled for a file system, edquota -p
will operate directly on the quota file. It will incorrectly write the prototype user's usage information for each new quota it sets. Fixed to read in the current quota information and update the file correctly. If quotas are enabled the kernel handles this case fine. PR: bin/15410
This commit is contained in:
parent
055867a06c
commit
dbbc0c8312
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=166480
|
@ -375,7 +375,13 @@ getprivs(id, quotatype, fspath)
|
|||
getentry(quotagroup, GRPQUOTA));
|
||||
(void) fchmod(fd, 0640);
|
||||
}
|
||||
lseek(fd, (long)(id * sizeof(struct dqblk)), L_SET);
|
||||
if (lseek(fd, (off_t)id * sizeof(struct dqblk),
|
||||
L_SET) < 0) {
|
||||
warn("seek error on %s", qfpathname);
|
||||
close(fd);
|
||||
free(qup);
|
||||
continue;
|
||||
}
|
||||
switch (read(fd, &qup->dqblk, sizeof(struct dqblk))) {
|
||||
case 0: /* EOF */
|
||||
/*
|
||||
|
@ -421,21 +427,70 @@ putprivs(id, quotatype, quplist)
|
|||
{
|
||||
register struct quotause *qup;
|
||||
int qcmd, fd;
|
||||
struct dqblk dqbuf;
|
||||
|
||||
qcmd = QCMD(Q_SETQUOTA, quotatype);
|
||||
for (qup = quplist; qup; qup = qup->next) {
|
||||
if (quotactl(qup->fsname, qcmd, id, &qup->dqblk) == 0)
|
||||
continue;
|
||||
if ((fd = open(qup->qfname, O_WRONLY)) < 0) {
|
||||
if ((fd = open(qup->qfname, O_RDWR)) < 0) {
|
||||
warn("%s", qup->qfname);
|
||||
} else {
|
||||
lseek(fd, (long)id * (long)sizeof (struct dqblk), 0);
|
||||
if (write(fd, &qup->dqblk, sizeof (struct dqblk)) !=
|
||||
sizeof (struct dqblk)) {
|
||||
warn("%s", qup->qfname);
|
||||
}
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
if (lseek(fd, (off_t)id * sizeof(struct dqblk), L_SET) < 0) {
|
||||
warn("seek error on %s", qup->qfname);
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
switch (read(fd, &dqbuf, sizeof(struct dqblk))) {
|
||||
case 0: /* EOF */
|
||||
/*
|
||||
* Convert implicit 0 quota (EOF)
|
||||
* into an explicit one (zero'ed dqblk)
|
||||
*/
|
||||
bzero(&dqbuf, sizeof(struct dqblk));
|
||||
break;
|
||||
|
||||
case sizeof(struct dqblk): /* OK */
|
||||
break;
|
||||
|
||||
default: /* ERROR */
|
||||
warn("read error in %s", qup->qfname);
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Reset time limit if have a soft limit and were
|
||||
* previously under it, but are now over it
|
||||
* or if there previously was no soft limit, but
|
||||
* now have one and are over it.
|
||||
*/
|
||||
if (dqbuf.dqb_bsoftlimit && id != 0 &&
|
||||
dqbuf.dqb_curblocks < dqbuf.dqb_bsoftlimit &&
|
||||
dqbuf.dqb_curblocks >= qup->dqblk.dqb_bsoftlimit)
|
||||
qup->dqblk.dqb_btime = 0;
|
||||
if (dqbuf.dqb_bsoftlimit == 0 && id != 0 &&
|
||||
dqbuf.dqb_curblocks >= qup->dqblk.dqb_bsoftlimit)
|
||||
qup->dqblk.dqb_btime = 0;
|
||||
if (dqbuf.dqb_isoftlimit && id != 0 &&
|
||||
dqbuf.dqb_curinodes < dqbuf.dqb_isoftlimit &&
|
||||
dqbuf.dqb_curinodes >= qup->dqblk.dqb_isoftlimit)
|
||||
qup->dqblk.dqb_itime = 0;
|
||||
if (dqbuf.dqb_isoftlimit == 0 && id !=0 &&
|
||||
dqbuf.dqb_curinodes >= qup->dqblk.dqb_isoftlimit)
|
||||
qup->dqblk.dqb_itime = 0;
|
||||
qup->dqblk.dqb_curinodes = dqbuf.dqb_curinodes;
|
||||
qup->dqblk.dqb_curblocks = dqbuf.dqb_curblocks;
|
||||
if (lseek(fd, (off_t)id * sizeof(struct dqblk), L_SET) < 0) {
|
||||
warn("seek error on %s", qup->qfname);
|
||||
close(fd);
|
||||
continue;
|
||||
}
|
||||
if (write(fd, &qup->dqblk, sizeof (struct dqblk)) !=
|
||||
sizeof (struct dqblk)) {
|
||||
warn("%s", qup->qfname);
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue