Source-Changes-HG archive

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

[src/trunk]: src/lib/libperfuse = Open files =



details:   https://anonhg.NetBSD.org/src/rev/6fe91c3eb315
branches:  trunk
changeset: 757860:6fe91c3eb315
user:      manu <manu%NetBSD.org@localhost>
date:      Wed Sep 29 08:01:10 2010 +0000

description:
= Open files =
- Restore open on our own in fsycn and readdir, as the node may not already
be open, and FUSE really wants it to be. No need to close immediatly, it
can be done at inactive time.

= Write operations =
- fix a nasty bug that corrupted files on write (written added twice)
- Keep track of file size in order to honour PUFFS_IO_APPEND

= many fixes in rename =
- handler overwritten nodes correctly
- wait for all operations on the node to drain before doing rename, as
filesystems may not cope with operations on a moving file.
- setback PUFFS_SETBACK_INACT_N1 cannot be used from rename, we therefore
miss the inactive time for an overwritten node. This bounds us to give up
PUFFS_KFLAG_IAONDEMAND.

= Removed files =
- forbid most operations on a removed node, return ENOENT
- setback PUFFS_SETBACK_NOREF_N1 at inactive stage to cause removed
file reclaim

= Misc =
- Update outdated ARGSUSED for lint
- Fix a memory leak (puffs_pn_remove instead of puffs_pn_put)
- Do not use PUFFS_FLAG_BUILDPATH except for debug output. It makes the
lookup code much simplier.

diffstat:

 lib/libperfuse/debug.c        |    3 +-
 lib/libperfuse/ops.c          |  417 ++++++++++++++++++++++++-----------------
 lib/libperfuse/perfuse.c      |    9 +-
 lib/libperfuse/perfuse_priv.h |    7 +-
 lib/libperfuse/subr.c         |    4 +-
 5 files changed, 257 insertions(+), 183 deletions(-)

diffs (truncated from 965 to 300 lines):

