Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Jun 2011 09:52:21 GMT
From:      Ilya Putsikau <ilya@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 195353 for review
Message-ID:  <201106260952.p5Q9qLij012557@skunkworks.freebsd.org>

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

Change 195353 by ilya@ilya_triton2011 on 2011/06/26 09:51:38

	Filehandle rewrite. Don't try to count opened filehandles, perform close
	in vop_inactive.
	
	Remove unused flags and structure members. Use sx lock and condvar to
	serialize creation.
	
	Add fuse_vnode_open to initialize vnode after open
	
	Assert at least one handle is opened in vnop_close
	
	Add enum fuse_op_waitfor
	Partial merge http://macfuse.googlecode.com/svn/trunk@549

Affected files ...

.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse.h#10 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.c#6 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.h#4 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.c#12 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.c#8 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#10 edit
.. //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#26 edit

Differences ...

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse.h#10 (text+ko) ====

@@ -178,3 +178,8 @@
     DEBUGX(FUSE_DEBUG_LOCK, "1: unlock(%s): %s@%d by %d\n",             \
         __STRING(mtx), __func__, __LINE__, curthread->td_proc->p_pid);  \
     } while (0)
+
+typedef enum fuse_op_waitfor {
+    FUSE_OP_BACKGROUNDED = 0,
+    FUSE_OP_FOREGROUNDED = 1,
+} fuse_op_waitfor_t;

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_file.c#6 (text+ko) ====

@@ -37,33 +37,35 @@
             &fuse_fh_upcall_count, 0, "");
 
 int
