Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 7 Jun 2011 10:58:25 GMT
From:      Ilya Putsikau <ilya@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 194386 for review
Message-ID:  <201106071058.p57AwPrj053241@skunkworks.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://p4web.freebsd.org/@@194386?ac=10

Change 194386 by ilya@ilya_triton2011 on 2011/06/07 10:58:20

	Start macfuse merge

Affected files ...

.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_device.c#4 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.h#2 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.c#5 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#7 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#3 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.c#3 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.h#5 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#3 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#10 edit

Differences ...

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_device.c#4 (text+ko) ====

@@ -291,7 +291,7 @@
 		DEBUG2G("reader is to be sacked\n");
 		if (tick) {
 			DEBUG2G("weird -- \"kick\" is set tho there is message\n");
-			fuse_ticket_drop_notowned(tick);
+			fuse_ticket_drop_invalid(tick);
 		}
 		return (ENODEV); /* This should make the daemon get off of us */
 	}
@@ -343,7 +343,7 @@
 	 * (used when the one who inserted the message thinks the daemon
 	 * won't aswer)
 	 */
-	fuse_ticket_drop_notowned(tick);
+	fuse_ticket_drop_invalid(tick);
 
 	return (err);
 }

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.h#2 (text+ko) ====

@@ -1,26 +1,92 @@
 /*
- * Fuse filehandle, for in-kernel bookkeping of daemon's filehandles
- * (which are presented to us as an opque 64 bit id, see the fh_id
- * member of the struct).
- * It serves as private data for in-kernel file structures, but can
- * as well occur standalone.
+ * Copyright (C) 2006 Google. All Rights Reserved.
+ * Amit Singh <singh@>
  */
 
+#ifndef _FUSE_FILE_H_
+#define _FUSE_FILE_H_
+
+#include <sys/types.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <sys/vnode.h>
+
+typedef enum fufh_type {
+    FUFH_INVALID = -1,
+    FUFH_RDONLY  = 0,
+    FUFH_WRONLY  = 1,
+    FUFH_RDWR    = 2,
+    FUFH_MAXTYPE = 3,
+} fufh_type_t;
+
+#define FUFH_VALID    0x00000001
+#define FUFH_MAPPED   0x00000002
+#define FUFH_STRATEGY 0x00000004
+
 struct fuse_filehandle {
-	struct vnode *fh_vp;
-	uint64_t fh_id;
-	int mode;
-	struct ucred *cred;
-	pid_t pid;
-	int useco;
-	LIST_ENTRY(fuse_filehandle) fh_link;
-	struct file *fp;
-	int flags;
-	enum fuse_opcode op;
+    uint64_t    fh_id;
+    fufh_type_t type;
+    int         fufh_flags;
+    int         open_count;
+    int         open_flags;
+    int         fuse_open_flags;
 };
+typedef struct fuse_filehandle * fuse_filehandle_t;
+
+static __inline__ fufh_type_t
+fuse_filehandle_xlate_from_mmap(int fflags)
+{
+    if (fflags & (PROT_READ | PROT_WRITE)) {
+        return FUFH_RDWR;
+    } else if (fflags & (PROT_WRITE)) {
+        return FUFH_WRONLY;
+    } else if ((fflags & PROT_READ) || (fflags & PROT_EXEC)) {
+        return FUFH_RDONLY;
+    } else {
+        return FUFH_INVALID;
+    }
+}
+
+static __inline__ fufh_type_t
+fuse_filehandle_xlate_from_fflags(int fflags)
+{
+    if ((fflags & FREAD) && (fflags & FWRITE)) {
+        return FUFH_RDWR;
+    } else if (fflags & (FWRITE)) {
+        return FUFH_WRONLY;
+    } else if (fflags & (FREAD)) {
+        return FUFH_RDONLY;
+    } else {
+        panic("What kind of a flag is this?");
+    }
+}
 
-#define FTOFH(fp) ((struct fuse_filehandle *)(fp)->f_data)
+static __inline__ int
+fuse_filehandle_xlate_to_oflags(fufh_type_t type)
+{
+    int oflags = -1;
+
+    switch (type) {
+    case FUFH_RDONLY:
+        oflags = O_RDONLY;
+        break;
+    case FUFH_WRONLY:
+        oflags = O_WRONLY;
+        break;
+    case FUFH_RDWR:
+        oflags = O_RDWR;
+        break;
+    default:
+        break;
+    }
+
+    return oflags;
+}
 
