From 342d847db355d81299218e07a1e58ece82080a04 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 2 Jul 2001 11:54:09 -0400 Subject: Add initial support for extended attribute blocks --- lib/e2p/ChangeLog | 3 ++ lib/e2p/feature.c | 2 + lib/ext2fs/ChangeLog | 4 ++ lib/ext2fs/Makefile.in | 4 +- lib/ext2fs/ext2_ext_attr.h | 60 ++++++++++++++++++++++++++++ lib/ext2fs/ext2fs.h | 7 +++- lib/ext2fs/ext_attr.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 lib/ext2fs/ext2_ext_attr.h create mode 100644 lib/ext2fs/ext_attr.c (limited to 'lib') diff --git a/lib/e2p/ChangeLog b/lib/e2p/ChangeLog index 0df0008a..4b066268 100644 --- a/lib/e2p/ChangeLog +++ b/lib/e2p/ChangeLog @@ -1,5 +1,8 @@ 2001-06-23 Theodore Tso + * feature.c: Add entry in feature table to interpret + EXT2_FEATURE_COMPAT_EXT_ATTR. + * Release of E2fsprogs 1.22 2001-06-15 Theodore Tso diff --git a/lib/e2p/feature.c b/lib/e2p/feature.c index c9d2427c..2586727c 100644 --- a/lib/e2p/feature.c +++ b/lib/e2p/feature.c @@ -29,6 +29,8 @@ static struct feature feature_list[] = { "has_journal" }, { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES, "imagic_inodes" }, + { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXT_ATTR, + "ext_attr" }, { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX, "dir_index" }, { E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE, diff --git a/lib/ext2fs/ChangeLog b/lib/ext2fs/ChangeLog index e9541663..43e23f66 100644 --- a/lib/ext2fs/ChangeLog +++ b/lib/ext2fs/ChangeLog @@ -1,5 +1,9 @@ 2001-06-23 Theodore Tso + * Makefile.in, ext_attr.c, ext2_attr.c, ext2fs.h: Add new files + ext2_ext_attr.h and ext_attr.c for extended attributes + support. + * Release of E2fsprogs 1.22 2001-06-22 Theodore Tso diff --git a/lib/ext2fs/Makefile.in b/lib/ext2fs/Makefile.in index d5adcb67..948a8736 100644 --- a/lib/ext2fs/Makefile.in +++ b/lib/ext2fs/Makefile.in @@ -31,6 +31,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \ dirblock.o \ dir_iterate.o \ expanddir.o \ + ext_attr.o \ finddev.o \ flushb.o \ freefs.o \ @@ -78,6 +79,7 @@ SRCS= ext2_err.c \ $(srcdir)/dir_iterate.c \ $(srcdir)/dupfs.c \ $(srcdir)/expanddir.c \ + $(srcdir)/ext_attr.c \ $(srcdir)/fileio.c \ $(srcdir)/finddev.c \ $(srcdir)/flushb.c \ @@ -112,7 +114,7 @@ SRCS= ext2_err.c \ $(srcdir)/version.c \ $(srcdir)/write_bb_file.c -HFILES= bitops.h ext2fs.h ext2_io.h ext2_fs.h +HFILES= bitops.h ext2fs.h ext2_io.h ext2_fs.h ext2_ext_attr.h HFILES_IN= ext2_err.h ext2_types.h LIBRARY= libext2fs diff --git a/lib/ext2fs/ext2_ext_attr.h b/lib/ext2fs/ext2_ext_attr.h new file mode 100644 index 00000000..bbc90d9f --- /dev/null +++ b/lib/ext2fs/ext2_ext_attr.h @@ -0,0 +1,60 @@ +/* + File: linux/ext2_ext_attr.h + + On-disk format of extended attributes for the ext2 filesystem. + + (C) 2000 Andreas Gruenbacher, +*/ + +#include + +/* Magic value in attribute blocks */ +#define EXT2_EXT_ATTR_MAGIC 0xEA010000 + +/* Maximum number of references to one attribute block */ +#define EXT2_EXT_ATTR_REFCOUNT_MAX 1024 + +struct ext2_ext_attr_header { + __u32 h_magic; /* magic number for identification */ + __u32 h_refcount; /* reference count */ + __u32 h_blocks; /* number of disk blocks used */ + __u32 h_hash; /* hash value of all attributes */ + __u32 h_reserved[4]; /* zero right now */ +}; + +struct ext2_ext_attr_entry { + __u8 e_name_len; /* length of name */ + __u8 e_name_index; /* index into table of names (n/i) */ + __u16 e_value_offs; /* offset in disk block of value */ + __u32 e_value_block; /* disk block attribute is stored on (n/i) */ + __u32 e_value_size; /* size of attribute value */ + __u32 e_hash; /* hash value of name and value */ + char e_name[0]; /* attribute name */ +}; + +#define EXT2_EXT_ATTR_PAD_BITS 2 +#define EXT2_EXT_ATTR_PAD (1<e_name_len)) ) +#define EXT2_EXT_ATTR_SIZE(size) \ + (((size) + EXT2_EXT_ATTR_ROUND) & ~EXT2_EXT_ATTR_ROUND) + +#ifdef __KERNEL__ +# ifdef CONFIG_EXT2_FS_EXT_ATTR +extern int ext2_get_ext_attr(struct inode *, const char *, char *, size_t, int); +extern int ext2_set_ext_attr(struct inode *, const char *, char *, size_t, int); +extern void ext2_ext_attr_free_inode(struct inode *inode); +extern void ext2_ext_attr_put_super(struct super_block *sb); +extern int ext2_ext_attr_init(void); +extern void ext2_ext_attr_done(void); +# else +# define ext2_get_ext_attr NULL +# define ext2_set_ext_attr NULL +# endif +#endif /* __KERNEL__ */ + diff --git a/lib/ext2fs/ext2fs.h b/lib/ext2fs/ext2fs.h index f89ccc7e..2b23e04a 100644 --- a/lib/ext2fs/ext2fs.h +++ b/lib/ext2fs/ext2fs.h @@ -402,7 +402,8 @@ typedef struct ext2_icount *ext2_icount_t; */ #define EXT2_LIB_FEATURE_COMPAT_SUPP (EXT2_FEATURE_COMPAT_DIR_PREALLOC|\ EXT2_FEATURE_COMPAT_IMAGIC_INODES|\ - EXT3_FEATURE_COMPAT_HAS_JOURNAL) + EXT3_FEATURE_COMPAT_HAS_JOURNAL|\ + EXT2_FEATURE_COMPAT_EXT_ATTR) /* This #ifdef is temporary until compression is fully supported */ #ifdef ENABLE_COMPRESSION @@ -607,6 +608,10 @@ extern errcode_t ext2fs_dup_handle(ext2_filsys src, ext2_filsys *dest); /* expanddir.c */ extern errcode_t ext2fs_expand_dir(ext2_filsys fs, ext2_ino_t dir); +/* ext_attr.c */ +void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from); +extern errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf); +extern errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *buf); /* fileio.c */ extern errcode_t ext2fs_file_open(ext2_filsys fs, ext2_ino_t ino, int flags, ext2_file_t *ret); diff --git a/lib/ext2fs/ext_attr.c b/lib/ext2fs/ext_attr.c new file mode 100644 index 00000000..480df36b --- /dev/null +++ b/lib/ext2fs/ext_attr.c @@ -0,0 +1,98 @@ +/* + * ext_attr.c --- extended attribute blocks + * + * Copyright (C) Andreas Gruenbacher, + * + * %Begin-Header% + * This file may be redistributed under the terms of the GNU Public + * License. + * %End-Header% + */ + +#include +#if HAVE_UNISTD_H +#include +#endif +#include +#include + +#include "ext2_fs.h" +#include "ext2_ext_attr.h" + +#include "ext2fs.h" + +#ifdef EXT2FS_ENABLE_SWAPFS +void ext2fs_swap_ext_attr(ext2_filsys fs, char *to, char *from) +{ + struct ext2_ext_attr_header *from_header = + (struct ext2_ext_attr_header *)from; + struct ext2_ext_attr_header *to_header = + (struct ext2_ext_attr_header *)to; + struct ext2_ext_attr_entry *from_entry, *to_entry; + char *from_end = (char *)from_header + fs->blocksize; + int n; + + if (to_header != from_header) + memcpy(to_header, from_header, fs->blocksize); + + to_header->h_magic = ext2fs_swab32(from_header->h_magic); + to_header->h_blocks = ext2fs_swab32(from_header->h_blocks); + to_header->h_refcount = ext2fs_swab32(from_header->h_refcount); + for (n=0; n<4; n++) + to_header->h_reserved[n] = + ext2fs_swab32(from_header->h_reserved[n]); + + from_entry = (struct ext2_ext_attr_entry *)(from_header+1); + to_entry = (struct ext2_ext_attr_entry *)(to_header+1); + while ((char *)from_entry < from_end && *(__u32 *)from_entry) { + to_entry->e_value_offs = + ext2fs_swab16(from_entry->e_value_offs); + to_entry->e_value_block = + ext2fs_swab32(from_entry->e_value_block); + to_entry->e_value_size = + ext2fs_swab32(from_entry->e_value_size); + from_entry = EXT2_EXT_ATTR_NEXT(from_entry); + to_entry = EXT2_EXT_ATTR_NEXT(to_entry); + } +} +#endif + +errcode_t ext2fs_read_ext_attr(ext2_filsys fs, blk_t block, void *buf) +{ + errcode_t retval; + struct ext2_ext_attr_entry *entry; + + retval = io_channel_read_blk(fs->io, block, 1, buf); + if (retval) + return retval; +#ifdef EXT2FS_ENABLE_SWAPFS + if ((fs->flags & (EXT2_FLAG_SWAP_BYTES| + EXT2_FLAG_SWAP_BYTES_READ)) != 0) + ext2fs_swap_ext_attr(fs, buf, buf); +#endif + return 0; +} + +errcode_t ext2fs_write_ext_attr(ext2_filsys fs, blk_t block, void *inbuf) +{ + errcode_t retval; + char *p, *end, *write_buf; + char *buf = NULL; + struct ext2_dir_entry *dirent; + +#ifdef EXT2FS_ENABLE_SWAPFS + if ((fs->flags & EXT2_FLAG_SWAP_BYTES) || + (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)) { + retval = ext2fs_get_mem(fs->blocksize, (void **) &buf); + if (retval) + return retval; + write_buf = buf; + ext2fs_swap_ext_attr(fs, buf, inbuf); + } else +#endif + write_buf = (char *) inbuf; + retval = io_channel_write_blk(fs->io, block, 1, write_buf); + if (buf) + ext2fs_free_mem((void **) &buf); + return retval; +} -- cgit v1.2.3