All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] erofs-utils: fuse: support get/list xattr
@ 2022-08-03 14:22 Sheng Yong via Linux-erofs
  2022-08-03 14:22 ` [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir Sheng Yong via Linux-erofs
                   ` (2 more replies)
  0 siblings, 3 replies; 14+ messages in thread
From: Sheng Yong via Linux-erofs @ 2022-08-03 14:22 UTC (permalink / raw)
  To: xiang, bluce.lee, linux-erofs, chao; +Cc: shengyong

Hi erofs folks,

I tried to make an erofs image based on an existing image. However,
the fuse client does not support xattr operations, so that the new
image cannot inherit xattrs from the old one which is mouted through
fuse.

So this patchset adds xattr support for erofs fuse client. Besides,
readdir is also modified to help mkfs.erofs get the correct file
type.

Sheng Yong (3):
  erofs-utils: fuse: set d_type for readdir
  erofs-utils: fuse: export erofs_xattr_foreach
  erofs-utils: fuse: support get/list xattr

 fsck/main.c           |  85 ++++--------------------
 fuse/main.c           | 140 ++++++++++++++++++++++++++++++++++++++-
 include/erofs/inode.h |   1 +
 include/erofs/xattr.h |  15 ++++-
 lib/inode.c           |  19 ++++++
 lib/xattr.c           | 149 ++++++++++++++++++++++++++++++++++++++++--
 6 files changed, 330 insertions(+), 79 deletions(-)

--
2.25.1

________________________________
OPPO

本电子邮件及其附件含有OPPO公司的保密信息,仅限于邮件指明的收件人使用(包含个人及群组)。禁止任何人在未经授权的情况下以任何形式使用。如果您错收了本邮件,请立即以电子邮件通知发件人并删除本邮件及其附件。

This e-mail and its attachments contain confidential information from OPPO, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir
  2022-08-03 14:22 [RFC PATCH 0/3] erofs-utils: fuse: support get/list xattr Sheng Yong via Linux-erofs
@ 2022-08-03 14:22 ` Sheng Yong via Linux-erofs
  2022-08-03 19:43   ` Gao Xiang
  2022-08-03 14:22 ` [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach Sheng Yong via Linux-erofs
  2022-08-03 14:22 ` [RFC PATCH 3/3] erofs-utils: fuse: support get/list xattr Sheng Yong via Linux-erofs
  2 siblings, 1 reply; 14+ messages in thread
From: Sheng Yong via Linux-erofs @ 2022-08-03 14:22 UTC (permalink / raw)
  To: xiang, bluce.lee, linux-erofs, chao; +Cc: shengyong

Set inode mode for libfuse readdir filler so that readdir count get
correct d_type.

Signed-off-by: Sheng Yong <shengyong@oppo.com>
---
 fuse/main.c           |  5 ++++-
 include/erofs/inode.h |  1 +
 lib/inode.c           | 19 +++++++++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/fuse/main.c b/fuse/main.c
index 95f939e..345bcb5 100644
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -13,6 +13,7 @@
 #include "erofs/print.h"
 #include "erofs/io.h"
 #include "erofs/dir.h"
