summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/e2p/ChangeLog11
-rw-r--r--lib/e2p/Makefile.in12
-rw-r--r--lib/e2p/e2p.h8
-rw-r--r--lib/e2p/feature.c214
-rw-r--r--lib/e2p/ls.c31
5 files changed, 261 insertions, 15 deletions
diff --git a/lib/e2p/ChangeLog b/lib/e2p/ChangeLog
index 249b4c57..0aa3db8d 100644
--- a/lib/e2p/ChangeLog
+++ b/lib/e2p/ChangeLog
@@ -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
diff --git a/lib/e2p/Makefile.in b/lib/e2p/Makefile.in
index 2ffa7a8e..bc5df3e6 100644
--- a/lib/e2p/Makefile.in
+++ b/lib/e2p/Makefile.in
@@ -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
diff --git a/lib/e2p/e2p.h b/lib/e2p/e2p.h
index fa4a03bd..a56bcf2a 100644
--- a/lib/e2p/e2p.h
+++ b/lib/e2p/e2p.h
@@ -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
index 00000000..f25ee911
--- /dev/null
+++ b/lib/e2p/feature.c
@@ -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;
+}
+
diff --git a/lib/e2p/ls.c b/lib/e2p/ls.c
index 31695b8d..5544e256 100644
--- a/lib/e2p/ls.c
+++ b/lib/e2p/ls.c
@@ -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");