+// SPDX-License-Identifier: GPL-2.0
/*
- * Copyright (c) 2005 Silicon Graphics, Inc. All Rights Reserved.
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2 of the GNU General Public License as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Further, this software is distributed without any warranty that it is
- * free of the rightful claim of any third person regarding infringement
- * or the like. Any license provided herein, whether implied or
- * otherwise, applies only to this software file. Patent licenses, if
- * any, provided herein do not apply to combinations of this program with
- * other software, or any other product whatsoever.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write the Free Software Foundation, Inc., 59
- * Temple Place - Suite 330, Boston MA 02111-1307, USA.
- *
- * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
- * Mountain View, CA 94043, or:
- *
- * http://www.sgi.com
- *
- * For further information regarding this notice, see:
- *
- * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ * Copyright (c) 2005 Silicon Graphics, Inc.
+ * All Rights Reserved.
*/
-#include <xfs/command.h>
+#include <stdbool.h>
+#include "command.h"
#include "init.h"
#include "quota.h"
+#include "libfrog/logging.h"
+#include "libfrog/fsgeom.h"
static cmdinfo_t free_cmd;
"\n"));
}
+/*
+ * The data and realtime block counts returned (count, used, and
+ * free) are all in basic block units.
+ */
static int
mount_free_space_data(
struct fs_path *mount,
- __uint64_t *bcount,
- __uint64_t *bused,
- __uint64_t *bfree,
- __uint64_t *icount,
- __uint64_t *iused,
- __uint64_t *ifree,
- __uint64_t *rcount,
- __uint64_t *rused,
- __uint64_t *rfree)
+ uint64_t *bcount,
+ uint64_t *bused,
+ uint64_t *bfree,
+ uint64_t *icount,
+ uint64_t *iused,
+ uint64_t *ifree,
+ uint64_t *rcount,
+ uint64_t *rused,
+ uint64_t *rfree)
{
struct xfs_fsop_counts fscounts;
struct xfs_fsop_geom fsgeo;
struct statfs st;
- __uint64_t logsize, count, free;
- int fd;
+ uint64_t logsize, count, free;
+ int fd, ret;
if ((fd = open(mount->fs_dir, O_RDONLY)) < 0) {
+ exitcode = 1;
fprintf(stderr, "%s: cannot open %s: %s\n",
progname, mount->fs_dir, strerror(errno));
return 0;
close(fd);
return 0;
}
- if ((xfsctl(mount->fs_dir, fd, XFS_IOC_FSGEOMETRY_V1, &fsgeo)) < 0) {
- perror("XFS_IOC_FSGEOMETRY_V1");
- close(fd);
- return 0;
- }
- if ((xfsctl(mount->fs_dir, fd, XFS_IOC_FSCOUNTS, &fscounts)) < 0) {
- perror("XFS_IOC_FSCOUNTS");
- close(fd);
- return 0;
+
+ if (!(mount->fs_flags & FS_FOREIGN)) {
+ ret = -xfrog_geometry(fd, &fsgeo);
+ if (ret) {
+ xfrog_perror(ret, "XFS_IOC_FSGEOMETRY");
+ close(fd);
+ return 0;
+ }
+ if ((xfsctl(mount->fs_dir, fd, XFS_IOC_FSCOUNTS,
+ &fscounts)) < 0) {
+ perror("XFS_IOC_FSCOUNTS");
+ close(fd);
+ return 0;
+ }
+
+ logsize = fsgeo.logstart ? fsgeo.logblocks : 0;
+ count = (fsgeo.datablocks - logsize) * fsgeo.blocksize;
+ free = fscounts.freedata * fsgeo.blocksize;
+ *bcount = BTOBB(count);
+ *bfree = BTOBB(free);
+ *bused = BTOBB(count - free);
+
+ count = fsgeo.rtextents * fsgeo.rtextsize * fsgeo.blocksize;
+ free = fscounts.freertx * fsgeo.rtextsize * fsgeo.blocksize;
+ *rcount = BTOBB(count);
+ *rfree = BTOBB(free);
+ *rused = BTOBB(count - free);
+ } else {
+ count = st.f_blocks * st.f_bsize;
+ free = st.f_bfree * st.f_bsize;
+ *bcount = BTOBB(count);
+ *bfree = BTOBB(free);
+ *bused = BTOBB(count - free);
+
+ *rcount = BTOBB(0);
+ *rfree = BTOBB(0);
+ *rused = BTOBB(0);
}
- logsize = fsgeo.logstart ? fsgeo.logblocks : 0;
- count = (fsgeo.datablocks - logsize) * fsgeo.blocksize;
- free = fscounts.freedata * fsgeo.blocksize;
- *bcount = BTOBB(count);
- *bfree = BTOBB(free);
- *bused = BTOBB(count - free);
*icount = st.f_files;
*ifree = st.f_ffree;
*iused = st.f_files - st.f_ffree;
- count = fsgeo.rtextents * fsgeo.rtextsize;
- free = fscounts.freertx * fsgeo.rtextsize;
- *rcount = BTOBB(count);
- *rfree = BTOBB(free);
- *rused = BTOBB(count - free);
-
close(fd);
return 1;
}
+/*
+ * The data and realtime block counts returned (count, used, and
+ * free) are all in basic block units.
+ */
static int
projects_free_space_data(
struct fs_path *path,
- __uint64_t *bcount,
- __uint64_t *bused,
- __uint64_t *bfree,
- __uint64_t *icount,
- __uint64_t *iused,
- __uint64_t *ifree,
- __uint64_t *rcount,
- __uint64_t *rused,
- __uint64_t *rfree)
+ uint64_t *bcount,
+ uint64_t *bused,
+ uint64_t *bfree,
+ uint64_t *icount,
+ uint64_t *iused,
+ uint64_t *ifree,
+ uint64_t *rcount,
+ uint64_t *rused,
+ uint64_t *rfree)
{
+ fs_quota_stat_t qfs;
fs_disk_quota_t d;
struct fsxattr fsx;
uint type = XFS_PROJ_QUOTA;
char *dev = path->fs_name;
int fd;
+ if (xfsquotactl(XFS_GETQSTAT, dev, type, 0, &qfs) < 0 ||
+ !(qfs.qs_flags & XFS_QUOTA_PDQ_ACCT))
+ return 0;
+
if ((fd = open(path->fs_dir, O_RDONLY)) < 0) {
+ exitcode = 1;
fprintf(stderr, "%s: cannot open %s: %s\n",
progname, path->fs_dir, strerror(errno));
return 0;
}
- if ((xfsctl(path->fs_dir, fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
- perror("XFS_IOC_FSGETXATTR");
+ if ((xfsctl(path->fs_dir, fd, FS_IOC_FSGETXATTR, &fsx)) < 0) {
+ exitcode = 1;
+ perror("FS_IOC_FSGETXATTR");
close(fd);
return 0;
}
- if (!(fsx.fsx_xflags & XFS_XFLAG_PROJINHERIT)) {
+ if (!(fsx.fsx_xflags & FS_XFLAG_PROJINHERIT)) {
+ exitcode = 1;
fprintf(stderr, _("%s: project quota flag not set on %s\n"),
progname, path->fs_dir);
close(fd);
}
if (path->fs_prid != fsx.fsx_projid) {
+ exitcode = 1;
fprintf(stderr,
_("%s: project ID %u (%s) doesn't match ID %u (%s)\n"),
progname, path->fs_prid, projects_file,
}
if (d.d_blk_softlimit) {
- *bcount = d.d_blk_softlimit << 1;
- *bfree = (d.d_blk_softlimit - d.d_bcount) << 1;
+ *bcount = d.d_blk_softlimit;
+ *bfree = (d.d_blk_softlimit - d.d_bcount);
}
- *bused = d.d_bcount << 1;
+ *bused = d.d_bcount;
+
if (d.d_ino_softlimit) {
*icount = d.d_ino_softlimit;
*ifree = (d.d_ino_softlimit - d.d_icount);
}
*iused = d.d_icount;
+
if (d.d_rtb_softlimit) {
- *rcount = d.d_rtb_softlimit << 1;
- *rfree = (d.d_rtb_softlimit - d.d_rtbcount) << 1;
+ *rcount = d.d_rtb_softlimit;
+ *rfree = (d.d_rtb_softlimit - d.d_rtbcount);
}
- *rcount = d.d_rtbcount << 1;
+ *rused = d.d_rtbcount;
close(fd);
return 1;
fs_path_t *path,
uint flags)
{
- __uint64_t bcount, bused, bfree;
- __uint64_t icount, iused, ifree;
- __uint64_t rcount, rused, rfree;
+ uint64_t bcount, bused, bfree;
+ uint64_t icount, iused, ifree;
+ uint64_t rcount, rused, rfree;
char a[8], s[8], u[8], p[8];
int count;
free_space_list(
FILE *fp,
uint form,
- uint type,
char *dir,
uint flags)
{
fs_cursor_t cursor;
fs_path_t *path;
- fs_cursor_initialise(dir, type, &cursor);
+ fs_cursor_initialise(dir, 0, &cursor);
while ((path = fs_cursor_next_entry(&cursor))) {
if (free_space(fp, form, path, flags))
flags |= NO_HEADER_FLAG;
{
FILE *fp = NULL;
char *fname = NULL;
- int c, flags = 0, form = 0, type = 0;
+ int c, flags = 0, form = 0;
while ((c = getopt(argc, argv, "bf:hNir")) != EOF) {
switch (c) {
if (!form)
form = XFS_BLOCK_QUOTA;
- if (!type)
- type = FS_MOUNT_POINT|FS_PROJECT_PATH;
-
if ((fp = fopen_write_secure(fname)) == NULL)
return 0;
if (argc == optind)
- free_space_list(fp, form, type, NULL, flags);
+ free_space_list(fp, form, NULL, flags);
else while (argc > optind)
- free_space_list(fp, form, type, argv[optind++], flags);
+ free_space_list(fp, form, argv[optind++], flags);
if (fname)
fclose(fp);
void
free_init(void)
{
- free_cmd.name = _("df");
- free_cmd.altname = _("free");
+ free_cmd.name = "df";
+ free_cmd.altname = "free";
free_cmd.cfunc = free_f;
free_cmd.argmin = 0;
free_cmd.argmax = -1;
- free_cmd.args = _("[-bir] [-hn] [-f file]");
+ free_cmd.args = _("[-bir] [-hN] [-f file]");
free_cmd.oneline = _("show free and used counts for blocks and inodes");
free_cmd.help = free_help;
+ free_cmd.flags = CMD_FLAG_FOREIGN_OK;
add_command(&free_cmd);
}