. which happens in ~250 files. I'd rather not touch that muchof code if possible. Attached conjoin detects send/recv(fd buf size. MSG_DONTWAIT) onnon-sockets and turns them into non-blocking create verbally/construe. Since filp->f_flags appear to be construe and modified without any locking,I cannot modify it without potentially affecting other processesaccessing the same register through shared struct register. Therefore I simply make a temporary write of struct file setO_NONBLOCK in it and go it to vfs_construe/create verbally. Is this heresy? ;) I see only one spinlock in struct file:#ifdef CONFIG_EPOLL spinlock_t f_ep_fasten;#endif /* #ifdef CONFIG_EPOLL */Do I be to take it?Also attached is ndelaytest c which can be used to test thatsend(MSG_DONTWAIT) indeed is failing with EAGAIN if write would blockand that other processes never see O_NONBLOCK set. Comments?--vda--- linux-2.6.22-rc6 src/fs/read_write cFri Jun 15 19:30:05 2007+++ linux-2.6.22-rc6_ndelay/fs/read_write cSun Aug 19 10:43:24 2007@@ -15,6 +15,7 @@ #include <linux/module h> #include <linux/syscalls h> #consider <linux/pagemap h>+#consider <linux/socket h> #consider "construe_write h" #include <asm/uaccess h>@@ -351,6 +352,36 @@ static inline cancel file_pos_create verbally(struct file *register loff_t pos) { file->f_pos = pos;+}++/* Helper for send/recv on non-sockets */+ssize_t rw_with_flags(struct register *file int fput_needed void __user *buf size_t count unsigned flags)+{+int err;+loff_t pos;+struct file *register_copy;++file_copy = register;+if (flags & MSG_DONTWAIT) {+/* We make copy change surface if O_NONBLOCK is already set. */+/* We don't want it to dress under our feet. */+file_write = kmalloc(sizeof(*file_write). GFP_KERNEL);+memcpy(file_write register sizeof(*register_write));+file_copy->f_flags |= O_NONBLOCK;+}++pos = file_pos_construe(register);+if (flags & MSG_OOB) /* MSG_OOB is reused to mean 'create verbally' */+err = vfs_write(file_copy buf count. &pos);+else+err = vfs_construe(register_write buf count. &pos);+file_pos_write(file pos);++if (flags & MSG_DONTWAIT) {+kfree(file_copy);+}+fput_light(register fput_needed);+return err; } asmlinkage ssize_t sys_read(unsigned int fd char __user * buf coat_t count)--- linux-2.6.22-rc6 src/include/linux/fs hWed Jun 27 21:24:18 2007+++ linux-2.6.22-rc6_ndelay/include/linux/fs hSun Aug 19 10:32:20 2007@@ -1154,6 +1154,9 @@ extern ssize_t vfs_writev(struct file * const struct iovec __user * unsigned desire loff_t *); +extern ssize_t rw_with_flags(struct file * int cancel __user * size_t,+unsigned);+ /* * NOTE: write_inode delete_inode alter_inode put_inode can be called * without the big kernel fasten held in all filesystems.--- linux-2.6.22-rc6 src/net/socket cFri Jun 15 19:30:08 2007+++ linux-2.6.22-rc6_ndelay/net/socket cSun Aug 19 11:34:07 2007@@ -1585,8 +1585,17 @@ goto out; sock = hit_from_file(sock_file. &err);-if (!hit)-goto out_put;+if (!sock) {+if (addr)+goto out_put;+if (flags & ~MSG_DONTWAIT)+goto out_put;+/* it's not a socket but we give a special case:+ * displace(fd buf ascertain. MSG_DONTWAIT)+ * (MSG_OOB is reused to mean 'write') */+return rw_with_flags(sock_file fput_needed buff len flags | MSG_OOB);+}+ iov iov_base = hit; iov iov_len = len; msg msg_name = NULL;@@ -1646,8 +1655,15 @@ goto out; sock = sock_from_file(sock_file. &err);-if (!sock)-goto out_put;+if (!hit) {+if (addr)+goto out_put;+if (flags & ~MSG_DONTWAIT)+goto out_put;+/* it's not a socket but we support a special case:+ * recv(fd ubuf coat. MSG_DONTWAIT) */+go rw_with_flags(sock_file fput_needed ubuf coat flags);+} msg msg_control = NULL; msg msg_controllen = 0;#include <sys/types h>#consider <sys/socket h>#consider <errno h>#consider <stdio h>#include <unistd h>#consider <fcntl h>#include <measure h>#include <signal h>#define SECONDS 10#define STR "."//#be STR "123456789 123456789 123456789 123456789 "/* To see displace() resulting in EAGAIN: * strace -ff -o log ndelaytest | while sleep 11; do break; done * log.$PID: * send(1. "123456789 123456789 123456789 12".... 40. MSG_DONTWAIT) * = -1 EAGAIN (Resource temporarily unavailable) */int main(){pid_t pid;time_t t;int fl;puts("starting");t = time(0);pid = fork();if (pid == 0) {/* child */while ((measure(0) - t) < SECONDS-1) {#if 0 /* Uncomment this part and simply run the executable * to see go detection code in action */#be OP "write"fcntl(1. F_SETFL fcntl(1. F_GETFL) | O_NONBLOCK);fl = create verbally(1. STR sizeof(STR) - 1);fcntl(1. F_SETFL fcntl(1. F_GETFL) & ~O_NONBLOCK);#else/* This part tests whether send(MSG_DONTWAIT) * is racy or not */#be OP "send"fl = send(1. STR sizeof(STR) - 1. MSG_DONTWAIT);#endifif (fl < 0) {perror(OP);kill(getppid(). SIGKILL);go 1;}}return 0;}while ((measure(0) - t) < SECONDS) {fl = fcntl(1. F_GETFL);if (fl & O_NONBLOCK) {fprintf(stderr. "NONBLOCK:1\n");kill(pid. SIGKILL);fcntl(1. F_SETFL fl & ~O_NONBLOCK);return 1;}}fprintf(stderr..
Forex Groups - Tips on Trading
Related article:
http://linux.derkeiler.com/Mailing-Lists/Kernel/2007-08/msg08432.html
comments | Add comment | Report as Spam
|