Whamcloud - gitweb
ChangeLog, Makefile.in, e2p.h, feature.c, ls.c:
authorTheodore Ts'o <tytso@mit.edu>
Tue, 14 Sep 1999 20:17:38 +0000 (20:17 +0000)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 14 Sep 1999 20:17:38 +0000 (20:17 +0000)
  Makefile.in, feature.c, e2p.h: New file which is used for displaying
   and editing superblock feature sets.
  ls.c (print_features, list_super): Add new function print_features
   which is used to display the feature bits in the superblock.

lib/e2p/ChangeLog
lib/e2p/Makefile.in
lib/e2p/e2p.h
lib/e2p/feature.c [new file with mode: 0644]
lib/e2p/ls.c

index 249b4c5..0aa3db8 100644 (file)
@@ -1,4 +1,13 @@
-1999-07-18  Theodore Ts'o  <tytso@rsts-11.mit.edu>
+1999-09-07    <tytso@valinux.com>
+
+       * Makefile.in, feature.c, e2p.h: New file which is used for
+               displaying and editing superblock feature sets.
+
+       * ls.c (print_features, list_super): Add new function
+               print_features which is used to display the feature
+               bits in the superblock.
+
+1999-07-18  Theodore Ts'o  <tytso@valinux.com>
 
        * Release of E2fsprogs 1.15
 
index 2ffa7a8..bc5df3e 100644 (file)
@@ -16,15 +16,15 @@ INSTALL = @INSTALL@
 
 all::
 
-OBJS=          fgetflags.o fsetflags.o fgetversion.o fsetversion.o \
+OBJS=          feature.o fgetflags.o fsetflags.o fgetversion.o fsetversion.o \
                getflags.o getversion.o iod.o ls.o pe.o pf.o ps.o \
                setflags.o setversion.o uuid.o
 
-SRCS=          $(srcdir)/fgetflags.c $(srcdir)/fsetflags.c \
-               $(srcdir)/fgetversion.c $(srcdir)/fsetversion.c \
-               $(srcdir)/getflags.c $(srcdir)/getversion.c \
-               $(srcdir)/iod.c $(srcdir)/ls.c $(srcdir)/pe.c \
-               $(srcdir)/pf.c $(srcdir)/ps.c \
+SRCS=          $(srcdir)/feature.c $(srcdir)/fgetflags.c \
+               $(srcdir)/fsetflags.c $(srcdir)/fgetversion.c \
+               $(srcdir)/fsetversion.c $(srcdir)/getflags.c \
+               $(srcdir)/getversion.c $(srcdir)/iod.c $(srcdir)/ls.c \
+               $(srcdir)/pe.c $(srcdir)/pf.c $(srcdir)/ps.c \
                $(srcdir)/setflags.c $(srcdir)/setversion.c \
                $(srcdir)/uuid.c
 
index fa4a03b..a56bcf2 100644 (file)
@@ -4,6 +4,10 @@
 
 #include <linux/ext2_fs.h>
 
+#define E2P_FEATURE_COMPAT     0
+#define E2P_FEATURE_INCOMPAT   1
+#define E2P_FEATURE_RO_INCOMPAT        2
+
 int fgetflags (const char * name, unsigned long * flags);
 int fgetversion (const char * name, unsigned long * version);
 int fsetflags (const char * name, unsigned long flags);
@@ -20,5 +24,9 @@ void print_fs_state (FILE * f, unsigned short state);
 int setflags (int fd, unsigned long flags);
 int setversion (int fd, unsigned long version);
 
+char *e2p_feature2string(int compat, unsigned int mask);
+int e2p_string2feature(char *string, int *compat, unsigned int *mask);
+int e2p_edit_feature(char *str, __u32 *compat_array);
+
 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