-#define ASSERT_VOP_ELOCKED__FH(vp) ASSERT_VOP_ELOCKED((vp), "unsafe filehandle access")
-#define ASSERT_VOP_LOCKED__FH(vp) ASSERT_VOP_LOCKED((vp), "unsafe filehandle access")
+int fuse_filehandle_get(struct vnode *vp, struct thread *td, struct ucred *cred,
+                        fufh_type_t fufh_type);
+int fuse_filehandle_put(struct vnode *vp, struct thread *td, struct ucred *cred,
+                        fufh_type_t fufh_type, int foregrounded);
 
+#endif /* _FUSE_FILE_H_ */

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.c#5 (text+ko) ====

@@ -1,3 +1,8 @@
+/*
+ * Copyright (C) 2006 Google. All Rights Reserved.
+ * Amit Singh <singh@>
+ */
+
 #include "config.h"
 
 #include <sys/types.h>
@@ -29,9 +34,14 @@
 #include <sys/priv.h>
 
 #include "fuse.h"
+#include "fuse_file.h"
+#include "fuse_internal.h"
+#include "fuse_ipc.h"
 #include "fuse_node.h"
-#include "fuse_ipc.h"
-#include "fuse_internal.h"
+#include "fuse_file.h"
+// #include "fuse_nodehash.h"
+#include "fuse_param.h"
+// #include "fuse_sysctl.h"
 
 /* access */
 
@@ -213,62 +223,106 @@
 fuse_check_spyable(struct fuse_dispatcher *fdip, struct mount *mp,
                    struct thread *td, struct ucred *cred)
 {
-	struct fuse_data *data = fusefs_get_data(mp);
-	struct fuse_secondary_data *x_fsdat;
-	int denied;
+	return (0);
+}
+
+/* fsync */
+
+int
+fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio)
+{
+    fuse_trace_printf_func();
+
+    if (tick->tk_aw_ohead.error == ENOSYS) {
+        tick->tk_data->dataflag |= (fticket_opcode(tick) == FUSE_FSYNC) ?
+                                        FSESS_NOFSYNC : FSESS_NOFSYNCDIR;
+    }
+
+    fuse_ticket_drop(tick);
+
+    return 0;
+}
 
-	if (data->dataflag & FSESS_DAEMON_CAN_SPY)
-		return (0);
+int
+fuse_internal_fsync(struct vnode           *vp,
+                    struct thread          *td,
+                    struct ucred           *cred,
+                    struct fuse_filehandle *fufh,
+                    void                   *param)
+{
+    int op = FUSE_FSYNC;
+    struct fuse_fsync_in *ffsi;
+    struct fuse_dispatcher *fdip = param;
 
-	/*
-	 * The policy is to forbid a user from using the filesystem,
-	 * unless she has it mounted.
-	 *
-	 * This is primarily to
-	 * protect her from the daemon spying on her I/O
-	 * operations. Although this is not a concern if the user
-	 * is more privileged than the daemon, we consistently
-	 * demand the per-user mount, in order to be compatible
-	 * with the Linux implementation.
-	 *
-	 * Secondary mounts let arbitrary number of users mount and
-	 * use the filesystem. However, the primary mounter must explicitly
-	 * allow secondary mounts. This is again for providing Linux like
-	 * defaults.
-	 */
+    fuse_trace_printf_func();
 
-	denied = fuse_match_cred(mp->mnt_cred, cred);
-	if (! denied)
-		goto allow;
+    fdip->iosize = sizeof(*ffsi);
+    fdip->tick = NULL;
+    if (vnode_vtype(vp) == VDIR) {
+        op = FUSE_FSYNCDIR;
+    }
+    
+    fdisp_make_vp(fdip, op, vp, td, cred);
+    ffsi = fdip->indata;
+    ffsi->fh = fufh->fh_id;
 
-	LIST_FOREACH(x_fsdat, &data->slaves_head, slaves_link) {
-		denied = fuse_match_cred(x_fsdat->mp->mnt_cred, cred);
-		if (! denied)
-			goto allow;
-	}
+    ffsi->fsync_flags = 1;
+  
+    fuse_insert_callback(fdip->tick, fuse_internal_fsync_callback);
+    fuse_insert_message(fdip->tick);
 
-	return (EACCES);
+    return 0;
 
-allow:
-	return (0);
 }
 
-/* fsync */
+/* readdir */
 
 int
-fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio)
+fuse_internal_readdir(struct vnode           *vp,
+                      struct uio             *uio,
+                      struct thread          *td,
+                      struct ucred           *cred,
+                      struct fuse_filehandle *fufh,
+                      struct fuse_iov        *cookediov)
 {
-    if (tick->tk_aw_ohead.error == ENOSYS)
-        tick->tk_data->dataflag |=
-         fticket_opcode(tick) == FUSE_FSYNC ?
-         FSESS_NOFSYNC : FSESS_NOFSYNCDIR;
+    int err = 0;
+    struct fuse_dispatcher fdi;
+    struct fuse_read_in   *fri;
+
+    if (uio_resid(uio) == 0) {
+        return (0);
+    }
+
+    fdisp_init(&fdi, 0);
+
+    /* Note that we DO NOT have a UIO_SYSSPACE here (so no need for p2p I/O). */
+
+    while (uio_resid(uio) > 0) {
+
+        fdi.iosize = sizeof(*fri);
+        fdisp_make_vp(&fdi, FUSE_READDIR, vp, td, cred);
+
+        fri = fdi.indata;
+        fri->fh = fufh->fh_id;
+        fri->offset = uio_offset(uio);
+        fri->size = min(uio_resid(uio), FUSE_DEFAULT_IOSIZE); // mp->max_read
+
+        if ((err = fdisp_wait_answ(&fdi))) {
+            goto out;
+        }
+
+        if ((err = fuse_internal_readdir_processdata(uio, fri->size, fdi.answ,
+                                                     fdi.iosize, cookediov))) {
+            break;
+        }
+    }
+
+    fuse_ticket_drop(fdi.tick);
 
-    fuse_ticket_drop(tick);
-    return (0);
+out:
+    return ((err == -1) ? 0 : err);
 }
 
