FS-Cache: Simplify cookie retention for fscache_objects, fixing oops
[platform/adaptation/renesas_rcar/renesas_kernel.git] / fs / fscache / page.c
index b4e4b42..780bac6 100644 (file)
@@ -163,10 +163,12 @@ static void fscache_attr_changed_op(struct fscache_operation *op)
 
        fscache_stat(&fscache_n_attr_changed_calls);
 
-       if (fscache_object_is_active(object)) {
+       if (fscache_object_is_active(object) &&
+           fscache_use_cookie(object)) {
                fscache_stat(&fscache_n_cop_attr_changed);
                ret = object->cache->ops->attr_changed(object);
                fscache_stat_d(&fscache_n_cop_attr_changed);
+               fscache_unuse_cookie(object);
                if (ret < 0)
                        fscache_abort_object(object);
        }
@@ -246,6 +248,7 @@ static void fscache_release_retrieval_op(struct fscache_operation *_op)
  * allocate a retrieval op
  */
 static struct fscache_retrieval *fscache_alloc_retrieval(
+       struct fscache_cookie *cookie,
        struct address_space *mapping,
        fscache_rw_complete_t end_io_func,
        void *context)
@@ -260,7 +263,10 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
        }
 
        fscache_operation_init(&op->op, NULL, fscache_release_retrieval_op);
-       op->op.flags    = FSCACHE_OP_MYTHREAD | (1 << FSCACHE_OP_WAITING);
+       atomic_inc(&cookie->n_active);
+       op->op.flags    = FSCACHE_OP_MYTHREAD |
+               (1UL << FSCACHE_OP_WAITING) |
+               (1UL << FSCACHE_OP_UNUSE_COOKIE);
        op->mapping     = mapping;
        op->end_io_func = end_io_func;
        op->context     = context;
@@ -394,7 +400,8 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
        if (fscache_wait_for_deferred_lookup(cookie) < 0)
                return -ERESTARTSYS;
 
-       op = fscache_alloc_retrieval(page->mapping, end_io_func, context);
+       op = fscache_alloc_retrieval(cookie, page->mapping,
+                                    end_io_func,context);
        if (!op) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
@@ -465,6 +472,7 @@ nobufs_unlock_dec:
        atomic_dec(&object->n_reads);
 nobufs_unlock:
        spin_unlock(&cookie->lock);
+       atomic_dec(&cookie->n_active);
        kfree(op);
 nobufs:
        fscache_stat(&fscache_n_retrievals_nobufs);
@@ -522,7 +530,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
        if (fscache_wait_for_deferred_lookup(cookie) < 0)
                return -ERESTARTSYS;
 
-       op = fscache_alloc_retrieval(mapping, end_io_func, context);
+       op = fscache_alloc_retrieval(cookie, mapping, end_io_func, context);
        if (!op)
                return -ENOMEM;
        op->n_pages = *nr_pages;
@@ -589,6 +597,7 @@ nobufs_unlock_dec:
        atomic_dec(&object->n_reads);
 nobufs_unlock:
        spin_unlock(&cookie->lock);
+       atomic_dec(&cookie->n_active);
        kfree(op);
 nobufs:
        fscache_stat(&fscache_n_retrievals_nobufs);
@@ -631,7 +640,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
        if (fscache_wait_for_deferred_lookup(cookie) < 0)
                return -ERESTARTSYS;
 
-       op = fscache_alloc_retrieval(page->mapping, NULL, NULL);
+       op = fscache_alloc_retrieval(cookie, page->mapping, NULL, NULL);
        if (!op)
                return -ENOMEM;
        op->n_pages = 1;
@@ -675,6 +684,7 @@ error:
 
 nobufs_unlock:
        spin_unlock(&cookie->lock);
+       atomic_dec(&cookie->n_active);
        kfree(op);
 nobufs:
        fscache_stat(&fscache_n_allocs_nobufs);
@@ -876,7 +886,9 @@ int __fscache_write_page(struct fscache_cookie *cookie,
 
        fscache_operation_init(&op->op, fscache_write_op,
                               fscache_release_write_op);
-       op->op.flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_WAITING);
+       op->op.flags = FSCACHE_OP_ASYNC |
+               (1 << FSCACHE_OP_WAITING) |
+               (1 << FSCACHE_OP_UNUSE_COOKIE);
 
        ret = radix_tree_preload(gfp & ~__GFP_HIGHMEM);
        if (ret < 0)
@@ -922,6 +934,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        op->op.debug_id = atomic_inc_return(&fscache_op_debug_id);
        op->store_limit = object->store_limit;
 
+       atomic_inc(&cookie->n_active);
        if (fscache_submit_op(object, &op->op) < 0)
                goto submit_failed;
 
@@ -948,6 +961,7 @@ already_pending:
        return 0;
 
 submit_failed:
+       atomic_dec(&cookie->n_active);
        spin_lock(&cookie->stores_lock);
        radix_tree_delete(&cookie->stores, page->index);
        spin_unlock(&cookie->stores_lock);