-fuse_filehandle_get(struct vnode *vp,
-                    struct thread *td,
-                    struct ucred *cred,
-                    fufh_type_t fufh_type)
+fuse_filehandle_open(struct vnode *vp,
+                     fufh_type_t fufh_type,
+                     struct fuse_filehandle **fufhp,
+                     struct thread *td,
+                     struct ucred *cred)
 {
     struct fuse_dispatcher  fdi;
     struct fuse_open_in    *foi;
     struct fuse_open_out   *foo;
-    struct fuse_filehandle *fufh;
-    struct fuse_vnode_data *fvdat = VTOFUD(vp);
 
     int err    = 0;
     int isdir  = 0;
-    int oflags = fuse_filehandle_xlate_to_oflags(fufh_type);
+    int oflags = 0;
     int op     = FUSE_OPEN;
 
     fuse_trace_printf("fuse_filehandle_get(vp=%p, fufh_type=%d)\n",
                       vp, fufh_type);
 
-    fufh = &(fvdat->fufh[fufh_type]);
-
-    if (fufh->fufh_flags & FUFH_VALID) {
-        printf("FUSE: filehandle_get called despite valid fufh (type=%d)",
+    if (fuse_filehandle_valid(vp, fufh_type)) {
+        panic("FUSE: filehandle_get called despite valid fufh (type=%d)",
               fufh_type);
-        return 0;
+        /* NOTREACHED */
     }
 
+    /*
+     * Note that this means we are effectively FILTERING OUT open() flags.
+     */
+    oflags = fuse_filehandle_xlate_to_oflags(fufh_type);
+
     if (vnode_isdir(vp)) {
         isdir = 1;
         op = FUSE_OPENDIR;
@@ -87,12 +89,8 @@
 
     foo = fdi.answ;
 
-    fufh->fh_id = foo->fh;
-    fufh->fufh_flags |= (0 | FUFH_VALID);
-    fufh->open_count = 1;
-    fufh->open_flags = oflags;
-    fufh->fuse_open_flags = foo->open_flags;
-    fufh->type = fufh_type;
+    fuse_filehandle_init(vp, fufh_type, fufhp, foo->fh);
+    fuse_vnode_open(vp, foo->open_flags, td);
     
     fuse_ticket_drop(fdi.tick);
 
@@ -100,8 +98,11 @@
 }
 
 int
-fuse_filehandle_put(struct vnode *vp, struct thread *td, struct ucred *cred, fufh_type_t fufh_type,
-                    int foregrounded)
+fuse_filehandle_close(struct vnode *vp,
+                      fufh_type_t fufh_type,
+                      struct thread *td,
+                      struct ucred *cred,
+                      fuse_op_waitfor_t waitfor)
 {
     struct fuse_dispatcher  fdi;
     struct fuse_release_in *fri;
@@ -116,21 +117,12 @@
                       vp, fufh_type);
 
     fufh = &(fvdat->fufh[fufh_type]);
-    if (!(fufh->fufh_flags & FUFH_VALID)) {
-        printf("trying to put invalid filehandle?\n");
-        return 0;
-    }
-
-    if (fufh->open_count != 0) {
-        panic("FUSE: filehandle_put called on a valid fufh (type=%d)",
+    if (!FUFH_IS_VALID(fufh)) {
+        panic("FUSE: filehandle_put called on invalid fufh (type=%d)",
               fufh_type);
         /* NOTREACHED */
     }
 
-    if (fufh->fufh_flags & FUFH_MAPPED) {
-        panic("trying to put mapped fufh\n");
-    }
-
     if (vnode_isdir(vp)) {
         op = FUSE_RELEASEDIR;
         isdir = 1;
@@ -140,9 +132,9 @@
     fdisp_make_vp(&fdi, op, vp, td, cred);
     fri = fdi.indata;
     fri->fh = fufh->fh_id;
-    fri->flags = fufh->open_flags;
+    fri->flags = fuse_filehandle_xlate_to_oflags(fufh_type);
 
-    if (foregrounded) {
+    if (waitfor == FUSE_OP_FOREGROUNDED) {
         if ((err = fdisp_wait_answ(&fdi))) {
             goto out;
         } else {
@@ -154,7 +146,71 @@
     }
 
 out:
-    fufh->fufh_flags &= ~FUFH_VALID;
+    fufh->fh_id = (uint64_t)-1;
+    fufh->fh_type = FUFH_INVALID;
 
     return err;
 }
+
+int
+fuse_filehandle_valid(struct vnode *vp, fufh_type_t fufh_type)
+{
+    struct fuse_vnode_data *fvdat = VTOFUD(vp);
+    struct fuse_filehandle *fufh;
+
+    fufh = &(fvdat->fufh[fufh_type]);
+    return FUFH_IS_VALID(fufh);
+}
+
+int
+fuse_filehandle_get(struct vnode *vp, fufh_type_t fufh_type,
+    struct fuse_filehandle **fufhp)
+{
+    struct fuse_vnode_data *fvdat = VTOFUD(vp);
+    struct fuse_filehandle *fufh;
+
+    fufh = &(fvdat->fufh[fufh_type]);
+    if (!FUFH_IS_VALID(fufh)) {
+        printf("FUSE: filehandle is not valid (type=%d)\n", fufh_type);
+	return EBADF;
+    }
+    if (fufhp != NULL)
+        *fufhp = fufh;
+    return 0;
+}
+
+int
+fuse_filehandle_getrw(struct vnode *vp, fufh_type_t fufh_type,
+    struct fuse_filehandle **fufhp)
+{
+    struct fuse_vnode_data *fvdat = VTOFUD(vp);
+    struct fuse_filehandle *fufh;
+
+    fufh = &(fvdat->fufh[fufh_type]);
+    if (!FUFH_IS_VALID(fufh)) {
+        fufh_type = FUFH_RDWR;
+    }
+    return fuse_filehandle_get(vp, fufh_type, fufhp);
+}
+
+void
+fuse_filehandle_init(struct vnode *vp,
+                     fufh_type_t fufh_type,
+		     struct fuse_filehandle **fufhp,
+                     uint64_t fh_id)
+{
+    struct fuse_vnode_data *fvdat = VTOFUD(vp);
+    struct fuse_filehandle *fufh;
+
+    DEBUG("id=%jd type=%d\n", (intmax_t)fh_id, fufh_type);
+    fufh = &(fvdat->fufh[fufh_type]);
+    MPASS(!FUFH_IS_VALID(fufh));
+    fufh->fh_id = fh_id;
+    fufh->fh_type = fufh_type;
+    if (!FUFH_IS_VALID(fufh)) {
+        panic("FUSE: init: invalid filehandle id (type=%d)", fufh_type);
+    }
+
+    if (fufhp != NULL)
+        *fufhp = fufh;
+}

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

@@ -20,19 +20,12 @@
     FUFH_MAXTYPE = 3,
 } fufh_type_t;
 
-#define FUFH_VALID    0x00000001
-#define FUFH_MAPPED   0x00000002
-#define FUFH_STRATEGY 0x00000004
-
 struct fuse_filehandle {
     uint64_t fh_id;
-    int      open_count;
-    int      open_flags;
-    int      fuse_open_flags;
-    fufh_type_t type;
-    int      fufh_flags;
+    fufh_type_t fh_type;
 };
-typedef struct fuse_filehandle * fuse_filehandle_t;
+
+#define FUFH_IS_VALID(f)  ((f)->fh_type != FUFH_INVALID)
 
 static __inline__
 fufh_type_t
@@ -91,9 +84,19 @@
     return oflags;
 }
 
-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);
+int fuse_filehandle_valid(struct vnode *vp, fufh_type_t fufh_type);
+int fuse_filehandle_get(struct vnode *vp, fufh_type_t fufh_type,
+                        struct fuse_filehandle **fufhp);
+int fuse_filehandle_getrw(struct vnode *vp, fufh_type_t fufh_type,
+                          struct fuse_filehandle **fufhp);
+
+void fuse_filehandle_init(struct vnode *vp, fufh_type_t fufh_type,
+		          struct fuse_filehandle **fufhp, uint64_t fh_id);
+int fuse_filehandle_open(struct vnode *vp, fufh_type_t fufh_type,
+                         struct fuse_filehandle **fufhp, struct thread *td,
+                         struct ucred *cred);
+int fuse_filehandle_close(struct vnode *vp, fufh_type_t fufh_type,
+                          struct thread *td, struct ucred *cred,
+                          fuse_op_waitfor_t waitfor);
 
 #endif /* _FUSE_FILE_H_ */

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_io.c#12 (text+ko) ====

@@ -52,52 +52,6 @@
 
 static fuse_buffeater_t fuse_std_buffeater; 
 
-static int
-fuse_io_filehandle_get(struct vnode *vp, int rdonly,
-    struct ucred *cred, struct fuse_filehandle **fufhp)
-{
-    struct fuse_vnode_data *fvdat = VTOFUD(vp);
-    struct fuse_filehandle *fufh;
-    fufh_type_t fufh_type;
-    int err = 0;
-
-    if (rdonly) {
-        fufh_type = FUFH_RDONLY; // FUFH_RDWR will also do
-    } else {
-        fufh_type = FUFH_WRONLY; // FUFH_RDWR will also do
-    }
-
-    fufh = &(fvdat->fufh[fufh_type]);
-    if (!(fufh->fufh_flags & FUFH_VALID)) {
-        fufh_type = FUFH_RDWR;
-        fufh = &(fvdat->fufh[fufh_type]);
-        if (!(fufh->fufh_flags & FUFH_VALID)) {
-            fufh = NULL;
-        } else {
-            debug_printf("strategy falling back to FUFH_RDWR ... OK\n");
-        }
-    }
-
-    if (fufh == NULL) {
-        if (rdonly) {
-            fufh_type = FUFH_RDONLY;
-        } else {
-            fufh_type = FUFH_RDWR;
-        }
-        err = fuse_filehandle_get(vp, NULL, cred, fufh_type);
-        if (!err) {
-            fufh = &(fvdat->fufh[fufh_type]);
-            debug_printf("STRATEGY: created *new* fufh of type %d\n",
-                fufh_type);
-        }
-    } else {
-        debug_printf("STRATEGY: using existing fufh of type %d\n", fufh_type);
-    }
-
-    *fufhp = fufh;
-    return (err);
-}
-
 /****************
  *
  * >>> Low level I/O routines and interface to them
@@ -113,10 +67,12 @@
     struct fuse_io_data fioda;
     int err, directio;
 
-    err = fuse_io_filehandle_get(vp, (uio->uio_rw == UIO_READ),
-        cred, &fufh);
-    if (err)
-        return (err);
+    err = fuse_filehandle_getrw(vp,
+        (uio->uio_rw == UIO_READ) ? FUFH_RDONLY : FUFH_WRONLY, &fufh);
+    if (err) {
+        DEBUG("fetching filehandle failed\n");
+        return err;
+    }
 
     bzero(&fioda, sizeof(fioda));
     fioda.vp = vp;
@@ -780,13 +736,12 @@
 
     cred = bp->b_iocmd == BIO_READ ? bp->b_rcred : bp->b_wcred;
 
-    err = fuse_io_filehandle_get(vp, (bp->b_iocmd == BIO_READ),
-        cred, &fufh);
+    err = fuse_filehandle_getrw(vp,
+	(bp->b_iocmd == BIO_READ) ? FUFH_RDONLY : FUFH_WRONLY, &fufh);
     if (err) {
-        DEBUG2G("fetching filehandle failed\n");
+        DEBUG("fetching filehandle failed\n");
         goto out;
     }
-    fufh->fufh_flags |= FUFH_STRATEGY;
 
     DEBUG2G("vp #%ju, fufh #%ju\n",
 	(uintmax_t)VTOILLU(vp), (uintmax_t)fufh->fh_id);

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.c#8 (text+ko) ====

@@ -43,16 +43,22 @@
 fuse_vnode_init(struct vnode *vp, struct fuse_vnode_data *fvdat,
     uint64_t nodeid, enum vtype vtyp)
 {
+    int i;
+
     fvdat->nid = nodeid;
     if (nodeid == FUSE_ROOT_ID) {
         vp->v_vflag |= VV_ROOT;
     }
     vp->v_type = vtyp;
     vp->v_data = fvdat;
-    fvdat->creator = curthread->td_tid;
-    mtx_init(&fvdat->createlock, "fuse node create mutex", NULL, MTX_DEF);
+    fvdat->create_owner = curthread->td_tid;
+    cv_init(&fvdat->create_cv, "fuse node create cv");
+    sx_init(&fvdat->create_lock, "fuse node create lock");
     sx_init(&fvdat->nodelock, "fuse node sx lock");
     sx_init(&fvdat->truncatelock, "fuse node truncate sx lock");
+
+    for (i = 0; i < FUFH_MAXTYPE; i++)
+        fvdat->fufh[i].fh_type = FUFH_INVALID;
 }
 
 void
@@ -61,7 +67,8 @@
     struct fuse_vnode_data *fvdat = vp->v_data;
 
     vp->v_data = NULL;
-    mtx_destroy(&fvdat->createlock);
+    cv_destroy(&fvdat->create_cv);
+    sx_destroy(&fvdat->create_lock);
     sx_destroy(&fvdat->nodelock);
     sx_destroy(&fvdat->truncatelock);
     free(fvdat, M_FUSEVN);
@@ -176,3 +183,19 @@
 
     return 0;
 }
+
+void
+fuse_vnode_open(struct vnode *vp, int32_t fuse_open_flags, struct thread *td)
+{
+    /*
+     * Funcation is called for every vnode open.
+     * Merge fuse_open_flags it may be 0
+     *
+     * XXXIP: Handle FOPEN_DIRECT_IO and FOPEN_KEEP_CACHE
+     */
+
+    if (vnode_vtype(vp) == VREG) {
+        /* XXXIP prevent getattr, by using cached node size */
+        vnode_create_vobject(vp, 0, td);
+    }
+}

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_node.h#10 (text+ko) ====

@@ -40,8 +40,9 @@
 
     /** locking **/
 
-    struct mtx createlock;
-    lwpid_t    creator;
+    struct sx  create_lock;
+    struct cv  create_cv;
+    lwpid_t    create_owner;
 
     /*
      * The nodelock must be held when data in the FUSE node is accessed or
@@ -116,4 +117,8 @@
                enum vtype            vtyp,
                uint64_t              size);
 
+void fuse_vnode_open(struct vnode *vp,
+                     int32_t fuse_open_flags,
+                     struct thread *td);
+
 #endif /* _FUSE_NODE_H_ */

==== //depot/projects/soc2011/ilya_fuse/fuse_module/fuse_vnops.c#26 (text+ko) ====

@@ -184,9 +184,6 @@
     int isdir = (vnode_isdir(vp)) ? 1 : 0;
     fufh_type_t fufh_type;
 
-    struct fuse_vnode_data *fvdat = VTOFUD(vp);
-    struct fuse_filehandle *fufh = NULL;
-
     fuse_trace_printf_vnop();
 
     if (fuse_isdeadfs_nop(vp)) {
@@ -199,16 +196,14 @@
         fufh_type = fuse_filehandle_xlate_from_fflags(fflag);
     }
 
-    fufh = &(fvdat->fufh[fufh_type]);
-
-    if (!(fufh->fufh_flags & FUFH_VALID)) {
-        panic("fufh type %d found to be invalid in close\n", fufh_type);
-    }
-
-    fufh->open_count--;
-
-    if ((fufh->open_count == 0) && !(fufh->fufh_flags & FUFH_MAPPED)) {
-        (void)fuse_filehandle_put(vp, NULL, NULL, fufh_type, 0);
+    if (!fuse_filehandle_valid(vp, fufh_type)) {
+        int i;
+        for (i = 0; i < FUFH_MAXTYPE; i++)
+            if (fuse_filehandle_valid(vp, i))
+                break;
+        if (i == FUFH_MAXTYPE)
+            panic("FUSE: fufh type %d found to be invalid in close (fflag=0x%x)\n",
+                fufh_type, fflag);
     }
 
     return 0;
@@ -334,29 +329,16 @@
        return err;
     }
 
+    ASSERT_VOP_ELOCKED(*vpp, "fuse_vnop_create");
+
     fdip->answ = gone_good_old ? NULL : feo + 1;
 
     if (!gone_good_old) {
-
         uint64_t x_fh_id = ((struct fuse_open_out *)(feo + 1))->fh;
         uint32_t x_open_flags = ((struct fuse_open_out *)(feo + 1))->open_flags;
-        struct fuse_vnode_data *fvdat = VTOFUD(*vpp);
-        struct fuse_filehandle *fufh = &(fvdat->fufh[FUFH_RDWR]);
 
-        fufh->fh_id = x_fh_id;
-        fufh->open_flags = x_open_flags;
-
-#if 0
-        struct fuse_dispatcher x_fdi;
-        struct fuse_release_in *x_fri;
-        fdisp_init(&x_fdi, sizeof(*x_fri));
-        fdisp_make_vp(&x_fdi, FUSE_RELEASE, *vpp, context);
-        x_fri = x_fdi.indata;
-        x_fri->fh = x_fh_id;
-        x_fri->flags = O_WRONLY;
-        fuse_insert_callback(x_fdi.tick, NULL);
-        fuse_insert_message(x_fdi.tick);
-#endif
+	fuse_filehandle_init(*vpp, FUFH_RDWR, NULL, x_fh_id);
+	fuse_vnode_open(*vpp, x_open_flags, td);
     }
 
     return 0;
@@ -415,7 +397,7 @@
     fdisp_init(&fdi, 0);
     for (type = 0; type < FUFH_MAXTYPE; type++) {
         fufh = &(fvdat->fufh[type]);
-        if (fufh->fufh_flags & FUFH_VALID) {
+        if (FUFH_IS_VALID(fufh)) {
             fuse_internal_fsync(vp, td, NULL, fufh, &fdi);
         }
     }
@@ -549,10 +531,8 @@
 
     for (type = 0; type < FUFH_MAXTYPE; type++) {
         fufh = &(fvdat->fufh[type]);
-        if (fufh->fufh_flags & FUFH_VALID) {
-            fufh->fufh_flags &= ~FUFH_MAPPED;
-            fufh->open_count = 0;
-            (void)fuse_filehandle_put(vp, td, NULL, type, 0);
+        if (FUFH_IS_VALID(fufh)) {
+            fuse_filehandle_close(vp, type, td, NULL, FUSE_OP_BACKGROUNDED);
         }
     }
 
@@ -1122,10 +1102,8 @@
 
     fufh_type_t             fufh_type;
     struct fuse_vnode_data *fvdat;
-    struct fuse_filehandle *fufh = NULL;
-    struct fuse_filehandle *fufh_rw = NULL;
 
-    int error, isdir = 0, oflags;
+    int error, isdir = 0;
 
     fuse_trace_printf_vnop();
 
@@ -1145,103 +1123,44 @@
         fufh_type = fuse_filehandle_xlate_from_fflags(mode);
     }
 
-    oflags = fuse_filehandle_xlate_to_oflags(fufh_type);
-
-    fufh = &(fvdat->fufh[fufh_type]);
-
     if (!isdir && (fvdat->flag & FN_CREATING)) {
 
-        fuse_lck_mtx_lock(fvdat->createlock);
+        sx_xlock(&fvdat->create_lock);
 
         if (fvdat->flag & FN_CREATING) { // check again
-            if (fvdat->creator == curthread->td_tid) {
-
-                /*
-                 * For testing the race condition we want to prevent here,
-                 * try something like the following:
-                 *
-                 *     int dummyctr = 0;
-                 *
-                 *     for (; dummyctr < 2048000000; dummyctr++);
-                 */
-
-                fufh_rw = &(fvdat->fufh[FUFH_RDWR]);
-
-                fufh->fufh_flags |= FUFH_VALID;
-                fufh->fufh_flags &= ~FUFH_MAPPED;
-                fufh->open_count = 1;
-                fufh->open_flags = oflags;
-                fufh->type = fufh_type;
-
-                fufh->fh_id = fufh_rw->fh_id;
-                fufh->open_flags = fufh_rw->open_flags;
-                debug_printf("creator picked up stashed handle, moved to %d\n",
-                             fufh_type);
-                
+            if (fvdat->create_owner == curthread->td_tid) {
+                fufh_type = FUFH_RDWR;
+                MPASS(fuse_filehandle_valid(vp, fufh_type));
                 fvdat->flag &= ~FN_CREATING;
-
-                fuse_lck_mtx_unlock(fvdat->createlock);
-                wakeup((caddr_t)&fvdat->creator); // wake up all
-                goto ok; /* return 0 */
+                sx_xunlock(&fvdat->create_lock);
+                cv_broadcast(&fvdat->create_cv); // wake up all
+                return 0;
             } else {
                 debug_printf("contender going to sleep\n");
-                error = msleep(&fvdat->creator, &fvdat->createlock,
-                               PDROP | PINOD | PCATCH, "fuse_open", 0);
-                /*
-                 * msleep will drop the mutex. since we have PDROP specified,
-                 * it will NOT regrab the mutex when it returns.
-                 */
+                error = cv_wait_sig(&fvdat->create_cv, &fvdat->create_lock);
                 debug_printf("contender awake (error = %d)\n", error);
-
                 if (error) {
                     /*
-                     * Since we specified PCATCH above, we'll be woken up in
-                     * case a signal arrives. The value of error could be
-                     * EINTR or ERESTART.
+                     * We'll be woken up in case a signal arrives.
+                     * The value of error could be EINTR or ERESTART.
                      */
                     return error;
                 }
             }
         } else {
-            fuse_lck_mtx_unlock(fvdat->createlock);
+            sx_xunlock(&fvdat->create_lock);
             /* Can proceed from here. */
         }
     }
 
-    if (fufh->fufh_flags & FUFH_VALID) {
-        fufh->open_count++;
-        goto ok; /* return 0 */
+    if (fuse_filehandle_valid(vp, fufh_type)) {
+        fuse_vnode_open(vp, 0, td);
+        return 0;
     }
 
-    error = fuse_filehandle_get(vp, td, cred, fufh_type);
-    if (error) {
-        return error;
-    }
+    error = fuse_filehandle_open(vp, fufh_type, NULL, td, cred);
 
-ok:
-    if (vnode_vtype(vp) == VREG) {
-        /* XXXIP prevent getattr, by using cached node size */
-        vnode_create_vobject(vp, 0, td);
-    }
-
-    /*
-     * Doing this here because when a vnode goes inactive, things like
-     * no-cache and no-readahead are cleared by the kernel.
-     */
-
-    {
-#ifdef XXXIP
-        int dataflags = fuse_get_mpdata(vnode_mount(vp))->dataflags;
-        if (dataflags & FSESS_NO_READAHEAD) {
-            vnode_setnoreadahead(vp);
-        }
-        if (dataflags & FSESS_NO_UBC) {
-            vnode_setnocache(vp);
-        }
-#endif
-    }
-
-    return 0;
+    return error;
 }
 
 /*
@@ -1306,14 +1225,15 @@
 
     fvdat = VTOFUD(vp);
 
-    fufh = &(fvdat->fufh[FUFH_RDONLY]);
-
-    if (!(fufh->fufh_flags & FUFH_VALID)) {
-        err = fuse_filehandle_get(vp, NULL, cred, FUFH_RDONLY);
-        if (err) {
-            return err;
-        }
-        freefufh = 1;
+    if (!fuse_filehandle_valid(vp, FUFH_RDONLY)) {
+	    DEBUG("calling readdir() before open()");
+	    err = fuse_filehandle_open(vp, FUFH_RDONLY, &fufh, NULL, cred);
+	    freefufh = 1;
+    } else {
+	    err = fuse_filehandle_get(vp, FUFH_RDONLY, &fufh);
+    }
+    if (err) {
+	    return (err);
     }
 
 #define DIRCOOKEDSIZE FUSE_DIRENT_ALIGN(FUSE_NAME_OFFSET + MAXNAMLEN + 1)
@@ -1323,8 +1243,8 @@
 
     fiov_teardown(&cookediov);
     if (freefufh) {
-        fufh->open_count--;
-        (void)fuse_filehandle_put(vp, NULL, NULL, FUFH_RDONLY, 0);
+        fuse_filehandle_close(vp, FUFH_RDONLY, NULL, cred,
+            FUSE_OP_FOREGROUNDED);
     }
 
     fuse_invalidate_attr(vp);
@@ -1404,15 +1324,10 @@
 
     for (type = 0; type < FUFH_MAXTYPE; type++) {
         fufh = &(fvdat->fufh[type]);
-        if (fufh->fufh_flags & FUFH_VALID) {
-            if (fufh->fufh_flags & FUFH_STRATEGY) {
-                fufh->fufh_flags &= ~FUFH_MAPPED;
-                fufh->open_count = 0;
-                (void)fuse_filehandle_put(vp, td, NULL, type, 0);
-            } else {
-                panic("vnode being reclaimed but fufh (type=%d) is valid",
-                      type);
-            }
+        if (FUFH_IS_VALID(fufh)) {
+            printf("FUSE: vnode being reclaimed but fufh (type=%d) is valid",
+                type);
+            fuse_filehandle_close(vp, type, td, NULL, FUSE_OP_BACKGROUNDED);
         }
     }
 
@@ -1636,8 +1551,6 @@
     if (vap->va_size != VNOVAL) {
 
         struct fuse_filehandle *fufh = NULL;
-        fufh_type_t fufh_type = FUFH_WRONLY;
-        struct fuse_vnode_data *fvdat = VTOFUD(vp);
 
         // Truncate to a new value.
         fsai->FUSEATTR(size) = vap->va_size;
@@ -1645,15 +1558,7 @@
         newsize = vap->va_size;
         fsai->valid |= FATTR_SIZE;      
 
-        fufh = &(fvdat->fufh[fufh_type]);
-        if (!(fufh->fufh_flags & FUFH_VALID)) {
-            fufh_type = FUFH_RDWR;
-            fufh = &(fvdat->fufh[fufh_type]);
-            if (!(fufh->fufh_flags & FUFH_VALID)) {
-                fufh = NULL;
-            }
-        }
-
+        fuse_filehandle_getrw(vp, FUFH_WRONLY, &fufh);
         if (fufh) {
             fsai->fh = fufh->fh_id;
             fsai->valid |= FATTR_FH;



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