]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_quota: add support for passing project paths on cmdline
authorArkadiusz Miśkiewicz <arekm@maven.pl>
Thu, 29 Jan 2009 21:57:34 +0000 (22:57 +0100)
committerChristoph Hellwig <hch@brick.lst.de>
Thu, 29 Jan 2009 21:57:34 +0000 (22:57 +0100)
/etc/project is currently required for using project quota. This
patch adds ability to specify paths at command line.

fs_table_insert_project_path() introduced in libxcmd. Allows to insert
arbitrary path to fs_* iterating engine. We insert our paths with
-1 as project id (because we know no "original" id for this path
and generally this knowledge is not needed).

New option introduced for paths passing - project -p <path>.

Example:
$ sudo rm -f /etc/projects /etc/projid

$ sudo ./xfs_quota -x -c "project -p /tmp/xx -s 60"
Setting up project 60 (path /tmp/xx)...
Processed 1 (/etc/projects and cmdline) paths for project 60 with
recursion depth infinite (-1).

$ sudo ./xfs_quota -x -c "project -p /tmp/xx -c 60"
Checking project 60 (path /tmp/xx)...
Processed 1 (/etc/projects and cmdline) paths for project 60 with
recursion depth infinite (-1).

$ sudo ./xfs_quota -x -c "project -p /tmp/xx -c 70"
Checking project 70 (path /tmp/xx)...
/tmp/xx - project identifier is not set (inode=60, tree=70)
/tmp/xx/file1 - project identifier is not set (inode=60, tree=70)
/tmp/xx/file2 - project identifier is not set (inode=60, tree=70)
/tmp/xx/file3 - project identifier is not set (inode=60, tree=70)
/tmp/xx/dir1 - project identifier is not set (inode=60, tree=70)
/tmp/xx/dir2 - project identifier is not set (inode=60, tree=70)
Processed 1 (/etc/projects and cmdline) paths for project 70 with
recursion depth infinite (-1).

$ sudo ./xfs_quota -x -c "project -p /tmp/xx -s 70"
Setting up project 70 (path /tmp/xx)...
Processed 1 (/etc/projects and cmdline) paths for project 70 with
recursion depth infinite (-1).

$ sudo ./xfs_quota -x -c "project -p /tmp/xx -c 70"
Checking project 70 (path /tmp/xx)...
Processed 1 (/etc/projects and cmdline) paths for project 70 with
recursion depth infinite (-1).

Signed-off-by: Arkadiusz Miśkiewicz <arekm@maven.pl>
Reviewed-by: Donald Douwsma <ddouwsma@bigpond.net.au>
Reviewed-by: Christoph Hellwig <hch@lst.de>
include/path.h
libxcmd/paths.c
quota/project.c

index 6bf7338f0aa7314edb80ecfd9348ffe522a91e57..b8c8b31587c5a95b8c387df4b7f46be0187351b6 100644 (file)
@@ -52,6 +52,8 @@ extern void fs_table_destroy(void);
 
 extern void fs_table_insert_mount(char *__mount);
 extern void fs_table_insert_project(char *__project);
+extern void fs_table_insert_project_path(char *__dir, uint __projid);
+
 
 extern fs_path_t *fs_table_lookup(const char *__dir, uint __flags);
 
index b84720a8c607724e7ceb52d7039d0191e9d5ec25..369c071fd11ff23ebf1c2dda2ff1768195554753 100644 (file)
@@ -402,6 +402,36 @@ fs_table_insert_project(
        }
 }
 
+void 
+fs_table_insert_project_path(
+       char            *udir,
+       prid_t          prid)
+{
+       fs_path_t       *fs;
+       char            *dir = NULL, *fsname = NULL;
+       int             error = 0;
+
+       if ((fs = fs_mount_point_from_path(udir)) != NULL) {
+               dir = strdup(udir);
+               fsname = strdup(fs->fs_name);
+               if (dir && fsname)
+                       error = fs_table_insert(dir, prid,
+                                       FS_PROJECT_PATH, fsname, NULL, NULL);
+               else
+                       error = ENOMEM;
+       } else
+               error = ENOENT;
+
+       if (error) {
+               if (dir)
+                       free(dir);
+               if (fsname)
+                       free(fsname);
+               fprintf(stderr, _("%s: cannot setup path for project dir %s: %s\n"),
+                               progname, udir, strerror(error));
+               exit(1);
+       }
+}
 /*
  * Table iteration (cursor-based) interfaces
  */
