diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/cachefiles/daemon.c | 19 | ||||
-rw-r--r-- | fs/cachefiles/internal.h | 3 | ||||
-rw-r--r-- | fs/cachefiles/ondemand.c | 3 |
3 files changed, 22 insertions, 3 deletions
diff --git a/fs/cachefiles/daemon.c b/fs/cachefiles/daemon.c index d5417da7f792..5b1d0642c749 100644 --- a/fs/cachefiles/daemon.c +++ b/fs/cachefiles/daemon.c @@ -111,6 +111,7 @@ static int cachefiles_daemon_open(struct inode *inode, struct file *file) INIT_LIST_HEAD(&cache->volumes); INIT_LIST_HEAD(&cache->object_list); spin_lock_init(&cache->object_list_lock); + refcount_set(&cache->unbind_pincount, 1); xa_init_flags(&cache->reqs, XA_FLAGS_ALLOC); xa_init_flags(&cache->ondemand_ids, XA_FLAGS_ALLOC1); @@ -164,6 +165,20 @@ static void cachefiles_flush_reqs(struct cachefiles_cache *cache) xa_destroy(&cache->ondemand_ids); } +void cachefiles_put_unbind_pincount(struct cachefiles_cache *cache) +{ + if (refcount_dec_and_test(&cache->unbind_pincount)) { + cachefiles_daemon_unbind(cache); + cachefiles_open = 0; + kfree(cache); + } +} + +void cachefiles_get_unbind_pincount(struct cachefiles_cache *cache) +{ + refcount_inc(&cache->unbind_pincount); +} + /* * Release a cache. */ @@ -179,14 +194,12 @@ static int cachefiles_daemon_release(struct inode *inode, struct file *file) if (cachefiles_in_ondemand_mode(cache)) cachefiles_flush_reqs(cache); - cachefiles_daemon_unbind(cache); /* clean up the control file interface */ cache->cachefilesd = NULL; file->private_data = NULL; - cachefiles_open = 0; - kfree(cache); + cachefiles_put_unbind_pincount(cache); _leave(""); return 0; diff --git a/fs/cachefiles/internal.h b/fs/cachefiles/internal.h index 4f5150a96849..e5c612888f84 100644 --- a/fs/cachefiles/internal.h +++ b/fs/cachefiles/internal.h @@ -109,6 +109,7 @@ struct cachefiles_cache { char *rootdirname; /* name of cache root directory */ char *secctx; /* LSM security context */ char *tag; /* cache binding tag */ + refcount_t unbind_pincount;/* refcount to do daemon unbind */ struct xarray reqs; /* xarray of pending on-demand requests */ struct xarray ondemand_ids; /* xarray for ondemand_id allocation */ u32 ondemand_id_next; @@ -171,6 +172,8 @@ extern int cachefiles_has_space(struct cachefiles_cache *cache, * daemon.c */ extern const struct file_operations cachefiles_daemon_fops; +extern void cachefiles_get_unbind_pincount(struct cachefiles_cache *cache); +extern void cachefiles_put_unbind_pincount(struct cachefiles_cache *cache); /* * error_inject.c diff --git a/fs/cachefiles/ondemand.c b/fs/cachefiles/ondemand.c index 64fc312b16d3..7946ee6c40be 100644 --- a/fs/cachefiles/ondemand.c +++ b/fs/cachefiles/ondemand.c @@ -14,6 +14,7 @@ static int cachefiles_ondemand_fd_release(struct inode *inode, object->ondemand_id = CACHEFILES_ONDEMAND_ID_CLOSED; xa_erase(&cache->ondemand_ids, object_id); cachefiles_put_object(object, cachefiles_obj_put_ondemand_fd); + cachefiles_put_unbind_pincount(cache); return 0; } @@ -169,6 +170,8 @@ static int cachefiles_ondemand_get_fd(struct cachefiles_req *req) load->fd = fd; req->msg.object_id = object_id; object->ondemand_id = object_id; + + cachefiles_get_unbind_pincount(cache); return 0; err_put_fd: |