mirror of
https://git.FreeBSD.org/src.git
synced 2024-11-25 07:49:18 +00:00
Add and document the quota_convert function which converts between the
old 32-bit and the new 64-bit formats.
This commit is contained in:
parent
3af26d4abb
commit
aee785babd
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/projects/quota64/; revision=201144
@ -154,6 +154,7 @@ int quota_check_path(const struct quotafile *, const char *path);
|
||||
int quota_read(struct quotafile *, struct dqblk *, int);
|
||||
int quota_write_limits(struct quotafile *, struct dqblk *, int);
|
||||
int quota_write_usage(struct quotafile *, struct dqblk *, int);
|
||||
int quota_convert(struct quotafile *, int);
|
||||
#endif
|
||||
|
||||
__END_DECLS
|
||||
|
@ -1,6 +1,6 @@
|
||||
.\"-
|
||||
.\" Copyright (c) 2008 Dag-Erling Coïdan Smørgrav
|
||||
.\" All rights reserved.
|
||||
.\" Copyright (c) 2009 Dag-Erling Coïdan Smørgrav and
|
||||
.\" Marshall Kirk McKusick. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
@ -25,7 +25,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 26, 2009
|
||||
.Dd December 28, 2009
|
||||
.Dt QUOTAFILE 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -40,6 +40,7 @@
|
||||
.Nm quota_qfname
|
||||
.Nm quota_maxid
|
||||
.Nm quota_check_path
|
||||
.Nm quota_convert
|
||||
.Nd "Manipulate quotas"
|
||||
.Sh LIBRARY
|
||||
.Lb libutil
|
||||
@ -72,6 +73,8 @@
|
||||
.Fn quota_maxid "const struct quotafile *qf"
|
||||
.Ft int
|
||||
.Fn quota_check_path "const struct quotafile *qf" "const char *path"
|
||||
.Ft int
|
||||
.Fn quota_convert "struct quotafile *qf" "int wordsize"
|
||||
.Sh DESCRIPTION
|
||||
These functions are designed to simplify access to filesystem quotas.
|
||||
If quotas are active on a filesystem,
|
||||
@ -219,9 +222,23 @@ If the
|
||||
argument refers to a symbolic link,
|
||||
.Fn quota_check_path
|
||||
will follow it.
|
||||
.Pp
|
||||
The
|
||||
.Fn quota_convert
|
||||
function converts the quota file associated with its
|
||||
.Va qf
|
||||
argument to the data size specified by its
|
||||
.Va wordsize
|
||||
argument.
|
||||
The supported wordsize arguments are 32 for the old 32-bit
|
||||
quota file format and 64 for the new 64-bit quota file format.
|
||||
The
|
||||
.Fn quota_convert
|
||||
function may only be called to operate on quota files that
|
||||
are not currently active.
|
||||
.Sh IMPLEMENTATION NOTES
|
||||
If the underlying quota file is in the old 32-bit format, limit and
|
||||
usage values written to the quota file will be clipped to 32 bits.
|
||||
If the underlying quota file is in or converted to the old 32-bit format,
|
||||
limit and usage values written to the quota file will be clipped to 32 bits.
|
||||
.Sh RETURN VALUES
|
||||
If the filesystem has quotas associated with it,
|
||||
.Fn quota_open
|
||||
@ -246,6 +263,7 @@ The
|
||||
.Fn quota_read ,
|
||||
.Fn quota_write_limits ,
|
||||
.Fn quota_write_usage ,
|
||||
.Fn quota_convert ,
|
||||
and
|
||||
.Fn quota_close
|
||||
functions return zero on success.
|
||||
@ -259,13 +277,13 @@ to indicate the error.
|
||||
.Xr quota.group 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
.Nm quotafile
|
||||
functions first appeared in
|
||||
.Fx 8.0 .
|
||||
.Fx 8.1 .
|
||||
.Sh AUTHORS
|
||||
.An -nosplit
|
||||
The
|
||||
.Nm
|
||||
.Nm quotafile
|
||||
functions and this manual page were written by
|
||||
.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org
|
||||
and
|
||||
|
@ -255,9 +255,9 @@ quota_maxid(struct quotafile *qf)
|
||||
return (0);
|
||||
switch (qf->wordsize) {
|
||||
case 32:
|
||||
return (st.st_size / sizeof(struct dqblk32));
|
||||
return (st.st_size / sizeof(struct dqblk32) - 1);
|
||||
case 64:
|
||||
return (st.st_size / sizeof(struct dqblk64) - 1);
|
||||
return (st.st_size / sizeof(struct dqblk64) - 2);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
@ -494,3 +494,98 @@ quota_write_limits(struct quotafile *qf, struct dqblk *dqb, int id)
|
||||
}
|
||||
/* not reached */
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a quota file from one format to another.
|
||||
*/
|
||||
int
|
||||
quota_convert(struct quotafile *qf, int wordsize)
|
||||
{
|
||||
struct quotafile *newqf;
|
||||
struct dqhdr64 dqh;
|
||||
struct dqblk dqblk;
|
||||
struct group *grp;
|
||||
int serrno, maxid, id, fd;
|
||||
|
||||
/*
|
||||
* Quotas must not be active and quotafile must be open
|
||||
* for reading and writing.
|
||||
*/
|
||||
if ((qf->accmode & O_RDWR) != O_RDWR || qf->fd == -1) {
|
||||
errno = EBADF;
|
||||
return (-1);
|
||||
}
|
||||
if ((wordsize != 32 && wordsize != 64) ||
|
||||
wordsize == qf->wordsize) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
maxid = quota_maxid(qf);
|
||||
if ((newqf = calloc(1, sizeof(*qf))) == NULL) {
|
||||
errno = ENOMEM;
|
||||
return (-1);
|
||||
}
|
||||
*newqf = *qf;
|
||||
snprintf(newqf->qfname, MAXPATHLEN + 1, "%s_%d.orig", qf->qfname,
|
||||
qf->wordsize);
|
||||
if (rename(qf->qfname, newqf->qfname) < 0) {
|
||||
free(newqf);
|
||||
return (-1);
|
||||
}
|
||||
if ((newqf->fd = open(qf->qfname, O_RDWR|O_CREAT|O_TRUNC, 0)) < 0) {
|
||||
serrno = errno;
|
||||
goto error;
|
||||
}
|
||||
newqf->wordsize = wordsize;
|
||||
if (wordsize == 64) {
|
||||
memset(&dqh, 0, sizeof(dqh));
|
||||
memcpy(dqh.dqh_magic, Q_DQHDR64_MAGIC, sizeof(dqh.dqh_magic));
|
||||
dqh.dqh_version = htobe32(Q_DQHDR64_VERSION);
|
||||
dqh.dqh_hdrlen = htobe32(sizeof(struct dqhdr64));
|
||||
dqh.dqh_reclen = htobe32(sizeof(struct dqblk64));
|
||||
if (write(newqf->fd, &dqh, sizeof(dqh)) != sizeof(dqh)) {
|
||||
serrno = errno;
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
grp = getgrnam(QUOTAGROUP);
|
||||
fchown(newqf->fd, 0, grp ? grp->gr_gid : 0);
|
||||
fchmod(newqf->fd, 0640);
|
||||
for (id = 0; id <= maxid; id++) {
|
||||
if ((quota_read(qf, &dqblk, id)) < 0)
|
||||
break;
|
||||
switch (newqf->wordsize) {
|
||||
case 32:
|
||||
if ((quota_write32(newqf, &dqblk, id)) < 0)
|
||||
break;
|
||||
continue;
|
||||
case 64:
|
||||
if ((quota_write64(newqf, &dqblk, id)) < 0)
|
||||
break;
|
||||
continue;
|
||||
default:
|
||||
errno = EINVAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (id < maxid) {
|
||||
serrno = errno;
|
||||
goto error;
|
||||
}
|
||||
/*
|
||||
* Update the passed in quotafile to reference the new file
|
||||
* of the converted format size.
|
||||
*/
|
||||
fd = qf->fd;
|
||||
qf->fd = newqf->fd;
|
||||
newqf->fd = fd;
|
||||
qf->wordsize = newqf->wordsize;
|
||||
quota_close(newqf);
|
||||
return (0);
|
||||
error:
|
||||
/* put back the original file */
|
||||
(void) rename(newqf->qfname, qf->qfname);
|
||||
quota_close(newqf);
|
||||
errno = serrno;
|
||||
return (-1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user