Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src - Use SOCK_DGRAM instead of SOCK_STREAM, as the filesystem s...



details:   https://anonhg.NetBSD.org/src/rev/f64155b7f263
branches:  trunk
changeset: 757702:f64155b7f263
user:      manu <manu%NetBSD.org@localhost>
date:      Wed Sep 15 01:51:43 2010 +0000

description:
- Use SOCK_DGRAM instead of SOCK_STREAM, as the filesystem seems to
assume datagram semantics: when using SOCK_STREAM, if perfused sends
frames faster than the filesystem consumes them, it will grab multiple
frames at once and discard anything beyond the first one. For now the
code can work both with SOCK_DGRAM and SOCK_STREAM, but SOCK_STREAM
support will probably have to be removed for the sake of readability.

- Remeber to sync parent directories when moving a node

- In debug output, display the requeue type (readdir, write, etc...)

diffstat:

 lib/libperfuse/debug.c        |    4 +-
 lib/libperfuse/fuse.h         |    6 +-
 lib/libperfuse/ops.c          |   25 +++--
 lib/libperfuse/perfuse.c      |  177 +++++++++++++++++++++++++++++------------
 lib/libperfuse/perfuse_if.h   |    8 +-
 lib/libperfuse/perfuse_priv.h |    6 +-
 usr.sbin/perfused/debug.c     |    3 +-
 usr.sbin/perfused/msg.c       |  101 ++++++++++++++++++++---
 usr.sbin/perfused/perfused.c  |  126 +++++++++++++++--------------
 usr.sbin/perfused/perfused.h  |    5 +-
 10 files changed, 316 insertions(+), 145 deletions(-)

diffs (truncated from 874 to 300 lines):