diff -r 2d209750ee6e -r 6fe91c3eb315 lib/libperfuse/debug.c
--- a/lib/libperfuse/debug.c    Wed Sep 29 00:44:04 2010 +0000
+++ b/lib/libperfuse/debug.c    Wed Sep 29 08:01:10 2010 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: debug.c,v 1.3 2010/09/23 16:02:34 manu Exp $ */
+/*  $NetBSD: debug.c,v 1.4 2010/09/29 08:01:10 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -85,6 +85,7 @@
        "WRITE",
        "AFTERWRITE",
        "OPEN"
+       "AFTERXCHG"
 };
 
 const char *
diff -r 2d209750ee6e -r 6fe91c3eb315 lib/libperfuse/ops.c
--- a/lib/libperfuse/ops.c      Wed Sep 29 00:44:04 2010 +0000
+++ b/lib/libperfuse/ops.c      Wed Sep 29 08:01:10 2010 +0000
@@ -1,4 +1,4 @@
-/*  $NetBSD: ops.c,v 1.17 2010/09/23 16:02:34 manu Exp $ */
+/*  $NetBSD: ops.c,v 1.18 2010/09/29 08:01:10 manu Exp $ */
 
 /*-
  *  Copyright (c) 2010 Emmanuel Dreyfus. All rights reserved.
@@ -54,12 +54,10 @@
     const char*, struct puffs_node **);
 static int node_mk_common(struct puffs_usermount *, puffs_cookie_t,
     struct puffs_newinfo *, const struct puffs_cn *pcn, perfuse_msg_t *);
-static const char *basename_r(const char *);
 static ssize_t fuse_to_dirent(struct puffs_usermount *, puffs_cookie_t,
     struct fuse_dirent *, size_t);
-static int readdir_buffered(struct perfuse_state *, puffs_cookie_t,
-    struct dirent *, off_t *, size_t *, const struct puffs_cred *,
-    int *, off_t *, size_t *);
+static int readdir_buffered(puffs_cookie_t, struct dirent *, off_t *, 
+    size_t *, const struct puffs_cred *, int *, off_t *, size_t *);
 static void requeue_request(struct puffs_usermount *, 
     puffs_cookie_t opc, enum perfuse_qtype);
 static int dequeue_requests(struct perfuse_state *, 
@@ -175,9 +173,13 @@
        enum perfuse_xchg_pb_reply wait;
 {
        struct perfuse_state *ps;
+       struct perfuse_node_data *pnd;
        int error;
 
        ps = puffs_getspecific(pu);
+       pnd = NULL;
+       if ((struct puffs_node *)opc != NULL)
+               pnd = PERFUSE_NODE_DATA(opc);
 
 #ifdef PERFUSE_DEBUG
        if ((perfuse_diagflags & PDF_FILENAME) && (opc != 0))
@@ -185,8 +187,16 @@
                        (char *)PNPATH((struct puffs_node *)opc), 
                        PERFUSE_NODE_DATA(opc)->pnd_flags);
 #endif
+       if (pnd)
+               pnd->pnd_flags |= PND_INXCHG;
+
        error = ps->ps_xchg_msg(pu, pm, len, wait);
 
+       if (pnd) {
+               pnd->pnd_flags &= ~PND_INXCHG;
+               (void)dequeue_requests(ps, opc, PCQ_AFTERXCHG, DEQUEUE_ALL);
+       }
+
        return error;
 }
 
@@ -306,7 +316,6 @@
 
        ps = puffs_getspecific(pu);
 
-       path = basename_r(path);
        len = strlen(path) + 1;
 
        pm = ps->ps_new_msg(pu, opc, FUSE_LOOKUP, len, NULL);
@@ -327,8 +336,9 @@
 
 #ifdef PERFUSE_DEBUG
        if (perfuse_diagflags & PDF_FILENAME)
-               DPRINTF("%s: opc = %p, looked up opc = %p, file = \"%s\"\n",
-                       __func__, (void *)opc, pn, (char *)PNPATH(pn));
+               DPRINTF("%s: opc = %p, looked up opc = %p, ino = %"PRId64" "
+                       "file = \"%s\"\n", __func__, (void *)opc, pn, 
+                       feo->nodeid, path);
 #endif
 out: 
        ps->ps_destroy_msg(pm);
@@ -402,41 +412,6 @@
        return error;
 }
 
-static const char *
-basename_r(string)
-       const char *string;
-{
-       char *result;
-
-       if ((result = rindex(string, '/')) == NULL)
-               return string;
-
-       /*
-        * We are finished if this is not a trailing /
-        */
-       if (result[1] != '\0')
-               return result + 1;
-
-       
-       /*
-        * Go back until we found something else than a /
-        */
-       while (result != string) {
-               result--;
-               if (result[0] != '/')
-                       break;
-       }
-
-       if (result == string)
-               return string;
-
-       if ((result = rindex(string, '/')) == NULL)
-               return string;
-
-       return result + 1;
-       
-}
-
 static ssize_t
 fuse_to_dirent(pu, opc, fd, fd_len)
        struct puffs_usermount *pu;
@@ -569,11 +544,10 @@
        return written;
 }
 
-/* ARGSUSED0 */
+/* ARGSUSED4 */
 static int 
-readdir_buffered(ps, opc, dent, readoff, 
-                    reslen, pcr, eofflag, cookies, ncookies)
-       struct perfuse_state *ps;
+readdir_buffered(opc, dent, readoff, 
+                reslen, pcr, eofflag, cookies, ncookies)
        puffs_cookie_t opc;
        struct dirent *dent;
        off_t *readoff;
@@ -622,7 +596,6 @@
        return 0;
 }
 
-/* ARGSUSED0 */
 static void
 requeue_request(pu, opc, type)
        struct puffs_usermount *pu;
@@ -907,31 +880,22 @@
        struct puffs_node *pn;
        int error;
        
+       error = 0;
+
        /*
         * Special case for ..
         */
