diff options
Diffstat (limited to 'fs/fscache/page.c')
| -rw-r--r-- | fs/fscache/page.c | 65 | 
1 files changed, 44 insertions, 21 deletions
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index 73899c1c344..ed70714503f 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c @@ -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; @@ -1083,10 +1108,8 @@ void fscache_mark_page_cached(struct fscache_retrieval *op, struct page *page)  		static bool once_only;  		if (!once_only) {  			once_only = true; -			printk(KERN_WARNING "FS-Cache:" -			       " Cookie type %s marked page %lx" -			       " multiple times\n", -			       cookie->def->name, page->index); +			pr_warn("Cookie type %s marked page %lx multiple times\n", +				cookie->def->name, page->index);  		}  	}  | 
