[PATCH v7 08/13] erofs-utils: lib: add erofs_read_xattrs_from_disk() helper
Gao Xiang
hsiangkao at linux.alibaba.com
Sun Sep 10 02:32:35 AEST 2023
From: Jingbo Xu <jefflexu at linux.alibaba.com>
Add erofs_read_xattrs_from_disk() helper to reading extended
attributes from disk.
Signed-off-by: Jingbo Xu <jefflexu at linux.alibaba.com>
Signed-off-by: Gao Xiang <hsiangkao at linux.alibaba.com>
---
include/erofs/internal.h | 1 +
include/erofs/xattr.h | 1 +
lib/xattr.c | 69 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 71 insertions(+)
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index ba4d6c6..c711c71 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -192,6 +192,7 @@ struct erofs_inode {
bool compressed_idata;
bool lazy_tailblock;
bool with_tmpfile;
+ bool opaque;
/* OVL: non-merge dir that may contain whiteout entries */
bool whiteouts;
diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 2ecb18e..0364f24 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -58,6 +58,7 @@ 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_set_origin_xattr(struct erofs_inode *inode);
+int erofs_read_xattrs_from_disk(struct erofs_inode *inode);
#ifdef __cplusplus
}
diff --git a/lib/xattr.c b/lib/xattr.c
index d755760..5ed0f0f 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -558,6 +558,75 @@ 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);
+ } else if (S_ISDIR(inode->i_mode) &&
+ !strcmp(key, OVL_XATTR_ORIGIN)) {
+ ret = 0;
+ inode->whiteouts = true;
+ continue;
+ }
+
+ 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.24.4
More information about the Linux-erofs
mailing list