Add 'lib_only' build target.
[lwext4.git] / lwext4 / ext4_inode.c
index 1097d6b902635ea2dd1f6ee3105bb670c21c9e8b..696a8d782f0004f16fb78b68de5057b2e1c98fd4 100644 (file)
-/*\r
- * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)\r
- *\r
- *\r
- * HelenOS:\r
- * Copyright (c) 2012 Martin Sucha\r
- * Copyright (c) 2012 Frantisek Princ\r
- * All rights reserved.\r
- *\r
- * Redistribution and use in source and binary forms, with or without\r
- * modification, are permitted provided that the following conditions\r
- * are met:\r
- *\r
- * - Redistributions of source code must retain the above copyright\r
- *   notice, this list of conditions and the following disclaimer.\r
- * - Redistributions in binary form must reproduce the above copyright\r
- *   notice, this list of conditions and the following disclaimer in the\r
- *   documentation and/or other materials provided with the distribution.\r
- * - The name of the author may not be used to endorse or promote products\r
- *   derived from this software without specific prior written permission.\r
- *\r
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\r
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\r
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\r
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\r
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\r
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\r
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\r
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- */\r
-\r
-/** @addtogroup lwext4\r
- * @{\r
- */\r
-/**\r
- * @file  ext4_inode.c\r
- * @brief Inode handle functions\r
- */\r
-\r
-#include <ext4_config.h>\r
-#include <ext4_types.h>\r
-#include <ext4_inode.h>\r
-#include <ext4_super.h>\r
-\r
-static uint32_t ext4_inode_block_bits_count(uint32_t block_size)\r
-{\r
-    uint32_t bits = 8;\r
-    uint32_t size = block_size;\r
-\r
-    do {\r
-        bits++;\r
-        size = size >> 1;\r
-    } while (size > 256);\r
-\r
-    return bits;\r
-}\r
-\r
-\r
-uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode)\r
-{\r
-    uint32_t v = to_le16(inode->mode);\r
-\r
-    if(ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD){\r
-        v |= ((uint32_t) to_le16(inode->osd2.hurd2.mode_high)) << 16;\r
-    }\r
-\r
-    return v;\r
-}\r
-\r
-void    ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,\r
-    uint32_t mode)\r
-{\r
-    inode->mode = to_le16((mode << 16) >> 16);\r
-\r
-    if(ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD)\r
-        inode->osd2.hurd2.mode_high = to_le16(mode >> 16);\r
-}\r
-\r
-\r
-\r
-uint32_t ext4_inode_get_uid(struct ext4_inode *inode)\r
-{\r
-    return to_le32(inode->uid);\r
-}\r
-\r
-void    ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid)\r
-{\r
-    inode->uid = to_le32(uid);\r
-}\r
-\r
-\r
-uint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode)\r
-{\r
-    uint64_t v = to_le32(inode->size_lo);\r
-\r
-    if ((ext4_get32(sb, rev_level) > 0) && (ext4_inode_is_type(sb, inode,\r
-            EXT4_INODE_MODE_FILE)))\r
-        v |= ((uint64_t)to_le32(inode->size_hi)) << 32;\r
-\r
-    return v;\r
-}\r
-\r
-void    ext4_inode_set_size(struct ext4_inode *inode, uint64_t size)\r
-{\r
-    inode->size_lo = to_le32((size << 32) >> 32);\r
-    inode->size_hi = to_le32(size >> 32);\r
-}\r
-\r
-\r
-uint32_t ext4_inode_get_access_time(struct ext4_inode *inode)\r
-{\r
-    return to_le32(inode->access_time);\r
-}\r
-void    ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time)\r
-{\r
-    inode->access_time = to_le32(time);\r
-}\r
-\r
-\r
-uint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode)\r
-{\r
-    return to_le32(inode->change_inode_time);\r
-}\r
-void    ext4_inode_set_change_inode_time(struct ext4_inode *inode,\r
-    uint32_t time)\r
-{\r
-    inode->change_inode_time = to_le32(time);\r
-}\r
-\r
-\r
-uint32_t ext4_inode_get_modification_time(struct ext4_inode *inode)\r
-{\r
-    return to_le32(inode->modification_time);\r
-}\r
-\r
-void    ext4_inode_set_modification_time(struct ext4_inode *inode,\r
-    uint32_t time)\r
-{\r
-    inode->modification_time = to_le32(time);\r
-}\r
-\r
-\r
-uint32_t ext4_inode_get_deletion_time(struct ext4_inode *inode)\r
-{\r
-    return to_le32(inode->deletion_time);\r
-}\r
-\r
-void    ext4_inode_set_deletion_time(struct ext4_inode *inode, uint32_t time)\r
-{\r
-    inode->deletion_time = to_le32(time);\r
-}\r
-\r
-uint32_t ext4_inode_get_gid(struct ext4_inode *inode)\r
-{\r
-    return to_le32(inode->gid);\r
-}\r
-void    ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid)\r
-{\r
-    inode->gid = to_le32(gid);\r
-}\r
-\r
-uint16_t ext4_inode_get_links_count(struct ext4_inode *inode)\r
-{\r
-    return to_le16(inode->links_count);\r
-}\r
-void    ext4_inode_set_links_count(struct ext4_inode *inode, uint16_t cnt)\r
-{\r
-    inode->links_count = to_le16(cnt);\r
-}\r
-\r
-\r
-uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,\r
-    struct ext4_inode *inode)\r
-{\r
-    uint64_t count = to_le32(inode->blocks_count_lo);\r
-\r
-    if (ext4_sb_check_read_only(sb,\r
-            EXT4_FEATURE_RO_COMPAT_HUGE_FILE)) {\r
-\r
-        /* 48-bit field */\r
-        count |= ((uint64_t) to_le16(inode->osd2.linux2.blocks_high)) << 32;\r
-\r
-        if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_HUGE_FILE)) {\r
-\r
-            uint32_t block_bits =\r
-                    ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));\r
-            return count << (block_bits - 9);\r
-        } else\r
-            return count;\r
-    }\r
-\r
-    return count;\r
-}\r
-\r
-\r
-int ext4_inode_set_blocks_count(struct ext4_sblock *sb,\r
-    struct ext4_inode *inode, uint64_t count)\r
-{\r
-    /* 32-bit maximum */\r
-    uint64_t max = 0;\r
-    max = ~max >> 32;\r
-\r
-    if (count <= max) {\r
-        inode->blocks_count_lo = to_le32(count);\r
-        inode->osd2.linux2.blocks_high = 0;\r
-        ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);\r
-\r
-        return EOK;\r
-    }\r
-\r
-    /* Check if there can be used huge files (many blocks) */\r
-    if (!ext4_sb_check_read_only(sb,\r
-            EXT4_FEATURE_RO_COMPAT_HUGE_FILE))\r
-        return EINVAL;\r
-\r
-    /* 48-bit maximum */\r
-    max = 0;\r
-    max = ~max >> 16;\r
-\r
-    if (count <= max) {\r
-        inode->blocks_count_lo = to_le32(count);\r
-        inode->osd2.linux2.blocks_high = to_le16(count >> 32);\r
-        ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);\r
-    } else {\r
-        uint32_t block_bits = ext4_inode_block_bits_count(ext4_sb_get_block_size(sb));\r
-\r
-        ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);\r
-        count = count >> (block_bits - 9);\r
-        inode->blocks_count_lo = to_le32(count);\r
-        inode->osd2.linux2.blocks_high = to_le16(count >> 32);\r
-    }\r
-\r
-    return EOK;\r
-}\r
-\r
-\r
-uint32_t ext4_inode_get_flags(struct ext4_inode *inode)\r
-{\r
-    return to_le32(inode->flags);\r
-}\r
-void    ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags)\r
-{\r
-    inode->flags =     to_le32(flags);\r
-}\r
-\r
-uint32_t ext4_inode_get_generation(struct ext4_inode *inode)\r
-{\r
-    return to_le32(inode->generation);\r
-}\r
-void    ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen)\r
-{\r
-    inode->generation = to_le32(gen);\r
-}\r
-\r
-uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,\r
-    struct ext4_sblock *sb)\r
-{\r
-    /*TODO: Verify it*/\r
-    uint64_t v = to_le32(inode->file_acl_lo);\r
-\r
-    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)\r
-        v |= ((uint32_t) to_le16(inode->osd2.linux2.file_acl_high)) << 16;\r
-\r
-\r
-    return v;\r
-}\r
-\r
-void ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb,\r
-    uint64_t acl)\r
-{\r
-    /*TODO: Verify it*/\r
-    inode->file_acl_lo = to_le32((acl << 32) >> 32);\r
-\r
-    if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)\r
-        inode->osd2.linux2.file_acl_high = to_le16(acl >> 32);\r
-}\r
-\r
-\r
-\r
-uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx)\r
-{\r
-    return to_le32(inode->blocks[idx]);\r
-}\r
-void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,\r
-    uint32_t block)\r
-{\r
-    inode->blocks[idx] = to_le32(block);\r
-}\r
-\r
-\r
-uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx)\r
-{\r
-    return to_le32(inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK]);\r
-}\r
-\r
-void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,\r
-    uint32_t block)\r
-{\r
-    inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = to_le32(block);\r
-}\r
-\r
-bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,\r
-    uint32_t type)\r
-{\r
-    return (ext4_inode_get_mode(sb, inode) &\r
-            EXT4_INODE_MODE_TYPE_MASK) == type;\r
-}\r
-\r
-bool    ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f)\r
-{\r
-    return ext4_inode_get_flags(inode) & f;\r
-}\r
-\r
-void    ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f)\r
-{\r
-    uint32_t flags = ext4_inode_get_flags(inode);\r
-    flags = flags & (~f);\r
-    ext4_inode_set_flags(inode, flags);\r
-}\r
-\r
-void    ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f)\r
-{\r
-    uint32_t flags = ext4_inode_get_flags(inode);\r
-    flags = flags | f;\r
-    ext4_inode_set_flags(inode, flags);\r
-}\r
-\r
-bool    ext4_inode_can_truncate(struct ext4_sblock *sb,\r
-    struct ext4_inode *inode)\r
-{\r
-    if ((ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)) ||\r
-            (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)))\r
-        return false;\r
-\r
-    if ((ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) ||\r
-            (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)))\r
-        return true;\r
-\r
-    return false;\r
-}\r
-\r
-\r
-struct ext4_extent_header * ext4_inode_get_extent_header(\r
-    struct ext4_inode *inode)\r
-{\r
-    return (struct ext4_extent_header *) inode->blocks;\r
-}\r
-\r
-/**\r
- * @}\r
- */\r
+/*
+ * Copyright (c) 2013 Grzegorz Kostka (kostka.grzegorz@gmail.com)
+ *
+ *
+ * HelenOS:
+ * Copyright (c) 2012 Martin Sucha
+ * Copyright (c) 2012 Frantisek Princ
+ * All rights reserved.
+ *
+ * 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.
+ */
+
+/** @addtogroup lwext4
+ * @{
+ */
+/**
+ * @file  ext4_inode.c
+ * @brief Inode handle functions
+ */
+
+#include "ext4_config.h"
+#include "ext4_types.h"
+#include "ext4_inode.h"
+#include "ext4_super.h"
+
+/**@brief  Compute number of bits for block count.
+ * @param block_size Filesystem block_size
+ * @return Number of bits
+ */
+static uint32_t ext4_inode_block_bits_count(uint32_t block_size)
+{
+       uint32_t bits = 8;
+       uint32_t size = block_size;
+
+       do {
+               bits++;
+               size = size >> 1;
+       } while (size > 256);
+
+       return bits;
+}
+
+uint32_t ext4_inode_get_mode(struct ext4_sblock *sb, struct ext4_inode *inode)
+{
+       uint32_t v = to_le16(inode->mode);
+
+       if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD) {
+               v |= ((uint32_t)to_le16(inode->osd2.hurd2.mode_high)) << 16;
+       }
+
+       return v;
+}
+
+void ext4_inode_set_mode(struct ext4_sblock *sb, struct ext4_inode *inode,
+                        uint32_t mode)
+{
+       inode->mode = to_le16((mode << 16) >> 16);
+
+       if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_HURD)
+               inode->osd2.hurd2.mode_high = to_le16(mode >> 16);
+}
+
+uint32_t ext4_inode_get_uid(struct ext4_inode *inode)
+{
+       return to_le32(inode->uid);
+}
+
+void ext4_inode_set_uid(struct ext4_inode *inode, uint32_t uid)
+{
+       inode->uid = to_le32(uid);
+}
+
+uint64_t ext4_inode_get_size(struct ext4_sblock *sb, struct ext4_inode *inode)
+{
+       uint64_t v = to_le32(inode->size_lo);
+
+       if ((ext4_get32(sb, rev_level) > 0) &&
+           (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)))
+               v |= ((uint64_t)to_le32(inode->size_hi)) << 32;
+
+       return v;
+}
+
+void ext4_inode_set_size(struct ext4_inode *inode, uint64_t size)
+{
+       inode->size_lo = to_le32((size << 32) >> 32);
+       inode->size_hi = to_le32(size >> 32);
+}
+
+uint32_t ext4_inode_get_csum(struct ext4_sblock *sb, struct ext4_inode *inode)
+{
+       uint16_t inode_size = ext4_get16(sb, inode_size);
+       uint32_t v = to_le16(inode->osd2.linux2.checksum_lo);
+
+       if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)
+               v |= ((uint32_t)to_le16(inode->checksum_hi)) << 16;
+
+       return v;
+}
+
+void ext4_inode_set_csum(struct ext4_sblock *sb, struct ext4_inode *inode,
+                       uint32_t checksum)
+{
+       uint16_t inode_size = ext4_get16(sb, inode_size);
+       inode->osd2.linux2.checksum_lo =
+               to_le16((checksum << 16) >> 16);
+
+       if (inode_size > EXT4_GOOD_OLD_INODE_SIZE)
+               inode->checksum_hi = to_le16(checksum >> 16);
+
+}
+
+uint32_t ext4_inode_get_access_time(struct ext4_inode *inode)
+{
+       return to_le32(inode->access_time);
+}
+void ext4_inode_set_access_time(struct ext4_inode *inode, uint32_t time)
+{
+       inode->access_time = to_le32(time);
+}
+
+uint32_t ext4_inode_get_change_inode_time(struct ext4_inode *inode)
+{
+       return to_le32(inode->change_inode_time);
+}
+void ext4_inode_set_change_inode_time(struct ext4_inode *inode, uint32_t time)
+{
+       inode->change_inode_time = to_le32(time);
+}
+
+uint32_t ext4_inode_get_modif_time(struct ext4_inode *inode)
+{
+       return to_le32(inode->modification_time);
+}
+
+void ext4_inode_set_modif_time(struct ext4_inode *inode, uint32_t time)
+{
+       inode->modification_time = to_le32(time);
+}
+
+uint32_t ext4_inode_get_del_time(struct ext4_inode *inode)
+{
+       return to_le32(inode->deletion_time);
+}
+
+void ext4_inode_set_del_time(struct ext4_inode *inode, uint32_t time)
+{
+       inode->deletion_time = to_le32(time);
+}
+
+uint32_t ext4_inode_get_gid(struct ext4_inode *inode)
+{
+       return to_le32(inode->gid);
+}
+void ext4_inode_set_gid(struct ext4_inode *inode, uint32_t gid)
+{
+       inode->gid = to_le32(gid);
+}
+
+uint16_t ext4_inode_get_links_cnt(struct ext4_inode *inode)
+{
+       return to_le16(inode->links_count);
+}
+void ext4_inode_set_links_cnt(struct ext4_inode *inode, uint16_t cnt)
+{
+       inode->links_count = to_le16(cnt);
+}
+
+uint64_t ext4_inode_get_blocks_count(struct ext4_sblock *sb,
+                                    struct ext4_inode *inode)
+{
+       uint64_t cnt = to_le32(inode->blocks_count_lo);
+
+       if (ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_HUGE_FILE)) {
+
+               /* 48-bit field */
+               cnt |= (uint64_t)to_le16(inode->osd2.linux2.blocks_high) << 32;
+
+               if (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_HUGE_FILE)) {
+
+                       uint32_t block_count = ext4_sb_get_block_size(sb);
+                       uint32_t b = ext4_inode_block_bits_count(block_count);
+                       return cnt << (b - 9);
+               }
+       }
+
+       return cnt;
+}
+
+int ext4_inode_set_blocks_count(struct ext4_sblock *sb,
+                               struct ext4_inode *inode, uint64_t count)
+{
+       /* 32-bit maximum */
+       uint64_t max = 0;
+       max = ~max >> 32;
+
+       if (count <= max) {
+               inode->blocks_count_lo = to_le32(count);
+               inode->osd2.linux2.blocks_high = 0;
+               ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+
+               return EOK;
+       }
+
+       /* Check if there can be used huge files (many blocks) */
+       if (!ext4_sb_feature_ro_com(sb, EXT4_FRO_COM_HUGE_FILE))
+               return EINVAL;
+
+       /* 48-bit maximum */
+       max = 0;
+       max = ~max >> 16;
+
+       if (count <= max) {
+               inode->blocks_count_lo = to_le32(count);
+               inode->osd2.linux2.blocks_high = to_le16(count >> 32);
+               ext4_inode_clear_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+       } else {
+               uint32_t block_count = ext4_sb_get_block_size(sb);
+               uint32_t block_bits =ext4_inode_block_bits_count(block_count);
+
+               ext4_inode_set_flag(inode, EXT4_INODE_FLAG_HUGE_FILE);
+               count = count >> (block_bits - 9);
+               inode->blocks_count_lo = to_le32(count);
+               inode->osd2.linux2.blocks_high = to_le16(count >> 32);
+       }
+
+       return EOK;
+}
+
+uint32_t ext4_inode_get_flags(struct ext4_inode *inode)
+{
+       return to_le32(inode->flags);
+}
+void ext4_inode_set_flags(struct ext4_inode *inode, uint32_t flags)
+{
+       inode->flags = to_le32(flags);
+}
+
+uint32_t ext4_inode_get_generation(struct ext4_inode *inode)
+{
+       return to_le32(inode->generation);
+}
+void ext4_inode_set_generation(struct ext4_inode *inode, uint32_t gen)
+{
+       inode->generation = to_le32(gen);
+}
+
+uint16_t ext4_inode_get_extra_isize(struct ext4_inode *inode)
+{
+       return to_le16(inode->extra_isize);
+}
+
+void ext4_inode_set_extra_isize(struct ext4_inode *inode, uint16_t size)
+{
+       inode->extra_isize = to_le16(size);
+}
+
+uint64_t ext4_inode_get_file_acl(struct ext4_inode *inode,
+                                struct ext4_sblock *sb)
+{
+       uint64_t v = to_le32(inode->file_acl_lo);
+
+       if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
+               v |= (uint32_t)to_le16(inode->osd2.linux2.file_acl_high) << 16;
+
+       return v;
+}
+
+void ext4_inode_set_file_acl(struct ext4_inode *inode, struct ext4_sblock *sb,
+                            uint64_t acl)
+{
+       inode->file_acl_lo = to_le32((acl << 32) >> 32);
+
+       if (ext4_get32(sb, creator_os) == EXT4_SUPERBLOCK_OS_LINUX)
+               inode->osd2.linux2.file_acl_high = to_le16(acl >> 32);
+}
+
+uint32_t ext4_inode_get_direct_block(struct ext4_inode *inode, uint32_t idx)
+{
+       return to_le32(inode->blocks[idx]);
+}
+void ext4_inode_set_direct_block(struct ext4_inode *inode, uint32_t idx,
+                                uint32_t block)
+{
+       inode->blocks[idx] = to_le32(block);
+}
+
+uint32_t ext4_inode_get_indirect_block(struct ext4_inode *inode, uint32_t idx)
+{
+       return to_le32(inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK]);
+}
+
+void ext4_inode_set_indirect_block(struct ext4_inode *inode, uint32_t idx,
+                                  uint32_t block)
+{
+       inode->blocks[idx + EXT4_INODE_INDIRECT_BLOCK] = to_le32(block);
+}
+
+uint32_t ext4_inode_type(struct ext4_sblock *sb, struct ext4_inode *inode)
+{
+       return (ext4_inode_get_mode(sb, inode) & EXT4_INODE_MODE_TYPE_MASK);
+}
+
+bool ext4_inode_is_type(struct ext4_sblock *sb, struct ext4_inode *inode,
+                       uint32_t type)
+{
+       return ext4_inode_type(sb, inode) == type;
+}
+
+bool ext4_inode_has_flag(struct ext4_inode *inode, uint32_t f)
+{
+       return ext4_inode_get_flags(inode) & f;
+}
+
+void ext4_inode_clear_flag(struct ext4_inode *inode, uint32_t f)
+{
+       uint32_t flags = ext4_inode_get_flags(inode);
+       flags = flags & (~f);
+       ext4_inode_set_flags(inode, flags);
+}
+
+void ext4_inode_set_flag(struct ext4_inode *inode, uint32_t f)
+{
+       uint32_t flags = ext4_inode_get_flags(inode);
+       flags = flags | f;
+       ext4_inode_set_flags(inode, flags);
+}
+
+bool ext4_inode_can_truncate(struct ext4_sblock *sb, struct ext4_inode *inode)
+{
+       if ((ext4_inode_has_flag(inode, EXT4_INODE_FLAG_APPEND)) ||
+           (ext4_inode_has_flag(inode, EXT4_INODE_FLAG_IMMUTABLE)))
+               return false;
+
+       if ((ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_FILE)) ||
+           (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_DIRECTORY)) ||
+           (ext4_inode_is_type(sb, inode, EXT4_INODE_MODE_SOFTLINK)))
+               return true;
+
+       return false;
+}
+
+struct ext4_extent_header *
+ext4_inode_get_extent_header(struct ext4_inode *inode)
+{
+       return (struct ext4_extent_header *)inode->blocks;
+}
+
+/**
+ * @}
+ */