summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Pierre André <jpandre@users.sourceforge.net>2013-06-23 11:54:53 +0200
committerJean-Pierre André <jpandre@users.sourceforge.net>2013-06-23 11:54:53 +0200
commit671532be7af3692b24b2d415e04efb316cb06cc2 (patch)
treea7242cf5f3a4806f88de7bbc1d8574c30fd3ca43
parent88c04cb7fd357179e7214d264abc89142da04a9d (diff)
downloadillumos-fusefs-671532be7af3692b24b2d415e04efb316cb06cc2.tar.gz
Fixed sending a release for multiply closed files
-rw-r--r--kernel/fuse_vnops.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/kernel/fuse_vnops.c b/kernel/fuse_vnops.c
index 402b5b5..68dc0e4 100644
--- a/kernel/fuse_vnops.c
+++ b/kernel/fuse_vnops.c
@@ -928,9 +928,17 @@ static int fuse_close(struct vnode *vp, int flags, int count,
err = 0;
goto cleanup;
}
-
- fhp->ref--;
- if (fhp->ref == 1) {
+ /*
+ * As we have made a new reference in get_filehandle(),
+ * we have to decrement by 2 for a real close().
+ * However there may be several close() for a single open(),
+ * so when the count argument is not 1, this is not the
+ * last close(), and we should only decrement by 1.
+ * There are no known multiple close() for a directory,
+ * though the count may be 2 (happens on a "rm -f")
+ */
+ fhp->ref -= ((count > 1) && (vp->v_type != VDIR) ? 1 : 2);
+ if (fhp->ref <= 0) {
/* Remove it from the list */
DTRACE_PROBE2(fuse_close_info_release,
char *, "releasing file handle",
@@ -944,8 +952,8 @@ static int fuse_close(struct vnode *vp, int flags, int count,
kmem_free(fhp, sizeof (*fhp));
}
/*
- * If the file is not open any more (is this the same as having
- * a ref count of 1 above ?), check whether deleting the file
+ * If the file is not open any more (is this the same as getting
+ * a ref count of 0 above ?), check whether deleting the file
* has been requested while it was open.
* If so, release the file so that it becomes inactive and
* can be deleted.