X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=src%2Fext4_xattr.c;h=f8a577891c061e673746b2ffc0dec587c5d00e47;hb=6176f0aa46bc28e6f20626c71cceed3408684e5e;hp=6e096438de7edd24abfc78b8035b594be36c18e1;hpb=278e8d43d2bd28063cb0a0d30fec9ef3d9685e3d;p=lwext4.git diff --git a/src/ext4_xattr.c b/src/ext4_xattr.c index 6e09643..f8a5778 100644 --- a/src/ext4_xattr.c +++ b/src/ext4_xattr.c @@ -1,29 +1,11 @@ /* - * Copyright (c) 2015 Grzegorz Kostka (kostka.grzegorz@gmail.com) - * Copyright (c) 2015 Kaho Ng (ngkaho1234@gmail.com) + * Copyright (c) 2017 Grzegorz Kostka (kostka.grzegorz@gmail.com) + * Copyright (c) 2017 Kaho Ng (ngkaho1234@gmail.com) * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. */ /** @addtogroup lwext4 @@ -34,30 +16,105 @@ * @brief Extended Attribute manipulation. */ -#include "ext4_config.h" -#include "ext4_debug.h" -#include "ext4_errno.h" -#include "ext4_misc.h" -#include "ext4_types.h" - -#include "ext4_balloc.h" -#include "ext4_block_group.h" -#include "ext4_blockdev.h" -#include "ext4_crc32.h" -#include "ext4_fs.h" -#include "ext4_inode.h" -#include "ext4_super.h" -#include "ext4_trans.h" -#include "ext4_xattr.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include +#if CONFIG_XATTR_ENABLE + /** * @file ext4_xattr.c * @brief Extended Attribute Manipulation */ +/* Extended Attribute(EA) */ + +/* Magic value in attribute blocks */ +#define EXT4_XATTR_MAGIC 0xEA020000 + +/* Maximum number of references to one attribute block */ +#define EXT4_XATTR_REFCOUNT_MAX 1024 + +/* Name indexes */ +#define EXT4_XATTR_INDEX_USER 1 +#define EXT4_XATTR_INDEX_POSIX_ACL_ACCESS 2 +#define EXT4_XATTR_INDEX_POSIX_ACL_DEFAULT 3 +#define EXT4_XATTR_INDEX_TRUSTED 4 +#define EXT4_XATTR_INDEX_LUSTRE 5 +#define EXT4_XATTR_INDEX_SECURITY 6 +#define EXT4_XATTR_INDEX_SYSTEM 7 +#define EXT4_XATTR_INDEX_RICHACL 8 +#define EXT4_XATTR_INDEX_ENCRYPTION 9 + +#define EXT4_XATTR_PAD_BITS 2 +#define EXT4_XATTR_PAD (1 << EXT4_XATTR_PAD_BITS) +#define EXT4_XATTR_ROUND (EXT4_XATTR_PAD - 1) +#define EXT4_XATTR_LEN(name_len) \ + (((name_len) + EXT4_XATTR_ROUND + sizeof(struct ext4_xattr_entry)) & \ + ~EXT4_XATTR_ROUND) +#define EXT4_XATTR_NEXT(entry) \ + ((struct ext4_xattr_entry *)((char *)(entry) + \ + EXT4_XATTR_LEN((entry)->e_name_len))) +#define EXT4_XATTR_SIZE(size) (((size) + EXT4_XATTR_ROUND) & ~EXT4_XATTR_ROUND) +#define EXT4_XATTR_NAME(entry) ((char *)((entry) + 1)) + +#define EXT4_XATTR_IHDR(sb, raw_inode) \ + ((struct ext4_xattr_ibody_header *)((char *)raw_inode + \ + EXT4_GOOD_OLD_INODE_SIZE + \ + ext4_inode_get_extra_isize( \ + sb, raw_inode))) +#define EXT4_XATTR_IFIRST(hdr) ((struct ext4_xattr_entry *)((hdr) + 1)) + +#define EXT4_XATTR_BHDR(block) ((struct ext4_xattr_header *)((block)->data)) +#define EXT4_XATTR_ENTRY(ptr) ((struct ext4_xattr_entry *)(ptr)) +#define EXT4_XATTR_BFIRST(block) EXT4_XATTR_ENTRY(EXT4_XATTR_BHDR(block) + 1) +#define EXT4_XATTR_IS_LAST_ENTRY(entry) (*(uint32_t *)(entry) == 0) + +#define EXT4_ZERO_XATTR_VALUE ((void *)-1) + +#pragma pack(push, 1) + +struct ext4_xattr_header { + uint32_t h_magic; /* magic number for identification */ + uint32_t h_refcount; /* reference count */ + uint32_t h_blocks; /* number of disk blocks used */ + uint32_t h_hash; /* hash value of all attributes */ + uint32_t h_checksum; /* crc32c(uuid+id+xattrblock) */ + /* id = inum if refcount=1, blknum otherwise */ + uint32_t h_reserved[3]; /* zero right now */ +}; + +struct ext4_xattr_ibody_header { + uint32_t h_magic; /* magic number for identification */ +}; + +struct ext4_xattr_entry { + uint8_t e_name_len; /* length of name */ + uint8_t e_name_index; /* attribute name index */ + uint16_t e_value_offs; /* offset in disk block of value */ + uint32_t e_value_block; /* disk block attribute is stored on (n/i) */ + uint32_t e_value_size; /* size of attribute value */ + uint32_t e_hash; /* hash value of name and value */ +}; + +#pragma pack(pop) + + #define NAME_HASH_SHIFT 5 #define VALUE_HASH_SHIFT 16 @@ -974,6 +1031,13 @@ int ext4_xattr_get(struct ext4_inode_ref *inode_ref, uint8_t name_index, } } else { struct ext4_block block; + + /* Return ENODATA if there is no EA block */ + if (!xattr_block) { + ret = ENODATA; + goto out; + } + block_finder.i = i; ret = ext4_trans_block_get(fs->bdev, &block, xattr_block); if (ret != EOK) @@ -1427,6 +1491,8 @@ int ext4_xattr_set(struct ext4_inode_ref *inode_ref, uint8_t name_index, struct ext4_xattr_info i; bool block_found = false; ext4_fsblk_t orig_xattr_block; + size_t extra_isize = + ext4_inode_get_extra_isize(&fs->sb, inode_ref->inode); i.name_index = name_index; i.name = name; @@ -1464,7 +1530,12 @@ int ext4_xattr_set(struct ext4_inode_ref *inode_ref, uint8_t name_index, } else { try_insert: - ret = ext4_xattr_set_entry(&i, &ibody_finder.s, false); + /* Only try to set entry in ibody if inode is sufficiently large */ + if (extra_isize) + ret = ext4_xattr_set_entry(&i, &ibody_finder.s, false); + else + ret = ENOSPC; + if (ret == ENOSPC) { if (!block_found) { ret = ext4_xattr_block_set(inode_ref, &i, false); @@ -1486,6 +1557,8 @@ out: return ret; } +#endif + /** * @} */