summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorTheodore Ts'o <tytso@mit.edu>2001-07-02 11:54:09 -0400
committerTheodore Ts'o <tytso@mit.edu>2001-07-02 11:54:09 -0400
commit342d847db355d81299218e07a1e58ece82080a04 (patch)
treed9d1ebd757a7caf7066a3d5e119691a615b27d18 /lib
parent636a954a308aec91cf644f566d3e8a794a5dd8cb (diff)
downloade2fsprogs-342d847db355d81299218e07a1e58ece82080a04.tar.gz
Add initial support for extended attribute blocks
Diffstat (limited to 'lib')
-rw-r--r--lib/e2p/ChangeLog3
-rw-r--r--lib/e2p/feature.c2
-rw-r--r--lib/ext2fs/ChangeLog4
-rw-r--r--lib/ext2fs/Makefile.in4
-rw-r--r--lib/ext2fs/ext2_ext_attr.h60
-rw-r--r--lib/ext2fs/ext2fs.h7
-rw-r--r--lib/ext2fs/ext_attr.c98
7 files changed, 176 insertions, 2 deletions
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 <tytso@valinux.com>
+ * feature.c: Add entry in feature table to interpret
+ EXT2_FEATURE_COMPAT_EXT_ATTR.
+
* Release of E2fsprogs 1.22
2001-06-15 Theodore Tso <tytso@valinux.com>
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 <tytso@valinux.com>
+ * 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 <tytso@valinux.com>
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, <a.gruenbacher@computer.org>
+*/
+
+#include <linux/config.h>
+
+/* 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<<EXT2_EXT_ATTR_PAD_BITS)
+#define EXT2_EXT_ATTR_ROUND (EXT2_EXT_ATTR_PAD-1)
+#define EXT2_EXT_ATTR_LEN(name_len) \
+ (((name_len) + EXT2_EXT_ATTR_ROUND + \
+ sizeof(struct ext2_ext_attr_entry)) & ~EXT2_EXT_ATTR_ROUND)
+#define EXT2_EXT_ATTR_NEXT(entry) \
+ ( (struct ext2_ext_attr_entry *)( \
+ (char *)(entry) + EXT2_EXT_ATTR_LEN((entry)->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, <a.gruenbacher@computer.org>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include <stdio.h>
+#if HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <time.h>
+
+#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;
+}