diff -r 2b9a71914eec -r f64155b7f263 lib/libperfuse/debug.c
--- a/lib/libperfuse/debug.c    Tue Sep 14 21:35:53 2010 +0000
+++ b/lib/libperfuse/debug.c    Wed Sep 15 01:51:43 2010 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: debug.c,v 1.1 2010/08/25 07:16:00 manu Exp $ */
+/*  $NetBSD: debug.c,v 1.2 2010/09/15 01:51:43 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -79,6 +79,8 @@
        { 0, "UNKNOWN" },
 };
 
+const char *perfuse_qtypestr[] = { "READDIR", "READ", "WRITE", "AFTERWRITE" };
+
 const char *
 perfuse_opname(opcode)
        int opcode;
diff -r 2b9a71914eec -r f64155b7f263 lib/libperfuse/fuse.h
--- a/lib/libperfuse/fuse.h     Tue Sep 14 21:35:53 2010 +0000
+++ b/lib/libperfuse/fuse.h     Wed Sep 15 01:51:43 2010 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: fuse.h,v 1.1 2010/08/25 07:16:00 manu Exp $ */
+/*  $NetBSD: fuse.h,v 1.2 2010/09/15 01:51:43 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -33,9 +33,11 @@
 #define FUSE_ROOT_ID 1
 #define FUSE_UNKNOWN_FH (uint64_t)0
 
+#ifndef FUSE_BUFSIZE
 #define FUSE_MIN_BUFSIZE 0x21000
 #define FUSE_PREF_BUFSIZE (PAGE_SIZE + 0x1000)
-#define FUSE_BUFSIZE MAX(FUSE_PREF_BUFSIZE, FUSE_MIN_BUFSIZE)
+#define FUSE_BUFSIZE MAX(FUSE_PREF_BUFSIZE /* CONSTCOND */, FUSE_MIN_BUFSIZE)
+#endif /* FUSE_BUFSIZE */
 
 struct fuse_attr {
        uint64_t        ino;
diff -r 2b9a71914eec -r f64155b7f263 lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c      Tue Sep 14 21:35:53 2010 +0000
+++ b/lib/libperfuse/ops.c      Wed Sep 15 01:51:43 2010 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: ops.c,v 1.14 2010/09/09 09:12:35 manu Exp $ */
+/*  $NetBSD: ops.c,v 1.15 2010/09/15 01:51:43 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -613,10 +613,10 @@
        TAILQ_INSERT_TAIL(&pnd->pnd_pcq, &pcq, pcq_next);
 
 #ifdef PERFUSE_DEBUG
-
        if (perfuse_diagflags & PDF_REQUEUE)
-               DPRINTF("%s: REQUEUE opc = %p, pcc = %p\n", 
-                      __func__, (void *)opc, pcq.pcq_cc);
+               DPRINTF("%s: REQUEUE opc = %p, pcc = %p (%s)\n", 
+                       __func__, (void *)opc, pcq.pcq_cc,
+                       perfuse_qtypestr[type]);
 #endif
 
        puffs_cc_yield(pcq.pcq_cc);
@@ -624,8 +624,9 @@
 
 #ifdef PERFUSE_DEBUG
        if (perfuse_diagflags & PDF_REQUEUE)
-               DPRINTF("%s: RESUME opc = %p, pcc = %p\n",
-                       __func__, (void *)opc, pcq.pcq_cc);
+               DPRINTF("%s: RESUME opc = %p, pcc = %p (%s)\n",
+                       __func__, (void *)opc, pcq.pcq_cc,
+                       perfuse_qtypestr[type]);
 #endif
 
        return;
@@ -654,8 +655,9 @@
        
 #ifdef PERFUSE_DEBUG
                if (perfuse_diagflags & PDF_REQUEUE)
-                       DPRINTF("%s: SCHEDULE opc = %p, pcc = %p\n",
-                               __func__, (void *)opc, pcq->pcq_cc);
+                       DPRINTF("%s: SCHEDULE opc = %p, pcc = %p (%s)\n",
+                               __func__, (void *)opc, pcq->pcq_cc,
+                                perfuse_qtypestr[type]);
 #endif
                puffs_cc_schedule(pcq->pcq_cc);
                
@@ -1812,11 +1814,15 @@
        /*
         * Update source and destination directories child count
         * Update moved object parent directory
+        * Set dirty flag for source and parent
         */
        PERFUSE_NODE_DATA(opc)->pnd_childcount--;
        PERFUSE_NODE_DATA(targ_dir)->pnd_childcount++;
+
        PERFUSE_NODE_DATA(src)->pnd_parent = targ_dir;
 
+       PERFUSE_NODE_DATA(opc)->pnd_flags |= PND_DIRTY;
+       PERFUSE_NODE_DATA(targ_dir)->pnd_flags |= PND_DIRTY;
 out:
        ps->ps_destroy_msg(pm);
 
@@ -2219,13 +2225,14 @@
 #ifdef PERFUSE_DEBUG
        if (perfuse_diagflags & PDF_RECLAIM)
                DPRINTF("%s (nodeid %"PRId64") is %sreclaimed, "
-                       "has childcount %d %s%s%s, pending ops:%s%s\n", 
+                       "has childcount %d %s%s%s, pending ops:%s%s%s\n", 
                        (char *)PNPATH(pn), pnd->pnd_ino,
                        pnd->pnd_flags & PND_RECLAIMED ? "" : "not ",
                        pnd->pnd_childcount,
                        pnd->pnd_flags & PND_OPEN ? "open " : "not open",
                        pnd->pnd_flags & PND_RFH ? "r" : "",
                        pnd->pnd_flags & PND_WFH ? "w" : "",
+                       pnd->pnd_flags & PND_BUSY ? "" : " none",
                        pnd->pnd_flags & PND_INREADDIR ? " readdir" : "",
                        pnd->pnd_flags & PND_INWRITE ? " write" : "");
 #endif
diff -r 2b9a71914eec -r f64155b7f263 lib/libperfuse/perfuse.c
--- a/lib/libperfuse/perfuse.c  Tue Sep 14 21:35:53 2010 +0000
+++ b/lib/libperfuse/perfuse.c  Wed Sep 15 01:51:43 2010 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: perfuse.c,v 1.5 2010/09/07 02:11:04 manu Exp $ */
+/*  $NetBSD: perfuse.c,v 1.6 2010/09/15 01:51:43 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -35,6 +35,7 @@
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <sys/un.h>
+#include <machine/vmparam.h>
 
 #define LIBPERFUSE
 #include "perfuse.h"
@@ -109,17 +110,30 @@
        char fdstr[16];
        char *const argv[] = { progname, minus_i, fdstr, NULL};
        char *const envp[] = { NULL };
+       uint32_t opt;
 
        if (strcmp(path, _PATH_FUSE) != 0)
                return open(path, flags, mode);
 
-       if ((sv[0] = socket(PF_LOCAL, SOCK_STREAM, 0)) == -1) {
+       if ((sv[0] = socket(PF_LOCAL, PERFUSE_SOCKTYPE, 0)) == -1) {
 #ifdef PERFUSE_DEBUG
                DWARN("%s:%d socket failed: %s", __func__, __LINE__);
 #endif
                return -1;
        }
 
+       /*
+        * Set a buffer lentgh large enough so that any FUSE packet
+        * will fit.
+        */
+       opt = FUSE_BUFSIZE;
+       if (setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) != 0)
+               DWARN("%s: setsockopt SO_SNDBUF to %d failed", __func__, opt);
+
+       opt = FUSE_BUFSIZE;
+       if (setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) != 0)
+               DWARN("%s: setsockopt SO_RCVBUF to %d failed", __func__, opt);
+
        sa = (struct sockaddr *)(void *)&sun;
        sun.sun_len = sizeof(sun);
        sun.sun_family = AF_LOCAL;
