]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/blobdiff - quota/report.c
xfs: fix maxicount division by zero error
[thirdparty/xfsprogs-dev.git] / quota / report.c
index 48a3f2913476def70090a9842905cd75c26abf37..e6def916b82792dc4f44c69c59ffc6a4f95a5f26 100644 (file)
@@ -1,21 +1,9 @@
+// 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 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.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write the Free Software Foundation,
- * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  */
-
+#include <stdbool.h>
 #include "command.h"
 #include <sys/types.h>
 #include <pwd.h>
@@ -90,14 +78,20 @@ dump_file(
        else
                cmd = XFS_GETQUOTA;
 
+       /* Fall back silently if XFS_GETNEXTQUOTA fails, warn on XFS_GETQUOTA */
        if (xfsquotactl(cmd, dev, type, id, (void *)&d) < 0) {
-               if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
+               if (errno != ENOENT && errno != ENOSYS && errno != ESRCH &&
+                   cmd == XFS_GETQUOTA)
                        perror("XFS_GETQUOTA");
                return 0;
        }
 
-       if (oid)
+       if (oid) {
                *oid = d.d_id;
+               /* Did kernelspace wrap? */
+               if (*oid < id)
+                       return 0;
+       }
 
        if (!d.d_blk_softlimit && !d.d_blk_hardlimit &&
            !d.d_ino_softlimit && !d.d_ino_hardlimit &&
@@ -327,9 +321,9 @@ report_header(
 static int
 report_mount(
        FILE            *fp,
-       __uint32_t      id,
+       uint32_t        id,
        char            *name,
-       __uint32_t      *oid,
+       uint32_t        *oid,
        uint            form,
        uint            type,
        fs_path_t       *mount,
@@ -347,14 +341,20 @@ report_mount(
        else
                cmd = XFS_GETQUOTA;
 
+       /* Fall back silently if XFS_GETNEXTQUOTA fails, warn on XFS_GETQUOTA*/
        if (xfsquotactl(cmd, dev, type, id, (void *)&d) < 0) {
-               if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
+               if (errno != ENOENT && errno != ENOSYS && errno != ESRCH &&
+                   cmd == XFS_GETQUOTA)
                        perror("XFS_GETQUOTA");
                return 0;
        }
 
-       if (oid)
+       if (oid) {
                *oid = d.d_id;
+               /* Did kernelspace wrap? */
+               if (* oid < id)
+                       return 0;
+       }
 
        if (flags & TERSE_FLAG) {
                count = 0;
@@ -389,7 +389,11 @@ report_mount(
                                        name = p->pr_name;
                        }
                }
-               fprintf(fp, "%-10s", name);
+               /* If no name is found, print the id #num instead of (null) */
+               if (name != NULL)
+                       fprintf(fp, "%-10s", name);
+               else
+                       fprintf(fp, "#%-9u", d.d_id);
        }
 
        if (form & XFS_BLOCK_QUOTA) {
@@ -571,6 +575,16 @@ report_project_mount(
                        id = oid + 1;
                }
        } else {
+               if (!getprprid(0)) {
+                       /*
+                        * Print default project quota, even if projid 0
+                        * isn't defined
+                        */
+                       if (report_mount(fp, 0, NULL, NULL,
+                                       form, XFS_PROJ_QUOTA, mount, flags))
+                               flags |= NO_HEADER_FLAG;
+               }
+
                setprent();
                while ((p = getprent()) != NULL) {
                        if (report_mount(fp, p->pr_prid, p->pr_name, NULL,
@@ -600,6 +614,8 @@ report_any_type(
        if (type & XFS_USER_QUOTA) {
                fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
                while ((mount = fs_cursor_next_entry(&cursor))) {
+                       if (!foreign_allowed && (mount->fs_flags & FS_FOREIGN))
+                               continue;
                        if (xfsquotactl(XFS_QSYNC, mount->fs_name,
                                                XFS_USER_QUOTA, 0, NULL) < 0
                                        && errno != ENOENT && errno != ENOSYS)
@@ -611,6 +627,8 @@ report_any_type(
        if (type & XFS_GROUP_QUOTA) {
                fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
                while ((mount = fs_cursor_next_entry(&cursor))) {
+                       if (!foreign_allowed && (mount->fs_flags & FS_FOREIGN))
+                               continue;
                        if (xfsquotactl(XFS_QSYNC, mount->fs_name,
                                                XFS_GROUP_QUOTA, 0, NULL) < 0
                                        && errno != ENOENT && errno != ENOSYS)
@@ -622,6 +640,8 @@ report_any_type(
        if (type & XFS_PROJ_QUOTA) {
                fs_cursor_initialise(dir, FS_MOUNT_POINT, &cursor);
                while ((mount = fs_cursor_next_entry(&cursor))) {
+                       if (!foreign_allowed && (mount->fs_flags & FS_FOREIGN))
+                               continue;
                        if (xfsquotactl(XFS_QSYNC, mount->fs_name,
                                                XFS_PROJ_QUOTA, 0, NULL) < 0
                                        && errno != ENOENT && errno != ENOSYS)
@@ -736,16 +756,17 @@ report_init(void)
        dump_cmd.args = _("[-g|-p|-u] [-f file]");
        dump_cmd.oneline = _("dump quota information for backup utilities");
        dump_cmd.help = dump_help;
+       dump_cmd.flags = CMD_FLAG_FOREIGN_OK;
 
        report_cmd.name = "report";
        report_cmd.altname = "repquota";
        report_cmd.cfunc = report_f;
        report_cmd.argmin = 0;
        report_cmd.argmax = -1;
-       report_cmd.flags = CMD_FLAG_GLOBAL;
        report_cmd.args = _("[-bir] [-gpu] [-ahnt] [-f file]");
        report_cmd.oneline = _("report filesystem quota information");
        report_cmd.help = report_help;
+       report_cmd.flags = CMD_FLAG_ONESHOT | CMD_FLAG_FOREIGN_OK;
 
        if (expert) {
                add_command(&dump_cmd);