diff options
author | Jean-Pierre André <jpandre@users.sourceforge.net> | 2013-06-23 11:56:01 +0200 |
---|---|---|
committer | Jean-Pierre André <jpandre@users.sourceforge.net> | 2013-06-23 11:56:01 +0200 |
commit | 8eaabb6f6ee90fba52632cf92521e56540d76cb0 (patch) | |
tree | 5b5fbbb790685b1060ce24a789acd09742610d69 | |
parent | 671532be7af3692b24b2d415e04efb316cb06cc2 (diff) | |
download | illumos-fusefs-8eaabb6f6ee90fba52632cf92521e56540d76cb0.tar.gz |
Kept track of mapped files and released them accordingly
-rw-r--r-- | kernel/fuse_vnops.c | 28 |
1 files changed, 26 insertions, 2 deletions
diff --git a/kernel/fuse_vnops.c b/kernel/fuse_vnops.c index 68dc0e4..3a40703 100644 --- a/kernel/fuse_vnops.c +++ b/kernel/fuse_vnops.c @@ -4047,14 +4047,28 @@ fuse_addmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, size_t len, uchar_t prot, uchar_t maxprot, uint_t flags, cred_t *cr, caller_context_t *ct) { + long oldcnt; + int err = 0; + struct fuse_file_handle *fhp; + if (vp->v_flag & VNOMAP) return (ENOSYS); mutex_enter(&VTOFD(vp)->f_lock); + oldcnt = VTOFD(vp)->f_mapcnt; VTOFD(vp)->f_mapcnt += btopr(len); mutex_exit(&VTOFD(vp)->f_lock); + if (!oldcnt) { + /* + * Increment the reference count on the vnode, so that + * the data associated will not be freed on close() + * and kept available for subsequent getapage(). + */ + err = get_filehandle(vp, FREAD | FWRITE, cr, &fhp, + CACHE_LIST_CHECK); + } - return (0); + return (err); } /* ARGSUSED */ @@ -4063,6 +4077,8 @@ fuse_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, size_t len, uint_t prot, uint_t maxprot, uint_t flags, cred_t *cr, caller_context_t *ct) { + int err = 0; + if (vp->v_flag & VNOMAP) return (ENOSYS); @@ -4074,7 +4090,15 @@ fuse_delmap(vnode_t *vp, offset_t off, struct as *as, caddr_t addr, vn_has_cached_data(vp)) (void) VOP_PUTPAGE(vp, off, len, B_ASYNC, cr, ct); - return (0); + /* + * If there is no more reference to the vnode, we can + * now release the data which may have been delayed + * by incrementing the reference count in addmap(). + */ + if (!VTOFD(vp)->f_mapcnt) + err = fuse_close(vp, flags | FREAD | FWRITE, 1, 0, cr, ct); + + return (err); } static void |