[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH]: xfs project quota id support
From: |
Arkadiusz Miskiewicz |
Subject: |
[PATCH]: xfs project quota id support |
Date: |
Mon, 11 Oct 2010 10:43:05 +0200 |
User-agent: |
KMail/1.13.5 (Linux/2.6.36-rc7; KDE/4.5.2; x86_64; ; ) |
Hi,
Long time ago I've submitted xfs project quota id support
through patches interface (https://savannah.gnu.org/patch/?6698).
Topic isn't exciting as I got no comments ;)
Anyway I would like to clean up the patch and make it into mergeable
state iif such feature patches have a chance to be merged.
Little review of the patch would be welcome.
Thanks,
From 11745d10f0c0c702716b7d40ecd3c2a7e5994313 Mon Sep 17 00:00:00 2001
From: Arkadiusz Miskiewicz <address@hidden>
Date: Tue, 16 Dec 2008 17:12:55 +0100
Subject: [PATCH] find: "XFS project quota" support
XFS filesystem provides three different quota types. UID-based,
GID-based and "project quota" path name based.
Add support for test parameter "-xfsprojquota N" which allows
looking for files with specified project quota ID.
Add support for "%q" format which allows project quota ID
to be displayed.
Note that issuing ioctl(2) requires file to be open(2) which
is bad for some type of files (exclude these as xfs_quota does).
Example:
$ ./find /home/users/arekm/xtest -printf "name=%f projquotaid=%q\n"
name=xtest projquotaid=0
name=proj50 projquotaid=50
name=aaa projquotaid=50
name=aaadsfdsf projquotaid=50
name=something projquotaid=50
name=34knjf projquotaid=50
name=proj60 projquotaid=60
name=34knjf projquotaid=60
name=34knjfwenhwjqe projquotaid=60
name=dsfdsfknjfwenhwjqe projquotaid=60
name=proj70 projquotaid=70
name=7sfdsfdsf projquotaid=70
name=7sf4344 projquotaid=70
name=7sf4344ad projquotaid=70
$ ./find /home/users/arekm/xtest -xfsprojquota 50
/home/users/arekm/xtest/proj50
/home/users/arekm/xtest/proj50/aaa
/home/users/arekm/xtest/proj50/aaadsfdsf
/home/users/arekm/xtest/proj50/something
/home/users/arekm/xtest/proj50/34knjf
---
find/defs.h | 25 +++++++++++++++++-
find/find.1 | 2 +
find/parser.c | 20 +++++++++++++-
find/pred.c | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
find/tree.c | 1 +
5 files changed, 125 insertions(+), 3 deletions(-)
diff --git a/find/defs.h b/find/defs.h
index 1708d83..ccdddc3 100644
--- a/find/defs.h
+++ b/find/defs.h
@@ -39,6 +39,7 @@ Please stop compiling the program now
/* XXX: some of these includes probably don't belong in a common header file */
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <stdio.h> /* for FILE* */
#include <string.h>
#include <stdlib.h>
@@ -65,6 +66,27 @@ typedef bool boolean;
#include "buildcmd.h"
#include "quotearg.h"
+#ifndef XFS_IOC_FSGETXATTR
+struct fsxattr
+{
+ uint32_t fsx_xflags; /* xflags field value (get/set) */
+ uint32_t fsx_extsize; /* extsize field value (get/set)*/
+ uint32_t fsx_nextents; /* nextents field value (get) */
+ uint32_t fsx_projid; /* project identifier (get/set) */
+ unsigned char fsx_pad[12];
+};
+
+#define XFS_IOC_FSGETXATTR _IOR ('X', 31, struct fsxattr)
+#endif
+
+#define XFS_EXCLUDED_FILE_TYPES(x) \
+ (S_ISCHR((x)) \
+ || S_ISBLK((x)) \
+ || S_ISFIFO((x)) \
+ || S_ISLNK((x)) \
+ || S_ISSOCK((x)))
+
+
/* These days we will assume ANSI/ISO C protootypes work on our compiler. */
#define PARAMS(Args) Args
@@ -306,7 +328,7 @@ struct predicate
const char *str; /* fstype [i]lname [i]name [i]path */
struct re_pattern_buffer *regex; /* regex */
struct exec_val exec_vec; /* exec ok */
- struct long_val numinfo; /* gid inum links uid */
+ struct long_val numinfo; /* gid inum links uid xfsprojquota */
struct size_val size; /* size */
uid_t uid; /* user */
gid_t gid; /* group */
@@ -458,6 +480,7 @@ PREDICATEFUNCTION pred_uid;
PREDICATEFUNCTION pred_used;
PREDICATEFUNCTION pred_user;
PREDICATEFUNCTION pred_writable;
+PREDICATEFUNCTION pred_xfsprojquota;
PREDICATEFUNCTION pred_xtype;
diff --git a/find/find.1 b/find/find.1
index 25953fc..a4a783f 100644
--- a/find/find.1
+++ b/find/find.1
@@ -1327,6 +1327,8 @@ File's name.
.IP %P
File's name with the name of the command line argument under which
it was found removed.
+.IP %q
+XFS filesystem project quota ID.
.IP %s
File's size in bytes.
.IP %S
diff --git a/find/parser.c b/find/parser.c
index 102eb7d..feb3fea 100644
--- a/find/parser.c
+++ b/find/parser.c
@@ -145,6 +145,7 @@ static boolean parse_time PARAMS((const struct
parser_table*, char *arg
static boolean parse_true PARAMS((const struct parser_table*, char
*argv[], int *arg_ptr));
static boolean parse_type PARAMS((const struct parser_table*, char
*argv[], int *arg_ptr));
static boolean parse_uid PARAMS((const struct parser_table*, char
*argv[], int *arg_ptr));
+static boolean parse_xfsprojquota PARAMS((const struct parser_table*, char
*argv[], int *arg_ptr));
static boolean parse_used PARAMS((const struct parser_table*, char
*argv[], int *arg_ptr));
static boolean parse_user PARAMS((const struct parser_table*, char
*argv[], int *arg_ptr));
static boolean parse_version PARAMS((const struct parser_table*, char
*argv[], int *arg_ptr));
@@ -320,6 +321,7 @@ static struct parser_table const parse_table[] =
PARSE_TEST_NP ("wholename", wholename), /* GNU, replaced
-path, but anyway -path will soon be in POSIX */
{ARG_TEST, "writable", parse_accesscheck,
pred_writable}, /* GNU, 4.3.0+ */
PARSE_OPTION ("xdev", xdev), /* POSIX */
+ PARSE_TEST ("xfsprojquota", xfsprojquota), /* XFS Project
Quota ID */
PARSE_TEST ("xtype", xtype), /* GNU */
#ifdef UNIMPLEMENTED_UNIX
/* It's pretty ugly for find to know about archive formats.
@@ -1127,7 +1129,7 @@ tests (N can be +N or -N or N): -amin N -anewer FILE
-atime N -cmin N\n\
-nouser -nogroup -path PATTERN -perm [+-]MODE -regex PATTERN\n\
-readable -writable -executable\n\
-wholename PATTERN -size N[bcwkMG] -true -type [bcdpflsD] -uid N\n\
- -used N -user NAME -xtype [bcdpfls]\n"));
+ -used N -user NAME -xfsprojquota N -xtype [bcdpfls]\n"));
puts (_("\
actions: -delete -print0 -printf FORMAT -fprintf FILE FORMAT -print \n\
-fprint0 FILE -fprint FILE -ls -fls FILE -prune -quit\n\
@@ -2562,6 +2564,19 @@ parse_warn (const struct parser_table* entry, char
**argv, int *arg_ptr)
}
static boolean
+parse_xfsprojquota (const struct parser_table* entry, char **argv, int
*arg_ptr)
+{
+ struct predicate *p = insert_num (argv, arg_ptr, entry);
+ if (p)
+ {
+ /* XXX: how to do if (parent dir has xfsprojid) { est_success_rate = 99 }
else { 0.2 } ? */
+ p->est_success_rate = 0.2;
+ return true;
+ }
+ return false;
+}
+
+static boolean
parse_xtype (const struct parser_table* entry, char **argv, int *arg_ptr)
{
return insert_type (argv, arg_ptr, entry, pred_xtype);
@@ -2784,7 +2799,7 @@ insert_fprintf (struct format_val *vec,
if (*scan2 == '.')
for (scan2++; ISDIGIT (*scan2); scan2++)
/* Do nothing. */ ;
- if (strchr ("abcdDfFgGhHiklmMnpPsStuUyY", *scan2))
+ if (strchr ("abcdDfFgGhHiklmMnpPqsStuUyY", *scan2))
{
segmentp = make_segment (segmentp, format, scan2 - format,
KIND_FORMAT, *scan2, 0,
@@ -2927,6 +2942,7 @@ make_segment (struct segment **segment,
case 'D': /* Filesystem device on which the file exits */
case 'k': /* size in 1K blocks */
case 'n': /* number of links */
+ case 'q': /* XFS Project Quota ID */
pred->need_stat = true;
mycost = NeedsStatInfo;
*fmt++ = 's';
diff --git a/find/pred.c b/find/pred.c
index a458803..a51adbd 100644
--- a/find/pred.c
+++ b/find/pred.c
@@ -26,6 +26,7 @@
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
+#include <sys/ioctl.h>
#include <errno.h>
#include <assert.h>
#include <stdarg.h>
@@ -229,6 +230,7 @@ struct pred_assoc pred_table[] =
{pred_used, "used "},
{pred_user, "user "},
{pred_writable, "writable "},
+ {pred_xfsprojquota, "xfsprojquota "},
{pred_xtype, "xtype "},
{0, "none "}
};
@@ -954,6 +956,32 @@ do_fprintf(struct format_val *dest,
checked_print_quoted (dest, segment->text, cp);
break;
+ case 'q':
+ {
+ if (!XFS_EXCLUDED_FILE_TYPES(stat_buf->st_mode)
+ && (strcmp (filesystem_type (stat_buf, pathname),
"xfs") == 0)) {
+ int fd;
+ struct fsxattr fsx;
+
+ if ((fd = openat(state.cwd_dir_fd, state.rel_pathname,
O_RDONLY|O_NOCTTY
+#if defined O_LARGEFILE
+ |O_LARGEFILE
+#endif
+ )) >= 0) {
+ if ((ioctl(fd, XFS_IOC_FSGETXATTR, &fsx)) >= 0) {
+ checked_fprintf (dest, segment->text,
+ human_readable ((uintmax_t) fsx.fsx_projid,
hbuf,
+ human_ceiling, 1, 1));
+ }
+ close(fd);
+ }
+ }
+
+ /* Do nothing. */
+ /*FALLTHROUGH*/
+ break;
+ }
+
case 's': /* size in bytes */
/* UNTRUSTED, probably unexploitable */
checked_fprintf (dest, segment->text,
@@ -1804,6 +1832,58 @@ pred_user (const char *pathname, struct stat *stat_buf,
struct predicate *pred_p
else
return (false);
}
+
+boolean
+pred_xfsprojquota(const char *pathname, struct stat *stat_buf, struct
predicate *pred_ptr)
+{
+ int fd;
+ struct fsxattr fsx;
+
+ if (XFS_EXCLUDED_FILE_TYPES(stat_buf->st_mode))
+ return false;
+
+ if (strcmp (filesystem_type (stat_buf, pathname), "xfs"))
+ return false;
+
+ if ((fd = openat(state.cwd_dir_fd, state.rel_pathname, O_RDONLY|O_NOCTTY
+#if defined O_LARGEFILE
+ |O_LARGEFILE
+#endif
+ )) < 0)
+ {
+ error (0, errno, "%s", safely_quote_err_filename(0, pathname));
+ state.exit_status = 1;
+ return false;
+ }
+
+ if ((ioctl(fd, XFS_IOC_FSGETXATTR, &fsx)) < 0) {
+ error (0, errno, "%s", safely_quote_err_filename(0, pathname));
+ state.exit_status = 1;
+ close(fd);
+ return false;
+ }
+
+ close(fd);
+
+ switch (pred_ptr->args.numinfo.kind)
+ {
+ case COMP_GT:
+ if (fsx.fsx_projid > pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_LT:
+ if (fsx.fsx_projid < pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ case COMP_EQ:
+ if (fsx.fsx_projid == pred_ptr->args.numinfo.l_val)
+ return (true);
+ break;
+ }
+ return (false);
+
+}
+
boolean
pred_xtype (const char *pathname, struct stat *stat_buf, struct predicate
*pred_ptr)
diff --git a/find/tree.c b/find/tree.c
index 7420c60..e5c0683 100644
--- a/find/tree.c
+++ b/find/tree.c
@@ -950,6 +950,7 @@ static struct pred_cost_lookup costlookup[] =
{ pred_true , NeedsNothing },
{ pred_type , NeedsType },
{ pred_uid , NeedsStatInfo },
+ { pred_xfsprojquota, NeedsNothing },
{ pred_used , NeedsStatInfo },
{ pred_user , NeedsStatInfo },
{ pred_writable , NeedsAccessInfo },
--
1.6.0.5
--
Arkadiusz MiĆkiewicz PLD/Linux Team
arekm / maven.pl http://ftp.pld-linux.org/
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH]: xfs project quota id support,
Arkadiusz Miskiewicz <=