new file mode 100644 (file)
index 0000000..f25ee91
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * feature.c --- convert between features and strings
+ * 
+ * Copyright (C) 1999  Theodore Ts'o <tytso@mit.edu>
+ * 
+ * This file can be redistributed under the terms of the GNU Library General
+ * Public License
+ * 
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "e2p.h"
+
+/*
+ * Feature set definitions (that might not be in ext2_fs.h
+ */
+
+#ifndef EXT2_FEATURE_COMPAT_DIR_PREALLOC
+#define EXT2_FEATURE_COMPAT_DIR_PREALLOC       0x0001
+#endif
+
+#ifndef EXT2_FEATURE_COMPAT_IMAGIC_INODES /* for AFS, etc. */
+#define EXT2_FEATURE_COMPAT_IMAGIC_INODES              0x0002
+#endif
+
+#ifndef EXT3_FEATURE_COMPAT_HAS_JOURNAL
+#define EXT3_FEATURE_COMPAT_HAS_JOURNAL                0x0004
+#endif
+
+#ifndef EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER
+#define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER    0x0001
+#endif
+
+#ifndef EXT2_FEATURE_RO_COMPAT_LARGE_FILE
+#define EXT2_FEATURE_RO_COMPAT_LARGE_FILE      0x0002
+#define i_size_high i_dir_acl
+#endif
+
+#ifndef EXT2_FEATURE_RO_COMPAT_BTREE_DIR
+#define EXT2_FEATURE_RO_COMPAT_BTREE_DIR       0x0004
+#endif
+
+#ifndef EXT2_FEATURE_INCOMPAT_COMPRESSION
+#define EXT2_FEATURE_INCOMPAT_COMPRESSION      0x0001
+#endif
+
+#ifndef EXT2_FEATURE_INCOMPAT_FILETYPE
+#define EXT2_FEATURE_INCOMPAT_FILETYPE 0x0002
+#endif
+
+#ifndef EXT3_FEATURE_INCOMPAT_RECOVER
+#define EXT3_FEATURE_INCOMPAT_RECOVER  0x0004
+#endif
+
+struct feature {
+       int             compat;
+       unsigned int    mask;
+       char            *string;
+};
+
+struct feature feature_list[] = {
+       {       E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_PREALLOC,
+                       "dir_prealloc" },
+       {       E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL,
+                       "has_journal" },
+       {       E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES,
+                       "imagic_inodes" },
+       {       E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
+                       "sparse_super" },
+       {       E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
+                       "large_file" },
+       {       E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_BTREE_DIR,
+                       "btree_dir" },
+       {       E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
+                       "compression" },
+       {       E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE,
+                       "filetype" },
+       {       E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_RECOVER,
+                       "needs_recovery" },
+       {       0, 0, 0 },
+};
+
+char *e2p_feature2string(int compat, unsigned int mask)
+{
+       struct feature  *f;
+       static char buf[20];
+       char    fchar;
+       int     fnum;
+
+       for (f = feature_list; f->string; f++) {
+               if ((compat == f->compat) &&
+                   (mask == f->mask))
+                       return f->string;
+       }
+       switch (compat) {
+       case  E2P_FEATURE_COMPAT:
+               fchar = 'C';
+               break;
+       case E2P_FEATURE_INCOMPAT:
+               fchar = 'I';
+               break;
+       case E2P_FEATURE_RO_INCOMPAT:
+               fchar = 'R';
+               break;
+       default:
+               fchar = '?';
+               break;
+       }
+       for (fnum = 0; mask >>= 1; fnum++);
+       sprintf(buf, "FEATURE_%c%d", fchar, fnum);
+       return buf;
+}
+
+int e2p_string2feature(char *string, int *compat, unsigned int *mask)
+{
+       struct feature  *f;
+       char            *eptr;
+       int             num;
+
+       for (f = feature_list; f->string; f++) {
+               if (!strcasecmp(string, f->string)) {
+                       *compat = f->compat;
+                       *mask = f->mask;
+                       return 0;
+               }
+       }
+       if (strncasecmp(string, "FEATURE_", 8))
+               return 1;
+
+       switch (string[8]) {
+       case 'c':
+       case 'C':
+               *compat = E2P_FEATURE_COMPAT;
+               break;
+       case 'i':
+       case 'I':
+               *compat = E2P_FEATURE_INCOMPAT;
+               break;
+       case 'r':
+       case 'R':
+               *compat = E2P_FEATURE_RO_INCOMPAT;
+               break;
+       default:
+               return 1;
+       }
+       if (string[9] == 0)
+               return 1;
+       num = strtol(string+9, &eptr, 10);
+       if (num > 32 || num < 0)
+               return 1;
+       if (*eptr)
+               return 1;
+       *mask = 1 << num;
+       return 0;
+}
+
+static char *skip_over_blanks(char *cp)
+{
+       while (*cp && isspace(*cp))
+               cp++;
+       return cp;
+}
+
+char *skip_over_word(char *cp)
+{
+       while (*cp && !isspace(*cp))
+               cp++;
+       return cp;
+}
+
+int e2p_edit_feature(char *str, __u32 *compat_array)
+{
+       char    *cp, *buf, *next;
+       int     neg;
+       unsigned int    compat, mask;
+
+       buf = malloc(strlen(str)+1);
+       if (!buf) {
+               errno = ENOMEM;
+               return 1;
+       }
+       strcpy(buf, str);
+       cp = buf;
+       while (cp && *cp) {
+               neg = 0;
+               cp = skip_over_blanks(cp);
+               next = skip_over_word(cp);
+               if (*next == 0)
+                       next = 0;
+               else
+                       *next = 0;
+               switch (*cp) {
+               case '-':
+               case '^':
+                       neg++;
+               case '+':
+                       cp++;
+                       break;
+               }
+               if (e2p_string2feature(cp, &compat, &mask))
+                       return 1;
+               if (neg)
+                       compat_array[compat] &= ~mask;
+               else
+                       compat_array[compat] |= mask;
+               cp = next ? next+1 : 0;
+       }
+       return 0;
+}
+
index 31695b8..5544e25 100644 (file)
@@ -151,6 +151,28 @@ static const char *interval_string(unsigned int secs)
        return buf;
 }
 
+static void print_features(struct ext2_super_block * s)
+{
+#ifdef EXT2_DYNAMIC_REV
+       int     i, j, printed=0;
+       __u32   *mask = &s->s_feature_compat, m;
+
+       printf ("Filesystem features:     ");
+       for (i=0; i <3; i++,mask++) {
+               for (j=0,m=1; j < 32; j++, m<<=1) {
+                       if (*mask & m) {
+                               printf(" %s", e2p_feature2string(i, m));
+                               printed++;
+                       }
+               }
+       }
+       if (printed == 0)
+               printf("(none)");
+       printf("\n");
+#endif
+}
+
+
 
 #ifndef EXT2_INODE_SIZE
 #define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
@@ -199,14 +221,7 @@ void list_super (struct ext2_super_block * s)
 #endif
        } else
                printf("\n");
-#ifdef EXT2_DYNAMIC_REV
-       printf ("Filesystem features:      ");
-       if (s->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)
-               printf("sparse_super");
-       else
-               printf("(none)");
-       printf("\n");
-#endif
+       print_features(s);
        printf ("Filesystem state:        ");
        print_fs_state (stdout, s->s_state);
        printf ("\n");