Whamcloud - gitweb
e2fsck: clean up xattr checking code
authorAndreas Dilger <andreas.dilger@intel.com>
Fri, 13 Apr 2012 08:01:12 +0000 (02:01 -0600)
committerLi Dongyang <dongyangli@ddn.com>
Wed, 15 Aug 2018 02:08:04 +0000 (12:08 +1000)
Clean up xattr header/list processing for in-inode xattrs instead
of doing lots of explicit pointer math.

Signed-off-by: Andreas Dilger <andreas.dilger@intel.com>
e2fsck/pass1.c
lib/ext2fs/ext2_ext_attr.h
lib/ext2fs/ext_attr.c

index be46696..20f1d29 100644 (file)
@@ -436,13 +436,13 @@ static void check_ea_in_inode(e2fsck_t ctx, struct problem_context *pctx,
        ea_ibody_quota->inodes = 0;
 
        inode = (struct ext2_inode_large *) pctx->inode;
-       storage_size = EXT2_INODE_SIZE(ctx->fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
-               inode->i_extra_isize;
+       storage_size = EXT2_INODE_SIZE(ctx->fs->super) -
+               EXT2_GOOD_OLD_INODE_SIZE - inode->i_extra_isize;
        header = ((char *) inode) + EXT2_GOOD_OLD_INODE_SIZE +
                 inode->i_extra_isize;
        end = header + storage_size;
-       start = header + sizeof(__u32);
-       entry = (struct ext2_ext_attr_entry *) start;
+       entry = &IHDR(inode)->h_first_entry[0];
+       start = (char *)entry;
 
        /* scan all entry's headers first */
 
@@ -618,7 +618,7 @@ static void check_inode_extra_space(e2fsck_t ctx, struct problem_context *pctx,
        if (inode->i_extra_isize >= max - sizeof(__u32))
                return;
 
-       eamagic = IHDR(inode);
+       eamagic = &IHDR(inode)->h_magic;
        if (*eamagic != EXT2_EXT_ATTR_MAGIC &&
            (ctx->flags & E2F_FLAG_EXPAND_EISIZE) &&
            (inode->i_extra_isize < ctx->want_extra_isize)) {
@@ -910,9 +910,8 @@ int e2fsck_pass1_delete_attr(e2fsck_t ctx, struct ext2_inode_large *inode,
        int in_inode = 1, error;
        unsigned int freed_bytes = inode->i_extra_isize;
 
-       start = (char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
-                       inode->i_extra_isize + sizeof(__u32);
-       entry_ino = (struct ext2_ext_attr_entry *)start;
+       entry_ino = &IHDR(inode)->h_first_entry[0];
+       start = (char *)entry_ino;
 
        if (inode->i_file_acl) {
                error = ext2fs_read_ext_attr(ctx->fs, inode->i_file_acl,
index 7b95572..5b560fe 100644 (file)
@@ -37,9 +37,14 @@ struct ext2_ext_attr_entry {
 #endif
 };
 
+struct ext2_xattr_ibody_header {
+       __u32                           h_magic; /* EXT2_EXT_ATTR_MAGIC */
+       struct ext2_ext_attr_entry      h_first_entry[0];
+};
+
 #define BHDR(block) ((struct ext2_ext_attr_header *)block)
-#define IHDR(inode) ((__u32 *)((char *)inode + EXT2_GOOD_OLD_INODE_SIZE + \
-                               (inode)->i_extra_isize))
+#define IHDR(inode) ((struct ext2_xattr_ibody_header *)((char *)inode + \
+                   EXT2_GOOD_OLD_INODE_SIZE + (inode)->i_extra_isize))
 #define ENTRY(ptr) ((struct ext2_ext_attr_entry *)(ptr))
 
 /* Name indexes */
index ee544af..b5605fc 100644 (file)
@@ -1905,8 +1905,6 @@ static errcode_t ext2fs_attr_ibody_find(ext2_filsys fs,
                                        struct ext2_attr_info *i,
                                        struct ext2_attr_ibody_find *is)
 {
-       __u32 *eamagic;
-       char *start;
        errcode_t error;
 
        if (EXT2_INODE_SIZE(fs->super) == EXT2_GOOD_OLD_INODE_SIZE)
@@ -1914,17 +1912,13 @@ static errcode_t ext2fs_attr_ibody_find(ext2_filsys fs,
 
        if (inode->i_extra_isize == 0)
                return 0;
-       eamagic = IHDR(inode);
 
-       start = (char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
-                       inode->i_extra_isize + sizeof(__u32);
-       is->s.first = (struct ext2_ext_attr_entry *)start;
-       is->s.base = start;
+       is->s.first = &IHDR(inode)->h_first_entry[0];
+       is->s.base = (char *)is->s.first;
        is->s.here = is->s.first;
        is->s.end = (char *)inode + EXT2_INODE_SIZE(fs->super);
-       if (*eamagic == EXT2_EXT_ATTR_MAGIC) {
-               error = ext2fs_attr_check_names((struct ext2_ext_attr_entry *)
-                                               start, is->s.end);
+       if (IHDR(inode)->h_magic == EXT2_EXT_ATTR_MAGIC) {
+               error = ext2fs_attr_check_names(is->s.first, is->s.end);
                if (error)
                        return error;
                /* Find the named attribute. */
@@ -2142,7 +2136,6 @@ static errcode_t ext2fs_attr_ibody_set(ext2_filsys fs,
                                       struct ext2_attr_info *i,
                                       struct ext2_attr_ibody_find *is)
 {
-       __u32 *eamagic;
        struct ext2_attr_search *s = &is->s;
        errcode_t error;
 
@@ -2153,11 +2146,10 @@ static errcode_t ext2fs_attr_ibody_set(ext2_filsys fs,
        if (error)
                return error;
 
-       eamagic = IHDR(inode);
        if (!EXT2_EXT_IS_LAST_ENTRY(s->first))
-               *eamagic = EXT2_EXT_ATTR_MAGIC;
+               IHDR(inode)->h_magic = EXT2_EXT_ATTR_MAGIC;
        else
-               *eamagic = 0;
+               IHDR(inode)->h_magic = 0;
 
        return ext2fs_write_inode_full(fs, is->ino, (struct ext2_inode *)inode,
                                       EXT2_INODE_SIZE(fs->super));
@@ -2322,6 +2314,7 @@ static errcode_t ext2fs_attr_block_get(ext2_filsys fs, struct ext2_inode *inode,
                }
                memcpy(buffer, block_buf + entry->e_value_offs,
                       entry->e_value_size);
+               error = 0;
        }
 
 cleanup:
@@ -2330,6 +2323,22 @@ cleanup:
        return error;
 }
 
+static errcode_t ext2fs_attr_check_ibody(ext2_filsys fs,
+                                        struct ext2_inode_large *inode)
+{
+       const int inode_size = EXT2_INODE_SIZE(fs->super);
+
+       if (inode_size == EXT2_GOOD_OLD_INODE_SIZE)
+               return EXT2_ET_EA_NAME_NOT_FOUND;
+
+       if (IHDR(inode)->h_magic != EXT2_EXT_ATTR_MAGIC)
+               return EXT2_ET_EA_BAD_MAGIC;
+
+       return ext2fs_attr_check_names(&IHDR(inode)->h_first_entry[0],
+                                      (char *)inode + inode_size);
+}
+
+
 static errcode_t ext2fs_attr_ibody_get(ext2_filsys fs,
                                       struct ext2_inode_large *inode,
                                       int name_index, const char *name,
@@ -2338,26 +2347,16 @@ static errcode_t ext2fs_attr_ibody_get(ext2_filsys fs,
 {
        struct ext2_ext_attr_entry *entry;
        int error;
-       char *end, *start;
-       __u32 *eamagic;
-
-       if (EXT2_INODE_SIZE(fs->super) == EXT2_GOOD_OLD_INODE_SIZE)
-               return EXT2_ET_EA_NAME_NOT_FOUND;
 
-       eamagic = IHDR(inode);
-       error = ext2fs_attr_check_block(fs, buffer);
+       error = ext2fs_attr_check_ibody(fs, inode);
        if (error)
                return error;
 
-       start = (char *)inode + EXT2_GOOD_OLD_INODE_SIZE +
-                       inode->i_extra_isize + sizeof(__u32);
-       entry = (struct ext2_ext_attr_entry *)start;
-       end = (char *)inode + EXT2_INODE_SIZE(fs->super);
-       error = ext2fs_attr_check_names(entry, end);
-       if (error)
-               goto cleanup;
+       entry = &IHDR(inode)->h_first_entry[0];
+
        error = ext2fs_attr_find_entry(&entry, name_index, name,
-                                      end - (char *)entry, 0);
+                               (char *)inode + EXT2_INODE_SIZE(fs->super) -
+                               (char *)entry, 0);
        if (error)
                goto cleanup;
        if (easize)
@@ -2367,7 +2366,8 @@ static errcode_t ext2fs_attr_ibody_get(ext2_filsys fs,
                        error = EXT2_ET_EA_TOO_BIG;
                        goto cleanup;
                }
-               memcpy(buffer, start + entry->e_value_offs,entry->e_value_size);
+               memcpy(buffer, (char *)&IHDR(inode)->h_first_entry[0] +
+                              entry->e_value_offs, entry->e_value_size);
        }
 
 cleanup:
@@ -2427,7 +2427,6 @@ errcode_t ext2fs_expand_extra_isize(ext2_filsys fs, ext2_ino_t ino,
                                    int *needed_size)
 {
        struct ext2_inode *inode_buf = NULL;
-       __u32 *eamagic = NULL;
        struct ext2_ext_attr_header *header = NULL;
        struct ext2_ext_attr_entry *entry = NULL, *last = NULL;
        struct ext2_attr_ibody_find is = {
@@ -2465,10 +2464,9 @@ retry:
        if (inode->i_extra_isize >= new_extra_isize)
                goto cleanup;
 
-       eamagic = IHDR(inode);
        start = (char *)inode + EXT2_GOOD_OLD_INODE_SIZE + inode->i_extra_isize;
        /* No extended attributes present */
-       if (*eamagic != EXT2_EXT_ATTR_MAGIC) {
+       if (IHDR(inode)->h_magic != EXT2_EXT_ATTR_MAGIC) {
                memset(start, 0,
                       EXT2_INODE_SIZE(fs->super) - EXT2_GOOD_OLD_INODE_SIZE -
                       inode->i_extra_isize);