index f2ff19be45a1f8c98f21632d1cfa90928da11d86..151016c487dc5a1a59970c24feac303f063bfb08 100644 (file)
@@ -76,6 +76,11 @@ project_help(void)
 " which do not have the project ID of the rest of the tree, or if the inode\n"
 " flag is not set.\n"
 "\n"
+" The -p <path> option can be used to manually specify project path without\n"
+" need to create /etc/projects file. This option can be used multiple times\n"
+" to specify multiple paths. When using this option only one projid/name can\n"
+" be specified at command line. Note that /etc/projects is also used if exists.\n"
+"\n"
 " The -d <depth> option allows to descend at most <depth> levels of directories\n"
 " below the command line arguments. -d 0 means only apply the actions\n"
 " to the top level of the projects. -d -1 means no recursion limit (default).\n"
@@ -257,13 +262,13 @@ project(
 
        fs_cursor_initialise(NULL, FS_PROJECT_PATH, &cursor);
        while ((path = fs_cursor_next_entry(&cursor))) {
-               if (prid != path->fs_prid)
+               if (prid != path->fs_prid && path->fs_prid != -1)
                        continue;
                project_operations(project, path->fs_dir, type);
                count++;
        }
 
-       printf(_("Processed %d %s paths for project %s with recursion depth %s (%d)\n"),
+       printf(_("Processed %d (%s and cmdline) paths for project %s with recursion depth %s (%d).\n"),
                 count, projects_file, project,
                 recurse_depth < 0 ? _("infinite") : _("limited"), recurse_depth);
 }
@@ -273,9 +278,9 @@ project_f(
        int             argc,
        char            **argv)
 {
-       int             c, type = 0;
+       int             c, type = 0, ispath = 0;
 
-       while ((c = getopt(argc, argv, "cd:sC")) != EOF) {
+       while ((c = getopt(argc, argv, "cd:p:sC")) != EOF) {
                switch (c) {
                case 'c':
                        type = CHECK_PROJECT;
@@ -285,6 +290,10 @@ project_f(
                        if (recurse_depth < 0)
                                recurse_depth = -1;
                        break;
+               case 'p':
+                       ispath = 1;
+                       fs_table_insert_project_path(optarg, -1);
+                       break;
                case 's':
                        type = SETUP_PROJECT;
                        break;
@@ -304,13 +313,20 @@ project_f(
                type = CHECK_PROJECT;
 
        setprfiles();
-       if (access(projects_file, F_OK) != 0) {
+       if (!ispath && access(projects_file, F_OK) != 0) {
                exitcode = 1;
                fprintf(stderr, _("projects file \"%s\" doesn't exist\n"),
                        projects_file);
                return 0;
        }
 
+       if (ispath && argc - optind > 1) {
+               exitcode = 1;
+               fprintf(stderr, _("%s: only one projid/name can be specified when using -p <path>, %d found.\n"),
+                               progname, argc - optind);
+               return 0;
+       }
+
         while (argc > optind) {
                prid = prid_from_string(argv[optind]);
                if (prid == -1) {
@@ -331,7 +347,7 @@ project_init(void)
        project_cmd.name = _("project");
        project_cmd.altname = _("tree");
        project_cmd.cfunc = project_f;
-       project_cmd.args = _("[-c|-s|-C|-d <depth>] project ...");
+       project_cmd.args = _("[-c|-s|-C|-d <depth>|-p <path>] project ...");
        project_cmd.argmin = 1;
        project_cmd.argmax = -1;
        project_cmd.oneline = _("check, setup or clear project quota trees");