From e9615d46a09a5dc92bf1d2ee408f0c7efd717503 Mon Sep 17 00:00:00 2001
From: yangxin <245051644@qq.com>
Date: Fri, 10 Feb 2023 16:39:20 +0800
Subject: [PATCH 2/5] Fix-error-of-getxattr-and-listxattr

Signed-off-by: yangxin <245051644@qq.com>
---
 qtfs/conn.c              |  4 ---
 qtfs/qtfs/qtfs-mod.c     |  2 +-
 qtfs/qtfs/sb.c           |  6 ++---
 qtfs/qtfs/xattr.c        | 55 ++++++++++------------------------------
 qtfs/qtfs_server/fsops.c | 16 +++++++-----
 qtfs/qtinfo/qtinfo.h     | 10 ++++----
 qtfs/req.h               |  4 +--
 7 files changed, 34 insertions(+), 63 deletions(-)

diff --git a/qtfs/conn.c b/qtfs/conn.c
index af11fbe..26930b1 100644
--- a/qtfs/conn.c
+++ b/qtfs/conn.c
@@ -76,10 +76,6 @@ static int qtfs_conn_sockserver_init(struct qtfs_sock_var_s *pvar)
 {
 	struct socket *sock;
 	int ret;
-	struct sockaddr_in saddr;
-	saddr.sin_family = AF_INET;
-	saddr.sin_port = htons(pvar->port);
-	saddr.sin_addr.s_addr = in_aton(pvar->addr);
 	
 	if (!QTCONN_IS_EPOLL_CONN(pvar) && qtfs_server_main_sock != NULL) {
 		qtfs_info("qtfs server main sock is %lx, valid or out-of-date?", (unsigned long)qtfs_server_main_sock);
diff --git a/qtfs/qtfs/qtfs-mod.c b/qtfs/qtfs/qtfs-mod.c
index 9ccf0ee..abd9443 100644
--- a/qtfs/qtfs/qtfs-mod.c
+++ b/qtfs/qtfs/qtfs-mod.c
@@ -9,7 +9,7 @@ static struct file_system_type qtfs_fs_type = {
 	.owner		= THIS_MODULE,
 	.name		= QTFS_FSTYPE_NAME,
 	.mount		= qtfs_fs_mount,
-	.kill_sb	= qtfs_kill_sb,//qtfs_kill_sb,
+	.kill_sb	= qtfs_kill_sb,
 };
 MODULE_ALIAS_FS("qtfs");
 
diff --git a/qtfs/qtfs/sb.c b/qtfs/qtfs/sb.c
index 9374cfb..7445fad 100644
--- a/qtfs/qtfs/sb.c
+++ b/qtfs/qtfs/sb.c
@@ -18,7 +18,7 @@
 static struct inode_operations qtfs_inode_ops;
 static struct inode_operations qtfs_symlink_inode_ops;
 struct inode *qtfs_iget(struct super_block *sb, struct inode_info *ii);
-
+extern ssize_t qtfs_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size);
 int qtfs_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
 	struct qtfs_sock_var_s *pvar = qtfs_conn_get_param();
@@ -396,7 +396,6 @@ ssize_t qtfs_writeiter(struct kiocb *kio, struct iov_iter *iov)
 		leftlen -= wrbuflen;
 	} while (leftlen);
 
-	//if (qtfs_support_epoll(kio->ki_filp->f_inode->i_mode) || ) {
 	do {
 		struct inode *inode = kio->ki_filp->f_inode;
 		struct qtfs_inode_priv *priv = inode->i_private;
@@ -406,7 +405,6 @@ ssize_t qtfs_writeiter(struct kiocb *kio, struct iov_iter *iov)
 			wake_up_interruptible_poll(&priv->readq, EPOLLIN);
 			qtfs_err("writeiter file:%s char:<%s> wakup poll.", filp->f_path.dentry->d_iname, req->path_buf);
 		}
-		//qtfs_info("qtfs write iter fifo %s sync poll.", filp->f_path.dentry->d_iname);
 	} while (0);
 	qtfs_info("qtfs write %s over, leftlen:%lu.", filp->f_path.dentry->d_iname, leftlen);
 	qtfs_conn_put_param(pvar);
