From 3433279629243cd84b2cac964a3d839c545b099c Mon Sep 17 00:00:00 2001 From: liqiang Date: Sat, 20 Aug 2022 16:42:06 +0800 Subject: [PATCH 1/2] support epoll on any file mode, and add control switch in qtinfo Signed-off-by: liqiang --- qtfs/comm.h | 2 ++ qtfs/conn.c | 1 + qtfs/conn.h | 6 ++++++ qtfs/demo/cfifo_r.c | 13 ++++++++----- qtfs/misc.c | 9 +++++++++ qtfs/qtfs/qtfs-mod.c | 2 +- qtfs/qtfs/sb.c | 26 ++++++++++++++------------ qtfs/qtfs/syscall.c | 5 +++-- qtfs/qtinfo/qtinfo.c | 21 ++++++++++++++++++++- 9 files changed, 64 insertions(+), 21 deletions(-) diff --git a/qtfs/comm.h b/qtfs/comm.h index 56a3572..d639c19 100644 --- a/qtfs/comm.h +++ b/qtfs/comm.h @@ -16,6 +16,7 @@ enum { _QTFS_IOCTL_CLEARALL, _QTFS_IOCTL_LOG_LEVEL, + _QTFS_IOCTL_EPOLL_SUPPORT, }; #define QTFS_IOCTL_THREAD_INIT _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_EXEC) @@ -27,6 +28,7 @@ enum { #define QTFS_IOCTL_ALLINFO _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_ALLINFO) #define QTFS_IOCTL_CLEARALL _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_CLEARALL) #define QTFS_IOCTL_LOGLEVEL _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_LOG_LEVEL) +#define QTFS_IOCTL_EPOLL_SUPPORT _IO(QTFS_IOCTL_MAGIC, _QTFS_IOCTL_EPOLL_SUPPORT) #define QTINFO_MAX_EVENT_TYPE 36 // look qtreq_type at req.h #define QTFS_FUNCTION_LEN 64 diff --git a/qtfs/conn.c b/qtfs/conn.c index 4d30ee2..dd96089 100644 --- a/qtfs/conn.c +++ b/qtfs/conn.c @@ -18,6 +18,7 @@ int log_level = LOG_ERROR; int qtfs_server_port = 12345; int qtfs_sock_max_conn = QTFS_MAX_THREADS; struct qtinfo *qtfs_diag_info = NULL; +bool qtfs_epoll_mode = true; // true: support any mode; false: only support fifo static atomic_t g_qtfs_conn_num; static struct list_head g_vld_lst; diff --git a/qtfs/conn.h b/qtfs/conn.h index cf9c764..8dbf706 100644 --- a/qtfs/conn.h +++ b/qtfs/conn.h @@ -25,6 +25,7 @@ extern struct qtfs_sock_var_s *qtfs_epoll_var; extern char qtfs_log_level[QTFS_LOGLEVEL_STRLEN]; extern int log_level; extern struct qtinfo *qtfs_diag_info; +extern bool qtfs_epoll_mode; #define qtfs_conn_get_param(void) _qtfs_conn_get_param(__func__) @@ -38,6 +39,11 @@ static inline bool err_ptr(void *ptr) return false; } +static inline bool qtfs_support_epoll(umode_t mode) +{ + return (qtfs_epoll_mode || S_ISFIFO(mode)); +} + #define QTFS_SOCK_RCVTIMEO 1 #define QTFS_SOCK_SNDTIMEO 1 diff --git a/qtfs/demo/cfifo_r.c b/qtfs/demo/cfifo_r.c index 563e0f7..1326309 100644 --- a/qtfs/demo/cfifo_r.c +++ b/qtfs/demo/cfifo_r.c @@ -29,8 +29,8 @@ int single_read(int argc, char *argv[]) int my_epoll_read(int argc, char *argv[]) { - char buf[BUF_MAX]; int *fd = (int *)malloc((argc - 1) * sizeof(int)); + char *buf = (char *)malloc(65536); for (int i = 1; i < argc; i++) { fd[i-1] = open(argv[i], O_RDONLY|O_NONBLOCK); @@ -58,28 +58,31 @@ int my_epoll_read(int argc, char *argv[]) } printf("my epoll read epoll ctl fd:%d events:%x success.\n", fd[i], evt.events); } - evts = calloc(64, sizeof(evt)); - while (1) { int n = epoll_wait(epfd, evts, 64, -1); printf("epoll wait get new %d events.\n", n); for (int i = 0; i < n; i++) { int ret; + FILE *fp; printf(" > epoll wait new events, cur:%d key:%x data:%lx n:%d.\n", i, evts[i].events, evts[i].data, n); - memset(buf, 0, sizeof(buf)); + memset(buf, 0, 65536); if (evts[i].events & EPOLLHUP) { epoll_ctl(epfd, EPOLL_CTL_DEL, evts[i].data.fd, NULL); continue; } - ret = read(evts[i].data.fd, buf, sizeof(buf)); + fp = fdopen(evts[i].data.fd, "r"); + fseek(fp, 0, SEEK_SET); + ret = read(evts[i].data.fd, buf, 65536); if (ret <= 0) { printf(" >read fd:%d ret:%d data error.\n", evts[i].data.fd, ret); + goto end; } else { printf(" >read fd:%d ret:%d data:%s.\n", evts[i].data.fd, ret, buf); } } } +end: close(epfd); for (int i = 0; i < argc-1; i++) { close(fd[i]); diff --git a/qtfs/misc.c b/qtfs/misc.c index 2c694ed..90c8d36 100644 --- a/qtfs/misc.c +++ b/qtfs/misc.c @@ -149,6 +149,15 @@ long qtfs_misc_ioctl(struct file *file, unsigned int cmd, unsigned long arg) ret = (long)qtfs_log_init(level_str); break; } + case QTFS_IOCTL_EPOLL_SUPPORT: + { + if (arg == 0) { + qtfs_epoll_mode = false; + } else { + qtfs_epoll_mode = true; + } + break; + } } return ret; } diff --git a/qtfs/qtfs/qtfs-mod.c b/qtfs/qtfs/qtfs-mod.c index 4f2a833..9ccf0ee 100644 --- a/qtfs/qtfs/qtfs-mod.c +++ b/qtfs/qtfs/qtfs-mod.c @@ -146,7 +146,7 @@ connecting: } inode = file->f_inode; // 暂时只支持fifo文件的epoll - if (inode == NULL || !S_ISFIFO(inode->i_mode)) { + if (inode == NULL || !qtfs_support_epoll(inode->i_mode)) { qtfs_err("epoll thread event file:%lx not a fifo.", (unsigned long)file); continue; } diff --git a/qtfs/qtfs/sb.c b/qtfs/qtfs/sb.c index 6f7d734..3b64f72 100644 --- a/qtfs/qtfs/sb.c +++ b/qtfs/qtfs/sb.c @@ -393,7 +393,7 @@ ssize_t qtfs_writeiter(struct kiocb *kio, struct iov_iter *iov) leftlen -= wrbuflen; } while (leftlen); - if (S_ISFIFO(kio->ki_filp->f_inode->i_mode)) { + if (qtfs_support_epoll(kio->ki_filp->f_inode->i_mode)) { struct inode *inode = kio->ki_filp->f_inode; struct qtfs_inode_priv *priv = inode->i_private; wake_up_interruptible_sync_poll(&priv->readq, EPOLLIN | EPOLLRDNORM); @@ -533,17 +533,6 @@ long qtfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) } } -static struct file_operations qtfs_file_ops = { - .read_iter = qtfs_readiter, - .write_iter = qtfs_writeiter, - .open = qtfs_open, - .release = qtfs_release, - .mmap = qtfs_mmap, - .llseek = qtfs_llseek, - .fsync = qtfs_fsync, - .unlocked_ioctl = qtfs_ioctl, -}; - loff_t qtfs_dir_file_llseek(struct file *file, loff_t offset, int whence) { qtfs_info("qtfs generic file llseek: %s.", file->f_path.dentry->d_iname); @@ -619,6 +608,19 @@ struct file_operations qtfsfifo_ops = { .poll = qtfsfifo_poll, }; +static struct file_operations qtfs_file_ops = { + .read_iter = qtfs_readiter, + .write_iter = qtfs_writeiter, + .open = qtfs_open, + .release = qtfs_release, + .mmap = qtfs_mmap, + .llseek = qtfs_llseek, + .fsync = qtfs_fsync, + .unlocked_ioctl = qtfs_ioctl, + .poll = qtfsfifo_poll, +}; + + static int qtfs_readpage(struct file *file, struct page *page) { void *kaddr = NULL; diff --git a/qtfs/qtfs/syscall.c b/qtfs/qtfs/syscall.c index a83e025..afb712f 100644 --- a/qtfs/qtfs/syscall.c +++ b/qtfs/qtfs/syscall.c @@ -157,7 +157,7 @@ int qtfs_epoll_ctl_remote(int op, int fd, struct epoll_event __user * event) ret = 0; goto end; } - if (!S_ISFIFO(file->f_inode->i_mode)) { + if (!qtfs_support_epoll(file->f_inode->i_mode)) { char *fullname = (char *)kmalloc(MAX_PATH_LEN, GFP_KERNEL); memset(fullname, 0, MAX_PATH_LEN); if (qtfs_fullname(fullname, file->f_path.dentry) < 0) { @@ -179,7 +179,8 @@ int qtfs_epoll_ctl_remote(int op, int fd, struct epoll_event __user * event) goto end; } - qtfs_info("qtfs qtfs remote epoll file:%s mode:%x.", file->f_path.dentry->d_iname, file->f_inode->i_mode); + qtfs_info("qtfs qtfs remote epoll file:%s mode:%x file can poll:%lx.", + file->f_path.dentry->d_iname, file->f_inode->i_mode, (unsigned long)file->f_op->poll); do_epoll_ctl_remote(op, event, file); end: diff --git a/qtfs/qtinfo/qtinfo.c b/qtfs/qtinfo/qtinfo.c index 665d9a8..dc88da0 100644 --- a/qtfs/qtinfo/qtinfo.c +++ b/qtfs/qtinfo/qtinfo.c @@ -298,6 +298,21 @@ void qtinfo_opt_t(int fd) return; } +void qtinfo_opt_p(int fd, char *support) +{ + int ret; + int sup = atoi(support); + + ret = ioctl(fd, QTFS_IOCTL_EPOLL_SUPPORT, sup); + if (ret != 0) { + qtinfo_out("Set qtfs epoll support to:%s failed.", (sup == 1) ? "any file" : "fifo file"); + return; + } + qtinfo_out("Set qtfs epoll support to %s success.", (sup == 1) ? "any file" : "fifo file"); + return; +} + + static void qtinfo_help(char *exec) { qtinfo_out("Usage: %s [OPTION].", exec); @@ -306,6 +321,7 @@ static void qtinfo_help(char *exec) qtinfo_out(" -c, Clear all diag info."); qtinfo_out(" -l, Set log level(valid param: \"NONE\", \"ERROR\", \"WARN\", \"INFO\", \"DEBUG\")."); qtinfo_out(" -t, For test informations."); + qtinfo_out(" -p, Epoll support file mode(1: any files; 0: only fifo)."); } int main(int argc, char *argv[]) @@ -318,7 +334,7 @@ int main(int argc, char *argv[]) qtinfo_err("open file %s failed.", QTFS_DEV_NAME); return 0; } - while ((ch = getopt(argc, argv, "acl:t")) != -1) { + while ((ch = getopt(argc, argv, "acl:tp:")) != -1) { switch (ch) { case 'a': qtinfo_opt_a(fd); @@ -332,6 +348,9 @@ int main(int argc, char *argv[]) case 't': qtinfo_opt_t(fd); break; + case 'p': + qtinfo_opt_p(fd, optarg); + break; default: qtinfo_help(argv[0]); break; -- Gitee From 78036e4c537738c61ffb8e42a9eaa078362be91f Mon Sep 17 00:00:00 2001 From: liqiang Date: Mon, 22 Aug 2022 10:54:33 +0800 Subject: [PATCH 2/2] fix magic number Signed-off-by: liqiang --- qtfs/demo/cfifo_r.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/qtfs/demo/cfifo_r.c b/qtfs/demo/cfifo_r.c index 1326309..02e6258 100644 --- a/qtfs/demo/cfifo_r.c +++ b/qtfs/demo/cfifo_r.c @@ -27,10 +27,11 @@ int single_read(int argc, char *argv[]) return 0; } +#define MAX_READ_LEN 65536 int my_epoll_read(int argc, char *argv[]) { int *fd = (int *)malloc((argc - 1) * sizeof(int)); - char *buf = (char *)malloc(65536); + char *buf = (char *)malloc(MAX_READ_LEN); for (int i = 1; i < argc; i++) { fd[i-1] = open(argv[i], O_RDONLY|O_NONBLOCK); @@ -66,14 +67,14 @@ int my_epoll_read(int argc, char *argv[]) int ret; FILE *fp; printf(" > epoll wait new events, cur:%d key:%x data:%lx n:%d.\n", i, evts[i].events, evts[i].data, n); - memset(buf, 0, 65536); + memset(buf, 0, MAX_READ_LEN); if (evts[i].events & EPOLLHUP) { epoll_ctl(epfd, EPOLL_CTL_DEL, evts[i].data.fd, NULL); continue; } fp = fdopen(evts[i].data.fd, "r"); fseek(fp, 0, SEEK_SET); - ret = read(evts[i].data.fd, buf, 65536); + ret = read(evts[i].data.fd, buf, MAX_READ_LEN); if (ret <= 0) { printf(" >read fd:%d ret:%d data error.\n", evts[i].data.fd, ret); goto end; -- Gitee