The change in patches: 1. Fix cache issue when recreate file 2. Introduce CMAKE to build userspace apps 3. CleanCode Signed-off-by: Weifeng Su <suweifeng1@huawei.com>
287 lines
8.7 KiB
Diff
287 lines
8.7 KiB
Diff
From bf30c2c3dc20b2b5e9562313a4c50541ebe313de Mon Sep 17 00:00:00 2001
|
|
From: liqiang <liqiang64@huawei.com>
|
|
Date: Sat, 10 Jun 2023 11:30:37 +0800
|
|
Subject: ioctl enhance and rewrite duplicate code
|
|
|
|
Signed-off-by: liqiang <liqiang64@huawei.com>
|
|
---
|
|
qtfs/include/req.h | 2 +
|
|
qtfs/qtfs/sb.c | 43 +++++++++-----
|
|
qtfs/qtfs_server/fsops.c | 122 ++++++++++++++++-----------------------
|
|
3 files changed, 81 insertions(+), 86 deletions(-)
|
|
|
|
diff --git a/qtfs/include/req.h b/qtfs/include/req.h
|
|
index 7e0a4b2..407faef 100644
|
|
--- a/qtfs/include/req.h
|
|
+++ b/qtfs/include/req.h
|
|
@@ -135,6 +135,8 @@ struct qtreq_ioctl {
|
|
unsigned int cmd;
|
|
unsigned int size;
|
|
int fd;
|
|
+ int argtype; // 0--use pointer arg, 1--use long arg
|
|
+ unsigned long arg; // for long type arg
|
|
} d;
|
|
|
|
char path[QTFS_TAIL_LEN(struct qtreq_ioctl_len)];
|
|
diff --git a/qtfs/qtfs/sb.c b/qtfs/qtfs/sb.c
|
|
index 2038c55..9c03219 100644
|
|
--- a/qtfs/qtfs/sb.c
|
|
+++ b/qtfs/qtfs/sb.c
|
|
@@ -20,7 +20,7 @@
|
|
#include <linux/version.h>
|
|
#include <asm-generic/ioctls.h>
|
|
#include <asm-generic/termbits.h>
|
|
-
|
|
+#include <linux/if_tun.h>
|
|
|
|
#include "conn.h"
|
|
#include "qtfs-mod.h"
|
|
@@ -561,7 +561,7 @@ int qtfs_fsync(struct file *file, loff_t start, loff_t end, int datasync)
|
|
return 0;
|
|
}
|
|
|
|
-long qtfs_do_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, unsigned int size)
|
|
+long qtfs_do_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, unsigned int size, int argtype)
|
|
{
|
|
struct qtfs_conn_var_s *pvar = qtfs_conn_get_param();
|
|
struct qtreq_ioctl *req;
|
|
@@ -575,19 +575,22 @@ long qtfs_do_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, unsig
|
|
return -EINVAL;
|
|
}
|
|
|
|
- if (size >= MAX_PATH_LEN) {
|
|
- WARN_ON(1);
|
|
+ req = pvar->conn_ops->get_conn_msg_buf(pvar, QTFS_SEND);
|
|
+ rsp = pvar->conn_ops->get_conn_msg_buf(pvar, QTFS_RECV);
|
|
+ if (size >= sizeof(req->path)) {
|
|
+ qtfs_err("do ioctl failed, size:%u too big:%u", size, sizeof(req->path));
|
|
qtfs_conn_put_param(pvar);
|
|
return -EINVAL;
|
|
}
|
|
- req = pvar->conn_ops->get_conn_msg_buf(pvar, QTFS_SEND);
|
|
- rsp = pvar->conn_ops->get_conn_msg_buf(pvar, QTFS_RECV);
|
|
|
|
priv = (struct private_data *)filp->private_data;
|
|
req->d.fd = priv->fd;
|
|
-
|
|
+ req->d.argtype = argtype;
|
|
req->d.cmd = cmd;
|
|
- if (size > 0) {
|
|
+ if (argtype) {
|
|
+ req->d.arg = arg;
|
|
+ len = sizeof(struct qtreq_ioctl) - sizeof(req->path);
|
|
+ } else if (size > 0) {
|
|
ret = copy_from_user(req->path, (char __user *)arg, size);
|
|
if (ret) {
|
|
qtfs_err("%s: copy_from_user, size %u failed.", __func__, size);
|
|
@@ -597,7 +600,7 @@ long qtfs_do_ioctl(struct file *filp, unsigned int cmd, unsigned long arg, unsig
|
|
len = sizeof(struct qtreq_ioctl) - sizeof(req->path) + size;
|
|
req->d.size = size;
|
|
} else {
|
|
- len = sizeof(struct qtreq_ioctl) - sizeof(req->path) + strlen(req->path) + 1;
|
|
+ len = sizeof(struct qtreq_ioctl) - sizeof(req->path);
|
|
}
|
|
|
|
rsp = qtfs_remote_run(pvar, QTFS_REQ_IOCTL, len);
|
|
@@ -623,27 +626,41 @@ out:
|
|
return (long)ret;
|
|
}
|
|
|
|
+#define QTFS_IOCTL_CASE_WITH_BREAK(size, argtype)\
|
|
+ {\
|
|
+ ret = qtfs_do_ioctl(filp, cmd, arg, size, argtype);\
|
|
+ break;\
|
|
+ }
|
|
long qtfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|
{
|
|
+ unsigned int size;
|
|
+ long ret;
|
|
switch(cmd) {
|
|
+ // all case of size 0 type 0 enter here
|
|
case FS_IOC_FSGETXATTR:
|
|
case TCGETS:
|
|
- return qtfs_do_ioctl(filp, cmd, arg, 0);
|
|
+ QTFS_IOCTL_CASE_WITH_BREAK(0, 0);
|
|
+ // all case of size 0 type 1 enter here
|
|
+ case TUNSETPERSIST:
|
|
+ QTFS_IOCTL_CASE_WITH_BREAK(0, 1);
|
|
case FS_IOC_FSSETXATTR:
|
|
- return qtfs_do_ioctl(filp, cmd, arg, sizeof(struct fsxattr));
|
|
+ QTFS_IOCTL_CASE_WITH_BREAK(sizeof(struct fsxattr), 0);
|
|
case TCSETS:
|
|
- return qtfs_do_ioctl(filp, cmd, arg, sizeof(struct ktermios));
|
|
+ QTFS_IOCTL_CASE_WITH_BREAK(sizeof(struct ktermios), 0);
|
|
+ case TUNSETIFF:
|
|
+ QTFS_IOCTL_CASE_WITH_BREAK(sizeof(struct ifreq), 0);
|
|
default: {
|
|
char *fullname = kmalloc(MAX_PATH_LEN, GFP_KERNEL);
|
|
if (!fullname)
|
|
return -ENOMEM;
|
|
memset(fullname, 0, MAX_PATH_LEN);
|
|
qtfs_fullname(fullname, filp->f_path.dentry, MAX_PATH_LEN);
|
|
- qtfs_err("qtfs ioctl get not support cmd:%d file:%s TCGETS:%d", cmd, fullname, TCGETS);
|
|
+ qtfs_err("qtfs ioctl get not support cmd:%d file:%s", cmd, fullname);
|
|
kfree(fullname);
|
|
return -EOPNOTSUPP;
|
|
}
|
|
}
|
|
+ return ret;
|
|
}
|
|
|
|
loff_t qtfs_dir_file_llseek(struct file *file, loff_t offset, int whence)
|
|
diff --git a/qtfs/qtfs_server/fsops.c b/qtfs/qtfs_server/fsops.c
|
|
index 0ae95f3..e8e5742 100644
|
|
--- a/qtfs/qtfs_server/fsops.c
|
|
+++ b/qtfs/qtfs_server/fsops.c
|
|
@@ -29,6 +29,7 @@
|
|
#include <linux/uio.h>
|
|
#include <linux/blkdev.h>
|
|
#include <linux/version.h>
|
|
+#include <linux/if_tun.h>
|
|
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(5, 11, 0))
|
|
#include <linux/fdtable.h>
|
|
#endif
|
|
@@ -105,8 +106,20 @@ static inline void qtfs_inode_info_fill(struct inode_info *ii, struct inode *ino
|
|
return;
|
|
}
|
|
|
|
+#define QTFS_IOCTL_HANDLE_WITH_BREAK(rspsize)\
|
|
+ {\
|
|
+ ret = copy_from_user(rsp->buf, userp->userp, rspsize);\
|
|
+ if (ret) {\
|
|
+ qtfs_err("cmd:%d copy_from_user failed with:%d\n", req->d.cmd, ret);\
|
|
+ rsp->errno = -EFAULT;\
|
|
+ goto err;\
|
|
+ }\
|
|
+ rsp->size = rspsize;\
|
|
+ break;\
|
|
+ }
|
|
static int handle_ioctl(struct qtserver_arg *arg)
|
|
{
|
|
+ unsigned long ioctl_arg;
|
|
int ret;
|
|
int iret;
|
|
struct qtreq_ioctl *req = (struct qtreq_ioctl *)REQ(arg);
|
|
@@ -123,82 +136,45 @@ static int handle_ioctl(struct qtserver_arg *arg)
|
|
}
|
|
mutex_unlock(&fd_bitmap_lock);
|
|
|
|
- switch (req->d.cmd) {
|
|
- case FS_IOC_FSGETXATTR:
|
|
- iret = qtfs_syscall_ioctl(req->d.fd, req->d.cmd, (unsigned long)userp->userp);
|
|
- if (iret) {
|
|
- qtfs_err("fsgetxattr ioctl failed with %d\n", iret);
|
|
- rsp->errno = iret;
|
|
- goto err;
|
|
- }
|
|
- ret = copy_from_user(rsp->buf, userp->userp, sizeof(struct fsxattr));
|
|
- if (ret) {
|
|
- qtfs_err("fsgetxattr copy_from_user failed with %d\n", ret);
|
|
- rsp->errno = -EFAULT;
|
|
- goto err;
|
|
- }
|
|
- rsp->size = sizeof(struct fsxattr);
|
|
- break;
|
|
- case FS_IOC_FSSETXATTR:
|
|
- if (req->d.size <= 0 || req->d.size > sizeof(req->path) || req->d.size >= userp->size) {
|
|
- rsp->errno = -EINVAL;
|
|
- goto err;
|
|
- }
|
|
- ret = copy_to_user(userp->userp, req->path, req->d.size);
|
|
- if (ret) {
|
|
- qtfs_err("fssetxattr copy_to_user failed with %d\n", ret);
|
|
- rsp->errno = -EFAULT;
|
|
- goto err;
|
|
- }
|
|
- iret = qtfs_syscall_ioctl(req->d.fd, req->d.cmd, (unsigned long)userp->userp);
|
|
- if (iret) {
|
|
- qtfs_err("fssetxattr ioctl failed with %d\n", iret);
|
|
- rsp->errno = iret;
|
|
- goto err;
|
|
- }
|
|
- rsp->size = 0;
|
|
- break;
|
|
- case TCGETS:
|
|
- iret = qtfs_syscall_ioctl(req->d.fd, req->d.cmd, (unsigned long)userp->userp);
|
|
- if (iret) {
|
|
- qtfs_err("ioctl TCGETS failed with %d\n", iret);
|
|
- rsp->errno = iret;
|
|
- goto err;
|
|
- }
|
|
- qtfs_info("ioctl TCGETS ret:%d", iret);
|
|
-
|
|
- ret = copy_from_user(rsp->buf, userp->userp, sizeof(struct ktermios));
|
|
- if (ret) {
|
|
- qtfs_err("fsgetxattr copy_from_user failed with %d\n", ret);
|
|
- rsp->errno = -EFAULT;
|
|
- goto err;
|
|
- }
|
|
- rsp->size = sizeof(struct ktermios);
|
|
- break;
|
|
- case TCSETS:
|
|
- if (req->d.size <= 0 || req->d.size > sizeof(req->path)) {
|
|
- rsp->errno = -EINVAL;
|
|
- goto err;
|
|
- }
|
|
- ret = copy_to_user(userp->userp, req->path, req->d.size);
|
|
- if (ret) {
|
|
- qtfs_err("tcsets copy_to_user failed with %d\n", ret);
|
|
- rsp->errno = -EFAULT;
|
|
- goto err;
|
|
- }
|
|
- qtfs_info("tcsets size:%u sizeof ktermios:%lu", req->d.size, sizeof(struct ktermios));
|
|
- iret = qtfs_syscall_ioctl(req->d.fd, req->d.cmd, (unsigned long)userp->userp);
|
|
- if (iret) {
|
|
- qtfs_err("tcsets ioctl failed with %d\n", iret);
|
|
- rsp->errno = iret;
|
|
- goto err;
|
|
+ if (req->d.argtype) {
|
|
+ ioctl_arg = req->d.arg;
|
|
+ } else {
|
|
+ if (req->d.size) {
|
|
+ if (req->d.size <= 0 || req->d.size > sizeof(req->path) || req->d.size >= userp->size) {
|
|
+ rsp->errno = -EINVAL;
|
|
+ goto err;
|
|
+ }
|
|
+ ret = copy_to_user(userp->userp, req->path, req->d.size);
|
|
+ if (ret) {
|
|
+ qtfs_err("cmd:%d copy_to_user failed with:%d", req->d.cmd, ret);
|
|
+ rsp->errno = -EFAULT;
|
|
+ goto err;
|
|
+ }
|
|
}
|
|
- rsp->size = 0;
|
|
- break;
|
|
- default:
|
|
- rsp->errno = -EOPNOTSUPP;
|
|
+ ioctl_arg = (unsigned long)userp->userp;
|
|
+ }
|
|
+ iret = qtfs_syscall_ioctl(req->d.fd, req->d.cmd, ioctl_arg);
|
|
+ if (iret) {
|
|
+ qtfs_err("ioctl fd:%d cmd:%d failed with %d", req->d.fd, req->d.cmd, iret);
|
|
+ rsp->errno = iret;
|
|
goto err;
|
|
}
|
|
+ qtfs_info("ioctl fd:%d cmd:%d argtype:%d arg:%lx size:%u successed", req->d.fd, req->d.cmd, req->d.argtype, req->d.arg, req->d.size);
|
|
+ switch (req->d.cmd) {
|
|
+ case TUNSETPERSIST:
|
|
+ case TUNSETIFF:
|
|
+ case TCSETS:
|
|
+ case FS_IOC_FSSETXATTR:
|
|
+ rsp->size = 0;
|
|
+ break;
|
|
+ case FS_IOC_FSGETXATTR:
|
|
+ QTFS_IOCTL_HANDLE_WITH_BREAK(sizeof(struct fsxattr));
|
|
+ case TCGETS:
|
|
+ QTFS_IOCTL_HANDLE_WITH_BREAK(sizeof(struct ktermios));
|
|
+ default:
|
|
+ rsp->errno = -EOPNOTSUPP;
|
|
+ goto err;
|
|
+ }
|
|
rsp->ret = QTFS_OK;
|
|
rsp->errno = iret;
|
|
return sizeof(struct qtrsp_ioctl) - sizeof(rsp->buf) + rsp->size;
|
|
--
|
|
2.33.0
|
|
|