@@ -1338,12 +1336,14 @@ static struct inode_operations qtfs_inode_ops = {
 	.getattr = qtfs_getattr,
 	.setattr = qtfs_setattr,
 	.rename = qtfs_rename,
+	.listxattr = qtfs_xattr_list,
 };
 
 static struct inode_operations qtfs_symlink_inode_ops = {
 	.get_link = qtfs_getlink,
 	.getattr = qtfs_getattr,
 	.setattr = qtfs_setattr,
+	.listxattr = qtfs_xattr_list,
 };
 
 const struct xattr_handler *qtfs_xattr_handlers[] = {
diff --git a/qtfs/qtfs/xattr.c b/qtfs/qtfs/xattr.c
index a0d394a..a2a605d 100644
--- a/qtfs/qtfs/xattr.c
+++ b/qtfs/qtfs/xattr.c
@@ -6,69 +6,52 @@
 #include "req.h"
 #include "log.h"
 
-static bool qtfs_xattr_list(struct dentry *dentry)
+ssize_t qtfs_xattr_list(struct dentry *dentry, char *buffer, size_t buffer_size)
 {
 	struct qtreq_xattrlist *req;
 	struct qtrsp_xattrlist *rsp;
 	struct qtfs_sock_var_s *pvar = qtfs_conn_get_param();
-	bool ret;
+	ssize_t ret;
 
 	if (!pvar) {
 		qtfs_err("qtfs_xattr_list Failed to get qtfs sock var");
-		return -EINVAL;
+		return 0;
 	}
 
 	if (dentry == NULL) {
 		qtfs_err("qtfs_xattr_list dentry is NULL.");
 		qtfs_conn_put_param(pvar);
-		return false;
+		return 0;
 	}
 
 	req = qtfs_sock_msg_buf(pvar, QTFS_SEND);
 	if (qtfs_fullname(req->path, dentry) < 0) {
 		qtfs_err("qtfs fullname failed");
 		qtfs_conn_put_param(pvar);
-		return false;
+		return 0;
 	}
-
-	rsp = qtfs_remote_run(pvar, QTFS_REQ_XATTRLIST, strlen(req->path) + 1);
+	req->buffer_size = buffer_size;
+	rsp = qtfs_remote_run(pvar, QTFS_REQ_XATTRLIST, QTFS_SEND_SIZE(struct qtreq_xattrlist, req->path));
 	if (IS_ERR(rsp) || rsp == NULL) {
 		qtfs_err("qtfs_xattr_list remote run failed.");
 		qtfs_conn_put_param(pvar);
-		return false;
+		return 0;
 	}
 	
 	if (rsp->d.ret == QTFS_ERR) {
 		qtfs_err("qtfs_xattr_list failed with ret:%d.", rsp->d.ret);
-		ret = rsp->d.result;
+		ret = rsp->d.size;
 		qtfs_conn_put_param(pvar);
 		return ret;
 	}
-	ret = rsp->d.result;
+	ret = rsp->d.size;
+	if (buffer != NULL) {
+		memcpy(buffer, rsp->name, buffer_size);
+	}
 	qtfs_conn_put_param(pvar);
 	return ret;
 }
 
-static bool qtfs_xattr_user_list(struct dentry *dentry)
-{
-	return qtfs_xattr_list(dentry);
-}
-
-static bool qtfs_xattr_trusted_list(struct dentry *dentry)
-{
-	return qtfs_xattr_list(dentry);
-}
-
-static bool qtfs_xattr_security_list(struct dentry *dentry)
-{
-	return qtfs_xattr_list(dentry);
-}
-
-static bool qtfs_xattr_hurd_list(struct dentry *dentry)
-{
-	return qtfs_xattr_list(dentry);
-}
-
 static int qtfs_xattr_set(const struct xattr_handler *handler,
 		    struct dentry *dentry, struct inode *inode,
 		    const char *name, const void *value,
@@ -177,12 +160,6 @@ static int qtfs_xattr_get(const struct xattr_handler *handler,
 		qtfs_err("Failed to get qtfs sock var");
 		return 0;
 	}
-	/*if (buf == NULL || size <= 0) {
-		qtfs_err("xattr get failed, buf:%lx size:%d name:%s dentry:%lx",
-				(unsigned long)buf, size, (name == NULL) ? "NULL" : name, (unsigned long)dentry);
-		qtfs_conn_put_param(pvar);
-		return 0;
-	}*/
 
 	if (dentry == NULL) {
 		qtfs_err("xattr get dentry is NULL.");
@@ -216,7 +193,7 @@ static int qtfs_xattr_get(const struct xattr_handler *handler,
 			qtfs_conn_put_param(pvar);
 			return PTR_ERR(rsp);
 		}
-		if (rsp->d.ret == QTFS_ERR || rsp->d.size > req->d.size || leftlen < rsp->d.size) {
+		if (rsp->d.ret == QTFS_ERR || (size !=0 && (rsp->d.size > req->d.size || leftlen < rsp->d.size))) {
 			qtfs_err("ret:%d rsp size:%ld req size:%d leftlen:%lu", rsp->d.ret, rsp->d.size,
 					req->d.size, leftlen);
 			goto err_end;
@@ -239,28 +216,24 @@ err_end:
 
 const struct xattr_handler qtfs_xattr_user_handler = {
 	.prefix	= XATTR_USER_PREFIX,
-	.list	= qtfs_xattr_user_list,
 	.get	= qtfs_xattr_get,
 	.set	= qtfs_xattr_user_set,
 };
 
 const struct xattr_handler qtfs_xattr_trusted_handler = {
 	.prefix	= XATTR_TRUSTED_PREFIX,
-	.list	= qtfs_xattr_trusted_list,
 	.get	= qtfs_xattr_get,
 	.set	= qtfs_xattr_trusted_set,
 };
 
 const struct xattr_handler qtfs_xattr_security_handler = {
 	.prefix	= XATTR_SECURITY_PREFIX,
-	.list	= qtfs_xattr_security_list,
 	.get	= qtfs_xattr_get,
 	.set	= qtfs_xattr_security_set,
 };
 
 const struct xattr_handler qtfs_xattr_hurd_handler = {
 	.prefix	= XATTR_HURD_PREFIX,
-	.list	= qtfs_xattr_hurd_list,
 	.get	= qtfs_xattr_get,
 	.set	= qtfs_xattr_hurd_set,
 };
diff --git a/qtfs/qtfs_server/fsops.c b/qtfs/qtfs_server/fsops.c
index d00db6d..61e8895 100644
--- a/qtfs/qtfs_server/fsops.c
+++ b/qtfs/qtfs_server/fsops.c
@@ -576,6 +576,7 @@ static int handle_getattr(struct qtserver_arg *arg)
 	qtfs_debug("handle getattr path:%s\n", req->path);
 	ret = kern_path(req->path, 0, &path);
 	if (ret) {
+		rsp->errno = ret;
 		qtfs_err("handle getattr path:%s failed, ret:%d %s\n", req->path, ret, (ret != -ENOENT) ? "." : "file not exist");
 		goto failed;
 	}
@@ -866,26 +867,27 @@ int handle_xattrlist(struct qtserver_arg *arg)
 	struct qtrsp_xattrlist *rsp = (struct qtrsp_xattrlist *)RSP(arg);
 	struct path path;
 	int ret;
-	ssize_t size;
+	ssize_t size, buffer_size;
 	int i;
 
+	buffer_size = req->buffer_size;
 	ret = kern_path(req->path, 0, &path);
 	if (ret) {
 		qtfs_err("handle xattr list path error.\n");
-		rsp->d.errno = -ENOENT;
+		rsp->d.size = -ENOENT;
 		goto err_handle;
 	}
-	size = generic_listxattr(path.dentry, rsp->name, sizeof(rsp->name));
+	size = vfs_listxattr(path.dentry, buffer_size == 0 ? NULL : rsp->name, buffer_size);
 	path_put(&path);
 	if (size < 0) {
 		qtfs_err("handle list xattr failed, errno:%ld.\n", size);
-		rsp->d.errno = size;
+		rsp->d.size = size;
 		goto err_handle;
 	}
 	if (size == 0)
 		goto err_handle;
 	rsp->d.ret = QTFS_OK;
-	rsp->d.result = true;
+	rsp->d.size = size;
 	while (i < size) {
 		qtfs_info("handle list xattr result:%s\n", &rsp->name[i]);
 		i += strlen(&rsp->name[i]) + 1;
@@ -894,7 +896,7 @@ int handle_xattrlist(struct qtserver_arg *arg)
 
 err_handle:
 	rsp->d.ret = QTFS_ERR;
-	rsp->d.result = false;
+	rsp->d.size = size;
 	return sizeof(struct qtrsp_xattrlist);
 }
 
@@ -970,9 +972,9 @@ int handle_xattrget(struct qtserver_arg *arg)
 		}
 		qtfs_info("handle getxattr: path:%s prefix name:%s : (%s - 0x%llx), size:%ld, reqpos:%d\n", req->path, req->d.prefix_name, kvalue, (__u64)kvalue, error, req->d.pos);
 		len = (error - req->d.pos)>sizeof(rsp->buf)? sizeof(rsp->buf):(error - req->d.pos);
+		rsp->d.size = len;
 		if (req->d.size > 0) {
 			memcpy(rsp->buf, &kvalue[req->d.pos], len);
-			rsp->d.size = len;
 		}
 		rsp->d.pos = req->d.pos + len;
 	} else {
diff --git a/qtfs/qtinfo/qtinfo.h b/qtfs/qtinfo/qtinfo.h
index 0244a6e..eb7e8be 100644
--- a/qtfs/qtinfo/qtinfo.h
+++ b/qtfs/qtinfo/qtinfo.h
@@ -9,29 +9,29 @@ enum qtfs_req_type
 	QTFS_REQ_OPEN,
 	QTFS_REQ_CLOSE,
 	QTFS_REQ_READ,
-	QTFS_REQ_READITER, //5
+	QTFS_REQ_READITER, // 5
 	QTFS_REQ_WRITE,
 	QTFS_REQ_LOOKUP,
 	QTFS_REQ_READDIR,
 	QTFS_REQ_MKDIR,
-	QTFS_REQ_RMDIR, //10
+	QTFS_REQ_RMDIR, // 10
 	QTFS_REQ_GETATTR,
 	QTFS_REQ_SETATTR,
 	QTFS_REQ_ICREATE,
 	QTFS_REQ_MKNOD,
-	QTFS_REQ_UNLINK, //15
+	QTFS_REQ_UNLINK, // 15
 	QTFS_REQ_SYMLINK,
 	QTFS_REQ_LINK,
 	QTFS_REQ_GETLINK,
 	QTFS_REQ_READLINK,
-	QTFS_REQ_RENAME, //20
+	QTFS_REQ_RENAME, // 20
 
 	QTFS_REQ_XATTRLIST,
 	QTFS_REQ_XATTRGET,
 	QTFS_REQ_XATTRSET,
 
 	QTFS_REQ_SYSMOUNT,
-	QTFS_REQ_SYSUMOUNT, //25
+	QTFS_REQ_SYSUMOUNT, // 25
 	QTFS_REQ_FIFOPOLL,
 
 	QTFS_REQ_STATFS,
diff --git a/qtfs/req.h b/qtfs/req.h
index 3bcfa77..29f8964 100644
--- a/qtfs/req.h
+++ b/qtfs/req.h
@@ -414,14 +414,14 @@ struct qtrsp_rename {
 // xattr def
 #define QTFS_XATTR_LEN 64
 struct qtreq_xattrlist {
+	size_t buffer_size;
 	char path[MAX_PATH_LEN];
 };
 
 struct qtrsp_xattrlist {
 	struct qtrsp_xattrlist_len {
 		int ret;
-		int errno;
-		bool result;
+		ssize_t size;
 	}d;
 	char name[QTFS_TAIL_LEN(struct qtrsp_xattrlist_len)];
 };
-- 
2.33.0

