PERFORCE change 195353 for review
Ilya Putsikau
ilya at FreeBSD.org
Sun Jun 26 09:52:22 UTC 2011
http://p4web.freebsd.org/@@195353?ac=10
Change 195353 by ilya at 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;
More information about the p4-projects
mailing list