-/* readdir */
-
 int
 fuse_internal_readdir_processdata(struct uio *uio,
                                   size_t reqsize,
@@ -276,28 +330,6 @@
                                   size_t bufsize,
                                   void *param)
 {
-    /*
-     * The daemon presents us with a virtual geometry when reading dirents.
-     * This info is stored in the "off" field of fuse_dirent (which is the
-     * struct we can read from her). "off" shows the absolut position of
-     * the next entry (by definition). So I might pull 40 actual bytes from
-     * the daemon, that might count as 60 by her virtual geometry, and when
-     * I translate fuse_dirents to POSIX dirents, I have 20 bytes to pass
-     * to the userspace reader.
-     *	
-     * How to keep these in sync? We don't want to make the general read
-     * routine complex (to which here we serve a background, and which
-     * naively treats reading by a liner logic). So we artifically inflate
-     * dirents: we pad them with as much zeros as we need them to get to
-     * next offset (as the deamon declared), and we pass it to the reader
-     * thusly (this will work as fuse dirents are bigger than std ones). So
-     * we do more IO with the reader than absolutely necessary, but it's
-     * hardly a problem as the expensive thing is reading from the daemon,
-     * not sending data to the reader.
-     *
-     * There is no use to change this simple geometry translation scheme
-     * 'till we do page caching. [We do now, but it's still fine as is.]
-     */
     int err = 0;
     int cou = 0;
     int bytesavail;
@@ -307,33 +339,10 @@
     struct fuse_dirent *fudge;
     struct fuse_iov    *cookediov = param;
     
-    KASSERT(bufsize <= reqsize, ("read more than asked for?"));
-
-    DEBUG2G("starting\n");
-
-    /*
-     * Sanity check: if this fails, we would overrun the allocated space
-     * upon entering the loop below, so we'd better leave right now.
-     * If so, we return -1 to terminate reading.
-     */
     if (bufsize < FUSE_NAME_OFFSET) {
         return (-1);
     }
 
-    DEBUG2G("entering loop with bufsize %d\n", (int)bufsize);
-
-    /*
-     * Can we avoid infite loops? An infinite loop could occur only if we
-     * leave this function with 0 return value, because otherwise we wont't
-     * be called again. But both 0 exit points imply that some data has
-     * been consumed... because
-     *   1) if a turn is not aborted, it consumes positive amount of data
-     *   2) the 0 jump-out from within the loop can't occur in the first
-     *      turn
-     *   3) if we exit 0 after the loop is over, then at least one turn
-     *      was completed, otherwise we hed exited above with -1.
-     */  
-
     for (;;) {
 
         if (bufsize < FUSE_NAME_OFFSET) {
@@ -346,15 +355,6 @@
         fudge = (struct fuse_dirent *)buf;
         freclen = FUSE_DIRENT_SIZE(fudge);
 
-        DEBUG("bufsize %d, freclen %d\n", (int)bufsize, (int)freclen);
-
-        /*
-         * Here is an exit condition: we terminate the whole reading
-         * process if a fresh chunk of buffer is already too short to
-         * cut out an entry.
-         * (It it was not the first turn in the loop, nevermind,
-         * return with asking for more)
-         */
         if (bufsize < freclen) {
             err = ((cou == 1) ? -1 : 0);
             break;
@@ -367,25 +367,14 @@
         }
 #endif
 
-        /* Sanity checks */
-
         if (!fudge->namelen || fudge->namelen > MAXNAMLEN) {
-            DEBUG2G("bogus namelen %d at turn %d\n",
-                    fudge->namelen, cou);
             err = EINVAL;
             break;
         }
 
         bytesavail = GENERIC_DIRSIZ((struct pseudo_dirent *)&fudge->namelen); 
 
-        /*
-         * Exit condition 2: if the pretended amount of input is more
-         * than that the userspace wants, then it's time to stop
-         * reading.
-         */  
-        if (bytesavail > uio->uio_resid) {
-            DEBUG2G("leaving at %d-th item as we have %d bytes but only %d is asked for\n",
-                    cou, bytesavail, uio->uio_resid);
+        if (bytesavail > uio_resid(uio)) {
             err = -1;
             break;
         }
@@ -402,10 +391,6 @@
                (char *)buf + FUSE_NAME_OFFSET, fudge->namelen);
         ((char *)cookediov->base)[bytesavail] = '\0';
 
-        DEBUG("bytesavail %d, fudge->off %llu, fudge->namelen %d, uio->uio_offset %d, name %s\n",
-              bytesavail, (unsigned long long)fudge->off, fudge->namelen, (int)uio->uio_offset,
-              (char *)cookediov->base + sizeof(struct dirent) - MAXNAMLEN - 1);
-
         err = uiomove(cookediov->base, cookediov->len, uio);
         if (err) {
             break;
@@ -413,7 +398,7 @@
 
         buf = (char *)buf + freclen;
         bufsize -= freclen;
-        uio->uio_offset = fudge->off;
+        uio_setoffset(uio, fudge->off);
     }
 
     return (err);
@@ -421,6 +406,26 @@
 
 /* remove */
 
+#ifdef XXXIP
+static int
+fuse_unlink_callback(struct vnode *vp, void *cargs)
+{
+    struct vattr *vap;
+    uint64_t target_nlink;
+
+    vap = VTOVA(vp);
+
+    target_nlink = *(uint64_t *)cargs;
+
+    if ((vap->va_nlink == target_nlink) && (vnode_vtype(vp) == VREG)) {
+        fuse_invalidate_attr(vp);
+    }
+
+    return 0;
+}
+#endif
+
+#define INVALIDATE_CACHED_VATTRS_UPON_UNLINK 1
 int
 fuse_internal_remove(struct vnode *dvp,
                      struct vnode *vp,
@@ -428,9 +433,14 @@
                      enum fuse_opcode op)
 {
     struct fuse_dispatcher fdi;
+    struct vattr *vap = VTOVA(vp);
+#if INVALIDATE_CACHED_VATTRS_UPON_UNLINK
+    int need_invalidate = 0;
+    uint64_t target_nlink = 0;
+#endif
     int err = 0;
 
-    debug_printf("dvp=%p, cnp=%p, op=%d, context=%p\n", vp, cnp, op, context);
+    debug_printf("dvp=%p, cnp=%p, op=%d\n", vp, cnp, op);
 
     fdisp_init(&fdi, cnp->cn_namelen + 1);
     fdisp_make_vp(&fdi, op, dvp, curthread, NULL);
@@ -438,6 +448,13 @@
     memcpy(fdi.indata, cnp->cn_nameptr, cnp->cn_namelen);
     ((char *)fdi.indata)[cnp->cn_namelen] = '\0';
 
+#if INVALIDATE_CACHED_VATTRS_UPON_UNLINK
+    if (vap->va_nlink > 1) {
+        need_invalidate = 1;
+        target_nlink = vap->va_nlink;
+    }
+#endif
+
     if (!(err = fdisp_wait_answ(&fdi))) {
         fuse_ticket_drop(fdi.tick);
     }
@@ -445,6 +462,15 @@
     fuse_invalidate_attr(dvp);
     fuse_invalidate_attr(vp);
 
+#if INVALIDATE_CACHED_VATTRS_UPON_UNLINK
+#ifdef XXXIP
+    if (need_invalidate && !err) {
+        vnode_iterate(vnode_mount(vp), 0, fuse_unlink_callback,
+                      (void *)&target_nlink);
+    }
+#endif
+#endif
+
     return (err);
 }
 
@@ -511,6 +537,8 @@
 
     memcpy((char *)fdip->indata + bufsize, cnp->cn_nameptr, cnp->cn_namelen);
     ((char *)fdip->indata)[bufsize + cnp->cn_namelen] = '\0';
+
+    fdip->iosize = bufsize + cnp->cn_namelen + 1;
 }
 
 int
@@ -521,13 +549,10 @@
 {
     int err = 0;
     struct fuse_entry_out *feo;
-    struct mount *mp = dvp->v_mount;
+    struct mount *mp = vnode_mount(dvp);
 
     debug_printf("fdip=%p\n", fdip);
 
-    KASSERT(! (mp->mnt_flag & MNT_RDONLY),
-            ("request for new entry in a read-only mount"));
-
     if ((err = fdisp_wait_answ(fdip))) {
         return (err);
     }
@@ -538,24 +563,13 @@
         goto out;
     }
 
-    /*
-     * The Linux code doesn't seem to make a fuss about
-     * getting a nodeid for a new entry which is  already
-     * in use. Therefore we used to do the same.
-     * This is not possible with our implementation of
-     * atomic create+open; so, even if we could ignore this
-     * fuzz here, we don't do, for the sake of consistency.
-     */
     err = fuse_vget_i(mp, curthread, feo->nodeid, vtyp, vpp,
                       VG_FORCENEW, VTOI(dvp));
-
     if (err) {
-        DEBUG2G("failed to fetch vnode for nodeid\n");
         fuse_internal_forget_send(mp, curthread, NULL, feo->nodeid, 1, fdip);
         return err;
     }
 
-    VTOFUD(*vpp)->nlookup++;
     cache_attrs(*vpp, feo);
 
 out:
@@ -577,7 +591,7 @@
     struct fuse_dispatcher fdi;
 
     fdisp_init(&fdi, 0);
-    fuse_internal_newentry_makerequest(dvp->v_mount, VTOI(dvp), cnp,
+    fuse_internal_newentry_makerequest(vnode_mount(dvp), VTOI(dvp), cnp,
 	                               op, buf, bufsize, &fdi);
     err = fuse_internal_newentry_core(dvp, vpp, vtyp, &fdi);
     fuse_invalidate_attr(dvp);
@@ -587,51 +601,19 @@
 
 /* entity destruction */
 
-static void
-fuse_internal_forget_send_pid(struct mount *mp,
-                          pid_t pid,
-                          struct ucred *cred,
-                          uint64_t nodeid,
-                          uint64_t nlookup,
-                          struct fuse_dispatcher *fdip)
-{
-    struct fuse_forget_in *ffi;
-
-    KASSERT(nlookup > 0, ("zero-times forget for vp #%llu",
-            (long long unsigned) nodeid));
-
-    DEBUG("sending FORGET with %llu lookups\n", (unsigned long long)nlookup);
-
-    fdisp_init(fdip, sizeof(*ffi));
-    fdisp_make_pid(fdip, mp, FUSE_FORGET, nodeid, pid, cred);
-
-    ffi = fdip->indata;
-    ffi->nlookup = nlookup;
-
-    fticket_disown(fdip->tick);
-    fuse_insert_message(fdip->tick);
-}
-
 int
-fuse_internal_forget_callback(struct fuse_ticket *tick,
-                              struct uio *uio)
+fuse_internal_forget_callback(struct fuse_ticket *tick, struct uio *uio)
 {
     struct fuse_dispatcher fdi;
-    struct fuse_pidcred *pidcred;
 
-    /*
-     * XXX I think I'm right to send a forget regardless of possible
-     * errors, but...
-     */
+    debug_printf("tick=%p, uio=%p\n", tick, uio);
 
     fdi.tick = tick;
-    pidcred = tick->tk_aw_handler_parm.base;
+    fuse_internal_forget_send(tick->tk_data->mp, curthread, NULL,
+                     ((struct fuse_in_header *)tick->tk_ms_fiov.base)->nodeid,
+                     1, &fdi);
 
-    fuse_internal_forget_send_pid(tick->tk_data->mp, pidcred->pid, &pidcred->cred,
-               ((struct fuse_in_header *)tick->tk_ms_fiov.base)->nodeid,
-               1, &fdi);
-
-    return (0);
+    return 0;
 }
 
 void
@@ -642,9 +624,24 @@
                           uint64_t nlookup,
                           struct fuse_dispatcher *fdip)
 {
-    RECTIFY_TDCR(td, cred);
-    return (fuse_internal_forget_send_pid(mp, td->td_proc->p_pid, cred, nodeid,
-                                   nlookup, fdip));
+    struct fuse_forget_in *ffi;
+
+    debug_printf("mp=%p, nodeid=%llx, nlookup=%lld, fdip=%p\n",
+                 mp, nodeid, nlookup, fdip);
+
+    /*
+     * KASSERT(nlookup > 0, ("zero-times forget for vp #%llu",
+     *         (long long unsigned) nodeid));
+     */
+
+    fdisp_init(fdip, sizeof(*ffi));
+    fdisp_make(fdip, mp, FUSE_FORGET, nodeid, td, cred);
+
+    ffi = fdip->indata;
+    ffi->nlookup = nlookup;
+
+    fticket_invalidate(fdip->tick);
+    fuse_insert_message(fdip->tick);
 }
 
 /* fuse start/stop */
@@ -654,11 +651,7 @@
 {
     int err = 0;
     struct fuse_data     *data = tick->tk_data;
-#if FUSE_KERNELABI_GEQ(7, 5)
     struct fuse_init_out *fiio;
-#else
-    struct fuse_init_in_out *fiio;
-#endif
 
     if ((err = tick->tk_aw_ohead.error)) {
         goto out;
@@ -670,9 +663,9 @@
 
     fiio = fticket_resp(tick)->base;
 
-    /* XXX is the following check adequate? */
+    /* XXX: Do we want to check anything further besides this? */
     if (fiio->major < 7) {
-        DEBUG2G("userpace version too low\n");
+        debug_printf("userpace version too low\n");
         err = EPROTONOSUPPORT;
         goto out;
     }
@@ -680,14 +673,12 @@
     data->fuse_libabi_major = fiio->major;
     data->fuse_libabi_minor = fiio->minor;
 
-    if (FUSE_KERNELABI_GEQ(7, 5) && fuse_libabi_geq(data, 7, 5)) {
-#if FUSE_KERNELABI_GEQ(7, 5)
+    if (fuse_libabi_geq(data, 7, 5)) {
         if (fticket_resp(tick)->len == sizeof(struct fuse_init_out)) {
             data->max_write = fiio->max_write;
         } else {
             err = EINVAL;
         }
-#endif
     } else {
         /* Old fix values */
         data->max_write = 4096;
@@ -711,11 +702,7 @@
 void
 fuse_internal_send_init(struct fuse_data *data, struct thread *td)
 {
-#if FUSE_KERNELABI_GEQ(7, 5)
     struct fuse_init_in   *fiii;
-#else
-    struct fuse_init_in_out *fiii;
-#endif
     struct fuse_dispatcher fdi;
 
     fdisp_init(&fdi, sizeof(*fiii));
@@ -723,6 +710,8 @@
     fiii = fdi.indata;
     fiii->major = FUSE_KERNEL_VERSION;
     fiii->minor = FUSE_KERNEL_MINOR_VERSION;
+    fiii->max_readahead = FUSE_DEFAULT_IOSIZE * 16;
+    fiii->flags = 0;
 
     fuse_insert_callback(fdi.tick, fuse_internal_init_callback);
     fuse_insert_message(fdi.tick);

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_internal.h#7 (text+ko) ====

@@ -51,26 +51,26 @@
 }
 
 /* XXX */
+void cluster_push(struct vnode *vp, int a);
+
 struct fuse_pidcred {
-	pid_t pid;
-	struct ucred cred;
+    pid_t pid;
+    struct ucred cred;
 };
 
 /* access */
 
-#define FACCESS_VA_VALID   0x01 /* flag to sign to reuse cached attributes
-                                   regardless of cache timeout */
-#define FACCESS_DO_ACCESS  0x02 /* flag showing if we are to do access check */
-#define FACCESS_STICKY     0x04 /* do sticky dir permission check */
-#define FACCESS_CHOWN      0x08 /* do permission check for owner changing */
-#define FACCESS_NOCHECKSPY 0x10 /* don't check if daemon is allowed to spy on
-                                   user */
-#define FACCESS_SETGID     0x12 /* do permission check for setting setgid flag */
+#define FVP_ACCESS_NOOP   0x01
+
+#define FACCESS_VA_VALID   0x01
+#define FACCESS_DO_ACCESS  0x02
+#define FACCESS_STICKY     0x04
+#define FACCESS_CHOWN      0x08
+#define FACCESS_NOCHECKSPY 0x10
+#define FACCESS_SETGID     0x12
 
 #define FACCESS_XQUERIES FACCESS_STICKY | FACCESS_CHOWN | FACCESS_SETGID
 
-#define FVP_ACCESS_NOOP   0x01 /* vnode based control flag for doing access check */
-
 struct fuse_access_param {
     uid_t xuid;
     gid_t xgid;
@@ -142,12 +142,19 @@
                                                                                \
     timespecadd(&VTOFUD(vp)->cached_attrs_valid, &uptsp_ ## __func__);         \
                                                                                \
-    fuse_internal_attr_fat2vat((vp)->v_mount, &(fuse_out)->attr, VTOVA(vp));   \
+    fuse_internal_attr_fat2vat(vnode_mount(vp), &(fuse_out)->attr, VTOVA(vp)); \
 } while (0)
 
 /* fsync */
 
 int
+fuse_internal_fsync(struct vnode           *vp,
+                    struct thread          *td,
+                    struct ucred           *cred,
+                    struct fuse_filehandle *fufh,
+                    void                   *param);
+
+int
 fuse_internal_fsync_callback(struct fuse_ticket *tick, struct uio *uio);
 
 /* readdir */
@@ -157,6 +164,14 @@
 };
 
 int
+fuse_internal_readdir(struct vnode           *vp,
+                      struct uio             *uio,
+                      struct thread          *td,
+                      struct ucred           *cred,
+                      struct fuse_filehandle *fufh,
+                      struct fuse_iov        *cookediov);
+
+int
 fuse_internal_readdir_processdata(struct uio *uio,
                                   size_t reqsize,
                                   void *buf,
@@ -252,4 +267,27 @@
 int fuse_internal_init_callback(struct fuse_ticket *tick, struct uio *uio);
 void fuse_internal_send_init(struct fuse_data *data, struct thread *td);
 
+/* miscellaneous */
+
+#define fuse_isdeadfs_nop(vp) 0
+
+static __inline__
+int
+fuse_isdeadfs(struct vnode *vp)
+{
+    struct mount *mp = vnode_mount(vp);
+    struct fuse_data *data = fusefs_get_data(mp);
+
+    return (data->dataflag & FSESS_KICK);
+}
+
+static __inline__
+int
+fuse_isdeadfs_mp(struct mount *mp)
+{
+    struct fuse_data *data = fusefs_get_data(mp);
+
+    return (data->dataflag & FSESS_KICK);
+}
+
 #endif /* _FUSE_INTERNAL_H_ */

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.h#3 (text+ko) ====

@@ -41,8 +41,7 @@
                 fp->f_vnode->v_type == VBAD ||
                 fp->f_vnode->v_op == &dead_vnodeops ||
                 fp->f_vnode->v_data == NULL ||
-                fp->f_data == NULL ||
-                FTOFH(fp)->fh_vp->v_type == VBAD);
+                fp->f_data == NULL);
 }
 
 /*

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_ipc.c#3 (text+ko) ====

@@ -3,10 +3,6 @@
  * Amit Singh <singh@>
  */
 
-/*
- * Messaging related routines.
- */
-
 #include "config.h"
 
 #include <sys/types.h>
@@ -30,26 +26,27 @@
 #include "fuse.h"
 #include "fuse_node.h"
 #include "fuse_ipc.h"
+#include "fuse_internal.h"
 
 static struct fuse_ticket *fticket_alloc(struct fuse_data *data);
 static void                fticket_refresh(struct fuse_ticket *tick);
 static void                fticket_destroy(struct fuse_ticket *tick);
 static int                 fticket_wait_answer(struct fuse_ticket *tick);
-static __inline int        fticket_aw_pull_uio(struct fuse_ticket *tick,
-				                     struct uio *uio);
-static __inline void       fuse_push_freeticks(struct fuse_ticket *tick);
-static __inline
-struct fuse_ticket        *fuse_pop_freeticks(struct fuse_data *data);
-static __inline void       fuse_push_allticks(struct fuse_ticket *tick);
-static __inline void       fuse_remove_allticks(struct fuse_ticket *tick);
+static __inline__ int  fticket_aw_pull_uio(struct fuse_ticket *tick, struct uio *uio);
+static __inline__ void fuse_push_freeticks(struct fuse_ticket *tick);
+
+static __inline__ struct fuse_ticket *
+fuse_pop_freeticks(struct fuse_data *data);
+
+static __inline__ void     fuse_push_allticks(struct fuse_ticket *tick);
+static __inline__ void     fuse_remove_allticks(struct fuse_ticket *tick);
 static struct fuse_ticket *fuse_pop_allticks(struct fuse_data *data);
 
-static int                 fuse_body_audit(struct fuse_ticket *tick, size_t blen);
-static __inline void       fuse_setup_ihead(struct fuse_in_header *ihead,
-                                             struct fuse_ticket *tick, uint64_t nid,
-                                             enum fuse_opcode op, size_t blen,
-                                             pid_t pid, struct ucred *cred);
-
+static int             fuse_body_audit(struct fuse_ticket *tick, size_t blen);
+static __inline__ void fuse_setup_ihead(struct fuse_in_header *ihead,
+                                        struct fuse_ticket *tick, uint64_t nid,
+                                        enum fuse_opcode op, size_t blen,
+                                        pid_t pid, struct ucred *cred);
 static fuse_handler_t      fuse_standard_handler;
 
 SYSCTL_NODE(_vfs, OID_AUTO, fuse, CTLFLAG_RW, 0, "FUSE tunables");
@@ -73,14 +70,6 @@
 MALLOC_DEFINE(M_FUSEMSG, "fuse_messaging",
               "buffer for fuse messaging related things");
 
-/***************************************
- *
- * >>> Interface ("methods") of messaging related objects
- *
- ***************************************/
-
-/* fuse_iov methods ==> */
-
 void
 fiov_init(struct fuse_iov *fiov, size_t size)
 {
@@ -112,6 +101,9 @@
 
         fiov->base = realloc(fiov->base, FU_AT_LEAST(size), M_FUSEMSG,
                              M_WAITOK | M_ZERO);
+        if (!fiov->base) {
+            panic("FUSE: realloc failed");
+        }
 
         fiov->allocated_size = FU_AT_LEAST(size);
         fiov->credit = fuse_iov_credit;
@@ -168,6 +160,7 @@
 
     tick = malloc(sizeof(*tick), M_FUSEMSG, M_WAITOK | M_ZERO);
 
+    tick->tk_unique = data->ticketer++;
     tick->tk_data = data;
 
     fiov_init(&tick->tk_ms_fiov, sizeof(struct fuse_in_header));
@@ -175,7 +168,6 @@
 
     mtx_init(&tick->tk_aw_mtx, "fuse answer delivery mutex", NULL, MTX_DEF);
     fiov_init(&tick->tk_aw_fiov, 0);
-    fiov_init(&tick->tk_aw_handler_parm, 0);
     tick->tk_aw_type = FT_A_FIOV;
 
     return (tick);
@@ -192,8 +184,8 @@
     tick->tk_ms_type = FT_M_FIOV;
 
     bzero(&tick->tk_aw_ohead, sizeof(struct fuse_out_header));
+
     fiov_refresh(&tick->tk_aw_fiov);
-    fiov_adjust(&tick->tk_aw_handler_parm, 0);
     tick->tk_aw_errno = 0;
     tick->tk_aw_bufdata = NULL;
     tick->tk_aw_bufsize = 0;
@@ -212,7 +204,6 @@
 
     mtx_destroy(&tick->tk_aw_mtx);
     fiov_teardown(&tick->tk_aw_fiov);
-    fiov_teardown(&tick->tk_aw_handler_parm);
 
     free(tick, M_FUSEMSG);
 }
@@ -241,14 +232,6 @@
     mtx_unlock(&tick->tk_aw_mtx);
 
     if (!(err || fticket_answered(tick))) {
-        /*
-         * Some deadlocky scenarios can get us here, like SIGKILLing
-         * the fusexmp daemon after a fuse dir has been null mounted
-         * over its original copy in the "normal" fs
-         *
-         * (I guess there is no need of kicking the daemon at this
-         * point...)
-         */
         debug_printf("fuse requester was woken up but still no answer");
         err = ENXIO;
     }
@@ -260,11 +243,10 @@
 fticket_aw_pull_uio(struct fuse_ticket *tick, struct uio *uio)
 {
     int err = 0;
-    size_t len = uio->uio_resid;
+    size_t len = uio_resid(uio);
 
     debug_printf("tick=%p, uio=%p\n", tick, uio);
 
-
     if (len) {
         switch (tick->tk_aw_type) {
         case FT_A_FIOV:
@@ -304,7 +286,7 @@
         return (0);
     }
 
-    err = fuse_body_audit(tick, uio->uio_resid);

>>> TRUNCATED FOR MAIL (1000 lines) <<<



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201106071058.p57AwPrj053241>