diff options
-rw-r--r-- | lib/e2p/ChangeLog | 11 | ||||
-rw-r--r-- | lib/e2p/Makefile.in | 12 | ||||
-rw-r--r-- | lib/e2p/e2p.h | 8 | ||||
-rw-r--r-- | lib/e2p/feature.c | 214 | ||||
-rw-r--r-- | lib/e2p/ls.c | 31 |
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"); |