From: Dave Chinner <dchinner@xxxxxxxxxx>
When we initial xfs_quota, we place lots of information into the
fs_table. This includes all the devices/mount points the user has
specified as a global command line parameter to report on, as well
as all the paths under project quota control.
There is a "current path" pointer (fs_path) maintained by the code
that points somewhere into the fs_table. After the table is
initialised, fs_path always points to the last entry in the table,
and hence has to be re-initialised to point at the desired entry
before it can be used properly.
In the case of xfs_quota, if the command passed on the command line
is a non-global command, the command is called multiple times, each
time after the libxcmd args_command() callback is run. That starts
with an index of 0, and until the callback returns zero it will keep
passing whatever the last returned value was into the callback.
xfs_quota supplies such a callback, and it's purpose is to iterate
over the fs_table setting fs_path to the next mount point in the
table. IOWs, non-global quota functions get called once for each
mount point specified on the command line. However, it also means
that for global functions, the fs_path pointer is not
re-initialised and hence if there are project quotas configured the
fs_path pointer does not point to a mount point andhence commands
The problem that demonstrated this is the report function. It does
it's own fs_table iteration if the command requires it, and so only
should be called once to avoid outputting the same information
multiple times. That's what the previous patch fixed by making the
command global, but this now has the effect of making commands that
need to operate on the device specified on the global command rely
on the fs_path variable pointing at that device.
Further, commands executed by the interactive method are always
treated as global commands, so the report command never worked as a
global command in the presence of a configured project quota setup.
Fix the problem by initialising the fs_path pointer correctly.
Signed-off-by: Dave Chinner <dchinner@xxxxxxxxxx>
quota/init.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/quota/init.c b/quota/init.c
index 3293b90..0b481f7 100644
@@ -140,6 +140,15 @@ init(
+ * Ensure that global commands don't end up with an invalid path pointer
+ * by setting the default device at the first specified on the CLI
+ if (argc != optind)
+ fs_path = fs_table_lookup(argv[optind], FS_MOUNT_POINT);
+ fs_path = &fs_table;