Skip to content

Commit

Permalink
Merge pull request #185 from alexlarsson/decode-erofs
Browse files Browse the repository at this point in the history
Add support for decoding erofs into lcfs_node, and some tooling using it
  • Loading branch information
alexlarsson authored Sep 15, 2023
2 parents 9e83d42 + fbdf4e4 commit ca46d09
Show file tree
Hide file tree
Showing 32 changed files with 1,551 additions and 239 deletions.
2 changes: 1 addition & 1 deletion Makefile.am
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SUBDIRS=libcomposefs tools
SUBDIRS=libcomposefs tools tests

EXTRA_DIST=\
composefs.pc.in \
Expand Down
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ AC_CONFIG_FILES([
Makefile
libcomposefs/Makefile
tools/Makefile
tests/Makefile
composefs.spec
composefs.pc
])
Expand Down
1 change: 1 addition & 0 deletions libcomposefs/Makefile-lib.am
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ libcomposefs_la_SOURCES = \
$(COMPOSEFSDIR)/hash.h \
$(COMPOSEFSDIR)/lcfs-internal.h \
$(COMPOSEFSDIR)/lcfs-erofs.h \
$(COMPOSEFSDIR)/lcfs-erofs-internal.h \
$(COMPOSEFSDIR)/lcfs-fsverity.c \
$(COMPOSEFSDIR)/lcfs-fsverity.h \
$(COMPOSEFSDIR)/lcfs-writer-erofs.c \
Expand Down
9 changes: 9 additions & 0 deletions libcomposefs/erofs_fs_wrapper.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#include <stdbool.h>
#include <linux/types.h>

#define __packed __attribute__((__packed__))
Expand Down Expand Up @@ -33,6 +34,14 @@ static inline __u64 le64_to_cpu(__u64 val)
return le64toh(val);
}

/* Note: These only do power of 2 */
#define __round_mask(x, y) ((__typeof__(x))((y)-1))
#define round_up(x, y) ((((x)-1) | __round_mask(x, y)) + 1)
#define round_down(x, y) ((x) & ~__round_mask(x, y))

#define ALIGN_TO(_offset, _align_size) \
(((_offset) + _align_size - 1) & ~(_align_size - 1))

#define BIT(nr) (((uint64_t) 1) << (nr))
#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
Expand Down
134 changes: 134 additions & 0 deletions libcomposefs/lcfs-erofs-internal.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
/* lcfs
Copyright (C) 2023 Alexander Larsson <[email protected]>
This file is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This file is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */

#ifndef _LCFS_EROFS_INTERNAL_H
#define _LCFS_EROFS_INTERNAL_H

#include <string.h>

#include "lcfs-internal.h"
#include "lcfs-erofs.h"
#include "erofs_fs_wrapper.h"

typedef union {
__le16 i_format;
struct erofs_inode_compact compact;
struct erofs_inode_extended extended;
} erofs_inode;

static const char *erofs_xattr_prefixes[] = {
"",
"user.",
"system.posix_acl_access",
"system.posix_acl_default",
"trusted.",
"lustre.",
"security.",
};

static inline uint16_t erofs_inode_version(const erofs_inode *cino)
{
uint16_t i_format = lcfs_u16_from_file(cino->i_format);
return (i_format >> EROFS_I_VERSION_BIT) & EROFS_I_VERSION_MASK;
}

static inline bool erofs_inode_is_compact(const erofs_inode *cino)
{
return erofs_inode_version(cino) == 0;
}

static inline uint16_t erofs_inode_datalayout(const erofs_inode *cino)
{
uint16_t i_format = lcfs_u16_from_file(cino->i_format);
return (i_format >> EROFS_I_DATALAYOUT_BIT) & EROFS_I_DATALAYOUT_MASK;
}

static inline bool erofs_inode_is_tailpacked(const erofs_inode *cino)
{
return erofs_inode_datalayout(cino) == EROFS_INODE_FLAT_INLINE;
}

static inline bool erofs_inode_is_flat(const erofs_inode *cino)
{
return erofs_inode_datalayout(cino) == EROFS_INODE_FLAT_INLINE ||
erofs_inode_datalayout(cino) == EROFS_INODE_FLAT_PLAIN;
}

static inline size_t erofs_xattr_inode_size(uint16_t xattr_icount)
{
size_t xattr_size = 0;
if (xattr_icount > 0)
xattr_size = sizeof(struct erofs_xattr_ibody_header) +
(xattr_icount - 1) * 4;
return xattr_size;
}

#define EROFS_N_XATTR_PREFIXES (sizeof(erofs_xattr_prefixes) / sizeof(char *))

static inline bool erofs_is_acl_xattr(int prefix, const char *name, size_t name_len)
{
const char *const nfs_acl = "system.nfs4_acl";

if ((prefix == EROFS_XATTR_INDEX_POSIX_ACL_ACCESS ||
prefix == EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT) &&
name_len == 0)
return true;
if (prefix == 0 && name_len == strlen(nfs_acl) &&
memcmp(name, nfs_acl, strlen(nfs_acl)) == 0)
return true;
return false;
}

