]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - fs/fscache/page.c
arm: imx6: defconfig: update tx6 defconfigs
[karo-tx-linux.git] / fs / fscache / page.c
index 73899c1c34494555d73dd5714ecb21eb74c0296d..7f5c658af755f9b43296c1dacfab5def788c4a1c 100644 (file)
@@ -163,12 +163,10 @@ static void fscache_attr_changed_op(struct fscache_operation *op)
 
        fscache_stat(&fscache_n_attr_changed_calls);
 
-       if (fscache_object_is_active(object) &&
-           fscache_use_cookie(object)) {
+       if (fscache_object_is_active(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);
        }
@@ -184,6 +182,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
 {
        struct fscache_operation *op;
        struct fscache_object *object;
+       bool wake_cookie;
 
        _enter("%p", cookie);
 
@@ -199,15 +198,19 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
        }
 
        fscache_operation_init(op, fscache_attr_changed_op, NULL);
-       op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE);
+       op->flags = FSCACHE_OP_ASYNC |
+               (1 << FSCACHE_OP_EXCLUSIVE) |
+               (1 << FSCACHE_OP_UNUSE_COOKIE);
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
+       __fscache_use_cookie(cookie);
        if (fscache_submit_exclusive_op(object, op) < 0)
                goto nobufs;
        spin_unlock(&cookie->lock);
@@ -217,8 +220,11 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
        return 0;
 
 nobufs:
+       wake_cookie = __fscache_unuse_cookie(cookie);
        spin_unlock(&cookie->lock);
        kfree(op);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
        fscache_stat(&fscache_n_attr_changed_nobufs);
        _leave(" = %d", -ENOBUFS);
        return -ENOBUFS;
@@ -263,7 +269,6 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
        }
 
        fscache_operation_init(&op->op, NULL, fscache_release_retrieval_op);
-       atomic_inc(&cookie->n_active);
        op->op.flags    = FSCACHE_OP_MYTHREAD |
                (1UL << FSCACHE_OP_WAITING) |
                (1UL << FSCACHE_OP_UNUSE_COOKIE);
@@ -384,6 +389,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 {
        struct fscache_retrieval *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,%p,,,", cookie, page);
@@ -405,7 +411,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
                return -ERESTARTSYS;
 
        op = fscache_alloc_retrieval(cookie, page->mapping,
-                                    end_io_func,context);
+                                    end_io_func, context);
        if (!op) {
                _leave(" = -ENOMEM");
                return -ENOMEM;
@@ -414,13 +420,15 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs_unlock;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
        ASSERT(test_bit(FSCACHE_OBJECT_IS_LOOKED_UP, &object->flags));
 
+       __fscache_use_cookie(cookie);
        atomic_inc(&object->n_reads);
        __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
 
@@ -475,9 +483,11 @@ error:
 
 nobufs_unlock_dec:
        atomic_dec(&object->n_reads);
+       wake_cookie = __fscache_unuse_cookie(cookie);
 nobufs_unlock:
        spin_unlock(&cookie->lock);
-       atomic_dec(&cookie->n_active);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
        kfree(op);
 nobufs:
        fscache_stat(&fscache_n_retrievals_nobufs);
@@ -514,6 +524,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
 {
        struct fscache_retrieval *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,,%d,,,", cookie, *nr_pages);
@@ -542,11 +553,13 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs_unlock;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
+       __fscache_use_cookie(cookie);
        atomic_inc(&object->n_reads);
        __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
 
@@ -601,10 +614,12 @@ error:
 
 nobufs_unlock_dec:
        atomic_dec(&object->n_reads);
+       wake_cookie = __fscache_unuse_cookie(cookie);
 nobufs_unlock:
        spin_unlock(&cookie->lock);
-       atomic_dec(&cookie->n_active);
        kfree(op);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
 nobufs:
        fscache_stat(&fscache_n_retrievals_nobufs);
        _leave(" = -ENOBUFS");
@@ -626,6 +641,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
 {
        struct fscache_retrieval *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,%p,,,", cookie, page);
@@ -653,13 +669,15 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
 
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs_unlock;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
 
+       __fscache_use_cookie(cookie);
        if (fscache_submit_op(object, &op->op) < 0)
-               goto nobufs_unlock;
+               goto nobufs_unlock_dec;
        spin_unlock(&cookie->lock);
 
        fscache_stat(&fscache_n_alloc_ops);
@@ -689,10 +707,13 @@ error:
        _leave(" = %d", ret);
        return ret;
 
+nobufs_unlock_dec:
+       wake_cookie = __fscache_unuse_cookie(cookie);
 nobufs_unlock:
        spin_unlock(&cookie->lock);
-       atomic_dec(&cookie->n_active);
        kfree(op);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
 nobufs:
        fscache_stat(&fscache_n_allocs_nobufs);
        _leave(" = -ENOBUFS");
@@ -889,6 +910,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
 {
        struct fscache_storage *op;
        struct fscache_object *object;
+       bool wake_cookie = false;
        int ret;
 
        _enter("%p,%x,", cookie, (u32) page->flags);
@@ -920,7 +942,8 @@ int __fscache_write_page(struct fscache_cookie *cookie,
        ret = -ENOBUFS;
        spin_lock(&cookie->lock);
 
-       if (hlist_empty(&cookie->backing_objects))
+       if (!fscache_cookie_enabled(cookie) ||
+           hlist_empty(&cookie->backing_objects))
                goto nobufs;
        object = hlist_entry(cookie->backing_objects.first,
                             struct fscache_object, cookie_link);
@@ -957,7 +980,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);
+       __fscache_use_cookie(cookie);
        if (fscache_submit_op(object, &op->op) < 0)
                goto submit_failed;
 
@@ -984,10 +1007,10 @@ 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);
+       wake_cookie = __fscache_unuse_cookie(cookie);
        page_cache_release(page);
        ret = -ENOBUFS;
        goto nobufs;
@@ -999,6 +1022,8 @@ nobufs:
        spin_unlock(&cookie->lock);
        radix_tree_preload_end();
        kfree(op);
+       if (wake_cookie)
+               __fscache_wake_unused_cookie(cookie);
        fscache_stat(&fscache_n_stores_nobufs);
        _leave(" = -ENOBUFS");
        return -ENOBUFS;