[PATCH v6 04/11] erofs-utils: lib: add erofs_read_xattrs_from_disk() helper
Jingbo Xu
jefflexu at linux.alibaba.com
Tue Sep 5 20:02:20 AEST 2023
Add erofs_read_xattrs_from_disk() helper reading extended attributes
from disk, add checking if it's an opaque directory.
Move all xattr name related macros to xattr.c and introduce
erofs_set_opaque_xattr() helper to hide all these details.
Signed-off-by: Jingbo Xu <jefflexu at linux.alibaba.com>
---
include/erofs/internal.h | 1 +
include/erofs/xattr.h | 33 +-----------
lib/tar.c | 7 +--
lib/xattr.c | 112 +++++++++++++++++++++++++++++++++++++++
4 files changed, 116 insertions(+), 37 deletions(-)
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index 382024a..6020553 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -191,6 +191,7 @@ struct erofs_inode {
bool compressed_idata;
bool lazy_tailblock;
bool with_tmpfile;
+ bool opaque;
unsigned int xattr_isize;
unsigned int extent_isize;
diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index cf02257..9fa1ad1 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -43,37 +43,6 @@ static inline unsigned int xattrblock_offset(struct erofs_inode *vi,
(_size - sizeof(struct erofs_xattr_ibody_header)) / \
sizeof(struct erofs_xattr_entry) + 1; })
-#ifndef XATTR_SYSTEM_PREFIX
-#define XATTR_SYSTEM_PREFIX "system."
-#endif
-#ifndef XATTR_SYSTEM_PREFIX_LEN
-#define XATTR_SYSTEM_PREFIX_LEN (sizeof(XATTR_SYSTEM_PREFIX) - 1)
-#endif
-#ifndef XATTR_USER_PREFIX
-#define XATTR_USER_PREFIX "user."
-#endif
-#ifndef XATTR_USER_PREFIX_LEN
-#define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
-#endif
-#ifndef XATTR_SECURITY_PREFIX
-#define XATTR_SECURITY_PREFIX "security."
-#endif
-#ifndef XATTR_SECURITY_PREFIX_LEN
-#define XATTR_SECURITY_PREFIX_LEN (sizeof(XATTR_SECURITY_PREFIX) - 1)
-#endif
-#ifndef XATTR_TRUSTED_PREFIX
-#define XATTR_TRUSTED_PREFIX "trusted."
-#endif
-#ifndef XATTR_TRUSTED_PREFIX_LEN
-#define XATTR_TRUSTED_PREFIX_LEN (sizeof(XATTR_TRUSTED_PREFIX) - 1)
-#endif
-#ifndef XATTR_NAME_POSIX_ACL_ACCESS
-#define XATTR_NAME_POSIX_ACL_ACCESS "system.posix_acl_access"
-#endif
-#ifndef XATTR_NAME_POSIX_ACL_DEFAULT
-#define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
-#endif
-
int erofs_scan_file_xattrs(struct erofs_inode *inode);
int erofs_prepare_xattr_ibody(struct erofs_inode *inode);
char *erofs_export_xattr_ibody(struct erofs_inode *inode);
@@ -87,6 +56,8 @@ int erofs_xattr_prefixes_init(struct erofs_sb_info *sbi);
int erofs_setxattr(struct erofs_inode *inode, char *key,
const void *value, size_t size);
+int erofs_set_opaque_xattr(struct erofs_inode *inode);
+int erofs_read_xattrs_from_disk(struct erofs_inode *inode);
#ifdef __cplusplus
}
diff --git a/lib/tar.c b/lib/tar.c
index 53196c1..5b63cf5 100644
--- a/lib/tar.c
+++ b/lib/tar.c
@@ -19,11 +19,6 @@
#include "erofs/xattr.h"
#include "erofs/blobchunk.h"
-#define OVL_XATTR_NAMESPACE "overlay."
-#define OVL_XATTR_TRUSTED_PREFIX XATTR_TRUSTED_PREFIX OVL_XATTR_NAMESPACE
-#define OVL_XATTR_OPAQUE_POSTFIX "opaque"
-#define OVL_XATTR_OPAQUE OVL_XATTR_TRUSTED_PREFIX OVL_XATTR_OPAQUE_POSTFIX
-
#define EROFS_WHITEOUT_DEV 0
static char erofs_libbuf[16384];
@@ -788,7 +783,7 @@ restart:
} else if (opq) {
DBG_BUGON(d->type == EROFS_FT_UNKNOWN);
DBG_BUGON(!d->inode);
- ret = erofs_setxattr(d->inode, OVL_XATTR_OPAQUE, "y", 1);
+ ret = erofs_set_opaque_xattr(d->inode);
goto out;
} else if (th.typeflag == '1') { /* hard link cases */
struct erofs_dentry *d2;
diff --git a/lib/xattr.c b/lib/xattr.c
index 5acc1ae..cc6a393 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -21,6 +21,49 @@
#include "erofs/xxhash.h"
#include "liberofs_private.h"
+#ifndef XATTR_SYSTEM_PREFIX
+#define XATTR_SYSTEM_PREFIX "system."
+#endif
+#ifndef XATTR_SYSTEM_PREFIX_LEN
+#define XATTR_SYSTEM_PREFIX_LEN (sizeof(XATTR_SYSTEM_PREFIX) - 1)
+#endif
+#ifndef XATTR_USER_PREFIX
+#define XATTR_USER_PREFIX "user."
+#endif
+#ifndef XATTR_USER_PREFIX_LEN
+#define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
+#endif
+#ifndef XATTR_SECURITY_PREFIX
+#define XATTR_SECURITY_PREFIX "security."
+#endif
+#ifndef XATTR_SECURITY_PREFIX_LEN
+#define XATTR_SECURITY_PREFIX_LEN (sizeof(XATTR_SECURITY_PREFIX) - 1)
+#endif
+#ifndef XATTR_TRUSTED_PREFIX
+#define XATTR_TRUSTED_PREFIX "trusted."
+#endif
+#ifndef XATTR_TRUSTED_PREFIX_LEN
+#define XATTR_TRUSTED_PREFIX_LEN (sizeof(XATTR_TRUSTED_PREFIX) - 1)
+#endif
+#ifndef XATTR_NAME_POSIX_ACL_ACCESS
+#define XATTR_NAME_POSIX_ACL_ACCESS "system.posix_acl_access"
+#endif
+#ifndef XATTR_NAME_POSIX_ACL_DEFAULT
+#define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
+#endif
+#ifndef OVL_XATTR_NAMESPACE
+#define OVL_XATTR_NAMESPACE "overlay."
+#endif
+#ifndef OVL_XATTR_OPAQUE_POSTFIX
+#define OVL_XATTR_OPAQUE_POSTFIX "opaque"
+#endif
+#ifndef OVL_XATTR_TRUSTED_PREFIX
+#define OVL_XATTR_TRUSTED_PREFIX XATTR_TRUSTED_PREFIX OVL_XATTR_NAMESPACE
+#endif
+#ifndef OVL_XATTR_OPAQUE
+#define OVL_XATTR_OPAQUE OVL_XATTR_TRUSTED_PREFIX OVL_XATTR_OPAQUE_POSTFIX
+#endif
+
#define EA_HASHTABLE_BITS 16
struct xattr_item {
@@ -441,6 +484,11 @@ int erofs_setxattr(struct erofs_inode *inode, char *key,
return erofs_xattr_add(&inode->i_xattrs, item);
}
+int erofs_set_opaque_xattr(struct erofs_inode *inode)
+{
+ return erofs_setxattr(inode, OVL_XATTR_OPAQUE, "y", 1);
+}
+
#ifdef WITH_ANDROID
static int erofs_droid_xattr_set_caps(struct erofs_inode *inode)
{
@@ -497,6 +545,70 @@ int erofs_scan_file_xattrs(struct erofs_inode *inode)
return erofs_droid_xattr_set_caps(inode);
}
+int erofs_read_xattrs_from_disk(struct erofs_inode *inode)
+{
+ ssize_t kllen;
+ char *keylst, *key;
+ int ret;
+
+ init_list_head(&inode->i_xattrs);
+ kllen = erofs_listxattr(inode, NULL, 0);
+ if (kllen < 0)
+ return kllen;
+ if (kllen <= 1)
+ return 0;
+
+ keylst = malloc(kllen);
+ if (!keylst)
+ return -ENOMEM;
+
+ ret = erofs_listxattr(inode, keylst, kllen);
+ if (ret < 0)
+ goto out;
+
+ for (key = keylst; key < keylst + kllen; key += strlen(key) + 1) {
+ void *value = NULL;
+ size_t size = 0;
+
+ if (!strcmp(key, OVL_XATTR_OPAQUE)) {
+ if (!S_ISDIR(inode->i_mode)) {
+ erofs_dbg("file %s: opaque xattr on non-dir",
+ inode->i_srcpath);
+ ret = -EINVAL;
+ goto out;
+ }
+ inode->opaque = true;
+ }
+
+ ret = erofs_getxattr(inode, key, NULL, 0);
+ if (ret < 0)
+ goto out;
+ if (ret) {
+ size = ret;
+ value = malloc(size);
+ if (!value) {
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ ret = erofs_getxattr(inode, key, value, size);
+ if (ret < 0) {
+ free(value);
+ goto out;
+ }
+ DBG_BUGON(ret != size);
+ }
+
+ ret = erofs_setxattr(inode, key, value, size);
+ free(value);
+ if (ret)
+ break;
+ }
+out:
+ free(keylst);
+ return ret;
+}
+
int erofs_prepare_xattr_ibody(struct erofs_inode *inode)
{
int ret;
--
2.19.1.6.gb485710b
More information about the Linux-erofs
mailing list