+#include "erofs/inode.h"

 struct erofsfuse_dir_context {
        struct erofs_dir_context ctx;
@@ -24,11 +25,13 @@ struct erofsfuse_dir_context {
 static int erofsfuse_fill_dentries(struct erofs_dir_context *ctx)
 {
        struct erofsfuse_dir_context *fusectx = (void *)ctx;
+       struct stat st = {0};
        char dname[EROFS_NAME_LEN + 1];

        strncpy(dname, ctx->dname, ctx->de_namelen);
        dname[ctx->de_namelen] = '\0';
-       fusectx->filler(fusectx->buf, dname, NULL, 0);
+       st.st_mode = erofs_ftype_to_dtype(ctx->de_ftype) << 12;
+       fusectx->filler(fusectx->buf, dname, &st, 0);
        return 0;
 }

diff --git a/include/erofs/inode.h b/include/erofs/inode.h
index 79b39b0..79b8d89 100644
--- a/include/erofs/inode.h
+++ b/include/erofs/inode.h
@@ -16,6 +16,7 @@ extern "C"
 #include "erofs/internal.h"

 unsigned char erofs_mode_to_ftype(umode_t mode);
+unsigned char erofs_ftype_to_dtype(unsigned int filetype);
 void erofs_inode_manager_init(void);
 unsigned int erofs_iput(struct erofs_inode *inode);
 erofs_nid_t erofs_lookupnid(struct erofs_inode *inode);
diff --git a/lib/inode.c b/lib/inode.c
index f192510..ce75014 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -43,6 +43,25 @@ unsigned char erofs_mode_to_ftype(umode_t mode)
        return erofs_ftype_by_mode[(mode & S_IFMT) >> S_SHIFT];
 }

+static const unsigned char erofs_dtype_by_ftype[EROFS_FT_MAX] = {
+       [EROFS_FT_UNKNOWN]      = DT_UNKNOWN,
+       [EROFS_FT_REG_FILE]     = DT_REG,
+       [EROFS_FT_DIR]          = DT_DIR,
+       [EROFS_FT_CHRDEV]       = DT_CHR,
+       [EROFS_FT_BLKDEV]       = DT_BLK,
+       [EROFS_FT_FIFO]         = DT_FIFO,
+       [EROFS_FT_SOCK]         = DT_SOCK,
+       [EROFS_FT_SYMLINK]      = DT_LNK
+};
+
+unsigned char erofs_ftype_to_dtype(unsigned int filetype)
+{
+       if (filetype >= EROFS_FT_MAX)
+               return DT_UNKNOWN;
+
+       return erofs_dtype_by_ftype[filetype];
+}
+
 #define NR_INODE_HASHTABLE     16384

 struct list_head inode_hashtable[NR_INODE_HASHTABLE];
--
2.25.1

________________________________
OPPO

本电子邮件及其附件含有OPPO公司的保密信息,仅限于邮件指明的收件人使用(包含个人及群组)。禁止任何人在未经授权的情况下以任何形式使用。如果您错收了本邮件,请立即以电子邮件通知发件人并删除本邮件及其附件。

This e-mail and its attachments contain confidential information from OPPO, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach
  2022-08-03 14:22 [RFC PATCH 0/3] erofs-utils: fuse: support get/list xattr Sheng Yong via Linux-erofs
  2022-08-03 14:22 ` [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir Sheng Yong via Linux-erofs
@ 2022-08-03 14:22 ` Sheng Yong via Linux-erofs
  2022-08-03 19:46   ` Gao Xiang
  2022-08-03 14:22 ` [RFC PATCH 3/3] erofs-utils: fuse: support get/list xattr Sheng Yong via Linux-erofs
  2 siblings, 1 reply; 14+ messages in thread
From: Sheng Yong via Linux-erofs @ 2022-08-03 14:22 UTC (permalink / raw)
  To: xiang, bluce.lee, linux-erofs, chao; +Cc: shengyong

This patch exports erofs_xattr_foreach() to iterate all xattrs.
Each xattr entry is handled by operations defined in `struct
xattr_iter_ops'.

Signed-off-by: Sheng Yong <shengyong@oppo.com>
---
 fsck/main.c           |  83 ++++------------------------
 include/erofs/xattr.h |   7 ++-
 lib/xattr.c           | 123 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 139 insertions(+), 74 deletions(-)

diff --git a/fsck/main.c b/fsck/main.c
index 5a2f659..237ccc1 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -14,6 +14,7 @@
 #include "erofs/compress.h"
 #include "erofs/decompress.h"
 #include "erofs/dir.h"
+#include "erofs/xattr.h"

 static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid);

@@ -283,82 +284,18 @@ static int erofs_check_sb_chksum(void)
        return 0;
 }

-static int erofs_verify_xattr(struct erofs_inode *inode)
+static int erofs_verify_xattr_entry(const struct erofs_xattr_entry *entry)
 {
-       unsigned int xattr_hdr_size = sizeof(struct erofs_xattr_ibody_header);
-       unsigned int xattr_entry_size = sizeof(struct erofs_xattr_entry);
-       erofs_off_t addr;
-       unsigned int ofs, xattr_shared_count;
-       struct erofs_xattr_ibody_header *ih;
-       struct erofs_xattr_entry *entry;
-       int i, remaining = inode->xattr_isize, ret = 0;
-       char buf[EROFS_BLKSIZ];
-
-       if (inode->xattr_isize == xattr_hdr_size) {
-               erofs_err("xattr_isize %d of nid %llu is not supported yet",
-                         inode->xattr_isize, inode->nid | 0ULL);
-               ret = -EFSCORRUPTED;
-               goto out;
-       } else if (inode->xattr_isize < xattr_hdr_size) {
-               if (inode->xattr_isize) {
-                       erofs_err("bogus xattr ibody @ nid %llu",
-                                 inode->nid | 0ULL);
-                       ret = -EFSCORRUPTED;
-                       goto out;
-               }
-       }
-
-       addr = iloc(inode->nid) + inode->inode_isize;
-       ret = dev_read(0, buf, addr, xattr_hdr_size);
-       if (ret < 0) {
-               erofs_err("failed to read xattr header @ nid %llu: %d",
-                         inode->nid | 0ULL, ret);
-               goto out;
-       }
-       ih = (struct erofs_xattr_ibody_header *)buf;
-       xattr_shared_count = ih->h_shared_count;
-
-       ofs = erofs_blkoff(addr) + xattr_hdr_size;
-       addr += xattr_hdr_size;
-       remaining -= xattr_hdr_size;
-       for (i = 0; i < xattr_shared_count; ++i) {
-               if (ofs >= EROFS_BLKSIZ) {
-                       if (ofs != EROFS_BLKSIZ) {
-                               erofs_err("unaligned xattr entry in xattr shared area @ nid %llu",
-                                         inode->nid | 0ULL);
-                               ret = -EFSCORRUPTED;
-                               goto out;
-                       }
-                       ofs = 0;
-               }
-               ofs += xattr_entry_size;
-               addr += xattr_entry_size;
-               remaining -= xattr_entry_size;
-       }
-
-       while (remaining > 0) {
-               unsigned int entry_sz;
+       return 0;
+}

-               ret = dev_read(0, buf, addr, xattr_entry_size);
-               if (ret) {
-                       erofs_err("failed to read xattr entry @ nid %llu: %d",
-                                 inode->nid | 0ULL, ret);
-                       goto out;
-               }
+struct xattr_iter_ops erofs_verify_xattr_ops = {
+       .verify = erofs_verify_xattr_entry,
+};

-               entry = (struct erofs_xattr_entry *)buf;
-               entry_sz = erofs_xattr_entry_size(entry);
-               if (remaining < entry_sz) {
-                       erofs_err("xattr on-disk corruption: xattr entry beyond xattr_isize @ nid %llu",
-                                 inode->nid | 0ULL);
-                       ret = -EFSCORRUPTED;
-                       goto out;
-               }
-               addr += entry_sz;
-               remaining -= entry_sz;
-       }
-out:
-       return ret;
+static int erofs_verify_xattr(struct erofs_inode *inode)
+{
+       return erofs_xattr_foreach(inode, &erofs_verify_xattr_ops, NULL);
 }

 static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index 226e984..c592d47 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -45,10 +45,15 @@ extern "C"
 #define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
 #endif

+struct xattr_iter_ops {
+       int (*verify)(const struct erofs_xattr_entry *entry);
+};
+
 int erofs_prepare_xattr_ibody(struct erofs_inode *inode);
 char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size);
 int erofs_build_shared_xattrs_from_path(const char *path);
-
+int erofs_xattr_foreach(struct erofs_inode *vi, struct xattr_iter_ops *ops,
+                       void *data);
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/xattr.c b/lib/xattr.c
index c8ce278..92c155d 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -714,3 +714,126 @@ char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size)
        DBG_BUGON(p > size);
        return buf;
 }
+
+static struct erofs_xattr_entry *read_xattr_entry(erofs_blk_t addr,
+                                                 char *buf, size_t size)
+{
+       struct erofs_xattr_entry *entry;
+       size_t entry_sz = sizeof(struct erofs_xattr_entry);
+       int ret;
+
+       if (size < entry_sz)
+               return ERR_PTR(-ERANGE);
+
+       ret = dev_read(0, buf, addr, entry_sz);
+       if (ret) {
+               erofs_err("failed to read xattr entry at addr %x: %d",
+                         addr, ret);
+               return ERR_PTR(ret);
+       }
+
+       entry = (struct erofs_xattr_entry *)buf;
+       entry_sz = erofs_xattr_entry_size(entry);
+       if (size < entry_sz)
+               return ERR_PTR(-ERANGE);
+
+       ret = dev_read(0, buf, addr, entry_sz);
+       if (ret) {
+               erofs_err("failed to read xattr entry at addr %x: %d",
+                         addr, ret);
+               return ERR_PTR(ret);
+       }
+
+       return entry;
+}
+
+int erofs_xattr_foreach(struct erofs_inode *vi, struct xattr_iter_ops *ops,
+                       void *data)
+{
+       unsigned int xattr_hdr_size = sizeof(struct erofs_xattr_ibody_header);
+       unsigned int xattr_entry_size = sizeof(struct erofs_xattr_entry);
+       erofs_off_t addr;
+       unsigned int ofs, xattr_shared_count;
+       struct erofs_xattr_ibody_header *ih;
+       struct erofs_xattr_entry *entry;
+       int i, remaining = vi->xattr_isize, ret = 0;
+       char buf[EROFS_BLKSIZ];
+
+       if (vi->xattr_isize == xattr_hdr_size) {
+               erofs_err("xattr_isize %d of nid %llu is not supported yet",
+                         vi->xattr_isize, vi->nid | 0ULL);
+               return -EFSCORRUPTED;
+       } else if (vi->xattr_isize < xattr_hdr_size) {
+               if (vi->xattr_isize) {
+                       erofs_err("bogus xattr ibody @ nid %llu",
+                                 vi->nid | 0ULL);
+                       return -EFSCORRUPTED;
+               }
+       }
+
+       addr = iloc(vi->nid) + vi->inode_isize;
+       ret = dev_read(0, buf, addr, xattr_hdr_size);
+       if (ret < 0) {
+               erofs_err("failed to read xattr header @ nid %llu: %d",
+                         vi->nid | 0ULL, ret);
+               return ret;
+       }
+       ih = (struct erofs_xattr_ibody_header *)buf;
+       xattr_shared_count = ih->h_shared_count;
+
+       ofs = erofs_blkoff(addr) + xattr_hdr_size;
+       addr += xattr_hdr_size;
+       ret = dev_read(0, buf, addr, xattr_entry_size * xattr_shared_count);
+       remaining -= xattr_hdr_size;
+       for (i = 0; i < xattr_shared_count; ++i) {
+               unsigned int xattr_id;
+               erofs_blk_t xattr_addr;
+               char tmp[EROFS_BLKSIZ];
+
+               if (ofs >= EROFS_BLKSIZ) {
+                       if (ofs != EROFS_BLKSIZ) {
+                               erofs_err("unaligned xattr entry in xattr shared area @ nid %llu",
+                                         vi->nid | 0ULL);
+                               return -EFSCORRUPTED;
+                       }
+                       ofs = 0;
+               }
+
+               xattr_id = le32_to_cpu(*((__le32 *)buf + i));
+               xattr_addr = sbi.xattr_blkaddr * EROFS_BLKSIZ +  4 * xattr_id;
+
+               entry = read_xattr_entry(xattr_addr, tmp, EROFS_BLKSIZ);
+               if (IS_ERR(entry))
+                       return PTR_ERR(entry);
+
+               if (ops->verify) {
+                       ret = ops->verify(entry);
+                       if (ret < 0)
+                               return ret;
+               }
+
+               ofs += xattr_entry_size;
+               addr += xattr_entry_size;
+               remaining -= xattr_entry_size;
+       }
+
+       while (remaining > 0) {
+               unsigned int entry_sz;
+
+               entry = read_xattr_entry(addr, buf, EROFS_BLKSIZ);
+               if (IS_ERR(entry))
+                       return PTR_ERR(entry);
+               entry_sz = erofs_xattr_entry_size(entry);
+
+               if (ops->verify) {
+                       ret = ops->verify(entry);
+                       if (ret < 0)
+                               return ret;
+               }
+               addr += entry_sz;
+               remaining -= entry_sz;
+       }
+
+       return ret;
+
+}
--
2.25.1

________________________________
OPPO

本电子邮件及其附件含有OPPO公司的保密信息,仅限于邮件指明的收件人使用(包含个人及群组)。禁止任何人在未经授权的情况下以任何形式使用。如果您错收了本邮件,请立即以电子邮件通知发件人并删除本邮件及其附件。

This e-mail and its attachments contain confidential information from OPPO, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [RFC PATCH 3/3] erofs-utils: fuse: support get/list xattr
  2022-08-03 14:22 [RFC PATCH 0/3] erofs-utils: fuse: support get/list xattr Sheng Yong via Linux-erofs
  2022-08-03 14:22 ` [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir Sheng Yong via Linux-erofs
  2022-08-03 14:22 ` [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach Sheng Yong via Linux-erofs
@ 2022-08-03 14:22 ` Sheng Yong via Linux-erofs
  2 siblings, 0 replies; 14+ messages in thread
From: Sheng Yong via Linux-erofs @ 2022-08-03 14:22 UTC (permalink / raw)
  To: xiang, bluce.lee, linux-erofs, chao; +Cc: shengyong

Add new options get and list to xattr iteration operations to
support getxattr and listxattr.

Signed-off-by: Sheng Yong <shengyong@oppo.com>
---
 fsck/main.c           |   2 +
 fuse/main.c           | 135 ++++++++++++++++++++++++++++++++++++++++++
 include/erofs/xattr.h |   8 +++
 lib/xattr.c           |  26 ++++++--
 4 files changed, 167 insertions(+), 4 deletions(-)

diff --git a/fsck/main.c b/fsck/main.c
index 237ccc1..ceaab3d 100644
--- a/fsck/main.c
+++ b/fsck/main.c
@@ -291,6 +291,8 @@ static int erofs_verify_xattr_entry(const struct erofs_xattr_entry *entry)

 struct xattr_iter_ops erofs_verify_xattr_ops = {
        .verify = erofs_verify_xattr_entry,
+       .list = NULL,
+       .get = NULL,
 };

 static int erofs_verify_xattr(struct erofs_inode *inode)
diff --git a/fuse/main.c b/fuse/main.c
index 345bcb5..7997234 100644
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -14,6 +14,7 @@
 #include "erofs/io.h"
 #include "erofs/dir.h"
 #include "erofs/inode.h"
+#include "erofs/xattr.h"

 struct erofsfuse_dir_context {
        struct erofs_dir_context ctx;
@@ -142,6 +143,138 @@ static int erofsfuse_readlink(const char *path, char *buffer, size_t size)
        return 0;
 }

+struct listxattr_iter {
+       char *buffer;
+       size_t size;
+       unsigned int ofs;
+};
+
+static int list_one_xattr(const struct erofs_xattr_entry *entry, void *data)
+{
+       struct listxattr_iter *it = (struct listxattr_iter *)data;
+       const char *prefix = xattr_types[entry->e_name_index].prefix;
+       unsigned int prefix_len = xattr_types[entry->e_name_index].prefix_len;
+       int i;
+
+       /* if size is 0, return the total size without copying data */
+       if (it->size == 0) {
+               it->ofs += prefix_len + entry->e_name_len + 1;
+               return it->ofs;
+       }
+
+       if (it->ofs + prefix_len + entry->e_name_len + 1 > it->size)
+               return -ERANGE;
+
+       switch (entry->e_name_index) {
+       case EROFS_XATTR_INDEX_USER:
+       case EROFS_XATTR_INDEX_TRUSTED:
+       case EROFS_XATTR_INDEX_SECURITY:
+               memcpy(it->buffer + it->ofs, prefix, prefix_len);
+               it->ofs += prefix_len;
+               for (i = 0; i < entry->e_name_len; i++, it->ofs++)
+                       it->buffer[it->ofs] = entry->e_name[i];
+               it->buffer[it->ofs++] = '\0';
+               break;
+       case EROFS_XATTR_INDEX_POSIX_ACL_ACCESS:
+       case EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT:
+               memcpy(it->buffer + it->ofs, prefix, prefix_len);
+               it->ofs += prefix_len;
+               it->buffer[it->ofs++] = '\0';
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       return it->ofs;
+}
+
+struct xattr_iter_ops erofs_listxattr_ops = {
+       .verify = NULL,
+       .list = list_one_xattr,
+       .get = NULL,
+};
+
+static int erofsfuse_listxattr(const char *path, char *list, size_t size)
+{
+       struct erofs_inode vi = {};
+       struct listxattr_iter it = {
+               .buffer = list,
+               .size = size,
+               .ofs = 0,
+       };
+
+       erofs_dbg("listxattr(%s) size %zu", path, size);
+       if (erofs_ilookup(path, &vi))
+               return -ENOENT;
+
+       return erofs_xattr_foreach(&vi, &erofs_listxattr_ops, &it);
+}
+
+struct getxattr_iter {
+       const char *name;
+       char *buffer;
+       size_t size;
+};
+
+static int get_one_xattr(const struct erofs_xattr_entry *entry, void *data)
+{
+       struct getxattr_iter *it = (struct getxattr_iter *)data;
+       const char *prefix = xattr_types[entry->e_name_index].prefix;
+       int prefix_len = xattr_types[entry->e_name_index].prefix_len;
+       int name_len, val_len;
+
+       name_len = entry->e_name_len;
+       if (strlen(it->name) != prefix_len + name_len  ||
+           strncmp(it->name, prefix, prefix_len) ||
+           strncmp(it->name + prefix_len, entry->e_name, name_len))
+               /* not match */
+               return -ENODATA;
+
+       val_len = le16_to_cpu(entry->e_value_size);
+       if (it->size == 0)
+               return val_len;
+       if (val_len > it->size)
+               return -ERANGE;
+
+       switch (entry->e_name_index) {
+       case EROFS_XATTR_INDEX_USER:
+       case EROFS_XATTR_INDEX_POSIX_ACL_ACCESS:
+       case EROFS_XATTR_INDEX_POSIX_ACL_DEFAULT:
+       case EROFS_XATTR_INDEX_TRUSTED:
+       case EROFS_XATTR_INDEX_SECURITY:
+               memcpy(it->buffer, entry->e_name + name_len, val_len);
+               break;
+       default:
+               return -EINVAL;
+       }
+
+       /* found */
+       return val_len;
+}
+
+struct xattr_iter_ops erofs_getxattr_ops = {
+       .verify = NULL,
+       .list = NULL,
+       .get = get_one_xattr,
+};
+
+static int erofsfuse_getxattr(const char *path, const char *name,
+                             char *value, size_t size)
+{
+       struct erofs_inode vi = {};
+       struct getxattr_iter it = {
+               .name = name,
+               .buffer = value,
+               .size = size,
+       };
+
+       erofs_dbg("getxattr(%s) name %s size %zu", path, name, size);
+       if (erofs_ilookup(path, &vi))
+               return -ENOENT;
+
+       return erofs_xattr_foreach(&vi, &erofs_getxattr_ops, &it);
+}
+
 static struct fuse_operations erofs_ops = {
        .readlink = erofsfuse_readlink,
        .getattr = erofsfuse_getattr,
@@ -149,6 +282,8 @@ static struct fuse_operations erofs_ops = {
        .open = erofsfuse_open,
        .read = erofsfuse_read,
        .init = erofsfuse_init,
+       .listxattr = erofsfuse_listxattr,
+       .getxattr = erofsfuse_getxattr,
 };

 static struct options {
diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
index c592d47..eea3a2a 100644
--- a/include/erofs/xattr.h
+++ b/include/erofs/xattr.h
@@ -45,8 +45,16 @@ extern "C"
 #define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
 #endif

+struct xattr_prefix {
+       const char *prefix;
+       u16 prefix_len;
+};
+extern struct xattr_prefix xattr_types[];
+
 struct xattr_iter_ops {
        int (*verify)(const struct erofs_xattr_entry *entry);
+       int (*list)(const struct erofs_xattr_entry *entry, void *data);
+       int (*get)(const struct erofs_xattr_entry *entry, void *data);
 };

 int erofs_prepare_xattr_ibody(struct erofs_inode *inode);
diff --git a/lib/xattr.c b/lib/xattr.c
index 92c155d..eed3c71 100644
--- a/lib/xattr.c
+++ b/lib/xattr.c
@@ -39,10 +39,7 @@ static DECLARE_HASHTABLE(ea_hashtable, EA_HASHTABLE_BITS);
 static LIST_HEAD(shared_xattrs_list);
 static unsigned int shared_xattrs_count, shared_xattrs_size;

-static struct xattr_prefix {
-       const char *prefix;
-       u16 prefix_len;
-} xattr_types[] = {
+struct xattr_prefix xattr_types[] = {
        [EROFS_XATTR_INDEX_USER] = {
                XATTR_USER_PREFIX,
                XATTR_USER_PREFIX_LEN
@@ -811,6 +808,17 @@ int erofs_xattr_foreach(struct erofs_inode *vi, struct xattr_iter_ops *ops,
                        if (ret < 0)
                                return ret;
                }
+               if (ops->list) {
+                       ret = ops->list(entry, data);
+                       if (ret < 0)
+                               return ret;
+               }
+               if (ops->get) {
+                       ret = ops->get(entry, data);
+                       if ((ret < 0 && ret != -ENODATA) || ret >= 0)
+                               /* error or found */
+                               return ret;
+               }

                ofs += xattr_entry_size;
                addr += xattr_entry_size;
@@ -830,6 +838,16 @@ int erofs_xattr_foreach(struct erofs_inode *vi, struct xattr_iter_ops *ops,
                        if (ret < 0)
                                return ret;
                }
+               if (ops->list) {
+                       ret = ops->list(entry, data);
+                       if (ret < 0)
+                               return ret;
+               }
+               if (ops->get) {
+                       ret = ops->get(entry, data);
+                       if ((ret < 0 && ret != -ENODATA) || ret >= 0)
+                               return ret;
+               }
                addr += entry_sz;
                remaining -= entry_sz;
        }
--
2.25.1

________________________________
OPPO

本电子邮件及其附件含有OPPO公司的保密信息,仅限于邮件指明的收件人使用(包含个人及群组)。禁止任何人在未经授权的情况下以任何形式使用。如果您错收了本邮件,请立即以电子邮件通知发件人并删除本邮件及其附件。

This e-mail and its attachments contain confidential information from OPPO, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir
  2022-08-03 14:22 ` [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir Sheng Yong via Linux-erofs
@ 2022-08-03 19:43   ` Gao Xiang
  2022-08-04 15:02     ` Gao Xiang
  0 siblings, 1 reply; 14+ messages in thread
From: Gao Xiang @ 2022-08-03 19:43 UTC (permalink / raw)
  To: Sheng Yong; +Cc: linux-erofs

On Wed, Aug 03, 2022 at 10:22:21PM +0800, Sheng Yong wrote:
> Set inode mode for libfuse readdir filler so that readdir count get
> correct d_type.
> 
> Signed-off-by: Sheng Yong <shengyong@oppo.com>

Reviewed-by: Gao Xiang <xiang@kernel.org>

Thanks,
Gao Xiang

> ---
>  fuse/main.c           |  5 ++++-
>  include/erofs/inode.h |  1 +
>  lib/inode.c           | 19 +++++++++++++++++++
>  3 files changed, 24 insertions(+), 1 deletion(-)
> 
> diff --git a/fuse/main.c b/fuse/main.c
> index 95f939e..345bcb5 100644
> --- a/fuse/main.c
> +++ b/fuse/main.c
> @@ -13,6 +13,7 @@
>  #include "erofs/print.h"
>  #include "erofs/io.h"
>  #include "erofs/dir.h"
> +#include "erofs/inode.h"
> 
>  struct erofsfuse_dir_context {
>         struct erofs_dir_context ctx;
> @@ -24,11 +25,13 @@ struct erofsfuse_dir_context {
>  static int erofsfuse_fill_dentries(struct erofs_dir_context *ctx)
>  {
>         struct erofsfuse_dir_context *fusectx = (void *)ctx;
> +       struct stat st = {0};
>         char dname[EROFS_NAME_LEN + 1];
> 
>         strncpy(dname, ctx->dname, ctx->de_namelen);
>         dname[ctx->de_namelen] = '\0';
> -       fusectx->filler(fusectx->buf, dname, NULL, 0);
> +       st.st_mode = erofs_ftype_to_dtype(ctx->de_ftype) << 12;
> +       fusectx->filler(fusectx->buf, dname, &st, 0);
>         return 0;
>  }
> 
> diff --git a/include/erofs/inode.h b/include/erofs/inode.h
> index 79b39b0..79b8d89 100644
> --- a/include/erofs/inode.h
> +++ b/include/erofs/inode.h
> @@ -16,6 +16,7 @@ extern "C"
>  #include "erofs/internal.h"
> 
>  unsigned char erofs_mode_to_ftype(umode_t mode);
> +unsigned char erofs_ftype_to_dtype(unsigned int filetype);
>  void erofs_inode_manager_init(void);
>  unsigned int erofs_iput(struct erofs_inode *inode);
>  erofs_nid_t erofs_lookupnid(struct erofs_inode *inode);
> diff --git a/lib/inode.c b/lib/inode.c
> index f192510..ce75014 100644
> --- a/lib/inode.c
> +++ b/lib/inode.c
> @@ -43,6 +43,25 @@ unsigned char erofs_mode_to_ftype(umode_t mode)
>         return erofs_ftype_by_mode[(mode & S_IFMT) >> S_SHIFT];
>  }
> 
> +static const unsigned char erofs_dtype_by_ftype[EROFS_FT_MAX] = {
> +       [EROFS_FT_UNKNOWN]      = DT_UNKNOWN,
> +       [EROFS_FT_REG_FILE]     = DT_REG,
> +       [EROFS_FT_DIR]          = DT_DIR,
> +       [EROFS_FT_CHRDEV]       = DT_CHR,
> +       [EROFS_FT_BLKDEV]       = DT_BLK,
> +       [EROFS_FT_FIFO]         = DT_FIFO,
> +       [EROFS_FT_SOCK]         = DT_SOCK,
> +       [EROFS_FT_SYMLINK]      = DT_LNK
> +};
> +
> +unsigned char erofs_ftype_to_dtype(unsigned int filetype)
> +{
> +       if (filetype >= EROFS_FT_MAX)
> +               return DT_UNKNOWN;
> +
> +       return erofs_dtype_by_ftype[filetype];
> +}
> +
>  #define NR_INODE_HASHTABLE     16384
> 
>  struct list_head inode_hashtable[NR_INODE_HASHTABLE];
> --
> 2.25.1
> 
> ________________________________
> OPPO
> 
> 本电子邮件及其附件含有OPPO公司的保密信息,仅限于邮件指明的收件人使用(包含个人及群组)。禁止任何人在未经授权的情况下以任何形式使用。如果您错收了本邮件,请立即以电子邮件通知发件人并删除本邮件及其附件。
> 
> This e-mail and its attachments contain confidential information from OPPO, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach
  2022-08-03 14:22 ` [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach Sheng Yong via Linux-erofs
@ 2022-08-03 19:46   ` Gao Xiang
  2022-08-09  3:58     ` Gao Xiang
  0 siblings, 1 reply; 14+ messages in thread
From: Gao Xiang @ 2022-08-03 19:46 UTC (permalink / raw)
  To: Sheng Yong; +Cc: linux-erofs

Hi Yong,

On Wed, Aug 03, 2022 at 10:22:22PM +0800, Sheng Yong wrote:
> This patch exports erofs_xattr_foreach() to iterate all xattrs.
> Each xattr entry is handled by operations defined in `struct
> xattr_iter_ops'.
> 

Thanks for your hard effort! 

Could we import in-kernel xattr implementation with verify enabled
(or unify these implementations) instead?

( Jianan ported a kernel implementation before, could we enhance
  it with verification?
  https://lore.kernel.org/r/20220728120910.61636-1-jnhuang@linux.alibaba.com)

Thanks,
Gao Xiang

> Signed-off-by: Sheng Yong <shengyong@oppo.com>
> ---
>  fsck/main.c           |  83 ++++------------------------
>  include/erofs/xattr.h |   7 ++-
>  lib/xattr.c           | 123 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 139 insertions(+), 74 deletions(-)
> 
> diff --git a/fsck/main.c b/fsck/main.c
> index 5a2f659..237ccc1 100644
> --- a/fsck/main.c
> +++ b/fsck/main.c
> @@ -14,6 +14,7 @@
>  #include "erofs/compress.h"
>  #include "erofs/decompress.h"
>  #include "erofs/dir.h"
> +#include "erofs/xattr.h"
> 
>  static int erofsfsck_check_inode(erofs_nid_t pnid, erofs_nid_t nid);
> 
> @@ -283,82 +284,18 @@ static int erofs_check_sb_chksum(void)
>         return 0;
>  }
> 
> -static int erofs_verify_xattr(struct erofs_inode *inode)
> +static int erofs_verify_xattr_entry(const struct erofs_xattr_entry *entry)
>  {
> -       unsigned int xattr_hdr_size = sizeof(struct erofs_xattr_ibody_header);
> -       unsigned int xattr_entry_size = sizeof(struct erofs_xattr_entry);
> -       erofs_off_t addr;
> -       unsigned int ofs, xattr_shared_count;
> -       struct erofs_xattr_ibody_header *ih;
> -       struct erofs_xattr_entry *entry;
> -       int i, remaining = inode->xattr_isize, ret = 0;
> -       char buf[EROFS_BLKSIZ];
> -
> -       if (inode->xattr_isize == xattr_hdr_size) {
> -               erofs_err("xattr_isize %d of nid %llu is not supported yet",
> -                         inode->xattr_isize, inode->nid | 0ULL);
> -               ret = -EFSCORRUPTED;
> -               goto out;
> -       } else if (inode->xattr_isize < xattr_hdr_size) {
> -               if (inode->xattr_isize) {
> -                       erofs_err("bogus xattr ibody @ nid %llu",
> -                                 inode->nid | 0ULL);
> -                       ret = -EFSCORRUPTED;
> -                       goto out;
> -               }
> -       }
> -
> -       addr = iloc(inode->nid) + inode->inode_isize;
> -       ret = dev_read(0, buf, addr, xattr_hdr_size);
> -       if (ret < 0) {
> -               erofs_err("failed to read xattr header @ nid %llu: %d",
> -                         inode->nid | 0ULL, ret);
> -               goto out;
> -       }
> -       ih = (struct erofs_xattr_ibody_header *)buf;
> -       xattr_shared_count = ih->h_shared_count;
> -
> -       ofs = erofs_blkoff(addr) + xattr_hdr_size;
> -       addr += xattr_hdr_size;
> -       remaining -= xattr_hdr_size;
> -       for (i = 0; i < xattr_shared_count; ++i) {
> -               if (ofs >= EROFS_BLKSIZ) {
> -                       if (ofs != EROFS_BLKSIZ) {
> -                               erofs_err("unaligned xattr entry in xattr shared area @ nid %llu",
> -                                         inode->nid | 0ULL);
> -                               ret = -EFSCORRUPTED;
> -                               goto out;
> -                       }
> -                       ofs = 0;
> -               }
> -               ofs += xattr_entry_size;
> -               addr += xattr_entry_size;
> -               remaining -= xattr_entry_size;
> -       }
> -
> -       while (remaining > 0) {
> -               unsigned int entry_sz;
> +       return 0;
> +}
> 
> -               ret = dev_read(0, buf, addr, xattr_entry_size);
> -               if (ret) {
> -                       erofs_err("failed to read xattr entry @ nid %llu: %d",
> -                                 inode->nid | 0ULL, ret);
> -                       goto out;
> -               }
> +struct xattr_iter_ops erofs_verify_xattr_ops = {
> +       .verify = erofs_verify_xattr_entry,
> +};
> 
> -               entry = (struct erofs_xattr_entry *)buf;
> -               entry_sz = erofs_xattr_entry_size(entry);
> -               if (remaining < entry_sz) {
> -                       erofs_err("xattr on-disk corruption: xattr entry beyond xattr_isize @ nid %llu",
> -                                 inode->nid | 0ULL);
> -                       ret = -EFSCORRUPTED;
> -                       goto out;
> -               }
> -               addr += entry_sz;
> -               remaining -= entry_sz;
> -       }
> -out:
> -       return ret;
> +static int erofs_verify_xattr(struct erofs_inode *inode)
> +{
> +       return erofs_xattr_foreach(inode, &erofs_verify_xattr_ops, NULL);
>  }
> 
>  static int erofs_verify_inode_data(struct erofs_inode *inode, int outfd)
> diff --git a/include/erofs/xattr.h b/include/erofs/xattr.h
> index 226e984..c592d47 100644
> --- a/include/erofs/xattr.h
> +++ b/include/erofs/xattr.h
> @@ -45,10 +45,15 @@ extern "C"
>  #define XATTR_NAME_POSIX_ACL_DEFAULT "system.posix_acl_default"
>  #endif
> 
> +struct xattr_iter_ops {
> +       int (*verify)(const struct erofs_xattr_entry *entry);
> +};
> +
>  int erofs_prepare_xattr_ibody(struct erofs_inode *inode);
>  char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size);
>  int erofs_build_shared_xattrs_from_path(const char *path);
> -
> +int erofs_xattr_foreach(struct erofs_inode *vi, struct xattr_iter_ops *ops,
> +                       void *data);
>  #ifdef __cplusplus
>  }
>  #endif
> diff --git a/lib/xattr.c b/lib/xattr.c
> index c8ce278..92c155d 100644
> --- a/lib/xattr.c
> +++ b/lib/xattr.c
> @@ -714,3 +714,126 @@ char *erofs_export_xattr_ibody(struct list_head *ixattrs, unsigned int size)
>         DBG_BUGON(p > size);
>         return buf;
>  }
> +
> +static struct erofs_xattr_entry *read_xattr_entry(erofs_blk_t addr,
> +                                                 char *buf, size_t size)
> +{
> +       struct erofs_xattr_entry *entry;
> +       size_t entry_sz = sizeof(struct erofs_xattr_entry);
> +       int ret;
> +
> +       if (size < entry_sz)
> +               return ERR_PTR(-ERANGE);
> +
> +       ret = dev_read(0, buf, addr, entry_sz);
> +       if (ret) {
> +               erofs_err("failed to read xattr entry at addr %x: %d",
> +                         addr, ret);
> +               return ERR_PTR(ret);
> +       }
> +
> +       entry = (struct erofs_xattr_entry *)buf;
> +       entry_sz = erofs_xattr_entry_size(entry);
> +       if (size < entry_sz)
> +               return ERR_PTR(-ERANGE);
> +
> +       ret = dev_read(0, buf, addr, entry_sz);
> +       if (ret) {
> +               erofs_err("failed to read xattr entry at addr %x: %d",
> +                         addr, ret);
> +               return ERR_PTR(ret);
> +       }
> +
> +       return entry;
> +}
> +
> +int erofs_xattr_foreach(struct erofs_inode *vi, struct xattr_iter_ops *ops,
> +                       void *data)
> +{
> +       unsigned int xattr_hdr_size = sizeof(struct erofs_xattr_ibody_header);
> +       unsigned int xattr_entry_size = sizeof(struct erofs_xattr_entry);
> +       erofs_off_t addr;
> +       unsigned int ofs, xattr_shared_count;
> +       struct erofs_xattr_ibody_header *ih;
> +       struct erofs_xattr_entry *entry;
> +       int i, remaining = vi->xattr_isize, ret = 0;
> +       char buf[EROFS_BLKSIZ];
> +
> +       if (vi->xattr_isize == xattr_hdr_size) {
> +               erofs_err("xattr_isize %d of nid %llu is not supported yet",
> +                         vi->xattr_isize, vi->nid | 0ULL);
> +               return -EFSCORRUPTED;
> +       } else if (vi->xattr_isize < xattr_hdr_size) {
> +               if (vi->xattr_isize) {
> +                       erofs_err("bogus xattr ibody @ nid %llu",
> +                                 vi->nid | 0ULL);
> +                       return -EFSCORRUPTED;
> +               }
> +       }
> +
> +       addr = iloc(vi->nid) + vi->inode_isize;
> +       ret = dev_read(0, buf, addr, xattr_hdr_size);
> +       if (ret < 0) {
> +               erofs_err("failed to read xattr header @ nid %llu: %d",
> +                         vi->nid | 0ULL, ret);
> +               return ret;
> +       }
> +       ih = (struct erofs_xattr_ibody_header *)buf;
> +       xattr_shared_count = ih->h_shared_count;
> +
> +       ofs = erofs_blkoff(addr) + xattr_hdr_size;
> +       addr += xattr_hdr_size;
> +       ret = dev_read(0, buf, addr, xattr_entry_size * xattr_shared_count);
> +       remaining -= xattr_hdr_size;
> +       for (i = 0; i < xattr_shared_count; ++i) {
> +               unsigned int xattr_id;
> +               erofs_blk_t xattr_addr;
> +               char tmp[EROFS_BLKSIZ];
> +
> +               if (ofs >= EROFS_BLKSIZ) {
> +                       if (ofs != EROFS_BLKSIZ) {
> +                               erofs_err("unaligned xattr entry in xattr shared area @ nid %llu",
> +                                         vi->nid | 0ULL);
> +                               return -EFSCORRUPTED;
> +                       }
> +                       ofs = 0;
> +               }
> +
> +               xattr_id = le32_to_cpu(*((__le32 *)buf + i));
> +               xattr_addr = sbi.xattr_blkaddr * EROFS_BLKSIZ +  4 * xattr_id;
> +
> +               entry = read_xattr_entry(xattr_addr, tmp, EROFS_BLKSIZ);
> +               if (IS_ERR(entry))
> +                       return PTR_ERR(entry);
> +
> +               if (ops->verify) {
> +                       ret = ops->verify(entry);
> +                       if (ret < 0)
> +                               return ret;
> +               }
> +
> +               ofs += xattr_entry_size;
> +               addr += xattr_entry_size;
> +               remaining -= xattr_entry_size;
> +       }
> +
> +       while (remaining > 0) {
> +               unsigned int entry_sz;
> +
> +               entry = read_xattr_entry(addr, buf, EROFS_BLKSIZ);
> +               if (IS_ERR(entry))
> +                       return PTR_ERR(entry);
> +               entry_sz = erofs_xattr_entry_size(entry);
> +
> +               if (ops->verify) {
> +                       ret = ops->verify(entry);
> +                       if (ret < 0)
> +                               return ret;
> +               }
> +               addr += entry_sz;
> +               remaining -= entry_sz;
> +       }
> +
> +       return ret;
> +
> +}
> --
> 2.25.1
> 
> ________________________________
> OPPO
> 
> 本电子邮件及其附件含有OPPO公司的保密信息,仅限于邮件指明的收件人使用(包含个人及群组)。禁止任何人在未经授权的情况下以任何形式使用。如果您错收了本邮件,请立即以电子邮件通知发件人并删除本邮件及其附件。
> 
> This e-mail and its attachments contain confidential information from OPPO, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir
  2022-08-03 19:43   ` Gao Xiang
@ 2022-08-04 15:02     ` Gao Xiang
  2022-08-04 15:14       ` Sheng Yong via Linux-erofs
  0 siblings, 1 reply; 14+ messages in thread
From: Gao Xiang @ 2022-08-04 15:02 UTC (permalink / raw)
  To: Sheng Yong; +Cc: linux-erofs

On Thu, Aug 04, 2022 at 03:43:04AM +0800, Gao Xiang wrote:
> On Wed, Aug 03, 2022 at 10:22:21PM +0800, Sheng Yong wrote:
> > Set inode mode for libfuse readdir filler so that readdir count get
> > correct d_type.
> > 
> > Signed-off-by: Sheng Yong <shengyong@oppo.com>
> 
> Reviewed-by: Gao Xiang <xiang@kernel.org>
> 

I'm not able to apply this patch since it's badly
space-damaged...

Thanks,
Gao Xiang

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir
  2022-08-04 15:02     ` Gao Xiang
@ 2022-08-04 15:14       ` Sheng Yong via Linux-erofs
  2022-08-07  8:08         ` [PATCH v2] " Sheng Yong
  0 siblings, 1 reply; 14+ messages in thread
From: Sheng Yong via Linux-erofs @ 2022-08-04 15:14 UTC (permalink / raw)
  To: bluce.lee, linux-erofs, chao



在 2022/8/4 23:02, Gao Xiang 写道:
> On Thu, Aug 04, 2022 at 03:43:04AM +0800, Gao Xiang wrote:
>> On Wed, Aug 03, 2022 at 10:22:21PM +0800, Sheng Yong wrote:
>>> Set inode mode for libfuse readdir filler so that readdir count get
>>> correct d_type.
>>>
>>> Signed-off-by: Sheng Yong <shengyong@oppo.com>
>>
>> Reviewed-by: Gao Xiang <xiang@kernel.org>
>>
>
> I'm not able to apply this patch since it's badly
> space-damaged...
Hi, Xiang,

It seems some invisible characters are inserted between spaces.
I'll re-send a new version.

Thanks,
Sheng Yong
>
> Thanks,
> Gao Xiang
________________________________
OPPO

本电子邮件及其附件含有OPPO公司的保密信息,仅限于邮件指明的收件人使用(包含个人及群组)。禁止任何人在未经授权的情况下以任何形式使用。如果您错收了本邮件,请立即以电子邮件通知发件人并删除本邮件及其附件。

This e-mail and its attachments contain confidential information from OPPO, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v2] erofs-utils: fuse: set d_type for readdir
  2022-08-04 15:14       ` Sheng Yong via Linux-erofs
@ 2022-08-07  8:08         ` Sheng Yong
  2022-08-07 10:26           ` Chao Yu
  0 siblings, 1 reply; 14+ messages in thread
From: Sheng Yong @ 2022-08-07  8:08 UTC (permalink / raw)
  To: xiang, bluce.lee, chao, linux-erofs; +Cc: shengyong

From: Sheng Yong <shengyong@oppo.com>

Set inode mode for libfuse readdir filler so that readdir count get
correct d_type.

Signed-off-by: Sheng Yong <shengyong@oppo.com>
---
 fuse/main.c           |  5 ++++-
 include/erofs/inode.h |  1 +
 lib/inode.c           | 19 +++++++++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/fuse/main.c b/fuse/main.c
index 95f939e..345bcb5 100644
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -13,6 +13,7 @@
 #include "erofs/print.h"
 #include "erofs/io.h"
 #include "erofs/dir.h"
+#include "erofs/inode.h"
 
 struct erofsfuse_dir_context {
 	struct erofs_dir_context ctx;
@@ -24,11 +25,13 @@ struct erofsfuse_dir_context {
 static int erofsfuse_fill_dentries(struct erofs_dir_context *ctx)
 {
 	struct erofsfuse_dir_context *fusectx = (void *)ctx;
+	struct stat st = {0};
 	char dname[EROFS_NAME_LEN + 1];
 
 	strncpy(dname, ctx->dname, ctx->de_namelen);
 	dname[ctx->de_namelen] = '\0';
-	fusectx->filler(fusectx->buf, dname, NULL, 0);
+	st.st_mode = erofs_ftype_to_dtype(ctx->de_ftype) << 12;
+	fusectx->filler(fusectx->buf, dname, &st, 0);
 	return 0;
 }
 
diff --git a/include/erofs/inode.h b/include/erofs/inode.h
index 79b39b0..79b8d89 100644
--- a/include/erofs/inode.h
+++ b/include/erofs/inode.h
@@ -16,6 +16,7 @@ extern "C"
 #include "erofs/internal.h"
 
 unsigned char erofs_mode_to_ftype(umode_t mode);
+unsigned char erofs_ftype_to_dtype(unsigned int filetype);
 void erofs_inode_manager_init(void);
 unsigned int erofs_iput(struct erofs_inode *inode);
 erofs_nid_t erofs_lookupnid(struct erofs_inode *inode);
diff --git a/lib/inode.c b/lib/inode.c
index f192510..ce75014 100644
--- a/lib/inode.c
+++ b/lib/inode.c
@@ -43,6 +43,25 @@ unsigned char erofs_mode_to_ftype(umode_t mode)
 	return erofs_ftype_by_mode[(mode & S_IFMT) >> S_SHIFT];
 }
 
+static const unsigned char erofs_dtype_by_ftype[EROFS_FT_MAX] = {
+	[EROFS_FT_UNKNOWN]	= DT_UNKNOWN,
+	[EROFS_FT_REG_FILE]	= DT_REG,
+	[EROFS_FT_DIR]		= DT_DIR,
+	[EROFS_FT_CHRDEV]	= DT_CHR,
+	[EROFS_FT_BLKDEV]	= DT_BLK,
+	[EROFS_FT_FIFO]		= DT_FIFO,
+	[EROFS_FT_SOCK]		= DT_SOCK,
+	[EROFS_FT_SYMLINK]	= DT_LNK
+};
+
+unsigned char erofs_ftype_to_dtype(unsigned int filetype)
+{
+	if (filetype >= EROFS_FT_MAX)
+		return DT_UNKNOWN;
+
+	return erofs_dtype_by_ftype[filetype];
+}
+
 #define NR_INODE_HASHTABLE	16384
 
 struct list_head inode_hashtable[NR_INODE_HASHTABLE];
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] erofs-utils: fuse: set d_type for readdir
  2022-08-07  8:08         ` [PATCH v2] " Sheng Yong
@ 2022-08-07 10:26           ` Chao Yu
  2022-08-08  1:59             ` Gao Xiang
  0 siblings, 1 reply; 14+ messages in thread
From: Chao Yu @ 2022-08-07 10:26 UTC (permalink / raw)
  To: Sheng Yong, xiang, bluce.lee, linux-erofs; +Cc: shengyong

On 2022/8/7 16:08, Sheng Yong wrote:
> From: Sheng Yong <shengyong@oppo.com>
> 
> Set inode mode for libfuse readdir filler so that readdir count get
> correct d_type.
> 
> Signed-off-by: Sheng Yong <shengyong@oppo.com>

Reviewed-by: Chao Yu <chao@kernel.org>

Thanks,

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v2] erofs-utils: fuse: set d_type for readdir
  2022-08-07 10:26           ` Chao Yu
@ 2022-08-08  1:59             ` Gao Xiang
  0 siblings, 0 replies; 14+ messages in thread
From: Gao Xiang @ 2022-08-08  1:59 UTC (permalink / raw)
  To: Sheng Yong, Chao Yu; +Cc: linux-erofs, shengyong

On Sun, Aug 07, 2022 at 06:26:16PM +0800, Chao Yu wrote:
> On 2022/8/7 16:08, Sheng Yong wrote:
> > From: Sheng Yong <shengyong@oppo.com>
> > 
> > Set inode mode for libfuse readdir filler so that readdir count get
> > correct d_type.
> > 
> > Signed-off-by: Sheng Yong <shengyong@oppo.com>
> 
> Reviewed-by: Chao Yu <chao@kernel.org>
> 

Thank all. Applied this time without problems

Thanks,
Gao Xiang

> Thanks,

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach
  2022-08-03 19:46   ` Gao Xiang
@ 2022-08-09  3:58     ` Gao Xiang
  2022-08-09  4:18       ` Sheng Yong via Linux-erofs
  0 siblings, 1 reply; 14+ messages in thread
From: Gao Xiang @ 2022-08-09  3:58 UTC (permalink / raw)
  To: Sheng Yong; +Cc: linux-erofs

Hi Yong,

On Thu, Aug 04, 2022 at 03:46:24AM +0800, Gao Xiang wrote:
> 
> On Wed, Aug 03, 2022 at 10:22:22PM +0800, Sheng Yong wrote:
> > This patch exports erofs_xattr_foreach() to iterate all xattrs.
> > Each xattr entry is handled by operations defined in `struct
> > xattr_iter_ops'.
> > 
> 
> Thanks for your hard effort! 
> 
> Could we import in-kernel xattr implementation with verify enabled
> (or unify these implementations) instead?
> 
> ( Jianan ported a kernel implementation before, could we enhance
>   it with verification?
>   https://lore.kernel.org/r/20220728120910.61636-1-jnhuang@linux.alibaba.com)
> 

We're about to fix FUSE extended attribute support... Would you mind
leaving your opinion about this?

Thanks,
Gao Xiang

> Thanks,
> Gao Xiang

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach
  2022-08-09  3:58     ` Gao Xiang
@ 2022-08-09  4:18       ` Sheng Yong via Linux-erofs
  2022-08-09  4:27         ` Gao Xiang
  0 siblings, 1 reply; 14+ messages in thread
From: Sheng Yong via Linux-erofs @ 2022-08-09  4:18 UTC (permalink / raw)
  To: Gao Xiang; +Cc: linux-erofs



在 2022/8/9 11:58, Gao Xiang 写道:
> Hi Yong,
>
> On Thu, Aug 04, 2022 at 03:46:24AM +0800, Gao Xiang wrote:
>>
>> On Wed, Aug 03, 2022 at 10:22:22PM +0800, Sheng Yong wrote:
>>> This patch exports erofs_xattr_foreach() to iterate all xattrs.
>>> Each xattr entry is handled by operations defined in `struct
>>> xattr_iter_ops'.
>>>
>>
>> Thanks for your hard effort!
>>
>> Could we import in-kernel xattr implementation with verify enabled
>> (or unify these implementations) instead?
>>
>> ( Jianan ported a kernel implementation before, could we enhance
>>    it with verification?
>>    https://lore.kernel.org/r/20220728120910.61636-1-jnhuang@linux.alibaba.com)
>>
>
> We're about to fix FUSE extended attribute support... Would you mind
> leaving your opinion about this?

Hi, Xiang

Sorry for late. At first glance, I though it would be too heavy to port
in-kernel code when I tried to add xattr to fuse client. But if we want
a more unified implementation and Jianan has already done it. I'd like
to try Jianan's version :-)

Thanks,
Sheng Yong

>
> Thanks,
> Gao Xiang
>
>> Thanks,
>> Gao Xiang
________________________________
OPPO

本电子邮件及其附件含有OPPO公司的保密信息,仅限于邮件指明的收件人使用(包含个人及群组)。禁止任何人在未经授权的情况下以任何形式使用。如果您错收了本邮件,请立即以电子邮件通知发件人并删除本邮件及其附件。

This e-mail and its attachments contain confidential information from OPPO, which is intended only for the person or entity whose address is listed above. Any use of the information contained herein in any way (including, but not limited to, total or partial disclosure, reproduction, or dissemination) by persons other than the intended recipient(s) is prohibited. If you receive this e-mail in error, please notify the sender by phone or email immediately and delete it!

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach
  2022-08-09  4:18       ` Sheng Yong via Linux-erofs
@ 2022-08-09  4:27         ` Gao Xiang
  0 siblings, 0 replies; 14+ messages in thread
From: Gao Xiang @ 2022-08-09  4:27 UTC (permalink / raw)
  To: Sheng Yong; +Cc: linux-erofs

On Tue, Aug 09, 2022 at 12:18:34PM +0800, Sheng Yong wrote:
> 
> 
> 在 2022/8/9 11:58, Gao Xiang 写道:
> > Hi Yong,
> > 
> > On Thu, Aug 04, 2022 at 03:46:24AM +0800, Gao Xiang wrote:
> > > 
> > > On Wed, Aug 03, 2022 at 10:22:22PM +0800, Sheng Yong wrote:
> > > > This patch exports erofs_xattr_foreach() to iterate all xattrs.
> > > > Each xattr entry is handled by operations defined in `struct
> > > > xattr_iter_ops'.
> > > > 
> > > 
> > > Thanks for your hard effort!
> > > 
> > > Could we import in-kernel xattr implementation with verify enabled
> > > (or unify these implementations) instead?
> > > 
> > > ( Jianan ported a kernel implementation before, could we enhance
> > >    it with verification?
> > >    https://lore.kernel.org/r/20220728120910.61636-1-jnhuang@linux.alibaba.com)
> > > 
> > 
> > We're about to fix FUSE extended attribute support... Would you mind
> > leaving your opinion about this?
> 
> Hi, Xiang
> 
> Sorry for late. At first glance, I though it would be too heavy to port
> in-kernel code when I tried to add xattr to fuse client. But if we want
> a more unified implementation and Jianan has already done it. I'd like
> to try Jianan's version :-)
> 

Okay, got it.  Also if kernel implementation has more chance to simplify
or clean up, let's do it now.  However, it's definitely better if we share
more code between kernel and erofs-utils in common, so we don't need to
maintain / test two different approaches and that could lead to more bugs
if we enhance them even further in the future...

Thanks,
Gao Xiang

> Thanks,
> Sheng Yong
> 
> > 
> > Thanks,
> > Gao Xiang
> > 
> > > Thanks,
> > > Gao Xiang

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2022-08-09  4:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-08-03 14:22 [RFC PATCH 0/3] erofs-utils: fuse: support get/list xattr Sheng Yong via Linux-erofs
2022-08-03 14:22 ` [RFC PATCH 1/3] erofs-utils: fuse: set d_type for readdir Sheng Yong via Linux-erofs
2022-08-03 19:43   ` Gao Xiang
2022-08-04 15:02     ` Gao Xiang
2022-08-04 15:14       ` Sheng Yong via Linux-erofs
2022-08-07  8:08         ` [PATCH v2] " Sheng Yong
2022-08-07 10:26           ` Chao Yu
2022-08-08  1:59             ` Gao Xiang
2022-08-03 14:22 ` [RFC PATCH 2/3] erofs-utils: fuse: export erofs_xattr_foreach Sheng Yong via Linux-erofs
2022-08-03 19:46   ` Gao Xiang
2022-08-09  3:58     ` Gao Xiang
2022-08-09  4:18       ` Sheng Yong via Linux-erofs
2022-08-09  4:27         ` Gao Xiang
2022-08-03 14:22 ` [RFC PATCH 3/3] erofs-utils: fuse: support get/list xattr Sheng Yong via Linux-erofs

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.