static inline int erofs_get_xattr_prefix(const char *str)
{
for (int i = 1; i < EROFS_N_XATTR_PREFIXES; i++) {
const char *prefix = erofs_xattr_prefixes[i];
if (strlen(str) >= strlen(prefix) &&
memcmp(str, prefix, strlen(prefix)) == 0) {
return i;
}
}
return 0;
}

static inline char *erofs_get_xattr_name(uint8_t index, const char *name,
size_t name_len)
{
char *res;
const char *prefix;
size_t prefix_len;

if (index >= EROFS_N_XATTR_PREFIXES) {
errno = EINVAL;
return NULL;
}

prefix = erofs_xattr_prefixes[index];
prefix_len = strlen(prefix);

res = malloc(prefix_len + name_len + 1);
if (res == NULL) {
errno = ENOMEM;
return NULL;
}
memcpy(res, prefix, prefix_len);
memcpy(res + prefix_len, name, name_len);
res[prefix_len + name_len] = 0;

return res;
}

#endif
31 changes: 31 additions & 0 deletions libcomposefs/lcfs-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,28 @@
*/
#define LCFS_BUILD_INLINE_FILE_SIZE_LIMIT 64

#define OVERLAY_XATTR_USER_PREFIX "user."
#define OVERLAY_XATTR_TRUSTED_PREFIX "trusted."
#define OVERLAY_XATTR_PARTIAL_PREFIX "overlay."
#define OVERLAY_XATTR_PREFIX \
OVERLAY_XATTR_TRUSTED_PREFIX OVERLAY_XATTR_PARTIAL_PREFIX
#define OVERLAY_XATTR_USERXATTR_PREFIX \
OVERLAY_XATTR_USER_PREFIX OVERLAY_XATTR_PARTIAL_PREFIX
#define OVERLAY_XATTR_ESCAPE_PREFIX OVERLAY_XATTR_PREFIX "overlay."
#define OVERLAY_XATTR_METACOPY OVERLAY_XATTR_PREFIX "metacopy"
#define OVERLAY_XATTR_REDIRECT OVERLAY_XATTR_PREFIX "redirect"
#define OVERLAY_XATTR_WHITEOUT OVERLAY_XATTR_PREFIX "whiteout"
#define OVERLAY_XATTR_WHITEOUTS OVERLAY_XATTR_PREFIX "whiteouts"
#define OVERLAY_XATTR_OPAQUE OVERLAY_XATTR_PREFIX "opaque"

#define OVERLAY_XATTR_ESCAPED_WHITEOUT OVERLAY_XATTR_ESCAPE_PREFIX "whiteout"
#define OVERLAY_XATTR_ESCAPED_WHITEOUTS OVERLAY_XATTR_ESCAPE_PREFIX "whiteouts"

#define OVERLAY_XATTR_USERXATTR_WHITEOUT \
OVERLAY_XATTR_USERXATTR_PREFIX "whiteout"
#define OVERLAY_XATTR_USERXATTR_WHITEOUTS \
OVERLAY_XATTR_USERXATTR_PREFIX "whiteouts"

#define ALIGN_TO(_offset, _align_size) \
(((_offset) + _align_size - 1) & ~(_align_size - 1))

Expand Down Expand Up @@ -147,6 +169,15 @@ struct lcfs_ctx_s {
void (*finalize)(struct lcfs_ctx_s *ctx);
};

static inline void lcfs_node_unrefp(struct lcfs_node_s **nodep)
{
if (*nodep != NULL) {
lcfs_node_unref(*nodep);
*nodep = NULL;
}
}
#define cleanup_node __attribute__((cleanup(lcfs_node_unrefp)))

/* lcfs-writer.c */
size_t hash_memory(const char *string, size_t len, size_t n_buckets);
int lcfs_write(struct lcfs_ctx_s *ctx, void *_data, size_t data_len);
Expand Down
29 changes: 29 additions & 0 deletions libcomposefs/lcfs-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,41 @@

#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>

#define max(a, b) ((a > b) ? (a) : (b))
#define min(a, b) (((a) < (b)) ? (a) : (b))

static inline bool str_has_prefix(const char *str, const char *prefix)
{
return strncmp(str, prefix, strlen(prefix)) == 0;
}

static inline char *memdup(const char *s, size_t len)
{
char *s2 = malloc(len);
if (s2 == NULL) {
errno = ENOMEM;
return NULL;
}
memcpy(s2, s, len);
return s2;
}

static inline char *str_join(const char *a, const char *b)
{
size_t a_len = strlen(a);
size_t b_len = strlen(b);
char *res = malloc(a_len + b_len + 1);
if (res) {
memcpy(res, a, a_len);
memcpy(res + a_len, b, b_len + 1);
}
return res;
}

static inline void _lcfs_reset_errno_(int *saved_errno)
{
if (*saved_errno < 0)
Expand Down
Loading

0 comments on commit ca46d09

Please sign in to comment.