OSDN Git Service

libe2p: New e2p_edit_feature2 which provides better error handling
authorTheodore Ts'o <tytso@mit.edu>
Tue, 26 Feb 2008 19:26:01 +0000 (14:26 -0500)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 26 Feb 2008 19:26:01 +0000 (14:26 -0500)
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" <tytso@mit.edu>
lib/e2p/e2p.h
lib/e2p/feature.c

index 5d9131f..06e2120 100644 (file)
@@ -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);
index fe7e65a..e5f3c3d 100644 (file)
@@ -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);
+}