@@ -135,13 +149,39 @@
         * we will talk using a socketpair 
         * instead of /dev/fuse.
         */
-       if (socketpair(PF_LOCAL, SOCK_STREAM, 0, sv) != 0) {
-#ifdef PERFUSE_DEBUG
+       if (socketpair(PF_LOCAL, PERFUSE_SOCKTYPE, 0, sv) != 0) {
                DWARN("%s:%d: socketpair failed", __func__, __LINE__);
-#endif
                return -1;
        }
 
+       /*
+        * Set a buffer lentgh large enough so that any FUSE packet
+        * will fit.
+        */
+       opt = FUSE_BUFSIZE;
+       if (setsockopt(sv[0], SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) != 0)
+               DWARN("%s: setsockopt SO_SNDBUF to %d failed", __func__, opt);
+
+       opt = FUSE_BUFSIZE;
+       if (setsockopt(sv[0], SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) != 0)
+               DWARN("%s: setsockopt SO_RCVBUF to %d failed", __func__, opt);
+
+       opt = FUSE_BUFSIZE;
+       if (setsockopt(sv[1], SOL_SOCKET, SO_SNDBUF, &opt, sizeof(opt)) != 0)
+               DWARN("%s: setsockopt SO_SNDBUF to %d failed", __func__, opt);
+
+       opt = FUSE_BUFSIZE;
+       if (setsockopt(sv[1], SOL_SOCKET, SO_RCVBUF, &opt, sizeof(opt)) != 0)
+               DWARN("%s: setsockopt SO_RCVBUF to %d failed", __func__, opt);
+
+       /*
+        * Request peer credentials. This musr be done before first 
+        * frame is sent.
+        */
+       opt = 1;
+       if (setsockopt(sv[1], 0, LOCAL_CREDS, &opt, sizeof(opt)) != 0)
+               DWARN("%s: setsockopt LOCAL_CREDS failed", __func__);
+
        (void)sprintf(fdstr, "%d", sv[1]);
 
        switch(fork()) {
@@ -167,7 +207,6 @@
        return sv[0];
 }
 
-
 int
 perfuse_mount(source, target, filesystemtype, mountflags, data)
        const char *source;
@@ -178,7 +217,16 @@
 {
        int s;
        size_t len;
-       struct perfuse_mount_out pmo;
+       struct perfuse_mount_out *pmo;
+#if (PERFUSE_SOCKTYPE == SOCK_DGRAM)
+       struct sockaddr_storage ss;
+       struct sockaddr_un sun;
+       struct sockaddr *sa;
+       socklen_t sa_len;
+#endif
+       size_t sock_len;
+       char *frame;
+       char *cp;
 
 #ifdef PERFUSE_DEBUG
        if (perfuse_diagflags & PDF_MISC)
@@ -189,70 +237,95 @@
 
        if ((s = get_fd(data)) == -1)
                return -1;
-       
-       pmo.pmo_len = sizeof(pmo);
-       pmo.pmo_len += source ? (uint32_t)strlen(source) : 0;
-       pmo.pmo_len += target ? (uint32_t)strlen(target) : 0;
-       pmo.pmo_len += filesystemtype ? (uint32_t)strlen(filesystemtype) : 0;
-       pmo.pmo_len += data ? (uint32_t)strlen(data) : 0;
-       pmo.pmo_error = 0;
-       pmo.pmo_unique = (uint64_t)-1;
+
+       /*
+        * If we are connected to /dev/fuse, we need a second
+        * socket to get replies from perfused.
+        * XXX This socket is not removed at exit time yet
+        */
+       sock_len = 0;
+#if (PERFUSE_SOCKTYPE == SOCK_DGRAM)
+       sa = (struct sockaddr *)(void *)&ss;
+       sa_len = sizeof(ss);
+       if ((getpeername(s, sa, &sa_len) == 0) &&
+           (sa->sa_family = AF_LOCAL) &&
+           (strcmp(((struct sockaddr_un *)sa)->sun_path, _PATH_FUSE) == 0)) {
 
-       (void)strcpy(pmo.pmo_magic, PERFUSE_MOUNT_MAGIC);
-       pmo.pmo_source_len = source ? (uint32_t)strlen(source) : 0;
-       pmo.pmo_target_len = target ? (uint32_t)strlen(target) : 0;
-       pmo.pmo_filesystemtype_len = 
-           filesystemtype ? (uint32_t)strlen(filesystemtype) : 0;
-       pmo.pmo_mountflags = (uint32_t)mountflags;
-       pmo.pmo_data_len = data ? (uint32_t)strlen(data) : 0;
-       
+               sa = (struct sockaddr *)(void *)&sun;
+               sun.sun_len = sizeof(sun);
+               sun.sun_family = AF_LOCAL;
+               (void)sprintf(sun.sun_path, "%s/%s-%d",
+                             _PATH_TMP, getprogname(), getpid());
+               
+               if (bind(s, sa, sa->sa_len) != 0)
+                       DERR(EX_OSERR, "%s:%d bind to \"%s\" failed",
+                            __func__, __LINE__, sun.sun_path);
 
-       if (write(s, &pmo, sizeof(pmo)) != sizeof(pmo)) {
+               sock_len = strlen(sun.sun_path) + 1;
+       }
+#endif /* PERFUSE_SOCKTYPE */
+               
+       len = sizeof(*pmo);
+       len += source ? (uint32_t)strlen(source) + 1 : 0;
+       len += target ? (uint32_t)strlen(target) + 1 : 0;
+       len += filesystemtype ? (uint32_t)strlen(filesystemtype) + 1 : 0;
+       len += data ? (uint32_t)strlen(data) + 1 : 0;
+       len += sock_len;
+
+       if ((frame = malloc(len)) == NULL) {
 #ifdef PERFUSE_DEBUG
                if (perfuse_diagflags & PDF_MISC)
-                       DPRINTF("%s:%d short write\n", __func__, __LINE__);
+                       DWARN("%s:%d malloc failed", __func__, __LINE__);
 #endif
                return -1;



Home | Main Index | Thread Index | Old Index