-       if (PCNISDOTDOT(pcn)) {
+       if (strcmp(pcn->pcn_name, "..") == 0) 
                pn = PERFUSE_NODE_DATA(opc)->pnd_parent;
-               PERFUSE_NODE_DATA(pn)->pnd_flags &= ~PND_RECLAIMED;
-               
-               puffs_newinfo_setcookie(pni, pn);
-               puffs_newinfo_setvtype(pni, VDIR);
-
-               return 0;
-       }
-
-       /*
-        * XXX This is borrowed from librefuse, 
-        * and __UNCONST is said to be fixed.
-        */
-        pn = puffs_pn_nodewalk(pu, puffs_path_walkcmp,
-                              __UNCONST(&pcn->pcn_po_full));
-
-       if (pn == NULL) {
-               error = node_lookup_common(pu, opc, (char *)PCNPATH(pcn), &pn);
-               if (error != 0)
-                       return error;
-       }
+       else
+               error = node_lookup_common(pu, (puffs_cookie_t)opc,
+                                          pcn->pcn_name, &pn);
+
+       if (error != 0)
+               return error;
+
+       if (PERFUSE_NODE_DATA(pn)->pnd_flags & PND_REMOVED)
+               return ENOENT;
 
        /*
         * If that node had a pending reclaim, wipe it out.
@@ -943,7 +907,7 @@
        puffs_newinfo_setsize(pni, (voff_t)pn->pn_va.va_size);
        puffs_newinfo_setrdev(pni, pn->pn_va.va_rdev);
 
-       return 0;
+       return error;
 }
 
 int
@@ -965,6 +929,9 @@
        size_t len;
        int error;
        
+       if (PERFUSE_NODE_DATA(opc)->pnd_flags & PND_REMOVED)
+               return ENOENT;
+
        /*
         * Create an object require -WX permission in the parent directory
         */
@@ -977,7 +944,7 @@
         */
        ps = puffs_getspecific(pu);
        if (ps->ps_flags & PS_NO_CREAT) {
-               error = node_lookup_common(pu, opc, (char*)PCNPATH(pcn), &pn);
+               error = node_lookup_common(pu, opc, pcn->pcn_name, &pn);
                if (error == 0) 
                        return EEXIST;
 
@@ -985,7 +952,7 @@
                if (error != 0)
                        return error;
 
-               error = node_lookup_common(pu, opc, (char*)PCNPATH(pcn), &pn);
+               error = node_lookup_common(pu, opc, pcn->pcn_name, &pn);
                if (error != 0) 
                        return error;
 
@@ -998,8 +965,8 @@
                return 0;
        }
 
-       name = basename_r((char *)PCNPATH(pcn));
-       namelen = strlen(name) + 1;
+       name = pcn->pcn_name;
+       namelen = pcn->pcn_namelen + 1;
        len = sizeof(*fci) + namelen;
 
        /*
@@ -1044,7 +1011,7 @@
        if (perfuse_diagflags & (PDF_FH|PDF_FILENAME))
                DPRINTF("%s: opc = %p, file = \"%s\", flags = 0x%x "
                        "ino = %"PRId64", wfh = 0x%"PRIx64"\n",
-                       __func__, (void *)pn, (char *)PCNPATH(pcn),
+                       __func__, (void *)pn, pcn->pcn_name,
                        PERFUSE_NODE_DATA(pn)->pnd_flags, feo->nodeid, foo->fh);
 #endif
 
@@ -1078,6 +1045,9 @@
        const char* path;
        size_t len;
        
+       if (PERFUSE_NODE_DATA(opc)->pnd_flags & PND_REMOVED)
+               return ENOENT;
+
        /*
         * Only superuser can mknod objects other than 
         * directories, files, socks, fifo and links.
@@ -1101,8 +1071,8 @@
 
 
        ps = puffs_getspecific(pu);
-       path = basename_r((char *)PCNPATH(pcn));
-       len = sizeof(*fmi) + strlen(path) + 1; 
+       path = pcn->pcn_name;
+       len = sizeof(*fmi) + pcn->pcn_namelen + 1; 
 
        /*      
         * mode must contain file type (ie: S_IFREG), use VTTOIF(vap->va_type)
@@ -1142,6 +1112,9 @@
        pm = NULL;
        error = 0;
 
+       if (pnd->pnd_flags & PND_REMOVED)
+               return ENOENT;
+
        /*
         * Queue open on a node so that we do not open
         * twice. This would be better with read and
@@ -1152,16 +1125,6 @@
        pnd->pnd_flags |= PND_INOPEN;
 
        if (puffs_pn_getvap(pn)->va_type == VDIR) {
-               /*
-                * We may open removed files, but it seems much more 
-                * troublesome to open removed directories. glusterfs says 
-                * "OPENDIR (null) (fuse_loc_fill() failed)"
-                */
-               if (pnd->pnd_flags & PND_REMOVED) {
-                       error = ENOENT;



Home | Main Index | Thread Index | Old Index