From 7100351d352903aa84cb2978ef9389ee5b0b09ad Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Tue, 26 Feb 2008 14:26:01 -0500 Subject: [PATCH] libe2p: New e2p_edit_feature2 which provides better error handling This creates a new enhanced edit_feature function for libe2p which supports a different set of feature flags that are OK to clear as opposed to set, and which returns more specific information about why the user provided an invalid edit feature command. Signed-off-by: "Theodore Ts'o" --- lib/e2p/e2p.h | 5 +++++ lib/e2p/feature.c | 47 +++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 44 insertions(+), 8 deletions(-) diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h index 5d9131fd..06e2120d 100644 --- a/lib/e2p/e2p.h +++ b/lib/e2p/e2p.h @@ -7,7 +7,9 @@ #define E2P_FEATURE_COMPAT 0 #define E2P_FEATURE_INCOMPAT 1 #define E2P_FEATURE_RO_INCOMPAT 2 +#define E2P_FEATURE_TYPE_MASK 0x03 +#define E2P_FEATURE_NEGATE_FLAG 0x80 /* `options' for print_flags() */ @@ -34,6 +36,9 @@ int setversion (int fd, unsigned long version); const char *e2p_feature2string(int compat, unsigned int mask); int e2p_string2feature(char *string, int *compat, unsigned int *mask); int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array); +int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array, + __u32 *clear_ok_array, int *type_err, + unsigned int *mask_err); int e2p_is_null_uuid(void *uu); void e2p_uuid_to_str(void *uu, char *out); diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c index fe7e65a8..e5f3c3d2 100644 --- a/lib/e2p/feature.c +++ b/lib/e2p/feature.c @@ -161,9 +161,12 @@ static char *skip_over_word(char *cp) /* * Edit a feature set array as requested by the user. The ok_array, * if set, allows the application to limit what features the user is - * allowed to set or clear using this function. + * allowed to set or clear using this function. If clear_ok_array is set, + * then use it tell whether or not it is OK to clear a filesystem feature. */ -int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array) +int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array, + __u32 *clear_ok_array, int *type_err, + unsigned int *mask_err) { char *cp, *buf, *next; int neg; @@ -171,6 +174,14 @@ int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array) int compat_type; int rc = 0; + if (!clear_ok_array) + clear_ok_array = ok_array; + + if (type_err) + *type_err = 0; + if (mask_err) + *mask_err = 0; + buf = malloc(strlen(str)+1); if (!buf) return 1; @@ -205,15 +216,35 @@ int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array) rc = 1; break; } - if (ok_array && !(ok_array[compat_type] & mask)) { - rc = 1; - break; - } - if (neg) + if (neg) { + if (clear_ok_array && + !(clear_ok_array[compat_type] & mask)) { + rc = 1; + if (type_err) + *type_err = (compat_type | + E2P_FEATURE_NEGATE_FLAG); + if (mask_err) + *mask_err = mask; + break; + } compat_array[compat_type] &= ~mask; - else + } else { + if (ok_array && !(ok_array[compat_type] & mask)) { + rc = 1; + if (type_err) + *type_err = compat_type; + if (mask_err) + *mask_err = mask; + break; + } compat_array[compat_type] |= mask; + } } free(buf); return rc; } + +int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array) +{ + return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0); +} -- 2.11.0