[WIP] [PATCH v4 02/12] erofs-utils: fuse: add special file support

Gao Xiang hsiangkao at aol.com
Sun Nov 15 05:25:07 AEDT 2020


From: Huang Jianan <huangjianan at oppo.com>

Signed-off-by: Huang Jianan <huangjianan at oppo.com>
Signed-off-by: Guo Weichao <guoweichao at oppo.com>
Signed-off-by: Gao Xiang <hsiangkao at aol.com>
---
 fuse/main.c              |  2 ++
 fuse/namei.c             | 14 ++++++++++----
 fuse/read.c              | 26 ++++++++++++++++++++++++++
 fuse/read.h              |  1 +
 include/erofs/internal.h |  1 +
 5 files changed, 40 insertions(+), 4 deletions(-)

diff --git a/fuse/main.c b/fuse/main.c
index 5121e8325f32..563b2c378952 100644
--- a/fuse/main.c
+++ b/fuse/main.c
@@ -146,6 +146,7 @@ int erofs_getattr(const char *path, struct stat *stbuf)
 	stbuf->st_blocks = stbuf->st_size / EROFS_BLKSIZ;
 	stbuf->st_uid = v.i_uid;
 	stbuf->st_gid = v.i_gid;
+	stbuf->st_rdev = v.i_rdev;
 	stbuf->st_atime = sbi.build_time;
 	stbuf->st_mtime = sbi.build_time;
 	stbuf->st_ctime = sbi.build_time;
@@ -153,6 +154,7 @@ int erofs_getattr(const char *path, struct stat *stbuf)
 }
 
 static struct fuse_operations erofs_ops = {
+	.readlink = erofs_readlink,
 	.getattr = erofs_getattr,
 	.readdir = erofs_readdir,
 	.open = erofs_open,
diff --git a/fuse/namei.c b/fuse/namei.c
index cd747ad1be56..e79e77d1e3c9 100644
--- a/fuse/namei.c
+++ b/fuse/namei.c
@@ -11,6 +11,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <sys/stat.h>
+#include <sys/sysmacros.h>
 
 #include "erofs/defs.h"
 #include "erofs/print.h"
@@ -37,6 +38,13 @@ static uint8_t get_path_token_len(const char *path)
 	return len;
 }
 
+static inline dev_t new_decode_dev(u32 dev)
+{
+	unsigned major = (dev & 0xfff00) >> 8;
+	unsigned minor = (dev & 0xff) | ((dev >> 12) & 0xfff00);
+	return makedev(major, minor);
+}
+
 int erofs_iget_by_nid(erofs_nid_t nid, struct erofs_vnode *vi)
 {
 	int ret;
@@ -63,13 +71,11 @@ int erofs_iget_by_nid(erofs_nid_t nid, struct erofs_vnode *vi)
 	switch (vi->i_mode & S_IFMT) {
 	case S_IFBLK:
 	case S_IFCHR:
-		/* fixme: add special devices support
-		 * vi->i_rdev = new_decode_dev(le32_to_cpu(v1->i_u.rdev));
-		 */
+		vi->i_rdev = new_decode_dev(le32_to_cpu(v1->i_u.rdev));
 		break;
 	case S_IFIFO:
 	case S_IFSOCK:
-		/*fixme: vi->i_rdev = 0; */
+		vi->i_rdev = 0;
 		break;
 	case S_IFREG:
 	case S_IFLNK:
diff --git a/fuse/read.c b/fuse/read.c
index 446e0837cbc4..a55c0f2f78cd 100644
--- a/fuse/read.c
+++ b/fuse/read.c
@@ -70,3 +70,29 @@ int erofs_read(const char *path, char *buffer, size_t size, off_t offset,
 	}
 }
 
+int erofs_readlink(const char *path, char *buffer, size_t size)
+{
+	int ret;
+	erofs_nid_t nid;
+	size_t lnksz;
+	struct erofs_vnode v;
+
+	ret = walk_path(path, &nid);
+	if (ret)
+		return ret;
+
+	ret = erofs_iget_by_nid(nid, &v);
+	if (ret)
+		return ret;
+
+	lnksz = min((size_t)v.i_size, size - 1);
+
+	ret = erofs_read(path, buffer, lnksz, 0, NULL);
+	buffer[lnksz] = '\0';
+	if (ret != (int)lnksz)
+		return ret;
+
+	erofs_info("path:%s link=%s size=%llu", path, buffer, (unsigned long long)lnksz);
+	return 0;
+}
+
diff --git a/fuse/read.h b/fuse/read.h
index 3f4af1495510..e901c607dc91 100644
--- a/fuse/read.h
+++ b/fuse/read.h
@@ -12,5 +12,6 @@
 
 int erofs_read(const char *path, char *buffer, size_t size, off_t offset,
 	    struct fuse_file_info *fi);
+int erofs_readlink(const char *path, char *buffer, size_t size);
 
 #endif
diff --git a/include/erofs/internal.h b/include/erofs/internal.h
index f9e757316efe..77fa8d82c746 100644
--- a/include/erofs/internal.h
+++ b/include/erofs/internal.h
@@ -168,6 +168,7 @@ struct erofs_vnode {
 	uint16_t i_uid;
 	uint16_t i_gid;
 	uint16_t i_nlink;
+	uint32_t i_rdev;
 
 	/* if file is inline read inline data witch inode */
 	char *idata;
-- 
2.24.0



More information about the Linux-erofs mailing list